From 4207f9c279e832e3afcb3f5fc6cd8d84cb4cfe4c Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sat, 28 Mar 2015 01:43:35 +0100 Subject: Bump OculusVR RIFT SDK to 0.5.0.1 --- 3rdParty/glext/GL/glext.h | 11081 ------------------- 3rdParty/glext/GL/wglext.h | 929 -- LibOVR/Include/Extras/OVR_Math.h | 3663 ++++++ LibOVR/Include/OVR.h | 12 +- LibOVR/Include/OVR_CAPI.h | 4 + LibOVR/Include/OVR_CAPI_0_5_0.h | 1178 ++ LibOVR/Include/OVR_CAPI_GL.h | 87 + LibOVR/Include/OVR_CAPI_Keys.h | 56 + LibOVR/Include/OVR_CAPI_Util.h | 79 + LibOVR/Include/OVR_ErrorCode.h | 66 + LibOVR/Include/OVR_Kernel.h | 30 +- LibOVR/Include/OVR_Version.h | 55 +- LibOVR/Projects/Mac/LibOVRRT.plist | 28 + .../Mac/LibOVRRT.xcodeproj/project.pbxproj | 793 ++ .../project.xcworkspace/contents.xcworkspacedata | 7 + .../xcshareddata/xcschemes/LibOVRRT.xcscheme | 100 + .../LibOVRRT.xcworkspace/contents.xcworkspacedata | 10 + .../Mac/Xcode/LibOVR.xcodeproj/project.pbxproj | 839 -- .../project.xcworkspace/contents.xcworkspacedata | 7 - LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj | 489 - .../Projects/Win32/VS2010/LibOVR.vcxproj.filters | 500 - LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj | 497 - .../Projects/Win32/VS2012/LibOVR.vcxproj.filters | 506 - LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj | 500 - .../Projects/Win32/VS2013/LibOVR.vcxproj.filters | 512 - LibOVR/Projects/Windows/VS2013/LibOVRRT.sln | 57 + LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj | 456 + .../Windows/VS2013/LibOVRRT.vcxproj.filters | 346 + LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp | 61 +- LibOVR/Src/CAPI/CAPI_DistortionRenderer.h | 76 +- LibOVR/Src/CAPI/CAPI_DistortionTiming.cpp | 620 ++ LibOVR/Src/CAPI/CAPI_DistortionTiming.h | 395 + LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.cpp | 253 + LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.h | 151 + LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp | 946 -- LibOVR/Src/CAPI/CAPI_FrameTimeManager.h | 327 - LibOVR/Src/CAPI/CAPI_FrameTimeManager3.cpp | 517 + LibOVR/Src/CAPI/CAPI_FrameTimeManager3.h | 228 + LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp | 36 +- LibOVR/Src/CAPI/CAPI_HMDRenderState.h | 12 +- LibOVR/Src/CAPI/CAPI_HMDState.cpp | 780 +- LibOVR/Src/CAPI/CAPI_HMDState.h | 134 +- LibOVR/Src/CAPI/CAPI_HSWDisplay.cpp | 67 +- LibOVR/Src/CAPI/CAPI_HSWDisplay.h | 21 +- LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp | 316 - LibOVR/Src/CAPI/CAPI_LatencyStatistics.h | 178 - .../CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp | 29 - .../Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h | 34 - LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp | 35 - LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h | 41 - .../CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp | 1707 ++- .../Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h | 240 +- LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp | 567 +- LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h | 113 +- LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.cpp | 758 ++ LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.h | 500 + .../CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp | 1414 --- .../Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h | 202 - LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp | 595 - LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h | 84 - LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp | 533 - LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h | 572 - LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h | 887 -- .../Src/CAPI/D3D1X/Shaders/DistortionCS2x2_refl.h | 16 - .../Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.h | 256 - .../Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.psh | 29 +- .../CAPI/D3D1X/Shaders/DistortionChroma_ps_refl.h | 9 - .../Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.h | 101 - .../CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h | 9 - .../D3D1X/Shaders/DistortionTimewarpChroma_vs.h | 214 - .../D3D1X/Shaders/DistortionTimewarpChroma_vs.vsh | 70 +- .../Shaders/DistortionTimewarpChroma_vs_refl.h | 11 - .../Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.h | 167 - .../CAPI/D3D1X/Shaders/DistortionTimewarp_vs.vsh | 63 - .../D3D1X/Shaders/DistortionTimewarp_vs_refl.h | 11 - LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.h | 65 - LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h | 1 - LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.h | 82 - LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.vsh | 41 - LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs_refl.h | 9 - LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.h | 51 - LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h | 8 - LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.h | 64 - LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h | 9 - .../Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.h | 77 - .../D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h | 8 - .../Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.h | 82 - .../D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h | 9 - .../CAPI/D3D1X/Shaders/genComputeShaderHeader.bat | 5 +- .../CAPI/D3D1X/Shaders/genPixelShaderHeader.bat | 7 +- .../CAPI/D3D1X/Shaders/genVertexShaderHeader.bat | 7 +- .../Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp | 845 +- .../Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h | 279 +- LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp | 855 +- LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h | 158 +- LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp | 559 +- LibOVR/Src/CAPI/GL/CAPI_GLE.cpp | 7884 ------------- LibOVR/Src/CAPI/GL/CAPI_GLE.h | 2003 ---- LibOVR/Src/CAPI/GL/CAPI_GLE_GL.h | 4761 -------- LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp | 253 +- LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h | 26 +- LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h | 99 - LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp | 45 +- LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp | 116 +- LibOVR/Src/CAPI/GL/CAPI_GL_Util.h | 37 +- LibOVR/Src/CAPI/Textures/healthAndSafety.tga | Bin 0 -> 107525 bytes LibOVR/Src/CAPI/Textures/overdriveLut_dk2.h | 8194 ++++++++++++++ LibOVR/Src/CAPI/Textures/overdriveLut_dk2_2.h | 8194 ++++++++++++++ LibOVR/Src/Displays/OVR_Display.cpp | 252 + LibOVR/Src/Displays/OVR_Display.h | 85 +- LibOVR/Src/Displays/OVR_Linux_Display.cpp | 163 +- LibOVR/Src/Displays/OVR_Linux_Display.h | 27 +- LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp | 5 +- LibOVR/Src/Displays/OVR_Linux_SDKWindow.h | 4 +- LibOVR/Src/Displays/OVR_OSX_Display.cpp | 60 +- LibOVR/Src/Displays/OVR_OSX_Display.h | 5 +- LibOVR/Src/Displays/OVR_OSX_FocusObserver.h | 75 - LibOVR/Src/Displays/OVR_OSX_FocusObserver.mm | 245 - LibOVR/Src/Displays/OVR_OSX_FocusReader.h | 45 - LibOVR/Src/Displays/OVR_OSX_FocusReader.mm | 75 - LibOVR/Src/Displays/OVR_Win32_Display.cpp | 2043 ++-- LibOVR/Src/Displays/OVR_Win32_Display.h | 335 +- LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h | 873 +- LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp | 158 +- LibOVR/Src/Displays/OVR_Win32_FocusReader.h | 162 +- LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp | 1965 ++-- LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp | 477 +- LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h | 158 +- LibOVR/Src/Displays/OVR_Win32_ShimVersion.h | 94 +- LibOVR/Src/Kernel/OVR_Alg.cpp | 57 - LibOVR/Src/Kernel/OVR_Alg.h | 1062 -- LibOVR/Src/Kernel/OVR_Allocator.cpp | 141 - LibOVR/Src/Kernel/OVR_Allocator.h | 360 - LibOVR/Src/Kernel/OVR_Array.h | 837 -- LibOVR/Src/Kernel/OVR_Atomic.cpp | 139 - LibOVR/Src/Kernel/OVR_Atomic.h | 915 -- LibOVR/Src/Kernel/OVR_CRC32.cpp | 85 - LibOVR/Src/Kernel/OVR_CRC32.h | 45 - LibOVR/Src/Kernel/OVR_Color.h | 73 - LibOVR/Src/Kernel/OVR_Compiler.h | 1524 --- LibOVR/Src/Kernel/OVR_ContainerAllocator.h | 267 - LibOVR/Src/Kernel/OVR_DebugHelp.cpp | 3926 ------- LibOVR/Src/Kernel/OVR_DebugHelp.h | 461 - LibOVR/Src/Kernel/OVR_Delegates.h | 541 - LibOVR/Src/Kernel/OVR_Deque.h | 316 - LibOVR/Src/Kernel/OVR_File.cpp | 585 - LibOVR/Src/Kernel/OVR_File.h | 530 - LibOVR/Src/Kernel/OVR_FileFILE.cpp | 609 - LibOVR/Src/Kernel/OVR_Hash.h | 1305 --- LibOVR/Src/Kernel/OVR_KeyCodes.h | 251 - LibOVR/Src/Kernel/OVR_List.h | 342 - LibOVR/Src/Kernel/OVR_Lockless.cpp | 225 - LibOVR/Src/Kernel/OVR_Lockless.h | 117 - LibOVR/Src/Kernel/OVR_Log.cpp | 432 - LibOVR/Src/Kernel/OVR_Log.h | 227 - LibOVR/Src/Kernel/OVR_Math.cpp | 58 - LibOVR/Src/Kernel/OVR_Math.h | 2791 ----- LibOVR/Src/Kernel/OVR_Nullptr.h | 150 - LibOVR/Src/Kernel/OVR_Observer.h | 457 - LibOVR/Src/Kernel/OVR_RefCount.cpp | 111 - LibOVR/Src/Kernel/OVR_RefCount.h | 565 - LibOVR/Src/Kernel/OVR_SharedMemory.cpp | 691 -- LibOVR/Src/Kernel/OVR_SharedMemory.h | 240 - LibOVR/Src/Kernel/OVR_Std.cpp | 1097 -- LibOVR/Src/Kernel/OVR_Std.h | 638 -- LibOVR/Src/Kernel/OVR_String.cpp | 779 -- LibOVR/Src/Kernel/OVR_String.h | 658 -- LibOVR/Src/Kernel/OVR_StringHash.h | 100 - LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp | 76 - LibOVR/Src/Kernel/OVR_String_PathUtil.cpp | 211 - LibOVR/Src/Kernel/OVR_SysFile.cpp | 138 - LibOVR/Src/Kernel/OVR_SysFile.h | 104 - LibOVR/Src/Kernel/OVR_System.cpp | 149 - LibOVR/Src/Kernel/OVR_System.h | 174 - LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp | 401 - LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h | 318 - LibOVR/Src/Kernel/OVR_Threads.h | 434 - LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp | 984 -- LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp | 1146 -- LibOVR/Src/Kernel/OVR_Timer.cpp | 551 - LibOVR/Src/Kernel/OVR_Timer.h | 99 - LibOVR/Src/Kernel/OVR_Types.h | 909 -- LibOVR/Src/Kernel/OVR_UTF8Util.cpp | 556 - LibOVR/Src/Kernel/OVR_UTF8Util.h | 99 - LibOVR/Src/Kernel/OVR_mach_exc_OSX.c | 2955 ----- LibOVR/Src/Kernel/OVR_mach_exc_OSX.h | 277 - LibOVR/Src/Net/OVR_BitStream.cpp | 25 +- LibOVR/Src/Net/OVR_BitStream.h | 17 +- LibOVR/Src/Net/OVR_NetworkTypes.h | 2 +- LibOVR/Src/Net/OVR_PacketizedTCPSocket.h | 4 +- LibOVR/Src/Net/OVR_RPC1.cpp | 16 +- LibOVR/Src/Net/OVR_RPC1.h | 15 +- LibOVR/Src/Net/OVR_Session.cpp | 455 +- LibOVR/Src/Net/OVR_Session.h | 309 +- LibOVR/Src/Net/OVR_Socket.h | 14 +- LibOVR/Src/Net/OVR_Unix_Socket.cpp | 18 +- LibOVR/Src/Net/OVR_Win32_Socket.cpp | 1226 +- LibOVR/Src/Net/OVR_Win32_Socket.h | 301 +- LibOVR/Src/OVR_CAPI.cpp | 1452 +-- LibOVR/Src/OVR_CAPI.h | 950 -- LibOVR/Src/OVR_CAPIShim.c | 1416 +++ LibOVR/Src/OVR_CAPI_D3D.h | 176 - LibOVR/Src/OVR_CAPI_GL.h | 76 - LibOVR/Src/OVR_CAPI_Keys.h | 56 - LibOVR/Src/OVR_CAPI_Util.cpp | 125 + LibOVR/Src/OVR_Error.h | 236 + LibOVR/Src/OVR_JSON.cpp | 1287 --- LibOVR/Src/OVR_JSON.h | 165 - LibOVR/Src/OVR_Linux_UDEV.cpp | 112 + LibOVR/Src/OVR_Linux_UDEV.h | 72 + LibOVR/Src/OVR_Profile.cpp | 49 +- LibOVR/Src/OVR_SerialFormat.cpp | 114 +- LibOVR/Src/OVR_SerialFormat.h | 7 +- LibOVR/Src/OVR_Stereo.cpp | 699 +- LibOVR/Src/OVR_Stereo.h | 278 +- LibOVR/Src/OVR_StereoProjection.cpp | 216 + LibOVR/Src/OVR_StereoProjection.h | 70 + LibOVR/Src/Resources/Windows/resource.h | 0 LibOVR/Src/Sensors/OVR_DeviceConstants.h | 18 +- LibOVR/Src/Service/Service_NetClient.cpp | 275 +- LibOVR/Src/Service/Service_NetClient.h | 54 +- LibOVR/Src/Service/Service_NetSessionCommon.cpp | 276 +- LibOVR/Src/Service/Service_NetSessionCommon.h | 53 +- .../Src/Service/Service_Win32_FastIPC_Client.cpp | 228 + LibOVR/Src/Service/Service_Win32_FastIPC_Client.h | 84 + LibOVR/Src/Tracking/Tracking_PoseState.h | 133 - LibOVR/Src/Tracking/Tracking_SensorState.h | 212 - LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp | 207 - LibOVR/Src/Tracking/Tracking_SensorStateReader.h | 87 - LibOVR/Src/Util/GUIConsole.h | 51 - LibOVR/Src/Util/Util_DataLogger.h | 168 + LibOVR/Src/Util/Util_ImageWindow.cpp | 574 - LibOVR/Src/Util/Util_ImageWindow.h | 204 - LibOVR/Src/Util/Util_Interface.h | 2 +- LibOVR/Src/Util/Util_LatencyTest2Reader.cpp | 4 +- LibOVR/Src/Util/Util_LatencyTest2Reader.h | 6 +- LibOVR/Src/Util/Util_LatencyTest2State.h | 17 +- LibOVR/Src/Util/Util_MatFile.cpp | 496 + LibOVR/Src/Util/Util_MatFile.h | 116 + LibOVR/Src/Util/Util_Render_Stereo.cpp | 81 +- LibOVR/Src/Util/Util_Render_Stereo.h | 22 +- LibOVR/Src/Util/Util_Stopwatch.h | 139 + LibOVR/Src/Util/Util_SystemGUI.cpp | 190 - LibOVR/Src/Util/Util_SystemGUI.h | 39 - LibOVR/Src/Util/Util_SystemGUI_OSX.mm | 69 - LibOVR/Src/Util/Util_SystemInfo.cpp | 289 - LibOVR/Src/Util/Util_SystemInfo.h | 51 - LibOVR/Src/Util/Util_SystemInfo_OSX.mm | 106 - .../Src/Vision/SensorFusion/Vision_SensorState.h | 161 + .../SensorFusion/Vision_SensorStateReader.cpp | 253 + .../Vision/SensorFusion/Vision_SensorStateReader.h | 121 + LibOVR/Src/Vision/Vision_Common.h | 299 + .../Mac/LibOVRKernel.xcodeproj/project.pbxproj | 792 ++ .../project.xcworkspace/contents.xcworkspacedata | 7 + LibOVRKernel/Src/GL/CAPI_GLE.cpp | 7894 +++++++++++++ LibOVRKernel/Src/GL/CAPI_GLE.h | 2016 ++++ LibOVRKernel/Src/GL/CAPI_GLE_GL.h | 4765 ++++++++ LibOVRKernel/Src/Kernel/OVR_Alg.cpp | 57 + LibOVRKernel/Src/Kernel/OVR_Alg.h | 1062 ++ LibOVRKernel/Src/Kernel/OVR_Allocator.cpp | 842 ++ LibOVRKernel/Src/Kernel/OVR_Allocator.h | 708 ++ LibOVRKernel/Src/Kernel/OVR_Array.h | 837 ++ LibOVRKernel/Src/Kernel/OVR_Atomic.cpp | 139 + LibOVRKernel/Src/Kernel/OVR_Atomic.h | 912 ++ LibOVRKernel/Src/Kernel/OVR_CRC32.cpp | 85 + LibOVRKernel/Src/Kernel/OVR_CRC32.h | 45 + LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp | 41 + LibOVRKernel/Src/Kernel/OVR_Callbacks.h | 320 + LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h | 331 + LibOVRKernel/Src/Kernel/OVR_Color.h | 73 + LibOVRKernel/Src/Kernel/OVR_Compiler.h | 1543 +++ LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h | 281 + LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp | 4101 +++++++ LibOVRKernel/Src/Kernel/OVR_DebugHelp.h | 510 + LibOVRKernel/Src/Kernel/OVR_Delegates.h | 541 + LibOVRKernel/Src/Kernel/OVR_Deque.h | 316 + LibOVRKernel/Src/Kernel/OVR_File.cpp | 585 + LibOVRKernel/Src/Kernel/OVR_File.h | 530 + LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp | 608 + LibOVRKernel/Src/Kernel/OVR_Hash.h | 1306 +++ LibOVRKernel/Src/Kernel/OVR_JSON.cpp | 1332 +++ LibOVRKernel/Src/Kernel/OVR_JSON.h | 171 + LibOVRKernel/Src/Kernel/OVR_KeyCodes.h | 255 + LibOVRKernel/Src/Kernel/OVR_List.h | 365 + LibOVRKernel/Src/Kernel/OVR_Lockless.cpp | 225 + LibOVRKernel/Src/Kernel/OVR_Lockless.h | 117 + LibOVRKernel/Src/Kernel/OVR_Log.cpp | 504 + LibOVRKernel/Src/Kernel/OVR_Log.h | 240 + LibOVRKernel/Src/Kernel/OVR_Nullptr.h | 150 + LibOVRKernel/Src/Kernel/OVR_Rand.cpp | 79 + LibOVRKernel/Src/Kernel/OVR_Rand.h | 201 + LibOVRKernel/Src/Kernel/OVR_RefCount.cpp | 105 + LibOVRKernel/Src/Kernel/OVR_RefCount.h | 512 + LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp | 742 ++ LibOVRKernel/Src/Kernel/OVR_SharedMemory.h | 254 + LibOVRKernel/Src/Kernel/OVR_Std.cpp | 1097 ++ LibOVRKernel/Src/Kernel/OVR_Std.h | 638 ++ LibOVRKernel/Src/Kernel/OVR_String.cpp | 779 ++ LibOVRKernel/Src/Kernel/OVR_String.h | 658 ++ LibOVRKernel/Src/Kernel/OVR_StringHash.h | 100 + LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp | 76 + LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp | 210 + LibOVRKernel/Src/Kernel/OVR_SysFile.cpp | 138 + LibOVRKernel/Src/Kernel/OVR_SysFile.h | 104 + LibOVRKernel/Src/Kernel/OVR_System.cpp | 148 + LibOVRKernel/Src/Kernel/OVR_System.h | 174 + LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.cpp | 405 + LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.h | 318 + LibOVRKernel/Src/Kernel/OVR_Threads.h | 437 + LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp | 1006 ++ LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp | 1150 ++ LibOVRKernel/Src/Kernel/OVR_Timer.cpp | 460 + LibOVRKernel/Src/Kernel/OVR_Timer.h | 98 + LibOVRKernel/Src/Kernel/OVR_Types.h | 1055 ++ LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp | 556 + LibOVRKernel/Src/Kernel/OVR_UTF8Util.h | 99 + LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h | 223 + LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.c | 2961 +++++ LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.h | 277 + LibOVRKernel/Src/Tracing/LibOVREvents.h | 1076 ++ LibOVRKernel/Src/Tracing/LibOVREvents.man | Bin 0 -> 42100 bytes LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN | Bin 0 -> 8874 bytes LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin | Bin 0 -> 884 bytes LibOVRKernel/Src/Tracing/README.md | 55 + LibOVRKernel/Src/Tracing/Tracing.h | 197 + LibOVRKernel/Src/Tracing/build.cmd | 15 + LibOVRKernel/Src/Tracing/clean.cmd | 6 + LibOVRKernel/Src/Tracing/install.cmd | 115 + LibOVRKernel/Src/Util/GUIConsole.h | 48 + LibOVRKernel/Src/Util/Util_Direct3D.cpp | 154 + LibOVRKernel/Src/Util/Util_Direct3D.h | 102 + LibOVRKernel/Src/Util/Util_GetSystemSpecs.cpp | 455 + LibOVRKernel/Src/Util/Util_ImageWindow.cpp | 591 + LibOVRKernel/Src/Util/Util_ImageWindow.h | 201 + LibOVRKernel/Src/Util/Util_LongPollThread.cpp | 97 + LibOVRKernel/Src/Util/Util_LongPollThread.h | 72 + LibOVRKernel/Src/Util/Util_SystemGUI.cpp | 239 + LibOVRKernel/Src/Util/Util_SystemGUI.h | 40 + LibOVRKernel/Src/Util/Util_SystemGUI_OSX.mm | 69 + LibOVRKernel/Src/Util/Util_SystemInfo.cpp | 416 + LibOVRKernel/Src/Util/Util_SystemInfo.h | 52 + LibOVRKernel/Src/Util/Util_SystemInfo_OSX.mm | 111 + LibOVRKernel/Src/Util/Util_Watchdog.cpp | 249 + LibOVRKernel/Src/Util/Util_Watchdog.h | 113 + Makefile | 148 +- 345 files changed, 96784 insertions(+), 85245 deletions(-) delete mode 100644 3rdParty/glext/GL/glext.h delete mode 100644 3rdParty/glext/GL/wglext.h create mode 100644 LibOVR/Include/Extras/OVR_Math.h create mode 100644 LibOVR/Include/OVR_CAPI.h create mode 100755 LibOVR/Include/OVR_CAPI_0_5_0.h create mode 100644 LibOVR/Include/OVR_CAPI_GL.h create mode 100644 LibOVR/Include/OVR_CAPI_Keys.h create mode 100644 LibOVR/Include/OVR_CAPI_Util.h create mode 100755 LibOVR/Include/OVR_ErrorCode.h mode change 100644 => 100755 LibOVR/Include/OVR_Version.h create mode 100644 LibOVR/Projects/Mac/LibOVRRT.plist create mode 100644 LibOVR/Projects/Mac/LibOVRRT.xcodeproj/project.pbxproj create mode 100644 LibOVR/Projects/Mac/LibOVRRT.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 LibOVR/Projects/Mac/LibOVRRT.xcodeproj/xcshareddata/xcschemes/LibOVRRT.xcscheme create mode 100644 LibOVR/Projects/Mac/LibOVRRT.xcworkspace/contents.xcworkspacedata delete mode 100644 LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.pbxproj delete mode 100644 LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.xcworkspace/contents.xcworkspacedata delete mode 100644 LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj delete mode 100644 LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters delete mode 100644 LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj delete mode 100644 LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters delete mode 100644 LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj delete mode 100644 LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters create mode 100644 LibOVR/Projects/Windows/VS2013/LibOVRRT.sln create mode 100644 LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj create mode 100644 LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj.filters create mode 100644 LibOVR/Src/CAPI/CAPI_DistortionTiming.cpp create mode 100644 LibOVR/Src/CAPI/CAPI_DistortionTiming.h create mode 100644 LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.cpp create mode 100644 LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.h delete mode 100644 LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp delete mode 100644 LibOVR/Src/CAPI/CAPI_FrameTimeManager.h create mode 100644 LibOVR/Src/CAPI/CAPI_FrameTimeManager3.cpp create mode 100644 LibOVR/Src/CAPI/CAPI_FrameTimeManager3.h mode change 100644 => 100755 LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp mode change 100644 => 100755 LibOVR/Src/CAPI/CAPI_HMDState.cpp mode change 100644 => 100755 LibOVR/Src/CAPI/CAPI_HMDState.h delete mode 100644 LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp delete mode 100644 LibOVR/Src/CAPI/CAPI_LatencyStatistics.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h create mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.cpp create mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp delete mode 100644 LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.vsh delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.vsh delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.h delete mode 100644 LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h delete mode 100644 LibOVR/Src/CAPI/GL/CAPI_GLE.cpp delete mode 100644 LibOVR/Src/CAPI/GL/CAPI_GLE.h delete mode 100644 LibOVR/Src/CAPI/GL/CAPI_GLE_GL.h create mode 100644 LibOVR/Src/CAPI/Textures/healthAndSafety.tga create mode 100644 LibOVR/Src/CAPI/Textures/overdriveLut_dk2.h create mode 100644 LibOVR/Src/CAPI/Textures/overdriveLut_dk2_2.h mode change 100644 => 100755 LibOVR/Src/Displays/OVR_Display.cpp mode change 100644 => 100755 LibOVR/Src/Displays/OVR_Linux_Display.cpp delete mode 100644 LibOVR/Src/Displays/OVR_OSX_FocusObserver.h delete mode 100644 LibOVR/Src/Displays/OVR_OSX_FocusObserver.mm delete mode 100644 LibOVR/Src/Displays/OVR_OSX_FocusReader.h delete mode 100644 LibOVR/Src/Displays/OVR_OSX_FocusReader.mm delete mode 100644 LibOVR/Src/Kernel/OVR_Alg.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Alg.h delete mode 100644 LibOVR/Src/Kernel/OVR_Allocator.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Allocator.h delete mode 100644 LibOVR/Src/Kernel/OVR_Array.h delete mode 100644 LibOVR/Src/Kernel/OVR_Atomic.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Atomic.h delete mode 100644 LibOVR/Src/Kernel/OVR_CRC32.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_CRC32.h delete mode 100644 LibOVR/Src/Kernel/OVR_Color.h delete mode 100644 LibOVR/Src/Kernel/OVR_Compiler.h delete mode 100644 LibOVR/Src/Kernel/OVR_ContainerAllocator.h delete mode 100644 LibOVR/Src/Kernel/OVR_DebugHelp.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_DebugHelp.h delete mode 100644 LibOVR/Src/Kernel/OVR_Delegates.h delete mode 100644 LibOVR/Src/Kernel/OVR_Deque.h delete mode 100644 LibOVR/Src/Kernel/OVR_File.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_File.h delete mode 100644 LibOVR/Src/Kernel/OVR_FileFILE.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Hash.h delete mode 100644 LibOVR/Src/Kernel/OVR_KeyCodes.h delete mode 100644 LibOVR/Src/Kernel/OVR_List.h delete mode 100644 LibOVR/Src/Kernel/OVR_Lockless.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Lockless.h delete mode 100644 LibOVR/Src/Kernel/OVR_Log.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Log.h delete mode 100644 LibOVR/Src/Kernel/OVR_Math.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Math.h delete mode 100644 LibOVR/Src/Kernel/OVR_Nullptr.h delete mode 100644 LibOVR/Src/Kernel/OVR_Observer.h delete mode 100644 LibOVR/Src/Kernel/OVR_RefCount.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_RefCount.h delete mode 100644 LibOVR/Src/Kernel/OVR_SharedMemory.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_SharedMemory.h delete mode 100644 LibOVR/Src/Kernel/OVR_Std.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Std.h delete mode 100644 LibOVR/Src/Kernel/OVR_String.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_String.h delete mode 100644 LibOVR/Src/Kernel/OVR_StringHash.h delete mode 100644 LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_String_PathUtil.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_SysFile.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_SysFile.h delete mode 100644 LibOVR/Src/Kernel/OVR_System.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_System.h delete mode 100644 LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h delete mode 100644 LibOVR/Src/Kernel/OVR_Threads.h delete mode 100644 LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Timer.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_Timer.h delete mode 100644 LibOVR/Src/Kernel/OVR_Types.h delete mode 100644 LibOVR/Src/Kernel/OVR_UTF8Util.cpp delete mode 100644 LibOVR/Src/Kernel/OVR_UTF8Util.h delete mode 100644 LibOVR/Src/Kernel/OVR_mach_exc_OSX.c delete mode 100644 LibOVR/Src/Kernel/OVR_mach_exc_OSX.h mode change 100644 => 100755 LibOVR/Src/Net/OVR_Session.h mode change 100644 => 100755 LibOVR/Src/OVR_CAPI.cpp delete mode 100644 LibOVR/Src/OVR_CAPI.h create mode 100755 LibOVR/Src/OVR_CAPIShim.c delete mode 100644 LibOVR/Src/OVR_CAPI_D3D.h delete mode 100644 LibOVR/Src/OVR_CAPI_GL.h delete mode 100644 LibOVR/Src/OVR_CAPI_Keys.h create mode 100644 LibOVR/Src/OVR_CAPI_Util.cpp create mode 100644 LibOVR/Src/OVR_Error.h delete mode 100644 LibOVR/Src/OVR_JSON.cpp delete mode 100644 LibOVR/Src/OVR_JSON.h create mode 100644 LibOVR/Src/OVR_Linux_UDEV.cpp create mode 100644 LibOVR/Src/OVR_Linux_UDEV.h mode change 100644 => 100755 LibOVR/Src/OVR_Profile.cpp mode change 100644 => 100755 LibOVR/Src/OVR_SerialFormat.cpp mode change 100644 => 100755 LibOVR/Src/OVR_SerialFormat.h mode change 100644 => 100755 LibOVR/Src/OVR_Stereo.h create mode 100644 LibOVR/Src/OVR_StereoProjection.cpp create mode 100644 LibOVR/Src/OVR_StereoProjection.h create mode 100644 LibOVR/Src/Resources/Windows/resource.h mode change 100644 => 100755 LibOVR/Src/Sensors/OVR_DeviceConstants.h mode change 100644 => 100755 LibOVR/Src/Service/Service_NetSessionCommon.h create mode 100644 LibOVR/Src/Service/Service_Win32_FastIPC_Client.cpp create mode 100644 LibOVR/Src/Service/Service_Win32_FastIPC_Client.h delete mode 100644 LibOVR/Src/Tracking/Tracking_PoseState.h delete mode 100644 LibOVR/Src/Tracking/Tracking_SensorState.h delete mode 100644 LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp delete mode 100644 LibOVR/Src/Tracking/Tracking_SensorStateReader.h delete mode 100644 LibOVR/Src/Util/GUIConsole.h create mode 100644 LibOVR/Src/Util/Util_DataLogger.h delete mode 100644 LibOVR/Src/Util/Util_ImageWindow.cpp delete mode 100644 LibOVR/Src/Util/Util_ImageWindow.h create mode 100644 LibOVR/Src/Util/Util_MatFile.cpp create mode 100644 LibOVR/Src/Util/Util_MatFile.h create mode 100644 LibOVR/Src/Util/Util_Stopwatch.h delete mode 100644 LibOVR/Src/Util/Util_SystemGUI.cpp delete mode 100644 LibOVR/Src/Util/Util_SystemGUI.h delete mode 100644 LibOVR/Src/Util/Util_SystemGUI_OSX.mm delete mode 100644 LibOVR/Src/Util/Util_SystemInfo.cpp delete mode 100644 LibOVR/Src/Util/Util_SystemInfo.h delete mode 100644 LibOVR/Src/Util/Util_SystemInfo_OSX.mm create mode 100755 LibOVR/Src/Vision/SensorFusion/Vision_SensorState.h create mode 100755 LibOVR/Src/Vision/SensorFusion/Vision_SensorStateReader.cpp create mode 100755 LibOVR/Src/Vision/SensorFusion/Vision_SensorStateReader.h create mode 100644 LibOVR/Src/Vision/Vision_Common.h create mode 100644 LibOVRKernel/Projects/Mac/LibOVRKernel.xcodeproj/project.pbxproj create mode 100644 LibOVRKernel/Projects/Mac/LibOVRKernel.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 LibOVRKernel/Src/GL/CAPI_GLE.cpp create mode 100644 LibOVRKernel/Src/GL/CAPI_GLE.h create mode 100644 LibOVRKernel/Src/GL/CAPI_GLE_GL.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Alg.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Alg.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Allocator.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Allocator.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Array.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Atomic.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Atomic.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_CRC32.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_CRC32.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Callbacks.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Color.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Compiler.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_DebugHelp.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Delegates.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Deque.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_File.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_File.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Hash.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_JSON.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_JSON.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_KeyCodes.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_List.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Lockless.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Lockless.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Log.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Log.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Nullptr.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Rand.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Rand.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_RefCount.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_RefCount.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_SharedMemory.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Std.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Std.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_String.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_String.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_StringHash.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_SysFile.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_SysFile.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_System.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_System.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Threads.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Timer.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_Timer.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Types.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp create mode 100644 LibOVRKernel/Src/Kernel/OVR_UTF8Util.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h create mode 100644 LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.c create mode 100644 LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.h create mode 100644 LibOVRKernel/Src/Tracing/LibOVREvents.h create mode 100644 LibOVRKernel/Src/Tracing/LibOVREvents.man create mode 100644 LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN create mode 100644 LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin create mode 100644 LibOVRKernel/Src/Tracing/README.md create mode 100644 LibOVRKernel/Src/Tracing/Tracing.h create mode 100644 LibOVRKernel/Src/Tracing/build.cmd create mode 100644 LibOVRKernel/Src/Tracing/clean.cmd create mode 100644 LibOVRKernel/Src/Tracing/install.cmd create mode 100644 LibOVRKernel/Src/Util/GUIConsole.h create mode 100644 LibOVRKernel/Src/Util/Util_Direct3D.cpp create mode 100644 LibOVRKernel/Src/Util/Util_Direct3D.h create mode 100644 LibOVRKernel/Src/Util/Util_GetSystemSpecs.cpp create mode 100644 LibOVRKernel/Src/Util/Util_ImageWindow.cpp create mode 100644 LibOVRKernel/Src/Util/Util_ImageWindow.h create mode 100644 LibOVRKernel/Src/Util/Util_LongPollThread.cpp create mode 100644 LibOVRKernel/Src/Util/Util_LongPollThread.h create mode 100644 LibOVRKernel/Src/Util/Util_SystemGUI.cpp create mode 100644 LibOVRKernel/Src/Util/Util_SystemGUI.h create mode 100644 LibOVRKernel/Src/Util/Util_SystemGUI_OSX.mm create mode 100644 LibOVRKernel/Src/Util/Util_SystemInfo.cpp create mode 100644 LibOVRKernel/Src/Util/Util_SystemInfo.h create mode 100644 LibOVRKernel/Src/Util/Util_SystemInfo_OSX.mm create mode 100644 LibOVRKernel/Src/Util/Util_Watchdog.cpp create mode 100644 LibOVRKernel/Src/Util/Util_Watchdog.h diff --git a/3rdParty/glext/GL/glext.h b/3rdParty/glext/GL/glext.h deleted file mode 100644 index 332f619..0000000 --- a/3rdParty/glext/GL/glext.h +++ /dev/null @@ -1,11081 +0,0 @@ -#ifndef __glext_h_ -#define __glext_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2007-2010 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -/* Header file version number, required by OpenGL ABI for Linux */ -/* glext.h last updated $Date: 2011-04-05 23:08:32 -0700 (Tue, 05 Apr 2011) $ */ -/* Current version at http://www.opengl.org/registry/ */ -#define GL_GLEXT_VERSION 68 -/* Function declaration macros - to move into glplatform.h */ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -/*************************************************************/ - -#ifndef GL_VERSION_1_2 -#define GL_UNSIGNED_BYTE_3_3_2 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2 0x8036 -#define GL_TEXTURE_BINDING_3D 0x806A -#define GL_PACK_SKIP_IMAGES 0x806B -#define GL_PACK_IMAGE_HEIGHT 0x806C -#define GL_UNPACK_SKIP_IMAGES 0x806D -#define GL_UNPACK_IMAGE_HEIGHT 0x806E -#define GL_TEXTURE_3D 0x806F -#define GL_PROXY_TEXTURE_3D 0x8070 -#define GL_TEXTURE_DEPTH 0x8071 -#define GL_TEXTURE_WRAP_R 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE 0x8073 -#define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 -#define GL_UNSIGNED_SHORT_5_6_5 0x8363 -#define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 -#define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 -#define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 -#define GL_BGR 0x80E0 -#define GL_BGRA 0x80E1 -#define GL_MAX_ELEMENTS_VERTICES 0x80E8 -#define GL_MAX_ELEMENTS_INDICES 0x80E9 -#define GL_CLAMP_TO_EDGE 0x812F -#define GL_TEXTURE_MIN_LOD 0x813A -#define GL_TEXTURE_MAX_LOD 0x813B -#define GL_TEXTURE_BASE_LEVEL 0x813C -#define GL_TEXTURE_MAX_LEVEL 0x813D -#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 -#define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 -#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 -#define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 -#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E -#endif - -#ifndef GL_VERSION_1_2_DEPRECATED -#define GL_RESCALE_NORMAL 0x803A -#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 -#define GL_SINGLE_COLOR 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR 0x81FA -#define GL_ALIASED_POINT_SIZE_RANGE 0x846D -#endif - -#ifndef GL_ARB_imaging -#define GL_CONSTANT_COLOR 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 -#define GL_CONSTANT_ALPHA 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 -#define GL_BLEND_COLOR 0x8005 -#define GL_FUNC_ADD 0x8006 -#define GL_MIN 0x8007 -#define GL_MAX 0x8008 -#define GL_BLEND_EQUATION 0x8009 -#define GL_FUNC_SUBTRACT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT 0x800B -#endif - -#ifndef GL_ARB_imaging_DEPRECATED -#define GL_CONVOLUTION_1D 0x8010 -#define GL_CONVOLUTION_2D 0x8011 -#define GL_SEPARABLE_2D 0x8012 -#define GL_CONVOLUTION_BORDER_MODE 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS 0x8015 -#define GL_REDUCE 0x8016 -#define GL_CONVOLUTION_FORMAT 0x8017 -#define GL_CONVOLUTION_WIDTH 0x8018 -#define GL_CONVOLUTION_HEIGHT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS 0x8023 -#define GL_HISTOGRAM 0x8024 -#define GL_PROXY_HISTOGRAM 0x8025 -#define GL_HISTOGRAM_WIDTH 0x8026 -#define GL_HISTOGRAM_FORMAT 0x8027 -#define GL_HISTOGRAM_RED_SIZE 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE 0x802C -#define GL_HISTOGRAM_SINK 0x802D -#define GL_MINMAX 0x802E -#define GL_MINMAX_FORMAT 0x802F -#define GL_MINMAX_SINK 0x8030 -#define GL_TABLE_TOO_LARGE 0x8031 -#define GL_COLOR_MATRIX 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS 0x80BB -#define GL_COLOR_TABLE 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE 0x80D2 -#define GL_PROXY_COLOR_TABLE 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE 0x80D5 -#define GL_COLOR_TABLE_SCALE 0x80D6 -#define GL_COLOR_TABLE_BIAS 0x80D7 -#define GL_COLOR_TABLE_FORMAT 0x80D8 -#define GL_COLOR_TABLE_WIDTH 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE 0x80DF -#define GL_CONSTANT_BORDER 0x8151 -#define GL_REPLICATE_BORDER 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR 0x8154 -#endif - -#ifndef GL_VERSION_1_3 -#define GL_TEXTURE0 0x84C0 -#define GL_TEXTURE1 0x84C1 -#define GL_TEXTURE2 0x84C2 -#define GL_TEXTURE3 0x84C3 -#define GL_TEXTURE4 0x84C4 -#define GL_TEXTURE5 0x84C5 -#define GL_TEXTURE6 0x84C6 -#define GL_TEXTURE7 0x84C7 -#define GL_TEXTURE8 0x84C8 -#define GL_TEXTURE9 0x84C9 -#define GL_TEXTURE10 0x84CA -#define GL_TEXTURE11 0x84CB -#define GL_TEXTURE12 0x84CC -#define GL_TEXTURE13 0x84CD -#define GL_TEXTURE14 0x84CE -#define GL_TEXTURE15 0x84CF -#define GL_TEXTURE16 0x84D0 -#define GL_TEXTURE17 0x84D1 -#define GL_TEXTURE18 0x84D2 -#define GL_TEXTURE19 0x84D3 -#define GL_TEXTURE20 0x84D4 -#define GL_TEXTURE21 0x84D5 -#define GL_TEXTURE22 0x84D6 -#define GL_TEXTURE23 0x84D7 -#define GL_TEXTURE24 0x84D8 -#define GL_TEXTURE25 0x84D9 -#define GL_TEXTURE26 0x84DA -#define GL_TEXTURE27 0x84DB -#define GL_TEXTURE28 0x84DC -#define GL_TEXTURE29 0x84DD -#define GL_TEXTURE30 0x84DE -#define GL_TEXTURE31 0x84DF -#define GL_ACTIVE_TEXTURE 0x84E0 -#define GL_MULTISAMPLE 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE 0x809F -#define GL_SAMPLE_COVERAGE 0x80A0 -#define GL_SAMPLE_BUFFERS 0x80A8 -#define GL_SAMPLES 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT 0x80AB -#define GL_TEXTURE_CUBE_MAP 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C -#define GL_COMPRESSED_RGB 0x84ED -#define GL_COMPRESSED_RGBA 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 -#define GL_TEXTURE_COMPRESSED 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 -#define GL_CLAMP_TO_BORDER 0x812D -#endif - -#ifndef GL_VERSION_1_3_DEPRECATED -#define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 -#define GL_MAX_TEXTURE_UNITS 0x84E2 -#define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 -#define GL_MULTISAMPLE_BIT 0x20000000 -#define GL_NORMAL_MAP 0x8511 -#define GL_REFLECTION_MAP 0x8512 -#define GL_COMPRESSED_ALPHA 0x84E9 -#define GL_COMPRESSED_LUMINANCE 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB -#define GL_COMPRESSED_INTENSITY 0x84EC -#define GL_COMBINE 0x8570 -#define GL_COMBINE_RGB 0x8571 -#define GL_COMBINE_ALPHA 0x8572 -#define GL_SOURCE0_RGB 0x8580 -#define GL_SOURCE1_RGB 0x8581 -#define GL_SOURCE2_RGB 0x8582 -#define GL_SOURCE0_ALPHA 0x8588 -#define GL_SOURCE1_ALPHA 0x8589 -#define GL_SOURCE2_ALPHA 0x858A -#define GL_OPERAND0_RGB 0x8590 -#define GL_OPERAND1_RGB 0x8591 -#define GL_OPERAND2_RGB 0x8592 -#define GL_OPERAND0_ALPHA 0x8598 -#define GL_OPERAND1_ALPHA 0x8599 -#define GL_OPERAND2_ALPHA 0x859A -#define GL_RGB_SCALE 0x8573 -#define GL_ADD_SIGNED 0x8574 -#define GL_INTERPOLATE 0x8575 -#define GL_SUBTRACT 0x84E7 -#define GL_CONSTANT 0x8576 -#define GL_PRIMARY_COLOR 0x8577 -#define GL_PREVIOUS 0x8578 -#define GL_DOT3_RGB 0x86AE -#define GL_DOT3_RGBA 0x86AF -#endif - -#ifndef GL_VERSION_1_4 -#define GL_BLEND_DST_RGB 0x80C8 -#define GL_BLEND_SRC_RGB 0x80C9 -#define GL_BLEND_DST_ALPHA 0x80CA -#define GL_BLEND_SRC_ALPHA 0x80CB -#define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 -#define GL_DEPTH_COMPONENT16 0x81A5 -#define GL_DEPTH_COMPONENT24 0x81A6 -#define GL_DEPTH_COMPONENT32 0x81A7 -#define GL_MIRRORED_REPEAT 0x8370 -#define GL_MAX_TEXTURE_LOD_BIAS 0x84FD -#define GL_TEXTURE_LOD_BIAS 0x8501 -#define GL_INCR_WRAP 0x8507 -#define GL_DECR_WRAP 0x8508 -#define GL_TEXTURE_DEPTH_SIZE 0x884A -#define GL_TEXTURE_COMPARE_MODE 0x884C -#define GL_TEXTURE_COMPARE_FUNC 0x884D -#endif - -#ifndef GL_VERSION_1_4_DEPRECATED -#define GL_POINT_SIZE_MIN 0x8126 -#define GL_POINT_SIZE_MAX 0x8127 -#define GL_POINT_DISTANCE_ATTENUATION 0x8129 -#define GL_GENERATE_MIPMAP 0x8191 -#define GL_GENERATE_MIPMAP_HINT 0x8192 -#define GL_FOG_COORDINATE_SOURCE 0x8450 -#define GL_FOG_COORDINATE 0x8451 -#define GL_FRAGMENT_DEPTH 0x8452 -#define GL_CURRENT_FOG_COORDINATE 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 -#define GL_FOG_COORDINATE_ARRAY 0x8457 -#define GL_COLOR_SUM 0x8458 -#define GL_CURRENT_SECONDARY_COLOR 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D -#define GL_SECONDARY_COLOR_ARRAY 0x845E -#define GL_TEXTURE_FILTER_CONTROL 0x8500 -#define GL_DEPTH_TEXTURE_MODE 0x884B -#define GL_COMPARE_R_TO_TEXTURE 0x884E -#endif - -#ifndef GL_VERSION_1_5 -#define GL_BUFFER_SIZE 0x8764 -#define GL_BUFFER_USAGE 0x8765 -#define GL_QUERY_COUNTER_BITS 0x8864 -#define GL_CURRENT_QUERY 0x8865 -#define GL_QUERY_RESULT 0x8866 -#define GL_QUERY_RESULT_AVAILABLE 0x8867 -#define GL_ARRAY_BUFFER 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER 0x8893 -#define GL_ARRAY_BUFFER_BINDING 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F -#define GL_READ_ONLY 0x88B8 -#define GL_WRITE_ONLY 0x88B9 -#define GL_READ_WRITE 0x88BA -#define GL_BUFFER_ACCESS 0x88BB -#define GL_BUFFER_MAPPED 0x88BC -#define GL_BUFFER_MAP_POINTER 0x88BD -#define GL_STREAM_DRAW 0x88E0 -#define GL_STREAM_READ 0x88E1 -#define GL_STREAM_COPY 0x88E2 -#define GL_STATIC_DRAW 0x88E4 -#define GL_STATIC_READ 0x88E5 -#define GL_STATIC_COPY 0x88E6 -#define GL_DYNAMIC_DRAW 0x88E8 -#define GL_DYNAMIC_READ 0x88E9 -#define GL_DYNAMIC_COPY 0x88EA -#define GL_SAMPLES_PASSED 0x8914 -#endif - -#ifndef GL_VERSION_1_5_DEPRECATED -#define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E -#define GL_FOG_COORD_SRC 0x8450 -#define GL_FOG_COORD 0x8451 -#define GL_CURRENT_FOG_COORD 0x8453 -#define GL_FOG_COORD_ARRAY_TYPE 0x8454 -#define GL_FOG_COORD_ARRAY_STRIDE 0x8455 -#define GL_FOG_COORD_ARRAY_POINTER 0x8456 -#define GL_FOG_COORD_ARRAY 0x8457 -#define GL_FOG_COORD_ARRAY_BUFFER_BINDING 0x889D -#define GL_SRC0_RGB 0x8580 -#define GL_SRC1_RGB 0x8581 -#define GL_SRC2_RGB 0x8582 -#define GL_SRC0_ALPHA 0x8588 -#define GL_SRC1_ALPHA 0x8589 -#define GL_SRC2_ALPHA 0x858A -#endif - -#ifndef GL_VERSION_2_0 -#define GL_BLEND_EQUATION_RGB 0x8009 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB 0x8626 -#define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 -#define GL_STENCIL_BACK_FUNC 0x8800 -#define GL_STENCIL_BACK_FAIL 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 -#define GL_MAX_DRAW_BUFFERS 0x8824 -#define GL_DRAW_BUFFER0 0x8825 -#define GL_DRAW_BUFFER1 0x8826 -#define GL_DRAW_BUFFER2 0x8827 -#define GL_DRAW_BUFFER3 0x8828 -#define GL_DRAW_BUFFER4 0x8829 -#define GL_DRAW_BUFFER5 0x882A -#define GL_DRAW_BUFFER6 0x882B -#define GL_DRAW_BUFFER7 0x882C -#define GL_DRAW_BUFFER8 0x882D -#define GL_DRAW_BUFFER9 0x882E -#define GL_DRAW_BUFFER10 0x882F -#define GL_DRAW_BUFFER11 0x8830 -#define GL_DRAW_BUFFER12 0x8831 -#define GL_DRAW_BUFFER13 0x8832 -#define GL_DRAW_BUFFER14 0x8833 -#define GL_DRAW_BUFFER15 0x8834 -#define GL_BLEND_EQUATION_ALPHA 0x883D -#define GL_MAX_VERTEX_ATTRIBS 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A -#define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 -#define GL_FRAGMENT_SHADER 0x8B30 -#define GL_VERTEX_SHADER 0x8B31 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A -#define GL_MAX_VARYING_FLOATS 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D -#define GL_SHADER_TYPE 0x8B4F -#define GL_FLOAT_VEC2 0x8B50 -#define GL_FLOAT_VEC3 0x8B51 -#define GL_FLOAT_VEC4 0x8B52 -#define GL_INT_VEC2 0x8B53 -#define GL_INT_VEC3 0x8B54 -#define GL_INT_VEC4 0x8B55 -#define GL_BOOL 0x8B56 -#define GL_BOOL_VEC2 0x8B57 -#define GL_BOOL_VEC3 0x8B58 -#define GL_BOOL_VEC4 0x8B59 -#define GL_FLOAT_MAT2 0x8B5A -#define GL_FLOAT_MAT3 0x8B5B -#define GL_FLOAT_MAT4 0x8B5C -#define GL_SAMPLER_1D 0x8B5D -#define GL_SAMPLER_2D 0x8B5E -#define GL_SAMPLER_3D 0x8B5F -#define GL_SAMPLER_CUBE 0x8B60 -#define GL_SAMPLER_1D_SHADOW 0x8B61 -#define GL_SAMPLER_2D_SHADOW 0x8B62 -#define GL_DELETE_STATUS 0x8B80 -#define GL_COMPILE_STATUS 0x8B81 -#define GL_LINK_STATUS 0x8B82 -#define GL_VALIDATE_STATUS 0x8B83 -#define GL_INFO_LOG_LENGTH 0x8B84 -#define GL_ATTACHED_SHADERS 0x8B85 -#define GL_ACTIVE_UNIFORMS 0x8B86 -#define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 -#define GL_SHADER_SOURCE_LENGTH 0x8B88 -#define GL_ACTIVE_ATTRIBUTES 0x8B89 -#define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B -#define GL_SHADING_LANGUAGE_VERSION 0x8B8C -#define GL_CURRENT_PROGRAM 0x8B8D -#define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 -#define GL_LOWER_LEFT 0x8CA1 -#define GL_UPPER_LEFT 0x8CA2 -#define GL_STENCIL_BACK_REF 0x8CA3 -#define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 -#define GL_STENCIL_BACK_WRITEMASK 0x8CA5 -#endif - -#ifndef GL_VERSION_2_0_DEPRECATED -#define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 -#define GL_POINT_SPRITE 0x8861 -#define GL_COORD_REPLACE 0x8862 -#define GL_MAX_TEXTURE_COORDS 0x8871 -#endif - -#ifndef GL_VERSION_2_1 -#define GL_PIXEL_PACK_BUFFER 0x88EB -#define GL_PIXEL_UNPACK_BUFFER 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF -#define GL_FLOAT_MAT2x3 0x8B65 -#define GL_FLOAT_MAT2x4 0x8B66 -#define GL_FLOAT_MAT3x2 0x8B67 -#define GL_FLOAT_MAT3x4 0x8B68 -#define GL_FLOAT_MAT4x2 0x8B69 -#define GL_FLOAT_MAT4x3 0x8B6A -#define GL_SRGB 0x8C40 -#define GL_SRGB8 0x8C41 -#define GL_SRGB_ALPHA 0x8C42 -#define GL_SRGB8_ALPHA8 0x8C43 -#define GL_COMPRESSED_SRGB 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA 0x8C49 -#endif - -#ifndef GL_VERSION_2_1_DEPRECATED -#define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F -#define GL_SLUMINANCE_ALPHA 0x8C44 -#define GL_SLUMINANCE8_ALPHA8 0x8C45 -#define GL_SLUMINANCE 0x8C46 -#define GL_SLUMINANCE8 0x8C47 -#define GL_COMPRESSED_SLUMINANCE 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B -#endif - -#ifndef GL_VERSION_3_0 -#define GL_COMPARE_REF_TO_TEXTURE 0x884E -#define GL_CLIP_DISTANCE0 0x3000 -#define GL_CLIP_DISTANCE1 0x3001 -#define GL_CLIP_DISTANCE2 0x3002 -#define GL_CLIP_DISTANCE3 0x3003 -#define GL_CLIP_DISTANCE4 0x3004 -#define GL_CLIP_DISTANCE5 0x3005 -#define GL_CLIP_DISTANCE6 0x3006 -#define GL_CLIP_DISTANCE7 0x3007 -#define GL_MAX_CLIP_DISTANCES 0x0D32 -#define GL_MAJOR_VERSION 0x821B -#define GL_MINOR_VERSION 0x821C -#define GL_NUM_EXTENSIONS 0x821D -#define GL_CONTEXT_FLAGS 0x821E -#define GL_DEPTH_BUFFER 0x8223 -#define GL_STENCIL_BUFFER 0x8224 -#define GL_COMPRESSED_RED 0x8225 -#define GL_COMPRESSED_RG 0x8226 -#define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 -#define GL_RGBA32F 0x8814 -#define GL_RGB32F 0x8815 -#define GL_RGBA16F 0x881A -#define GL_RGB16F 0x881B -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD -#define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF -#define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 -#define GL_CLAMP_READ_COLOR 0x891C -#define GL_FIXED_ONLY 0x891D -#define GL_MAX_VARYING_COMPONENTS 0x8B4B -#define GL_TEXTURE_1D_ARRAY 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 -#define GL_TEXTURE_2D_ARRAY 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D -#define GL_R11F_G11F_B10F 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B -#define GL_RGB9_E5 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E -#define GL_TEXTURE_SHARED_SIZE 0x8C3F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 -#define GL_PRIMITIVES_GENERATED 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 -#define GL_RASTERIZER_DISCARD 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B -#define GL_INTERLEAVED_ATTRIBS 0x8C8C -#define GL_SEPARATE_ATTRIBS 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F -#define GL_RGBA32UI 0x8D70 -#define GL_RGB32UI 0x8D71 -#define GL_RGBA16UI 0x8D76 -#define GL_RGB16UI 0x8D77 -#define GL_RGBA8UI 0x8D7C -#define GL_RGB8UI 0x8D7D -#define GL_RGBA32I 0x8D82 -#define GL_RGB32I 0x8D83 -#define GL_RGBA16I 0x8D88 -#define GL_RGB16I 0x8D89 -#define GL_RGBA8I 0x8D8E -#define GL_RGB8I 0x8D8F -#define GL_RED_INTEGER 0x8D94 -#define GL_GREEN_INTEGER 0x8D95 -#define GL_BLUE_INTEGER 0x8D96 -#define GL_RGB_INTEGER 0x8D98 -#define GL_RGBA_INTEGER 0x8D99 -#define GL_BGR_INTEGER 0x8D9A -#define GL_BGRA_INTEGER 0x8D9B -#define GL_SAMPLER_1D_ARRAY 0x8DC0 -#define GL_SAMPLER_2D_ARRAY 0x8DC1 -#define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW 0x8DC5 -#define GL_UNSIGNED_INT_VEC2 0x8DC6 -#define GL_UNSIGNED_INT_VEC3 0x8DC7 -#define GL_UNSIGNED_INT_VEC4 0x8DC8 -#define GL_INT_SAMPLER_1D 0x8DC9 -#define GL_INT_SAMPLER_2D 0x8DCA -#define GL_INT_SAMPLER_3D 0x8DCB -#define GL_INT_SAMPLER_CUBE 0x8DCC -#define GL_INT_SAMPLER_1D_ARRAY 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY 0x8DCF -#define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 -#define GL_QUERY_WAIT 0x8E13 -#define GL_QUERY_NO_WAIT 0x8E14 -#define GL_QUERY_BY_REGION_WAIT 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 -#define GL_BUFFER_ACCESS_FLAGS 0x911F -#define GL_BUFFER_MAP_LENGTH 0x9120 -#define GL_BUFFER_MAP_OFFSET 0x9121 -/* Reuse tokens from ARB_depth_buffer_float */ -/* reuse GL_DEPTH_COMPONENT32F */ -/* reuse GL_DEPTH32F_STENCIL8 */ -/* reuse GL_FLOAT_32_UNSIGNED_INT_24_8_REV */ -/* Reuse tokens from ARB_framebuffer_object */ -/* reuse GL_INVALID_FRAMEBUFFER_OPERATION */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */ -/* reuse GL_FRAMEBUFFER_DEFAULT */ -/* reuse GL_FRAMEBUFFER_UNDEFINED */ -/* reuse GL_DEPTH_STENCIL_ATTACHMENT */ -/* reuse GL_INDEX */ -/* reuse GL_MAX_RENDERBUFFER_SIZE */ -/* reuse GL_DEPTH_STENCIL */ -/* reuse GL_UNSIGNED_INT_24_8 */ -/* reuse GL_DEPTH24_STENCIL8 */ -/* reuse GL_TEXTURE_STENCIL_SIZE */ -/* reuse GL_TEXTURE_RED_TYPE */ -/* reuse GL_TEXTURE_GREEN_TYPE */ -/* reuse GL_TEXTURE_BLUE_TYPE */ -/* reuse GL_TEXTURE_ALPHA_TYPE */ -/* reuse GL_TEXTURE_DEPTH_TYPE */ -/* reuse GL_UNSIGNED_NORMALIZED */ -/* reuse GL_FRAMEBUFFER_BINDING */ -/* reuse GL_DRAW_FRAMEBUFFER_BINDING */ -/* reuse GL_RENDERBUFFER_BINDING */ -/* reuse GL_READ_FRAMEBUFFER */ -/* reuse GL_DRAW_FRAMEBUFFER */ -/* reuse GL_READ_FRAMEBUFFER_BINDING */ -/* reuse GL_RENDERBUFFER_SAMPLES */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ -/* reuse GL_FRAMEBUFFER_COMPLETE */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER */ -/* reuse GL_FRAMEBUFFER_UNSUPPORTED */ -/* reuse GL_MAX_COLOR_ATTACHMENTS */ -/* reuse GL_COLOR_ATTACHMENT0 */ -/* reuse GL_COLOR_ATTACHMENT1 */ -/* reuse GL_COLOR_ATTACHMENT2 */ -/* reuse GL_COLOR_ATTACHMENT3 */ -/* reuse GL_COLOR_ATTACHMENT4 */ -/* reuse GL_COLOR_ATTACHMENT5 */ -/* reuse GL_COLOR_ATTACHMENT6 */ -/* reuse GL_COLOR_ATTACHMENT7 */ -/* reuse GL_COLOR_ATTACHMENT8 */ -/* reuse GL_COLOR_ATTACHMENT9 */ -/* reuse GL_COLOR_ATTACHMENT10 */ -/* reuse GL_COLOR_ATTACHMENT11 */ -/* reuse GL_COLOR_ATTACHMENT12 */ -/* reuse GL_COLOR_ATTACHMENT13 */ -/* reuse GL_COLOR_ATTACHMENT14 */ -/* reuse GL_COLOR_ATTACHMENT15 */ -/* reuse GL_DEPTH_ATTACHMENT */ -/* reuse GL_STENCIL_ATTACHMENT */ -/* reuse GL_FRAMEBUFFER */ -/* reuse GL_RENDERBUFFER */ -/* reuse GL_RENDERBUFFER_WIDTH */ -/* reuse GL_RENDERBUFFER_HEIGHT */ -/* reuse GL_RENDERBUFFER_INTERNAL_FORMAT */ -/* reuse GL_STENCIL_INDEX1 */ -/* reuse GL_STENCIL_INDEX4 */ -/* reuse GL_STENCIL_INDEX8 */ -/* reuse GL_STENCIL_INDEX16 */ -/* reuse GL_RENDERBUFFER_RED_SIZE */ -/* reuse GL_RENDERBUFFER_GREEN_SIZE */ -/* reuse GL_RENDERBUFFER_BLUE_SIZE */ -/* reuse GL_RENDERBUFFER_ALPHA_SIZE */ -/* reuse GL_RENDERBUFFER_DEPTH_SIZE */ -/* reuse GL_RENDERBUFFER_STENCIL_SIZE */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */ -/* reuse GL_MAX_SAMPLES */ -/* Reuse tokens from ARB_framebuffer_sRGB */ -/* reuse GL_FRAMEBUFFER_SRGB */ -/* Reuse tokens from ARB_half_float_vertex */ -/* reuse GL_HALF_FLOAT */ -/* Reuse tokens from ARB_map_buffer_range */ -/* reuse GL_MAP_READ_BIT */ -/* reuse GL_MAP_WRITE_BIT */ -/* reuse GL_MAP_INVALIDATE_RANGE_BIT */ -/* reuse GL_MAP_INVALIDATE_BUFFER_BIT */ -/* reuse GL_MAP_FLUSH_EXPLICIT_BIT */ -/* reuse GL_MAP_UNSYNCHRONIZED_BIT */ -/* Reuse tokens from ARB_texture_compression_rgtc */ -/* reuse GL_COMPRESSED_RED_RGTC1 */ -/* reuse GL_COMPRESSED_SIGNED_RED_RGTC1 */ -/* reuse GL_COMPRESSED_RG_RGTC2 */ -/* reuse GL_COMPRESSED_SIGNED_RG_RGTC2 */ -/* Reuse tokens from ARB_texture_rg */ -/* reuse GL_RG */ -/* reuse GL_RG_INTEGER */ -/* reuse GL_R8 */ -/* reuse GL_R16 */ -/* reuse GL_RG8 */ -/* reuse GL_RG16 */ -/* reuse GL_R16F */ -/* reuse GL_R32F */ -/* reuse GL_RG16F */ -/* reuse GL_RG32F */ -/* reuse GL_R8I */ -/* reuse GL_R8UI */ -/* reuse GL_R16I */ -/* reuse GL_R16UI */ -/* reuse GL_R32I */ -/* reuse GL_R32UI */ -/* reuse GL_RG8I */ -/* reuse GL_RG8UI */ -/* reuse GL_RG16I */ -/* reuse GL_RG16UI */ -/* reuse GL_RG32I */ -/* reuse GL_RG32UI */ -/* Reuse tokens from ARB_vertex_array_object */ -/* reuse GL_VERTEX_ARRAY_BINDING */ -#endif - -#ifndef GL_VERSION_3_0_DEPRECATED -#define GL_CLAMP_VERTEX_COLOR 0x891A -#define GL_CLAMP_FRAGMENT_COLOR 0x891B -#define GL_ALPHA_INTEGER 0x8D97 -/* Reuse tokens from ARB_framebuffer_object */ -/* reuse GL_TEXTURE_LUMINANCE_TYPE */ -/* reuse GL_TEXTURE_INTENSITY_TYPE */ -#endif - -#ifndef GL_VERSION_3_1 -#define GL_SAMPLER_2D_RECT 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 -#define GL_SAMPLER_BUFFER 0x8DC2 -#define GL_INT_SAMPLER_2D_RECT 0x8DCD -#define GL_INT_SAMPLER_BUFFER 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 -#define GL_TEXTURE_BUFFER 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT 0x8C2E -#define GL_TEXTURE_RECTANGLE 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 -#define GL_RED_SNORM 0x8F90 -#define GL_RG_SNORM 0x8F91 -#define GL_RGB_SNORM 0x8F92 -#define GL_RGBA_SNORM 0x8F93 -#define GL_R8_SNORM 0x8F94 -#define GL_RG8_SNORM 0x8F95 -#define GL_RGB8_SNORM 0x8F96 -#define GL_RGBA8_SNORM 0x8F97 -#define GL_R16_SNORM 0x8F98 -#define GL_RG16_SNORM 0x8F99 -#define GL_RGB16_SNORM 0x8F9A -#define GL_RGBA16_SNORM 0x8F9B -#define GL_SIGNED_NORMALIZED 0x8F9C -#define GL_PRIMITIVE_RESTART 0x8F9D -#define GL_PRIMITIVE_RESTART_INDEX 0x8F9E -/* Reuse tokens from ARB_copy_buffer */ -/* reuse GL_COPY_READ_BUFFER */ -/* reuse GL_COPY_WRITE_BUFFER */ -/* Reuse tokens from ARB_draw_instanced (none) */ -/* Reuse tokens from ARB_uniform_buffer_object */ -/* reuse GL_UNIFORM_BUFFER */ -/* reuse GL_UNIFORM_BUFFER_BINDING */ -/* reuse GL_UNIFORM_BUFFER_START */ -/* reuse GL_UNIFORM_BUFFER_SIZE */ -/* reuse GL_MAX_VERTEX_UNIFORM_BLOCKS */ -/* reuse GL_MAX_FRAGMENT_UNIFORM_BLOCKS */ -/* reuse GL_MAX_COMBINED_UNIFORM_BLOCKS */ -/* reuse GL_MAX_UNIFORM_BUFFER_BINDINGS */ -/* reuse GL_MAX_UNIFORM_BLOCK_SIZE */ -/* reuse GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS */ -/* reuse GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS */ -/* reuse GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT */ -/* reuse GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH */ -/* reuse GL_ACTIVE_UNIFORM_BLOCKS */ -/* reuse GL_UNIFORM_TYPE */ -/* reuse GL_UNIFORM_SIZE */ -/* reuse GL_UNIFORM_NAME_LENGTH */ -/* reuse GL_UNIFORM_BLOCK_INDEX */ -/* reuse GL_UNIFORM_OFFSET */ -/* reuse GL_UNIFORM_ARRAY_STRIDE */ -/* reuse GL_UNIFORM_MATRIX_STRIDE */ -/* reuse GL_UNIFORM_IS_ROW_MAJOR */ -/* reuse GL_UNIFORM_BLOCK_BINDING */ -/* reuse GL_UNIFORM_BLOCK_DATA_SIZE */ -/* reuse GL_UNIFORM_BLOCK_NAME_LENGTH */ -/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS */ -/* reuse GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES */ -/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER */ -/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER */ -/* reuse GL_INVALID_INDEX */ -#endif - -#ifndef GL_VERSION_3_2 -#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 -#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 -#define GL_LINES_ADJACENCY 0x000A -#define GL_LINE_STRIP_ADJACENCY 0x000B -#define GL_TRIANGLES_ADJACENCY 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D -#define GL_PROGRAM_POINT_SIZE 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 -#define GL_GEOMETRY_SHADER 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT 0x8916 -#define GL_GEOMETRY_INPUT_TYPE 0x8917 -#define GL_GEOMETRY_OUTPUT_TYPE 0x8918 -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 -#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 -#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 -#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 -#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 -#define GL_CONTEXT_PROFILE_MASK 0x9126 -/* reuse GL_MAX_VARYING_COMPONENTS */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ -/* Reuse tokens from ARB_depth_clamp */ -/* reuse GL_DEPTH_CLAMP */ -/* Reuse tokens from ARB_draw_elements_base_vertex (none) */ -/* Reuse tokens from ARB_fragment_coord_conventions (none) */ -/* Reuse tokens from ARB_provoking_vertex */ -/* reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */ -/* reuse GL_FIRST_VERTEX_CONVENTION */ -/* reuse GL_LAST_VERTEX_CONVENTION */ -/* reuse GL_PROVOKING_VERTEX */ -/* Reuse tokens from ARB_seamless_cube_map */ -/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */ -/* Reuse tokens from ARB_sync */ -/* reuse GL_MAX_SERVER_WAIT_TIMEOUT */ -/* reuse GL_OBJECT_TYPE */ -/* reuse GL_SYNC_CONDITION */ -/* reuse GL_SYNC_STATUS */ -/* reuse GL_SYNC_FLAGS */ -/* reuse GL_SYNC_FENCE */ -/* reuse GL_SYNC_GPU_COMMANDS_COMPLETE */ -/* reuse GL_UNSIGNALED */ -/* reuse GL_SIGNALED */ -/* reuse GL_ALREADY_SIGNALED */ -/* reuse GL_TIMEOUT_EXPIRED */ -/* reuse GL_CONDITION_SATISFIED */ -/* reuse GL_WAIT_FAILED */ -/* reuse GL_TIMEOUT_IGNORED */ -/* reuse GL_SYNC_FLUSH_COMMANDS_BIT */ -/* reuse GL_TIMEOUT_IGNORED */ -/* Reuse tokens from ARB_texture_multisample */ -/* reuse GL_SAMPLE_POSITION */ -/* reuse GL_SAMPLE_MASK */ -/* reuse GL_SAMPLE_MASK_VALUE */ -/* reuse GL_MAX_SAMPLE_MASK_WORDS */ -/* reuse GL_TEXTURE_2D_MULTISAMPLE */ -/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE */ -/* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */ -/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */ -/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE */ -/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */ -/* reuse GL_TEXTURE_SAMPLES */ -/* reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */ -/* reuse GL_SAMPLER_2D_MULTISAMPLE */ -/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE */ -/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */ -/* reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY */ -/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */ -/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */ -/* reuse GL_MAX_COLOR_TEXTURE_SAMPLES */ -/* reuse GL_MAX_DEPTH_TEXTURE_SAMPLES */ -/* reuse GL_MAX_INTEGER_SAMPLES */ -/* Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core */ -#endif - -#ifndef GL_VERSION_3_3 -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE -/* Reuse tokens from ARB_blend_func_extended */ -/* reuse GL_SRC1_COLOR */ -/* reuse GL_ONE_MINUS_SRC1_COLOR */ -/* reuse GL_ONE_MINUS_SRC1_ALPHA */ -/* reuse GL_MAX_DUAL_SOURCE_DRAW_BUFFERS */ -/* Reuse tokens from ARB_explicit_attrib_location (none) */ -/* Reuse tokens from ARB_occlusion_query2 */ -/* reuse GL_ANY_SAMPLES_PASSED */ -/* Reuse tokens from ARB_sampler_objects */ -/* reuse GL_SAMPLER_BINDING */ -/* Reuse tokens from ARB_shader_bit_encoding (none) */ -/* Reuse tokens from ARB_texture_rgb10_a2ui */ -/* reuse GL_RGB10_A2UI */ -/* Reuse tokens from ARB_texture_swizzle */ -/* reuse GL_TEXTURE_SWIZZLE_R */ -/* reuse GL_TEXTURE_SWIZZLE_G */ -/* reuse GL_TEXTURE_SWIZZLE_B */ -/* reuse GL_TEXTURE_SWIZZLE_A */ -/* reuse GL_TEXTURE_SWIZZLE_RGBA */ -/* Reuse tokens from ARB_timer_query */ -/* reuse GL_TIME_ELAPSED */ -/* reuse GL_TIMESTAMP */ -/* Reuse tokens from ARB_vertex_type_2_10_10_10_rev */ -/* reuse GL_INT_2_10_10_10_REV */ -#endif - -#ifndef GL_VERSION_4_0 -#define GL_SAMPLE_SHADING 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F -#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B -#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F -/* Reuse tokens from ARB_texture_query_lod (none) */ -/* Reuse tokens from ARB_draw_buffers_blend (none) */ -/* Reuse tokens from ARB_draw_indirect */ -/* reuse GL_DRAW_INDIRECT_BUFFER */ -/* reuse GL_DRAW_INDIRECT_BUFFER_BINDING */ -/* Reuse tokens from ARB_gpu_shader5 */ -/* reuse GL_GEOMETRY_SHADER_INVOCATIONS */ -/* reuse GL_MAX_GEOMETRY_SHADER_INVOCATIONS */ -/* reuse GL_MIN_FRAGMENT_INTERPOLATION_OFFSET */ -/* reuse GL_MAX_FRAGMENT_INTERPOLATION_OFFSET */ -/* reuse GL_FRAGMENT_INTERPOLATION_OFFSET_BITS */ -/* reuse GL_MAX_VERTEX_STREAMS */ -/* Reuse tokens from ARB_gpu_shader_fp64 */ -/* reuse GL_DOUBLE_VEC2 */ -/* reuse GL_DOUBLE_VEC3 */ -/* reuse GL_DOUBLE_VEC4 */ -/* reuse GL_DOUBLE_MAT2 */ -/* reuse GL_DOUBLE_MAT3 */ -/* reuse GL_DOUBLE_MAT4 */ -/* reuse GL_DOUBLE_MAT2x3 */ -/* reuse GL_DOUBLE_MAT2x4 */ -/* reuse GL_DOUBLE_MAT3x2 */ -/* reuse GL_DOUBLE_MAT3x4 */ -/* reuse GL_DOUBLE_MAT4x2 */ -/* reuse GL_DOUBLE_MAT4x3 */ -/* Reuse tokens from ARB_shader_subroutine */ -/* reuse GL_ACTIVE_SUBROUTINES */ -/* reuse GL_ACTIVE_SUBROUTINE_UNIFORMS */ -/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS */ -/* reuse GL_ACTIVE_SUBROUTINE_MAX_LENGTH */ -/* reuse GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH */ -/* reuse GL_MAX_SUBROUTINES */ -/* reuse GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS */ -/* reuse GL_NUM_COMPATIBLE_SUBROUTINES */ -/* reuse GL_COMPATIBLE_SUBROUTINES */ -/* Reuse tokens from ARB_tessellation_shader */ -/* reuse GL_PATCHES */ -/* reuse GL_PATCH_VERTICES */ -/* reuse GL_PATCH_DEFAULT_INNER_LEVEL */ -/* reuse GL_PATCH_DEFAULT_OUTER_LEVEL */ -/* reuse GL_TESS_CONTROL_OUTPUT_VERTICES */ -/* reuse GL_TESS_GEN_MODE */ -/* reuse GL_TESS_GEN_SPACING */ -/* reuse GL_TESS_GEN_VERTEX_ORDER */ -/* reuse GL_TESS_GEN_POINT_MODE */ -/* reuse GL_ISOLINES */ -/* reuse GL_FRACTIONAL_ODD */ -/* reuse GL_FRACTIONAL_EVEN */ -/* reuse GL_MAX_PATCH_VERTICES */ -/* reuse GL_MAX_TESS_GEN_LEVEL */ -/* reuse GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS */ -/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS */ -/* reuse GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS */ -/* reuse GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS */ -/* reuse GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS */ -/* reuse GL_MAX_TESS_PATCH_COMPONENTS */ -/* reuse GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS */ -/* reuse GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS */ -/* reuse GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS */ -/* reuse GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS */ -/* reuse GL_MAX_TESS_CONTROL_INPUT_COMPONENTS */ -/* reuse GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS */ -/* reuse GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS */ -/* reuse GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS */ -/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER */ -/* reuse GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER */ -/* reuse GL_TESS_EVALUATION_SHADER */ -/* reuse GL_TESS_CONTROL_SHADER */ -/* Reuse tokens from ARB_texture_buffer_object_rgb32 (none) */ -/* Reuse tokens from ARB_transform_feedback2 */ -/* reuse GL_TRANSFORM_FEEDBACK */ -/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED */ -/* reuse GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE */ -/* reuse GL_TRANSFORM_FEEDBACK_BINDING */ -/* Reuse tokens from ARB_transform_feedback3 */ -/* reuse GL_MAX_TRANSFORM_FEEDBACK_BUFFERS */ -/* reuse GL_MAX_VERTEX_STREAMS */ -#endif - -#ifndef GL_VERSION_4_1 -/* Reuse tokens from ARB_ES2_compatibility */ -/* reuse GL_FIXED */ -/* reuse GL_IMPLEMENTATION_COLOR_READ_TYPE */ -/* reuse GL_IMPLEMENTATION_COLOR_READ_FORMAT */ -/* reuse GL_LOW_FLOAT */ -/* reuse GL_MEDIUM_FLOAT */ -/* reuse GL_HIGH_FLOAT */ -/* reuse GL_LOW_INT */ -/* reuse GL_MEDIUM_INT */ -/* reuse GL_HIGH_INT */ -/* reuse GL_SHADER_COMPILER */ -/* reuse GL_NUM_SHADER_BINARY_FORMATS */ -/* reuse GL_MAX_VERTEX_UNIFORM_VECTORS */ -/* reuse GL_MAX_VARYING_VECTORS */ -/* reuse GL_MAX_FRAGMENT_UNIFORM_VECTORS */ -/* Reuse tokens from ARB_get_program_binary */ -/* reuse GL_PROGRAM_BINARY_RETRIEVABLE_HINT */ -/* reuse GL_PROGRAM_BINARY_LENGTH */ -/* reuse GL_NUM_PROGRAM_BINARY_FORMATS */ -/* reuse GL_PROGRAM_BINARY_FORMATS */ -/* Reuse tokens from ARB_separate_shader_objects */ -/* reuse GL_VERTEX_SHADER_BIT */ -/* reuse GL_FRAGMENT_SHADER_BIT */ -/* reuse GL_GEOMETRY_SHADER_BIT */ -/* reuse GL_TESS_CONTROL_SHADER_BIT */ -/* reuse GL_TESS_EVALUATION_SHADER_BIT */ -/* reuse GL_ALL_SHADER_BITS */ -/* reuse GL_PROGRAM_SEPARABLE */ -/* reuse GL_ACTIVE_PROGRAM */ -/* reuse GL_PROGRAM_PIPELINE_BINDING */ -/* Reuse tokens from ARB_shader_precision (none) */ -/* Reuse tokens from ARB_vertex_attrib_64bit - all are in GL 3.0 and 4.0 already */ -/* Reuse tokens from ARB_viewport_array - some are in GL 1.1 and ARB_provoking_vertex already */ -/* reuse GL_MAX_VIEWPORTS */ -/* reuse GL_VIEWPORT_SUBPIXEL_BITS */ -/* reuse GL_VIEWPORT_BOUNDS_RANGE */ -/* reuse GL_LAYER_PROVOKING_VERTEX */ -/* reuse GL_VIEWPORT_INDEX_PROVOKING_VERTEX */ -/* reuse GL_UNDEFINED_VERTEX */ -#endif - -#ifndef GL_ARB_multitexture -#define GL_TEXTURE0_ARB 0x84C0 -#define GL_TEXTURE1_ARB 0x84C1 -#define GL_TEXTURE2_ARB 0x84C2 -#define GL_TEXTURE3_ARB 0x84C3 -#define GL_TEXTURE4_ARB 0x84C4 -#define GL_TEXTURE5_ARB 0x84C5 -#define GL_TEXTURE6_ARB 0x84C6 -#define GL_TEXTURE7_ARB 0x84C7 -#define GL_TEXTURE8_ARB 0x84C8 -#define GL_TEXTURE9_ARB 0x84C9 -#define GL_TEXTURE10_ARB 0x84CA -#define GL_TEXTURE11_ARB 0x84CB -#define GL_TEXTURE12_ARB 0x84CC -#define GL_TEXTURE13_ARB 0x84CD -#define GL_TEXTURE14_ARB 0x84CE -#define GL_TEXTURE15_ARB 0x84CF -#define GL_TEXTURE16_ARB 0x84D0 -#define GL_TEXTURE17_ARB 0x84D1 -#define GL_TEXTURE18_ARB 0x84D2 -#define GL_TEXTURE19_ARB 0x84D3 -#define GL_TEXTURE20_ARB 0x84D4 -#define GL_TEXTURE21_ARB 0x84D5 -#define GL_TEXTURE22_ARB 0x84D6 -#define GL_TEXTURE23_ARB 0x84D7 -#define GL_TEXTURE24_ARB 0x84D8 -#define GL_TEXTURE25_ARB 0x84D9 -#define GL_TEXTURE26_ARB 0x84DA -#define GL_TEXTURE27_ARB 0x84DB -#define GL_TEXTURE28_ARB 0x84DC -#define GL_TEXTURE29_ARB 0x84DD -#define GL_TEXTURE30_ARB 0x84DE -#define GL_TEXTURE31_ARB 0x84DF -#define GL_ACTIVE_TEXTURE_ARB 0x84E0 -#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 -#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 -#endif - -#ifndef GL_ARB_transpose_matrix -#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 -#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 -#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 -#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 -#endif - -#ifndef GL_ARB_multisample -#define GL_MULTISAMPLE_ARB 0x809D -#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F -#define GL_SAMPLE_COVERAGE_ARB 0x80A0 -#define GL_SAMPLE_BUFFERS_ARB 0x80A8 -#define GL_SAMPLES_ARB 0x80A9 -#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA -#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB -#define GL_MULTISAMPLE_BIT_ARB 0x20000000 -#endif - -#ifndef GL_ARB_texture_env_add -#endif - -#ifndef GL_ARB_texture_cube_map -#define GL_NORMAL_MAP_ARB 0x8511 -#define GL_REFLECTION_MAP_ARB 0x8512 -#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C -#endif - -#ifndef GL_ARB_texture_compression -#define GL_COMPRESSED_ALPHA_ARB 0x84E9 -#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA -#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB -#define GL_COMPRESSED_INTENSITY_ARB 0x84EC -#define GL_COMPRESSED_RGB_ARB 0x84ED -#define GL_COMPRESSED_RGBA_ARB 0x84EE -#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF -#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 -#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 -#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 -#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 -#endif - -#ifndef GL_ARB_texture_border_clamp -#define GL_CLAMP_TO_BORDER_ARB 0x812D -#endif - -#ifndef GL_ARB_point_parameters -#define GL_POINT_SIZE_MIN_ARB 0x8126 -#define GL_POINT_SIZE_MAX_ARB 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_ARB 0x8128 -#define GL_POINT_DISTANCE_ATTENUATION_ARB 0x8129 -#endif - -#ifndef GL_ARB_vertex_blend -#define GL_MAX_VERTEX_UNITS_ARB 0x86A4 -#define GL_ACTIVE_VERTEX_UNITS_ARB 0x86A5 -#define GL_WEIGHT_SUM_UNITY_ARB 0x86A6 -#define GL_VERTEX_BLEND_ARB 0x86A7 -#define GL_CURRENT_WEIGHT_ARB 0x86A8 -#define GL_WEIGHT_ARRAY_TYPE_ARB 0x86A9 -#define GL_WEIGHT_ARRAY_STRIDE_ARB 0x86AA -#define GL_WEIGHT_ARRAY_SIZE_ARB 0x86AB -#define GL_WEIGHT_ARRAY_POINTER_ARB 0x86AC -#define GL_WEIGHT_ARRAY_ARB 0x86AD -#define GL_MODELVIEW0_ARB 0x1700 -#define GL_MODELVIEW1_ARB 0x850A -#define GL_MODELVIEW2_ARB 0x8722 -#define GL_MODELVIEW3_ARB 0x8723 -#define GL_MODELVIEW4_ARB 0x8724 -#define GL_MODELVIEW5_ARB 0x8725 -#define GL_MODELVIEW6_ARB 0x8726 -#define GL_MODELVIEW7_ARB 0x8727 -#define GL_MODELVIEW8_ARB 0x8728 -#define GL_MODELVIEW9_ARB 0x8729 -#define GL_MODELVIEW10_ARB 0x872A -#define GL_MODELVIEW11_ARB 0x872B -#define GL_MODELVIEW12_ARB 0x872C -#define GL_MODELVIEW13_ARB 0x872D -#define GL_MODELVIEW14_ARB 0x872E -#define GL_MODELVIEW15_ARB 0x872F -#define GL_MODELVIEW16_ARB 0x8730 -#define GL_MODELVIEW17_ARB 0x8731 -#define GL_MODELVIEW18_ARB 0x8732 -#define GL_MODELVIEW19_ARB 0x8733 -#define GL_MODELVIEW20_ARB 0x8734 -#define GL_MODELVIEW21_ARB 0x8735 -#define GL_MODELVIEW22_ARB 0x8736 -#define GL_MODELVIEW23_ARB 0x8737 -#define GL_MODELVIEW24_ARB 0x8738 -#define GL_MODELVIEW25_ARB 0x8739 -#define GL_MODELVIEW26_ARB 0x873A -#define GL_MODELVIEW27_ARB 0x873B -#define GL_MODELVIEW28_ARB 0x873C -#define GL_MODELVIEW29_ARB 0x873D -#define GL_MODELVIEW30_ARB 0x873E -#define GL_MODELVIEW31_ARB 0x873F -#endif - -#ifndef GL_ARB_matrix_palette -#define GL_MATRIX_PALETTE_ARB 0x8840 -#define GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB 0x8841 -#define GL_MAX_PALETTE_MATRICES_ARB 0x8842 -#define GL_CURRENT_PALETTE_MATRIX_ARB 0x8843 -#define GL_MATRIX_INDEX_ARRAY_ARB 0x8844 -#define GL_CURRENT_MATRIX_INDEX_ARB 0x8845 -#define GL_MATRIX_INDEX_ARRAY_SIZE_ARB 0x8846 -#define GL_MATRIX_INDEX_ARRAY_TYPE_ARB 0x8847 -#define GL_MATRIX_INDEX_ARRAY_STRIDE_ARB 0x8848 -#define GL_MATRIX_INDEX_ARRAY_POINTER_ARB 0x8849 -#endif - -#ifndef GL_ARB_texture_env_combine -#define GL_COMBINE_ARB 0x8570 -#define GL_COMBINE_RGB_ARB 0x8571 -#define GL_COMBINE_ALPHA_ARB 0x8572 -#define GL_SOURCE0_RGB_ARB 0x8580 -#define GL_SOURCE1_RGB_ARB 0x8581 -#define GL_SOURCE2_RGB_ARB 0x8582 -#define GL_SOURCE0_ALPHA_ARB 0x8588 -#define GL_SOURCE1_ALPHA_ARB 0x8589 -#define GL_SOURCE2_ALPHA_ARB 0x858A -#define GL_OPERAND0_RGB_ARB 0x8590 -#define GL_OPERAND1_RGB_ARB 0x8591 -#define GL_OPERAND2_RGB_ARB 0x8592 -#define GL_OPERAND0_ALPHA_ARB 0x8598 -#define GL_OPERAND1_ALPHA_ARB 0x8599 -#define GL_OPERAND2_ALPHA_ARB 0x859A -#define GL_RGB_SCALE_ARB 0x8573 -#define GL_ADD_SIGNED_ARB 0x8574 -#define GL_INTERPOLATE_ARB 0x8575 -#define GL_SUBTRACT_ARB 0x84E7 -#define GL_CONSTANT_ARB 0x8576 -#define GL_PRIMARY_COLOR_ARB 0x8577 -#define GL_PREVIOUS_ARB 0x8578 -#endif - -#ifndef GL_ARB_texture_env_crossbar -#endif - -#ifndef GL_ARB_texture_env_dot3 -#define GL_DOT3_RGB_ARB 0x86AE -#define GL_DOT3_RGBA_ARB 0x86AF -#endif - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_MIRRORED_REPEAT_ARB 0x8370 -#endif - -#ifndef GL_ARB_depth_texture -#define GL_DEPTH_COMPONENT16_ARB 0x81A5 -#define GL_DEPTH_COMPONENT24_ARB 0x81A6 -#define GL_DEPTH_COMPONENT32_ARB 0x81A7 -#define GL_TEXTURE_DEPTH_SIZE_ARB 0x884A -#define GL_DEPTH_TEXTURE_MODE_ARB 0x884B -#endif - -#ifndef GL_ARB_shadow -#define GL_TEXTURE_COMPARE_MODE_ARB 0x884C -#define GL_TEXTURE_COMPARE_FUNC_ARB 0x884D -#define GL_COMPARE_R_TO_TEXTURE_ARB 0x884E -#endif - -#ifndef GL_ARB_shadow_ambient -#define GL_TEXTURE_COMPARE_FAIL_VALUE_ARB 0x80BF -#endif - -#ifndef GL_ARB_window_pos -#endif - -#ifndef GL_ARB_vertex_program -#define GL_COLOR_SUM_ARB 0x8458 -#define GL_VERTEX_PROGRAM_ARB 0x8620 -#define GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB 0x8622 -#define GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB 0x8623 -#define GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB 0x8624 -#define GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB 0x8625 -#define GL_CURRENT_VERTEX_ATTRIB_ARB 0x8626 -#define GL_PROGRAM_LENGTH_ARB 0x8627 -#define GL_PROGRAM_STRING_ARB 0x8628 -#define GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB 0x862E -#define GL_MAX_PROGRAM_MATRICES_ARB 0x862F -#define GL_CURRENT_MATRIX_STACK_DEPTH_ARB 0x8640 -#define GL_CURRENT_MATRIX_ARB 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_ARB 0x8643 -#define GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB 0x8645 -#define GL_PROGRAM_ERROR_POSITION_ARB 0x864B -#define GL_PROGRAM_BINDING_ARB 0x8677 -#define GL_MAX_VERTEX_ATTRIBS_ARB 0x8869 -#define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB 0x886A -#define GL_PROGRAM_ERROR_STRING_ARB 0x8874 -#define GL_PROGRAM_FORMAT_ASCII_ARB 0x8875 -#define GL_PROGRAM_FORMAT_ARB 0x8876 -#define GL_PROGRAM_INSTRUCTIONS_ARB 0x88A0 -#define GL_MAX_PROGRAM_INSTRUCTIONS_ARB 0x88A1 -#define GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A2 -#define GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB 0x88A3 -#define GL_PROGRAM_TEMPORARIES_ARB 0x88A4 -#define GL_MAX_PROGRAM_TEMPORARIES_ARB 0x88A5 -#define GL_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A6 -#define GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB 0x88A7 -#define GL_PROGRAM_PARAMETERS_ARB 0x88A8 -#define GL_MAX_PROGRAM_PARAMETERS_ARB 0x88A9 -#define GL_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AA -#define GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB 0x88AB -#define GL_PROGRAM_ATTRIBS_ARB 0x88AC -#define GL_MAX_PROGRAM_ATTRIBS_ARB 0x88AD -#define GL_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AE -#define GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB 0x88AF -#define GL_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B0 -#define GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB 0x88B1 -#define GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B2 -#define GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB 0x88B3 -#define GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB 0x88B4 -#define GL_MAX_PROGRAM_ENV_PARAMETERS_ARB 0x88B5 -#define GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB 0x88B6 -#define GL_TRANSPOSE_CURRENT_MATRIX_ARB 0x88B7 -#define GL_MATRIX0_ARB 0x88C0 -#define GL_MATRIX1_ARB 0x88C1 -#define GL_MATRIX2_ARB 0x88C2 -#define GL_MATRIX3_ARB 0x88C3 -#define GL_MATRIX4_ARB 0x88C4 -#define GL_MATRIX5_ARB 0x88C5 -#define GL_MATRIX6_ARB 0x88C6 -#define GL_MATRIX7_ARB 0x88C7 -#define GL_MATRIX8_ARB 0x88C8 -#define GL_MATRIX9_ARB 0x88C9 -#define GL_MATRIX10_ARB 0x88CA -#define GL_MATRIX11_ARB 0x88CB -#define GL_MATRIX12_ARB 0x88CC -#define GL_MATRIX13_ARB 0x88CD -#define GL_MATRIX14_ARB 0x88CE -#define GL_MATRIX15_ARB 0x88CF -#define GL_MATRIX16_ARB 0x88D0 -#define GL_MATRIX17_ARB 0x88D1 -#define GL_MATRIX18_ARB 0x88D2 -#define GL_MATRIX19_ARB 0x88D3 -#define GL_MATRIX20_ARB 0x88D4 -#define GL_MATRIX21_ARB 0x88D5 -#define GL_MATRIX22_ARB 0x88D6 -#define GL_MATRIX23_ARB 0x88D7 -#define GL_MATRIX24_ARB 0x88D8 -#define GL_MATRIX25_ARB 0x88D9 -#define GL_MATRIX26_ARB 0x88DA -#define GL_MATRIX27_ARB 0x88DB -#define GL_MATRIX28_ARB 0x88DC -#define GL_MATRIX29_ARB 0x88DD -#define GL_MATRIX30_ARB 0x88DE -#define GL_MATRIX31_ARB 0x88DF -#endif - -#ifndef GL_ARB_fragment_program -#define GL_FRAGMENT_PROGRAM_ARB 0x8804 -#define GL_PROGRAM_ALU_INSTRUCTIONS_ARB 0x8805 -#define GL_PROGRAM_TEX_INSTRUCTIONS_ARB 0x8806 -#define GL_PROGRAM_TEX_INDIRECTIONS_ARB 0x8807 -#define GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x8808 -#define GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x8809 -#define GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x880A -#define GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB 0x880B -#define GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB 0x880C -#define GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB 0x880D -#define GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB 0x880E -#define GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB 0x880F -#define GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB 0x8810 -#define GL_MAX_TEXTURE_COORDS_ARB 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_ARB 0x8872 -#endif - -#ifndef GL_ARB_vertex_buffer_object -#define GL_BUFFER_SIZE_ARB 0x8764 -#define GL_BUFFER_USAGE_ARB 0x8765 -#define GL_ARRAY_BUFFER_ARB 0x8892 -#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893 -#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894 -#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895 -#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896 -#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897 -#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898 -#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899 -#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A -#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B -#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C -#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D -#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E -#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F -#define GL_READ_ONLY_ARB 0x88B8 -#define GL_WRITE_ONLY_ARB 0x88B9 -#define GL_READ_WRITE_ARB 0x88BA -#define GL_BUFFER_ACCESS_ARB 0x88BB -#define GL_BUFFER_MAPPED_ARB 0x88BC -#define GL_BUFFER_MAP_POINTER_ARB 0x88BD -#define GL_STREAM_DRAW_ARB 0x88E0 -#define GL_STREAM_READ_ARB 0x88E1 -#define GL_STREAM_COPY_ARB 0x88E2 -#define GL_STATIC_DRAW_ARB 0x88E4 -#define GL_STATIC_READ_ARB 0x88E5 -#define GL_STATIC_COPY_ARB 0x88E6 -#define GL_DYNAMIC_DRAW_ARB 0x88E8 -#define GL_DYNAMIC_READ_ARB 0x88E9 -#define GL_DYNAMIC_COPY_ARB 0x88EA -#endif - -#ifndef GL_ARB_occlusion_query -#define GL_QUERY_COUNTER_BITS_ARB 0x8864 -#define GL_CURRENT_QUERY_ARB 0x8865 -#define GL_QUERY_RESULT_ARB 0x8866 -#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 -#define GL_SAMPLES_PASSED_ARB 0x8914 -#endif - -#ifndef GL_ARB_shader_objects -#define GL_PROGRAM_OBJECT_ARB 0x8B40 -#define GL_SHADER_OBJECT_ARB 0x8B48 -#define GL_OBJECT_TYPE_ARB 0x8B4E -#define GL_OBJECT_SUBTYPE_ARB 0x8B4F -#define GL_FLOAT_VEC2_ARB 0x8B50 -#define GL_FLOAT_VEC3_ARB 0x8B51 -#define GL_FLOAT_VEC4_ARB 0x8B52 -#define GL_INT_VEC2_ARB 0x8B53 -#define GL_INT_VEC3_ARB 0x8B54 -#define GL_INT_VEC4_ARB 0x8B55 -#define GL_BOOL_ARB 0x8B56 -#define GL_BOOL_VEC2_ARB 0x8B57 -#define GL_BOOL_VEC3_ARB 0x8B58 -#define GL_BOOL_VEC4_ARB 0x8B59 -#define GL_FLOAT_MAT2_ARB 0x8B5A -#define GL_FLOAT_MAT3_ARB 0x8B5B -#define GL_FLOAT_MAT4_ARB 0x8B5C -#define GL_SAMPLER_1D_ARB 0x8B5D -#define GL_SAMPLER_2D_ARB 0x8B5E -#define GL_SAMPLER_3D_ARB 0x8B5F -#define GL_SAMPLER_CUBE_ARB 0x8B60 -#define GL_SAMPLER_1D_SHADOW_ARB 0x8B61 -#define GL_SAMPLER_2D_SHADOW_ARB 0x8B62 -#define GL_SAMPLER_2D_RECT_ARB 0x8B63 -#define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 -#define GL_OBJECT_DELETE_STATUS_ARB 0x8B80 -#define GL_OBJECT_COMPILE_STATUS_ARB 0x8B81 -#define GL_OBJECT_LINK_STATUS_ARB 0x8B82 -#define GL_OBJECT_VALIDATE_STATUS_ARB 0x8B83 -#define GL_OBJECT_INFO_LOG_LENGTH_ARB 0x8B84 -#define GL_OBJECT_ATTACHED_OBJECTS_ARB 0x8B85 -#define GL_OBJECT_ACTIVE_UNIFORMS_ARB 0x8B86 -#define GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB 0x8B87 -#define GL_OBJECT_SHADER_SOURCE_LENGTH_ARB 0x8B88 -#endif - -#ifndef GL_ARB_vertex_shader -#define GL_VERTEX_SHADER_ARB 0x8B31 -#define GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB 0x8B4A -#define GL_MAX_VARYING_FLOATS_ARB 0x8B4B -#define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB 0x8B4C -#define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB 0x8B4D -#define GL_OBJECT_ACTIVE_ATTRIBUTES_ARB 0x8B89 -#define GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB 0x8B8A -#endif - -#ifndef GL_ARB_fragment_shader -#define GL_FRAGMENT_SHADER_ARB 0x8B30 -#define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB 0x8B49 -#define GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB 0x8B8B -#endif - -#ifndef GL_ARB_shading_language_100 -#define GL_SHADING_LANGUAGE_VERSION_ARB 0x8B8C -#endif - -#ifndef GL_ARB_texture_non_power_of_two -#endif - -#ifndef GL_ARB_point_sprite -#define GL_POINT_SPRITE_ARB 0x8861 -#define GL_COORD_REPLACE_ARB 0x8862 -#endif - -#ifndef GL_ARB_fragment_program_shadow -#endif - -#ifndef GL_ARB_draw_buffers -#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 -#define GL_DRAW_BUFFER0_ARB 0x8825 -#define GL_DRAW_BUFFER1_ARB 0x8826 -#define GL_DRAW_BUFFER2_ARB 0x8827 -#define GL_DRAW_BUFFER3_ARB 0x8828 -#define GL_DRAW_BUFFER4_ARB 0x8829 -#define GL_DRAW_BUFFER5_ARB 0x882A -#define GL_DRAW_BUFFER6_ARB 0x882B -#define GL_DRAW_BUFFER7_ARB 0x882C -#define GL_DRAW_BUFFER8_ARB 0x882D -#define GL_DRAW_BUFFER9_ARB 0x882E -#define GL_DRAW_BUFFER10_ARB 0x882F -#define GL_DRAW_BUFFER11_ARB 0x8830 -#define GL_DRAW_BUFFER12_ARB 0x8831 -#define GL_DRAW_BUFFER13_ARB 0x8832 -#define GL_DRAW_BUFFER14_ARB 0x8833 -#define GL_DRAW_BUFFER15_ARB 0x8834 -#endif - -#ifndef GL_ARB_texture_rectangle -#define GL_TEXTURE_RECTANGLE_ARB 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 -#endif - -#ifndef GL_ARB_color_buffer_float -#define GL_RGBA_FLOAT_MODE_ARB 0x8820 -#define GL_CLAMP_VERTEX_COLOR_ARB 0x891A -#define GL_CLAMP_FRAGMENT_COLOR_ARB 0x891B -#define GL_CLAMP_READ_COLOR_ARB 0x891C -#define GL_FIXED_ONLY_ARB 0x891D -#endif - -#ifndef GL_ARB_half_float_pixel -#define GL_HALF_FLOAT_ARB 0x140B -#endif - -#ifndef GL_ARB_texture_float -#define GL_TEXTURE_RED_TYPE_ARB 0x8C10 -#define GL_TEXTURE_GREEN_TYPE_ARB 0x8C11 -#define GL_TEXTURE_BLUE_TYPE_ARB 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE_ARB 0x8C13 -#define GL_TEXTURE_LUMINANCE_TYPE_ARB 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE_ARB 0x8C15 -#define GL_TEXTURE_DEPTH_TYPE_ARB 0x8C16 -#define GL_UNSIGNED_NORMALIZED_ARB 0x8C17 -#define GL_RGBA32F_ARB 0x8814 -#define GL_RGB32F_ARB 0x8815 -#define GL_ALPHA32F_ARB 0x8816 -#define GL_INTENSITY32F_ARB 0x8817 -#define GL_LUMINANCE32F_ARB 0x8818 -#define GL_LUMINANCE_ALPHA32F_ARB 0x8819 -#define GL_RGBA16F_ARB 0x881A -#define GL_RGB16F_ARB 0x881B -#define GL_ALPHA16F_ARB 0x881C -#define GL_INTENSITY16F_ARB 0x881D -#define GL_LUMINANCE16F_ARB 0x881E -#define GL_LUMINANCE_ALPHA16F_ARB 0x881F -#endif - -#ifndef GL_ARB_pixel_buffer_object -#define GL_PIXEL_PACK_BUFFER_ARB 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_ARB 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_ARB 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_ARB 0x88EF -#endif - -#ifndef GL_ARB_depth_buffer_float -#define GL_DEPTH_COMPONENT32F 0x8CAC -#define GL_DEPTH32F_STENCIL8 0x8CAD -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD -#endif - -#ifndef GL_ARB_draw_instanced -#endif - -#ifndef GL_ARB_framebuffer_object -#define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 -#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 -#define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 -#define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 -#define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 -#define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 -#define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 -#define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 -#define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 -#define GL_FRAMEBUFFER_DEFAULT 0x8218 -#define GL_FRAMEBUFFER_UNDEFINED 0x8219 -#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A -#define GL_MAX_RENDERBUFFER_SIZE 0x84E8 -#define GL_DEPTH_STENCIL 0x84F9 -#define GL_UNSIGNED_INT_24_8 0x84FA -#define GL_DEPTH24_STENCIL8 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE 0x88F1 -#define GL_TEXTURE_RED_TYPE 0x8C10 -#define GL_TEXTURE_GREEN_TYPE 0x8C11 -#define GL_TEXTURE_BLUE_TYPE 0x8C12 -#define GL_TEXTURE_ALPHA_TYPE 0x8C13 -#define GL_TEXTURE_DEPTH_TYPE 0x8C16 -#define GL_UNSIGNED_NORMALIZED 0x8C17 -#define GL_FRAMEBUFFER_BINDING 0x8CA6 -#define GL_DRAW_FRAMEBUFFER_BINDING GL_FRAMEBUFFER_BINDING -#define GL_RENDERBUFFER_BINDING 0x8CA7 -#define GL_READ_FRAMEBUFFER 0x8CA8 -#define GL_DRAW_FRAMEBUFFER 0x8CA9 -#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA -#define GL_RENDERBUFFER_SAMPLES 0x8CAB -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS 0x8CDF -#define GL_COLOR_ATTACHMENT0 0x8CE0 -#define GL_COLOR_ATTACHMENT1 0x8CE1 -#define GL_COLOR_ATTACHMENT2 0x8CE2 -#define GL_COLOR_ATTACHMENT3 0x8CE3 -#define GL_COLOR_ATTACHMENT4 0x8CE4 -#define GL_COLOR_ATTACHMENT5 0x8CE5 -#define GL_COLOR_ATTACHMENT6 0x8CE6 -#define GL_COLOR_ATTACHMENT7 0x8CE7 -#define GL_COLOR_ATTACHMENT8 0x8CE8 -#define GL_COLOR_ATTACHMENT9 0x8CE9 -#define GL_COLOR_ATTACHMENT10 0x8CEA -#define GL_COLOR_ATTACHMENT11 0x8CEB -#define GL_COLOR_ATTACHMENT12 0x8CEC -#define GL_COLOR_ATTACHMENT13 0x8CED -#define GL_COLOR_ATTACHMENT14 0x8CEE -#define GL_COLOR_ATTACHMENT15 0x8CEF -#define GL_DEPTH_ATTACHMENT 0x8D00 -#define GL_STENCIL_ATTACHMENT 0x8D20 -#define GL_FRAMEBUFFER 0x8D40 -#define GL_RENDERBUFFER 0x8D41 -#define GL_RENDERBUFFER_WIDTH 0x8D42 -#define GL_RENDERBUFFER_HEIGHT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 -#define GL_STENCIL_INDEX1 0x8D46 -#define GL_STENCIL_INDEX4 0x8D47 -#define GL_STENCIL_INDEX8 0x8D48 -#define GL_STENCIL_INDEX16 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 -#define GL_MAX_SAMPLES 0x8D57 -#endif - -#ifndef GL_ARB_framebuffer_object_DEPRECATED -#define GL_INDEX 0x8222 -#define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 -#define GL_TEXTURE_INTENSITY_TYPE 0x8C15 -#endif - -#ifndef GL_ARB_framebuffer_sRGB -#define GL_FRAMEBUFFER_SRGB 0x8DB9 -#endif - -#ifndef GL_ARB_geometry_shader4 -#define GL_LINES_ADJACENCY_ARB 0x000A -#define GL_LINE_STRIP_ADJACENCY_ARB 0x000B -#define GL_TRIANGLES_ADJACENCY_ARB 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY_ARB 0x000D -#define GL_PROGRAM_POINT_SIZE_ARB 0x8642 -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_ARB 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_ARB 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_ARB 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_ARB 0x8DA9 -#define GL_GEOMETRY_SHADER_ARB 0x8DD9 -#define GL_GEOMETRY_VERTICES_OUT_ARB 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_ARB 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_ARB 0x8DDC -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_ARB 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_ARB 0x8DDE -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_ARB 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_ARB 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_ARB 0x8DE1 -/* reuse GL_MAX_VARYING_COMPONENTS */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */ -#endif - -#ifndef GL_ARB_half_float_vertex -#define GL_HALF_FLOAT 0x140B -#endif - -#ifndef GL_ARB_instanced_arrays -#define GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB 0x88FE -#endif - -#ifndef GL_ARB_map_buffer_range -#define GL_MAP_READ_BIT 0x0001 -#define GL_MAP_WRITE_BIT 0x0002 -#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 -#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 -#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 -#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 -#endif - -#ifndef GL_ARB_texture_buffer_object -#define GL_TEXTURE_BUFFER_ARB 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_ARB 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_ARB 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_ARB 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_ARB 0x8C2E -#endif - -#ifndef GL_ARB_texture_compression_rgtc -#define GL_COMPRESSED_RED_RGTC1 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1 0x8DBC -#define GL_COMPRESSED_RG_RGTC2 0x8DBD -#define GL_COMPRESSED_SIGNED_RG_RGTC2 0x8DBE -#endif - -#ifndef GL_ARB_texture_rg -#define GL_RG 0x8227 -#define GL_RG_INTEGER 0x8228 -#define GL_R8 0x8229 -#define GL_R16 0x822A -#define GL_RG8 0x822B -#define GL_RG16 0x822C -#define GL_R16F 0x822D -#define GL_R32F 0x822E -#define GL_RG16F 0x822F -#define GL_RG32F 0x8230 -#define GL_R8I 0x8231 -#define GL_R8UI 0x8232 -#define GL_R16I 0x8233 -#define GL_R16UI 0x8234 -#define GL_R32I 0x8235 -#define GL_R32UI 0x8236 -#define GL_RG8I 0x8237 -#define GL_RG8UI 0x8238 -#define GL_RG16I 0x8239 -#define GL_RG16UI 0x823A -#define GL_RG32I 0x823B -#define GL_RG32UI 0x823C -#endif - -#ifndef GL_ARB_vertex_array_object -#define GL_VERTEX_ARRAY_BINDING 0x85B5 -#endif - -#ifndef GL_ARB_uniform_buffer_object -#define GL_UNIFORM_BUFFER 0x8A11 -#define GL_UNIFORM_BUFFER_BINDING 0x8A28 -#define GL_UNIFORM_BUFFER_START 0x8A29 -#define GL_UNIFORM_BUFFER_SIZE 0x8A2A -#define GL_MAX_VERTEX_UNIFORM_BLOCKS 0x8A2B -#define GL_MAX_GEOMETRY_UNIFORM_BLOCKS 0x8A2C -#define GL_MAX_FRAGMENT_UNIFORM_BLOCKS 0x8A2D -#define GL_MAX_COMBINED_UNIFORM_BLOCKS 0x8A2E -#define GL_MAX_UNIFORM_BUFFER_BINDINGS 0x8A2F -#define GL_MAX_UNIFORM_BLOCK_SIZE 0x8A30 -#define GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS 0x8A31 -#define GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS 0x8A32 -#define GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS 0x8A33 -#define GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT 0x8A34 -#define GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH 0x8A35 -#define GL_ACTIVE_UNIFORM_BLOCKS 0x8A36 -#define GL_UNIFORM_TYPE 0x8A37 -#define GL_UNIFORM_SIZE 0x8A38 -#define GL_UNIFORM_NAME_LENGTH 0x8A39 -#define GL_UNIFORM_BLOCK_INDEX 0x8A3A -#define GL_UNIFORM_OFFSET 0x8A3B -#define GL_UNIFORM_ARRAY_STRIDE 0x8A3C -#define GL_UNIFORM_MATRIX_STRIDE 0x8A3D -#define GL_UNIFORM_IS_ROW_MAJOR 0x8A3E -#define GL_UNIFORM_BLOCK_BINDING 0x8A3F -#define GL_UNIFORM_BLOCK_DATA_SIZE 0x8A40 -#define GL_UNIFORM_BLOCK_NAME_LENGTH 0x8A41 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS 0x8A42 -#define GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES 0x8A43 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER 0x8A44 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER 0x8A45 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER 0x8A46 -#define GL_INVALID_INDEX 0xFFFFFFFFu -#endif - -#ifndef GL_ARB_compatibility -/* ARB_compatibility just defines tokens from core 3.0 */ -#endif - -#ifndef GL_ARB_copy_buffer -#define GL_COPY_READ_BUFFER 0x8F36 -#define GL_COPY_WRITE_BUFFER 0x8F37 -#endif - -#ifndef GL_ARB_shader_texture_lod -#endif - -#ifndef GL_ARB_depth_clamp -#define GL_DEPTH_CLAMP 0x864F -#endif - -#ifndef GL_ARB_draw_elements_base_vertex -#endif - -#ifndef GL_ARB_fragment_coord_conventions -#endif - -#ifndef GL_ARB_provoking_vertex -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION 0x8E4D -#define GL_LAST_VERTEX_CONVENTION 0x8E4E -#define GL_PROVOKING_VERTEX 0x8E4F -#endif - -#ifndef GL_ARB_seamless_cube_map -#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F -#endif - -#ifndef GL_ARB_sync -#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111 -#define GL_OBJECT_TYPE 0x9112 -#define GL_SYNC_CONDITION 0x9113 -#define GL_SYNC_STATUS 0x9114 -#define GL_SYNC_FLAGS 0x9115 -#define GL_SYNC_FENCE 0x9116 -#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 -#define GL_UNSIGNALED 0x9118 -#define GL_SIGNALED 0x9119 -#define GL_ALREADY_SIGNALED 0x911A -#define GL_TIMEOUT_EXPIRED 0x911B -#define GL_CONDITION_SATISFIED 0x911C -#define GL_WAIT_FAILED 0x911D -#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001 -#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull -#endif - -#ifndef GL_ARB_texture_multisample -#define GL_SAMPLE_POSITION 0x8E50 -#define GL_SAMPLE_MASK 0x8E51 -#define GL_SAMPLE_MASK_VALUE 0x8E52 -#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 -#define GL_TEXTURE_2D_MULTISAMPLE 0x9100 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 -#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 -#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 -#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 -#define GL_TEXTURE_SAMPLES 0x9106 -#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 -#define GL_SAMPLER_2D_MULTISAMPLE 0x9108 -#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A -#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B -#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C -#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D -#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E -#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F -#define GL_MAX_INTEGER_SAMPLES 0x9110 -#endif - -#ifndef GL_ARB_vertex_array_bgra -/* reuse GL_BGRA */ -#endif - -#ifndef GL_ARB_draw_buffers_blend -#endif - -#ifndef GL_ARB_sample_shading -#define GL_SAMPLE_SHADING_ARB 0x8C36 -#define GL_MIN_SAMPLE_SHADING_VALUE_ARB 0x8C37 -#endif - -#ifndef GL_ARB_texture_cube_map_array -#define GL_TEXTURE_CUBE_MAP_ARRAY_ARB 0x9009 -#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_ARB 0x900A -#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY_ARB 0x900B -#define GL_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900C -#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW_ARB 0x900D -#define GL_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900E -#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY_ARB 0x900F -#endif - -#ifndef GL_ARB_texture_gather -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_ARB 0x8E5F -#endif - -#ifndef GL_ARB_texture_query_lod -#endif - -#ifndef GL_ARB_shading_language_include -#define GL_SHADER_INCLUDE_ARB 0x8DAE -#define GL_NAMED_STRING_LENGTH_ARB 0x8DE9 -#define GL_NAMED_STRING_TYPE_ARB 0x8DEA -#endif - -#ifndef GL_ARB_texture_compression_bptc -#define GL_COMPRESSED_RGBA_BPTC_UNORM_ARB 0x8E8C -#define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB 0x8E8D -#define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB 0x8E8E -#define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB 0x8E8F -#endif - -#ifndef GL_ARB_blend_func_extended -#define GL_SRC1_COLOR 0x88F9 -/* reuse GL_SRC1_ALPHA */ -#define GL_ONE_MINUS_SRC1_COLOR 0x88FA -#define GL_ONE_MINUS_SRC1_ALPHA 0x88FB -#define GL_MAX_DUAL_SOURCE_DRAW_BUFFERS 0x88FC -#endif - -#ifndef GL_ARB_explicit_attrib_location -#endif - -#ifndef GL_ARB_occlusion_query2 -#define GL_ANY_SAMPLES_PASSED 0x8C2F -#endif - -#ifndef GL_ARB_sampler_objects -#define GL_SAMPLER_BINDING 0x8919 -#endif - -#ifndef GL_ARB_shader_bit_encoding -#endif - -#ifndef GL_ARB_texture_rgb10_a2ui -#define GL_RGB10_A2UI 0x906F -#endif - -#ifndef GL_ARB_texture_swizzle -#define GL_TEXTURE_SWIZZLE_R 0x8E42 -#define GL_TEXTURE_SWIZZLE_G 0x8E43 -#define GL_TEXTURE_SWIZZLE_B 0x8E44 -#define GL_TEXTURE_SWIZZLE_A 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA 0x8E46 -#endif - -#ifndef GL_ARB_timer_query -#define GL_TIME_ELAPSED 0x88BF -#define GL_TIMESTAMP 0x8E28 -#endif - -#ifndef GL_ARB_vertex_type_2_10_10_10_rev -/* reuse GL_UNSIGNED_INT_2_10_10_10_REV */ -#define GL_INT_2_10_10_10_REV 0x8D9F -#endif - -#ifndef GL_ARB_draw_indirect -#define GL_DRAW_INDIRECT_BUFFER 0x8F3F -#define GL_DRAW_INDIRECT_BUFFER_BINDING 0x8F43 -#endif - -#ifndef GL_ARB_gpu_shader5 -#define GL_GEOMETRY_SHADER_INVOCATIONS 0x887F -#define GL_MAX_GEOMETRY_SHADER_INVOCATIONS 0x8E5A -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET 0x8E5C -#define GL_FRAGMENT_INTERPOLATION_OFFSET_BITS 0x8E5D -/* reuse GL_MAX_VERTEX_STREAMS */ -#endif - -#ifndef GL_ARB_gpu_shader_fp64 -/* reuse GL_DOUBLE */ -#define GL_DOUBLE_VEC2 0x8FFC -#define GL_DOUBLE_VEC3 0x8FFD -#define GL_DOUBLE_VEC4 0x8FFE -#define GL_DOUBLE_MAT2 0x8F46 -#define GL_DOUBLE_MAT3 0x8F47 -#define GL_DOUBLE_MAT4 0x8F48 -#define GL_DOUBLE_MAT2x3 0x8F49 -#define GL_DOUBLE_MAT2x4 0x8F4A -#define GL_DOUBLE_MAT3x2 0x8F4B -#define GL_DOUBLE_MAT3x4 0x8F4C -#define GL_DOUBLE_MAT4x2 0x8F4D -#define GL_DOUBLE_MAT4x3 0x8F4E -#endif - -#ifndef GL_ARB_shader_subroutine -#define GL_ACTIVE_SUBROUTINES 0x8DE5 -#define GL_ACTIVE_SUBROUTINE_UNIFORMS 0x8DE6 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_LOCATIONS 0x8E47 -#define GL_ACTIVE_SUBROUTINE_MAX_LENGTH 0x8E48 -#define GL_ACTIVE_SUBROUTINE_UNIFORM_MAX_LENGTH 0x8E49 -#define GL_MAX_SUBROUTINES 0x8DE7 -#define GL_MAX_SUBROUTINE_UNIFORM_LOCATIONS 0x8DE8 -#define GL_NUM_COMPATIBLE_SUBROUTINES 0x8E4A -#define GL_COMPATIBLE_SUBROUTINES 0x8E4B -/* reuse GL_UNIFORM_SIZE */ -/* reuse GL_UNIFORM_NAME_LENGTH */ -#endif - -#ifndef GL_ARB_tessellation_shader -#define GL_PATCHES 0x000E -#define GL_PATCH_VERTICES 0x8E72 -#define GL_PATCH_DEFAULT_INNER_LEVEL 0x8E73 -#define GL_PATCH_DEFAULT_OUTER_LEVEL 0x8E74 -#define GL_TESS_CONTROL_OUTPUT_VERTICES 0x8E75 -#define GL_TESS_GEN_MODE 0x8E76 -#define GL_TESS_GEN_SPACING 0x8E77 -#define GL_TESS_GEN_VERTEX_ORDER 0x8E78 -#define GL_TESS_GEN_POINT_MODE 0x8E79 -/* reuse GL_TRIANGLES */ -/* reuse GL_QUADS */ -#define GL_ISOLINES 0x8E7A -/* reuse GL_EQUAL */ -#define GL_FRACTIONAL_ODD 0x8E7B -#define GL_FRACTIONAL_EVEN 0x8E7C -/* reuse GL_CCW */ -/* reuse GL_CW */ -#define GL_MAX_PATCH_VERTICES 0x8E7D -#define GL_MAX_TESS_GEN_LEVEL 0x8E7E -#define GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E7F -#define GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E80 -#define GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS 0x8E81 -#define GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS 0x8E82 -#define GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS 0x8E83 -#define GL_MAX_TESS_PATCH_COMPONENTS 0x8E84 -#define GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS 0x8E85 -#define GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS 0x8E86 -#define GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS 0x8E89 -#define GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS 0x8E8A -#define GL_MAX_TESS_CONTROL_INPUT_COMPONENTS 0x886C -#define GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS 0x886D -#define GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS 0x8E1E -#define GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS 0x8E1F -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_CONTROL_SHADER 0x84F0 -#define GL_UNIFORM_BLOCK_REFERENCED_BY_TESS_EVALUATION_SHADER 0x84F1 -#define GL_TESS_EVALUATION_SHADER 0x8E87 -#define GL_TESS_CONTROL_SHADER 0x8E88 -#endif - -#ifndef GL_ARB_texture_buffer_object_rgb32 -/* reuse GL_RGB32F */ -/* reuse GL_RGB32UI */ -/* reuse GL_RGB32I */ -#endif - -#ifndef GL_ARB_transform_feedback2 -#define GL_TRANSFORM_FEEDBACK 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING 0x8E25 -#endif - -#ifndef GL_ARB_transform_feedback3 -#define GL_MAX_TRANSFORM_FEEDBACK_BUFFERS 0x8E70 -#define GL_MAX_VERTEX_STREAMS 0x8E71 -#endif - -#ifndef GL_ARB_ES2_compatibility -#define GL_FIXED 0x140C -#define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B -#define GL_LOW_FLOAT 0x8DF0 -#define GL_MEDIUM_FLOAT 0x8DF1 -#define GL_HIGH_FLOAT 0x8DF2 -#define GL_LOW_INT 0x8DF3 -#define GL_MEDIUM_INT 0x8DF4 -#define GL_HIGH_INT 0x8DF5 -#define GL_SHADER_COMPILER 0x8DFA -#define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 -#define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB -#define GL_MAX_VARYING_VECTORS 0x8DFC -#define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD -#endif - -#ifndef GL_ARB_get_program_binary -#define GL_PROGRAM_BINARY_RETRIEVABLE_HINT 0x8257 -#define GL_PROGRAM_BINARY_LENGTH 0x8741 -#define GL_NUM_PROGRAM_BINARY_FORMATS 0x87FE -#define GL_PROGRAM_BINARY_FORMATS 0x87FF -#endif - -#ifndef GL_ARB_separate_shader_objects -#define GL_VERTEX_SHADER_BIT 0x00000001 -#define GL_FRAGMENT_SHADER_BIT 0x00000002 -#define GL_GEOMETRY_SHADER_BIT 0x00000004 -#define GL_TESS_CONTROL_SHADER_BIT 0x00000008 -#define GL_TESS_EVALUATION_SHADER_BIT 0x00000010 -#define GL_ALL_SHADER_BITS 0xFFFFFFFF -#define GL_PROGRAM_SEPARABLE 0x8258 -#define GL_ACTIVE_PROGRAM 0x8259 -#define GL_PROGRAM_PIPELINE_BINDING 0x825A -#endif - -#ifndef GL_ARB_shader_precision -#endif - -#ifndef GL_ARB_vertex_attrib_64bit -/* reuse GL_RGB32I */ -/* reuse GL_DOUBLE_VEC2 */ -/* reuse GL_DOUBLE_VEC3 */ -/* reuse GL_DOUBLE_VEC4 */ -/* reuse GL_DOUBLE_MAT2 */ -/* reuse GL_DOUBLE_MAT3 */ -/* reuse GL_DOUBLE_MAT4 */ -/* reuse GL_DOUBLE_MAT2x3 */ -/* reuse GL_DOUBLE_MAT2x4 */ -/* reuse GL_DOUBLE_MAT3x2 */ -/* reuse GL_DOUBLE_MAT3x4 */ -/* reuse GL_DOUBLE_MAT4x2 */ -/* reuse GL_DOUBLE_MAT4x3 */ -#endif - -#ifndef GL_ARB_viewport_array -/* reuse GL_SCISSOR_BOX */ -/* reuse GL_VIEWPORT */ -/* reuse GL_DEPTH_RANGE */ -/* reuse GL_SCISSOR_TEST */ -#define GL_MAX_VIEWPORTS 0x825B -#define GL_VIEWPORT_SUBPIXEL_BITS 0x825C -#define GL_VIEWPORT_BOUNDS_RANGE 0x825D -#define GL_LAYER_PROVOKING_VERTEX 0x825E -#define GL_VIEWPORT_INDEX_PROVOKING_VERTEX 0x825F -#define GL_UNDEFINED_VERTEX 0x8260 -/* reuse GL_FIRST_VERTEX_CONVENTION */ -/* reuse GL_LAST_VERTEX_CONVENTION */ -/* reuse GL_PROVOKING_VERTEX */ -#endif - -#ifndef GL_ARB_cl_event -#define GL_SYNC_CL_EVENT_ARB 0x8240 -#define GL_SYNC_CL_EVENT_COMPLETE_ARB 0x8241 -#endif - -#ifndef GL_ARB_debug_output -#define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 -#define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 -#define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 -#define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 -#define GL_DEBUG_SOURCE_API_ARB 0x8246 -#define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 -#define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 -#define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 -#define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A -#define GL_DEBUG_SOURCE_OTHER_ARB 0x824B -#define GL_DEBUG_TYPE_ERROR_ARB 0x824C -#define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D -#define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E -#define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F -#define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 -#define GL_DEBUG_TYPE_OTHER_ARB 0x8251 -#define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 -#define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 -#define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 -#endif - -#ifndef GL_ARB_robustness -/* reuse GL_NO_ERROR */ -#define GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define GL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define GL_GUILTY_CONTEXT_RESET_ARB 0x8253 -#define GL_INNOCENT_CONTEXT_RESET_ARB 0x8254 -#define GL_UNKNOWN_CONTEXT_RESET_ARB 0x8255 -#define GL_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define GL_NO_RESET_NOTIFICATION_ARB 0x8261 -#endif - -#ifndef GL_ARB_shader_stencil_export -#endif - -#ifndef GL_EXT_abgr -#define GL_ABGR_EXT 0x8000 -#endif - -#ifndef GL_EXT_blend_color -#define GL_CONSTANT_COLOR_EXT 0x8001 -#define GL_ONE_MINUS_CONSTANT_COLOR_EXT 0x8002 -#define GL_CONSTANT_ALPHA_EXT 0x8003 -#define GL_ONE_MINUS_CONSTANT_ALPHA_EXT 0x8004 -#define GL_BLEND_COLOR_EXT 0x8005 -#endif - -#ifndef GL_EXT_polygon_offset -#define GL_POLYGON_OFFSET_EXT 0x8037 -#define GL_POLYGON_OFFSET_FACTOR_EXT 0x8038 -#define GL_POLYGON_OFFSET_BIAS_EXT 0x8039 -#endif - -#ifndef GL_EXT_texture -#define GL_ALPHA4_EXT 0x803B -#define GL_ALPHA8_EXT 0x803C -#define GL_ALPHA12_EXT 0x803D -#define GL_ALPHA16_EXT 0x803E -#define GL_LUMINANCE4_EXT 0x803F -#define GL_LUMINANCE8_EXT 0x8040 -#define GL_LUMINANCE12_EXT 0x8041 -#define GL_LUMINANCE16_EXT 0x8042 -#define GL_LUMINANCE4_ALPHA4_EXT 0x8043 -#define GL_LUMINANCE6_ALPHA2_EXT 0x8044 -#define GL_LUMINANCE8_ALPHA8_EXT 0x8045 -#define GL_LUMINANCE12_ALPHA4_EXT 0x8046 -#define GL_LUMINANCE12_ALPHA12_EXT 0x8047 -#define GL_LUMINANCE16_ALPHA16_EXT 0x8048 -#define GL_INTENSITY_EXT 0x8049 -#define GL_INTENSITY4_EXT 0x804A -#define GL_INTENSITY8_EXT 0x804B -#define GL_INTENSITY12_EXT 0x804C -#define GL_INTENSITY16_EXT 0x804D -#define GL_RGB2_EXT 0x804E -#define GL_RGB4_EXT 0x804F -#define GL_RGB5_EXT 0x8050 -#define GL_RGB8_EXT 0x8051 -#define GL_RGB10_EXT 0x8052 -#define GL_RGB12_EXT 0x8053 -#define GL_RGB16_EXT 0x8054 -#define GL_RGBA2_EXT 0x8055 -#define GL_RGBA4_EXT 0x8056 -#define GL_RGB5_A1_EXT 0x8057 -#define GL_RGBA8_EXT 0x8058 -#define GL_RGB10_A2_EXT 0x8059 -#define GL_RGBA12_EXT 0x805A -#define GL_RGBA16_EXT 0x805B -#define GL_TEXTURE_RED_SIZE_EXT 0x805C -#define GL_TEXTURE_GREEN_SIZE_EXT 0x805D -#define GL_TEXTURE_BLUE_SIZE_EXT 0x805E -#define GL_TEXTURE_ALPHA_SIZE_EXT 0x805F -#define GL_TEXTURE_LUMINANCE_SIZE_EXT 0x8060 -#define GL_TEXTURE_INTENSITY_SIZE_EXT 0x8061 -#define GL_REPLACE_EXT 0x8062 -#define GL_PROXY_TEXTURE_1D_EXT 0x8063 -#define GL_PROXY_TEXTURE_2D_EXT 0x8064 -#define GL_TEXTURE_TOO_LARGE_EXT 0x8065 -#endif - -#ifndef GL_EXT_texture3D -#define GL_PACK_SKIP_IMAGES_EXT 0x806B -#define GL_PACK_IMAGE_HEIGHT_EXT 0x806C -#define GL_UNPACK_SKIP_IMAGES_EXT 0x806D -#define GL_UNPACK_IMAGE_HEIGHT_EXT 0x806E -#define GL_TEXTURE_3D_EXT 0x806F -#define GL_PROXY_TEXTURE_3D_EXT 0x8070 -#define GL_TEXTURE_DEPTH_EXT 0x8071 -#define GL_TEXTURE_WRAP_R_EXT 0x8072 -#define GL_MAX_3D_TEXTURE_SIZE_EXT 0x8073 -#endif - -#ifndef GL_SGIS_texture_filter4 -#define GL_FILTER4_SGIS 0x8146 -#define GL_TEXTURE_FILTER4_SIZE_SGIS 0x8147 -#endif - -#ifndef GL_EXT_subtexture -#endif - -#ifndef GL_EXT_copy_texture -#endif - -#ifndef GL_EXT_histogram -#define GL_HISTOGRAM_EXT 0x8024 -#define GL_PROXY_HISTOGRAM_EXT 0x8025 -#define GL_HISTOGRAM_WIDTH_EXT 0x8026 -#define GL_HISTOGRAM_FORMAT_EXT 0x8027 -#define GL_HISTOGRAM_RED_SIZE_EXT 0x8028 -#define GL_HISTOGRAM_GREEN_SIZE_EXT 0x8029 -#define GL_HISTOGRAM_BLUE_SIZE_EXT 0x802A -#define GL_HISTOGRAM_ALPHA_SIZE_EXT 0x802B -#define GL_HISTOGRAM_LUMINANCE_SIZE_EXT 0x802C -#define GL_HISTOGRAM_SINK_EXT 0x802D -#define GL_MINMAX_EXT 0x802E -#define GL_MINMAX_FORMAT_EXT 0x802F -#define GL_MINMAX_SINK_EXT 0x8030 -#define GL_TABLE_TOO_LARGE_EXT 0x8031 -#endif - -#ifndef GL_EXT_convolution -#define GL_CONVOLUTION_1D_EXT 0x8010 -#define GL_CONVOLUTION_2D_EXT 0x8011 -#define GL_SEPARABLE_2D_EXT 0x8012 -#define GL_CONVOLUTION_BORDER_MODE_EXT 0x8013 -#define GL_CONVOLUTION_FILTER_SCALE_EXT 0x8014 -#define GL_CONVOLUTION_FILTER_BIAS_EXT 0x8015 -#define GL_REDUCE_EXT 0x8016 -#define GL_CONVOLUTION_FORMAT_EXT 0x8017 -#define GL_CONVOLUTION_WIDTH_EXT 0x8018 -#define GL_CONVOLUTION_HEIGHT_EXT 0x8019 -#define GL_MAX_CONVOLUTION_WIDTH_EXT 0x801A -#define GL_MAX_CONVOLUTION_HEIGHT_EXT 0x801B -#define GL_POST_CONVOLUTION_RED_SCALE_EXT 0x801C -#define GL_POST_CONVOLUTION_GREEN_SCALE_EXT 0x801D -#define GL_POST_CONVOLUTION_BLUE_SCALE_EXT 0x801E -#define GL_POST_CONVOLUTION_ALPHA_SCALE_EXT 0x801F -#define GL_POST_CONVOLUTION_RED_BIAS_EXT 0x8020 -#define GL_POST_CONVOLUTION_GREEN_BIAS_EXT 0x8021 -#define GL_POST_CONVOLUTION_BLUE_BIAS_EXT 0x8022 -#define GL_POST_CONVOLUTION_ALPHA_BIAS_EXT 0x8023 -#endif - -#ifndef GL_SGI_color_matrix -#define GL_COLOR_MATRIX_SGI 0x80B1 -#define GL_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B2 -#define GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI 0x80B3 -#define GL_POST_COLOR_MATRIX_RED_SCALE_SGI 0x80B4 -#define GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI 0x80B5 -#define GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI 0x80B6 -#define GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI 0x80B7 -#define GL_POST_COLOR_MATRIX_RED_BIAS_SGI 0x80B8 -#define GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI 0x80B9 -#define GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI 0x80BA -#define GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI 0x80BB -#endif - -#ifndef GL_SGI_color_table -#define GL_COLOR_TABLE_SGI 0x80D0 -#define GL_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D1 -#define GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D2 -#define GL_PROXY_COLOR_TABLE_SGI 0x80D3 -#define GL_PROXY_POST_CONVOLUTION_COLOR_TABLE_SGI 0x80D4 -#define GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE_SGI 0x80D5 -#define GL_COLOR_TABLE_SCALE_SGI 0x80D6 -#define GL_COLOR_TABLE_BIAS_SGI 0x80D7 -#define GL_COLOR_TABLE_FORMAT_SGI 0x80D8 -#define GL_COLOR_TABLE_WIDTH_SGI 0x80D9 -#define GL_COLOR_TABLE_RED_SIZE_SGI 0x80DA -#define GL_COLOR_TABLE_GREEN_SIZE_SGI 0x80DB -#define GL_COLOR_TABLE_BLUE_SIZE_SGI 0x80DC -#define GL_COLOR_TABLE_ALPHA_SIZE_SGI 0x80DD -#define GL_COLOR_TABLE_LUMINANCE_SIZE_SGI 0x80DE -#define GL_COLOR_TABLE_INTENSITY_SIZE_SGI 0x80DF -#endif - -#ifndef GL_SGIS_pixel_texture -#define GL_PIXEL_TEXTURE_SGIS 0x8353 -#define GL_PIXEL_FRAGMENT_RGB_SOURCE_SGIS 0x8354 -#define GL_PIXEL_FRAGMENT_ALPHA_SOURCE_SGIS 0x8355 -#define GL_PIXEL_GROUP_COLOR_SGIS 0x8356 -#endif - -#ifndef GL_SGIX_pixel_texture -#define GL_PIXEL_TEX_GEN_SGIX 0x8139 -#define GL_PIXEL_TEX_GEN_MODE_SGIX 0x832B -#endif - -#ifndef GL_SGIS_texture4D -#define GL_PACK_SKIP_VOLUMES_SGIS 0x8130 -#define GL_PACK_IMAGE_DEPTH_SGIS 0x8131 -#define GL_UNPACK_SKIP_VOLUMES_SGIS 0x8132 -#define GL_UNPACK_IMAGE_DEPTH_SGIS 0x8133 -#define GL_TEXTURE_4D_SGIS 0x8134 -#define GL_PROXY_TEXTURE_4D_SGIS 0x8135 -#define GL_TEXTURE_4DSIZE_SGIS 0x8136 -#define GL_TEXTURE_WRAP_Q_SGIS 0x8137 -#define GL_MAX_4D_TEXTURE_SIZE_SGIS 0x8138 -#define GL_TEXTURE_4D_BINDING_SGIS 0x814F -#endif - -#ifndef GL_SGI_texture_color_table -#define GL_TEXTURE_COLOR_TABLE_SGI 0x80BC -#define GL_PROXY_TEXTURE_COLOR_TABLE_SGI 0x80BD -#endif - -#ifndef GL_EXT_cmyka -#define GL_CMYK_EXT 0x800C -#define GL_CMYKA_EXT 0x800D -#define GL_PACK_CMYK_HINT_EXT 0x800E -#define GL_UNPACK_CMYK_HINT_EXT 0x800F -#endif - -#ifndef GL_EXT_texture_object -#define GL_TEXTURE_PRIORITY_EXT 0x8066 -#define GL_TEXTURE_RESIDENT_EXT 0x8067 -#define GL_TEXTURE_1D_BINDING_EXT 0x8068 -#define GL_TEXTURE_2D_BINDING_EXT 0x8069 -#define GL_TEXTURE_3D_BINDING_EXT 0x806A -#endif - -#ifndef GL_SGIS_detail_texture -#define GL_DETAIL_TEXTURE_2D_SGIS 0x8095 -#define GL_DETAIL_TEXTURE_2D_BINDING_SGIS 0x8096 -#define GL_LINEAR_DETAIL_SGIS 0x8097 -#define GL_LINEAR_DETAIL_ALPHA_SGIS 0x8098 -#define GL_LINEAR_DETAIL_COLOR_SGIS 0x8099 -#define GL_DETAIL_TEXTURE_LEVEL_SGIS 0x809A -#define GL_DETAIL_TEXTURE_MODE_SGIS 0x809B -#define GL_DETAIL_TEXTURE_FUNC_POINTS_SGIS 0x809C -#endif - -#ifndef GL_SGIS_sharpen_texture -#define GL_LINEAR_SHARPEN_SGIS 0x80AD -#define GL_LINEAR_SHARPEN_ALPHA_SGIS 0x80AE -#define GL_LINEAR_SHARPEN_COLOR_SGIS 0x80AF -#define GL_SHARPEN_TEXTURE_FUNC_POINTS_SGIS 0x80B0 -#endif - -#ifndef GL_EXT_packed_pixels -#define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 -#define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 -#define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 -#define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 -#define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 -#endif - -#ifndef GL_SGIS_texture_lod -#define GL_TEXTURE_MIN_LOD_SGIS 0x813A -#define GL_TEXTURE_MAX_LOD_SGIS 0x813B -#define GL_TEXTURE_BASE_LEVEL_SGIS 0x813C -#define GL_TEXTURE_MAX_LEVEL_SGIS 0x813D -#endif - -#ifndef GL_SGIS_multisample -#define GL_MULTISAMPLE_SGIS 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_SGIS 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_SGIS 0x809F -#define GL_SAMPLE_MASK_SGIS 0x80A0 -#define GL_1PASS_SGIS 0x80A1 -#define GL_2PASS_0_SGIS 0x80A2 -#define GL_2PASS_1_SGIS 0x80A3 -#define GL_4PASS_0_SGIS 0x80A4 -#define GL_4PASS_1_SGIS 0x80A5 -#define GL_4PASS_2_SGIS 0x80A6 -#define GL_4PASS_3_SGIS 0x80A7 -#define GL_SAMPLE_BUFFERS_SGIS 0x80A8 -#define GL_SAMPLES_SGIS 0x80A9 -#define GL_SAMPLE_MASK_VALUE_SGIS 0x80AA -#define GL_SAMPLE_MASK_INVERT_SGIS 0x80AB -#define GL_SAMPLE_PATTERN_SGIS 0x80AC -#endif - -#ifndef GL_EXT_rescale_normal -#define GL_RESCALE_NORMAL_EXT 0x803A -#endif - -#ifndef GL_EXT_vertex_array -#define GL_VERTEX_ARRAY_EXT 0x8074 -#define GL_NORMAL_ARRAY_EXT 0x8075 -#define GL_COLOR_ARRAY_EXT 0x8076 -#define GL_INDEX_ARRAY_EXT 0x8077 -#define GL_TEXTURE_COORD_ARRAY_EXT 0x8078 -#define GL_EDGE_FLAG_ARRAY_EXT 0x8079 -#define GL_VERTEX_ARRAY_SIZE_EXT 0x807A -#define GL_VERTEX_ARRAY_TYPE_EXT 0x807B -#define GL_VERTEX_ARRAY_STRIDE_EXT 0x807C -#define GL_VERTEX_ARRAY_COUNT_EXT 0x807D -#define GL_NORMAL_ARRAY_TYPE_EXT 0x807E -#define GL_NORMAL_ARRAY_STRIDE_EXT 0x807F -#define GL_NORMAL_ARRAY_COUNT_EXT 0x8080 -#define GL_COLOR_ARRAY_SIZE_EXT 0x8081 -#define GL_COLOR_ARRAY_TYPE_EXT 0x8082 -#define GL_COLOR_ARRAY_STRIDE_EXT 0x8083 -#define GL_COLOR_ARRAY_COUNT_EXT 0x8084 -#define GL_INDEX_ARRAY_TYPE_EXT 0x8085 -#define GL_INDEX_ARRAY_STRIDE_EXT 0x8086 -#define GL_INDEX_ARRAY_COUNT_EXT 0x8087 -#define GL_TEXTURE_COORD_ARRAY_SIZE_EXT 0x8088 -#define GL_TEXTURE_COORD_ARRAY_TYPE_EXT 0x8089 -#define GL_TEXTURE_COORD_ARRAY_STRIDE_EXT 0x808A -#define GL_TEXTURE_COORD_ARRAY_COUNT_EXT 0x808B -#define GL_EDGE_FLAG_ARRAY_STRIDE_EXT 0x808C -#define GL_EDGE_FLAG_ARRAY_COUNT_EXT 0x808D -#define GL_VERTEX_ARRAY_POINTER_EXT 0x808E -#define GL_NORMAL_ARRAY_POINTER_EXT 0x808F -#define GL_COLOR_ARRAY_POINTER_EXT 0x8090 -#define GL_INDEX_ARRAY_POINTER_EXT 0x8091 -#define GL_TEXTURE_COORD_ARRAY_POINTER_EXT 0x8092 -#define GL_EDGE_FLAG_ARRAY_POINTER_EXT 0x8093 -#endif - -#ifndef GL_EXT_misc_attribute -#endif - -#ifndef GL_SGIS_generate_mipmap -#define GL_GENERATE_MIPMAP_SGIS 0x8191 -#define GL_GENERATE_MIPMAP_HINT_SGIS 0x8192 -#endif - -#ifndef GL_SGIX_clipmap -#define GL_LINEAR_CLIPMAP_LINEAR_SGIX 0x8170 -#define GL_TEXTURE_CLIPMAP_CENTER_SGIX 0x8171 -#define GL_TEXTURE_CLIPMAP_FRAME_SGIX 0x8172 -#define GL_TEXTURE_CLIPMAP_OFFSET_SGIX 0x8173 -#define GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8174 -#define GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX 0x8175 -#define GL_TEXTURE_CLIPMAP_DEPTH_SGIX 0x8176 -#define GL_MAX_CLIPMAP_DEPTH_SGIX 0x8177 -#define GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX 0x8178 -#define GL_NEAREST_CLIPMAP_NEAREST_SGIX 0x844D -#define GL_NEAREST_CLIPMAP_LINEAR_SGIX 0x844E -#define GL_LINEAR_CLIPMAP_NEAREST_SGIX 0x844F -#endif - -#ifndef GL_SGIX_shadow -#define GL_TEXTURE_COMPARE_SGIX 0x819A -#define GL_TEXTURE_COMPARE_OPERATOR_SGIX 0x819B -#define GL_TEXTURE_LEQUAL_R_SGIX 0x819C -#define GL_TEXTURE_GEQUAL_R_SGIX 0x819D -#endif - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_CLAMP_TO_EDGE_SGIS 0x812F -#endif - -#ifndef GL_SGIS_texture_border_clamp -#define GL_CLAMP_TO_BORDER_SGIS 0x812D -#endif - -#ifndef GL_EXT_blend_minmax -#define GL_FUNC_ADD_EXT 0x8006 -#define GL_MIN_EXT 0x8007 -#define GL_MAX_EXT 0x8008 -#define GL_BLEND_EQUATION_EXT 0x8009 -#endif - -#ifndef GL_EXT_blend_subtract -#define GL_FUNC_SUBTRACT_EXT 0x800A -#define GL_FUNC_REVERSE_SUBTRACT_EXT 0x800B -#endif - -#ifndef GL_EXT_blend_logic_op -#endif - -#ifndef GL_SGIX_interlace -#define GL_INTERLACE_SGIX 0x8094 -#endif - -#ifndef GL_SGIX_pixel_tiles -#define GL_PIXEL_TILE_BEST_ALIGNMENT_SGIX 0x813E -#define GL_PIXEL_TILE_CACHE_INCREMENT_SGIX 0x813F -#define GL_PIXEL_TILE_WIDTH_SGIX 0x8140 -#define GL_PIXEL_TILE_HEIGHT_SGIX 0x8141 -#define GL_PIXEL_TILE_GRID_WIDTH_SGIX 0x8142 -#define GL_PIXEL_TILE_GRID_HEIGHT_SGIX 0x8143 -#define GL_PIXEL_TILE_GRID_DEPTH_SGIX 0x8144 -#define GL_PIXEL_TILE_CACHE_SIZE_SGIX 0x8145 -#endif - -#ifndef GL_SGIS_texture_select -#define GL_DUAL_ALPHA4_SGIS 0x8110 -#define GL_DUAL_ALPHA8_SGIS 0x8111 -#define GL_DUAL_ALPHA12_SGIS 0x8112 -#define GL_DUAL_ALPHA16_SGIS 0x8113 -#define GL_DUAL_LUMINANCE4_SGIS 0x8114 -#define GL_DUAL_LUMINANCE8_SGIS 0x8115 -#define GL_DUAL_LUMINANCE12_SGIS 0x8116 -#define GL_DUAL_LUMINANCE16_SGIS 0x8117 -#define GL_DUAL_INTENSITY4_SGIS 0x8118 -#define GL_DUAL_INTENSITY8_SGIS 0x8119 -#define GL_DUAL_INTENSITY12_SGIS 0x811A -#define GL_DUAL_INTENSITY16_SGIS 0x811B -#define GL_DUAL_LUMINANCE_ALPHA4_SGIS 0x811C -#define GL_DUAL_LUMINANCE_ALPHA8_SGIS 0x811D -#define GL_QUAD_ALPHA4_SGIS 0x811E -#define GL_QUAD_ALPHA8_SGIS 0x811F -#define GL_QUAD_LUMINANCE4_SGIS 0x8120 -#define GL_QUAD_LUMINANCE8_SGIS 0x8121 -#define GL_QUAD_INTENSITY4_SGIS 0x8122 -#define GL_QUAD_INTENSITY8_SGIS 0x8123 -#define GL_DUAL_TEXTURE_SELECT_SGIS 0x8124 -#define GL_QUAD_TEXTURE_SELECT_SGIS 0x8125 -#endif - -#ifndef GL_SGIX_sprite -#define GL_SPRITE_SGIX 0x8148 -#define GL_SPRITE_MODE_SGIX 0x8149 -#define GL_SPRITE_AXIS_SGIX 0x814A -#define GL_SPRITE_TRANSLATION_SGIX 0x814B -#define GL_SPRITE_AXIAL_SGIX 0x814C -#define GL_SPRITE_OBJECT_ALIGNED_SGIX 0x814D -#define GL_SPRITE_EYE_ALIGNED_SGIX 0x814E -#endif - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_TEXTURE_MULTI_BUFFER_HINT_SGIX 0x812E -#endif - -#ifndef GL_EXT_point_parameters -#define GL_POINT_SIZE_MIN_EXT 0x8126 -#define GL_POINT_SIZE_MAX_EXT 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_EXT 0x8128 -#define GL_DISTANCE_ATTENUATION_EXT 0x8129 -#endif - -#ifndef GL_SGIS_point_parameters -#define GL_POINT_SIZE_MIN_SGIS 0x8126 -#define GL_POINT_SIZE_MAX_SGIS 0x8127 -#define GL_POINT_FADE_THRESHOLD_SIZE_SGIS 0x8128 -#define GL_DISTANCE_ATTENUATION_SGIS 0x8129 -#endif - -#ifndef GL_SGIX_instruments -#define GL_INSTRUMENT_BUFFER_POINTER_SGIX 0x8180 -#define GL_INSTRUMENT_MEASUREMENTS_SGIX 0x8181 -#endif - -#ifndef GL_SGIX_texture_scale_bias -#define GL_POST_TEXTURE_FILTER_BIAS_SGIX 0x8179 -#define GL_POST_TEXTURE_FILTER_SCALE_SGIX 0x817A -#define GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX 0x817B -#define GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX 0x817C -#endif - -#ifndef GL_SGIX_framezoom -#define GL_FRAMEZOOM_SGIX 0x818B -#define GL_FRAMEZOOM_FACTOR_SGIX 0x818C -#define GL_MAX_FRAMEZOOM_FACTOR_SGIX 0x818D -#endif - -#ifndef GL_SGIX_tag_sample_buffer -#endif - -#ifndef GL_FfdMaskSGIX -#define GL_TEXTURE_DEFORMATION_BIT_SGIX 0x00000001 -#define GL_GEOMETRY_DEFORMATION_BIT_SGIX 0x00000002 -#endif - -#ifndef GL_SGIX_polynomial_ffd -#define GL_GEOMETRY_DEFORMATION_SGIX 0x8194 -#define GL_TEXTURE_DEFORMATION_SGIX 0x8195 -#define GL_DEFORMATIONS_MASK_SGIX 0x8196 -#define GL_MAX_DEFORMATION_ORDER_SGIX 0x8197 -#endif - -#ifndef GL_SGIX_reference_plane -#define GL_REFERENCE_PLANE_SGIX 0x817D -#define GL_REFERENCE_PLANE_EQUATION_SGIX 0x817E -#endif - -#ifndef GL_SGIX_flush_raster -#endif - -#ifndef GL_SGIX_depth_texture -#define GL_DEPTH_COMPONENT16_SGIX 0x81A5 -#define GL_DEPTH_COMPONENT24_SGIX 0x81A6 -#define GL_DEPTH_COMPONENT32_SGIX 0x81A7 -#endif - -#ifndef GL_SGIS_fog_function -#define GL_FOG_FUNC_SGIS 0x812A -#define GL_FOG_FUNC_POINTS_SGIS 0x812B -#define GL_MAX_FOG_FUNC_POINTS_SGIS 0x812C -#endif - -#ifndef GL_SGIX_fog_offset -#define GL_FOG_OFFSET_SGIX 0x8198 -#define GL_FOG_OFFSET_VALUE_SGIX 0x8199 -#endif - -#ifndef GL_HP_image_transform -#define GL_IMAGE_SCALE_X_HP 0x8155 -#define GL_IMAGE_SCALE_Y_HP 0x8156 -#define GL_IMAGE_TRANSLATE_X_HP 0x8157 -#define GL_IMAGE_TRANSLATE_Y_HP 0x8158 -#define GL_IMAGE_ROTATE_ANGLE_HP 0x8159 -#define GL_IMAGE_ROTATE_ORIGIN_X_HP 0x815A -#define GL_IMAGE_ROTATE_ORIGIN_Y_HP 0x815B -#define GL_IMAGE_MAG_FILTER_HP 0x815C -#define GL_IMAGE_MIN_FILTER_HP 0x815D -#define GL_IMAGE_CUBIC_WEIGHT_HP 0x815E -#define GL_CUBIC_HP 0x815F -#define GL_AVERAGE_HP 0x8160 -#define GL_IMAGE_TRANSFORM_2D_HP 0x8161 -#define GL_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8162 -#define GL_PROXY_POST_IMAGE_TRANSFORM_COLOR_TABLE_HP 0x8163 -#endif - -#ifndef GL_HP_convolution_border_modes -#define GL_IGNORE_BORDER_HP 0x8150 -#define GL_CONSTANT_BORDER_HP 0x8151 -#define GL_REPLICATE_BORDER_HP 0x8153 -#define GL_CONVOLUTION_BORDER_COLOR_HP 0x8154 -#endif - -#ifndef GL_INGR_palette_buffer -#endif - -#ifndef GL_SGIX_texture_add_env -#define GL_TEXTURE_ENV_BIAS_SGIX 0x80BE -#endif - -#ifndef GL_EXT_color_subtable -#endif - -#ifndef GL_PGI_vertex_hints -#define GL_VERTEX_DATA_HINT_PGI 0x1A22A -#define GL_VERTEX_CONSISTENT_HINT_PGI 0x1A22B -#define GL_MATERIAL_SIDE_HINT_PGI 0x1A22C -#define GL_MAX_VERTEX_HINT_PGI 0x1A22D -#define GL_COLOR3_BIT_PGI 0x00010000 -#define GL_COLOR4_BIT_PGI 0x00020000 -#define GL_EDGEFLAG_BIT_PGI 0x00040000 -#define GL_INDEX_BIT_PGI 0x00080000 -#define GL_MAT_AMBIENT_BIT_PGI 0x00100000 -#define GL_MAT_AMBIENT_AND_DIFFUSE_BIT_PGI 0x00200000 -#define GL_MAT_DIFFUSE_BIT_PGI 0x00400000 -#define GL_MAT_EMISSION_BIT_PGI 0x00800000 -#define GL_MAT_COLOR_INDEXES_BIT_PGI 0x01000000 -#define GL_MAT_SHININESS_BIT_PGI 0x02000000 -#define GL_MAT_SPECULAR_BIT_PGI 0x04000000 -#define GL_NORMAL_BIT_PGI 0x08000000 -#define GL_TEXCOORD1_BIT_PGI 0x10000000 -#define GL_TEXCOORD2_BIT_PGI 0x20000000 -#define GL_TEXCOORD3_BIT_PGI 0x40000000 -#define GL_TEXCOORD4_BIT_PGI 0x80000000 -#define GL_VERTEX23_BIT_PGI 0x00000004 -#define GL_VERTEX4_BIT_PGI 0x00000008 -#endif - -#ifndef GL_PGI_misc_hints -#define GL_PREFER_DOUBLEBUFFER_HINT_PGI 0x1A1F8 -#define GL_CONSERVE_MEMORY_HINT_PGI 0x1A1FD -#define GL_RECLAIM_MEMORY_HINT_PGI 0x1A1FE -#define GL_NATIVE_GRAPHICS_HANDLE_PGI 0x1A202 -#define GL_NATIVE_GRAPHICS_BEGIN_HINT_PGI 0x1A203 -#define GL_NATIVE_GRAPHICS_END_HINT_PGI 0x1A204 -#define GL_ALWAYS_FAST_HINT_PGI 0x1A20C -#define GL_ALWAYS_SOFT_HINT_PGI 0x1A20D -#define GL_ALLOW_DRAW_OBJ_HINT_PGI 0x1A20E -#define GL_ALLOW_DRAW_WIN_HINT_PGI 0x1A20F -#define GL_ALLOW_DRAW_FRG_HINT_PGI 0x1A210 -#define GL_ALLOW_DRAW_MEM_HINT_PGI 0x1A211 -#define GL_STRICT_DEPTHFUNC_HINT_PGI 0x1A216 -#define GL_STRICT_LIGHTING_HINT_PGI 0x1A217 -#define GL_STRICT_SCISSOR_HINT_PGI 0x1A218 -#define GL_FULL_STIPPLE_HINT_PGI 0x1A219 -#define GL_CLIP_NEAR_HINT_PGI 0x1A220 -#define GL_CLIP_FAR_HINT_PGI 0x1A221 -#define GL_WIDE_LINE_HINT_PGI 0x1A222 -#define GL_BACK_NORMALS_HINT_PGI 0x1A223 -#endif - -#ifndef GL_EXT_paletted_texture -#define GL_COLOR_INDEX1_EXT 0x80E2 -#define GL_COLOR_INDEX2_EXT 0x80E3 -#define GL_COLOR_INDEX4_EXT 0x80E4 -#define GL_COLOR_INDEX8_EXT 0x80E5 -#define GL_COLOR_INDEX12_EXT 0x80E6 -#define GL_COLOR_INDEX16_EXT 0x80E7 -#define GL_TEXTURE_INDEX_SIZE_EXT 0x80ED -#endif - -#ifndef GL_EXT_clip_volume_hint -#define GL_CLIP_VOLUME_CLIPPING_HINT_EXT 0x80F0 -#endif - -#ifndef GL_SGIX_list_priority -#define GL_LIST_PRIORITY_SGIX 0x8182 -#endif - -#ifndef GL_SGIX_ir_instrument1 -#define GL_IR_INSTRUMENT1_SGIX 0x817F -#endif - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_CALLIGRAPHIC_FRAGMENT_SGIX 0x8183 -#endif - -#ifndef GL_SGIX_texture_lod_bias -#define GL_TEXTURE_LOD_BIAS_S_SGIX 0x818E -#define GL_TEXTURE_LOD_BIAS_T_SGIX 0x818F -#define GL_TEXTURE_LOD_BIAS_R_SGIX 0x8190 -#endif - -#ifndef GL_SGIX_shadow_ambient -#define GL_SHADOW_AMBIENT_SGIX 0x80BF -#endif - -#ifndef GL_EXT_index_texture -#endif - -#ifndef GL_EXT_index_material -#define GL_INDEX_MATERIAL_EXT 0x81B8 -#define GL_INDEX_MATERIAL_PARAMETER_EXT 0x81B9 -#define GL_INDEX_MATERIAL_FACE_EXT 0x81BA -#endif - -#ifndef GL_EXT_index_func -#define GL_INDEX_TEST_EXT 0x81B5 -#define GL_INDEX_TEST_FUNC_EXT 0x81B6 -#define GL_INDEX_TEST_REF_EXT 0x81B7 -#endif - -#ifndef GL_EXT_index_array_formats -#define GL_IUI_V2F_EXT 0x81AD -#define GL_IUI_V3F_EXT 0x81AE -#define GL_IUI_N3F_V2F_EXT 0x81AF -#define GL_IUI_N3F_V3F_EXT 0x81B0 -#define GL_T2F_IUI_V2F_EXT 0x81B1 -#define GL_T2F_IUI_V3F_EXT 0x81B2 -#define GL_T2F_IUI_N3F_V2F_EXT 0x81B3 -#define GL_T2F_IUI_N3F_V3F_EXT 0x81B4 -#endif - -#ifndef GL_EXT_compiled_vertex_array -#define GL_ARRAY_ELEMENT_LOCK_FIRST_EXT 0x81A8 -#define GL_ARRAY_ELEMENT_LOCK_COUNT_EXT 0x81A9 -#endif - -#ifndef GL_EXT_cull_vertex -#define GL_CULL_VERTEX_EXT 0x81AA -#define GL_CULL_VERTEX_EYE_POSITION_EXT 0x81AB -#define GL_CULL_VERTEX_OBJECT_POSITION_EXT 0x81AC -#endif - -#ifndef GL_SGIX_ycrcb -#define GL_YCRCB_422_SGIX 0x81BB -#define GL_YCRCB_444_SGIX 0x81BC -#endif - -#ifndef GL_SGIX_fragment_lighting -#define GL_FRAGMENT_LIGHTING_SGIX 0x8400 -#define GL_FRAGMENT_COLOR_MATERIAL_SGIX 0x8401 -#define GL_FRAGMENT_COLOR_MATERIAL_FACE_SGIX 0x8402 -#define GL_FRAGMENT_COLOR_MATERIAL_PARAMETER_SGIX 0x8403 -#define GL_MAX_FRAGMENT_LIGHTS_SGIX 0x8404 -#define GL_MAX_ACTIVE_LIGHTS_SGIX 0x8405 -#define GL_CURRENT_RASTER_NORMAL_SGIX 0x8406 -#define GL_LIGHT_ENV_MODE_SGIX 0x8407 -#define GL_FRAGMENT_LIGHT_MODEL_LOCAL_VIEWER_SGIX 0x8408 -#define GL_FRAGMENT_LIGHT_MODEL_TWO_SIDE_SGIX 0x8409 -#define GL_FRAGMENT_LIGHT_MODEL_AMBIENT_SGIX 0x840A -#define GL_FRAGMENT_LIGHT_MODEL_NORMAL_INTERPOLATION_SGIX 0x840B -#define GL_FRAGMENT_LIGHT0_SGIX 0x840C -#define GL_FRAGMENT_LIGHT1_SGIX 0x840D -#define GL_FRAGMENT_LIGHT2_SGIX 0x840E -#define GL_FRAGMENT_LIGHT3_SGIX 0x840F -#define GL_FRAGMENT_LIGHT4_SGIX 0x8410 -#define GL_FRAGMENT_LIGHT5_SGIX 0x8411 -#define GL_FRAGMENT_LIGHT6_SGIX 0x8412 -#define GL_FRAGMENT_LIGHT7_SGIX 0x8413 -#endif - -#ifndef GL_IBM_rasterpos_clip -#define GL_RASTER_POSITION_UNCLIPPED_IBM 0x19262 -#endif - -#ifndef GL_HP_texture_lighting -#define GL_TEXTURE_LIGHTING_MODE_HP 0x8167 -#define GL_TEXTURE_POST_SPECULAR_HP 0x8168 -#define GL_TEXTURE_PRE_SPECULAR_HP 0x8169 -#endif - -#ifndef GL_EXT_draw_range_elements -#define GL_MAX_ELEMENTS_VERTICES_EXT 0x80E8 -#define GL_MAX_ELEMENTS_INDICES_EXT 0x80E9 -#endif - -#ifndef GL_WIN_phong_shading -#define GL_PHONG_WIN 0x80EA -#define GL_PHONG_HINT_WIN 0x80EB -#endif - -#ifndef GL_WIN_specular_fog -#define GL_FOG_SPECULAR_TEXTURE_WIN 0x80EC -#endif - -#ifndef GL_EXT_light_texture -#define GL_FRAGMENT_MATERIAL_EXT 0x8349 -#define GL_FRAGMENT_NORMAL_EXT 0x834A -#define GL_FRAGMENT_COLOR_EXT 0x834C -#define GL_ATTENUATION_EXT 0x834D -#define GL_SHADOW_ATTENUATION_EXT 0x834E -#define GL_TEXTURE_APPLICATION_MODE_EXT 0x834F -#define GL_TEXTURE_LIGHT_EXT 0x8350 -#define GL_TEXTURE_MATERIAL_FACE_EXT 0x8351 -#define GL_TEXTURE_MATERIAL_PARAMETER_EXT 0x8352 -/* reuse GL_FRAGMENT_DEPTH_EXT */ -#endif - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_ALPHA_MIN_SGIX 0x8320 -#define GL_ALPHA_MAX_SGIX 0x8321 -#endif - -#ifndef GL_SGIX_impact_pixel_texture -#define GL_PIXEL_TEX_GEN_Q_CEILING_SGIX 0x8184 -#define GL_PIXEL_TEX_GEN_Q_ROUND_SGIX 0x8185 -#define GL_PIXEL_TEX_GEN_Q_FLOOR_SGIX 0x8186 -#define GL_PIXEL_TEX_GEN_ALPHA_REPLACE_SGIX 0x8187 -#define GL_PIXEL_TEX_GEN_ALPHA_NO_REPLACE_SGIX 0x8188 -#define GL_PIXEL_TEX_GEN_ALPHA_LS_SGIX 0x8189 -#define GL_PIXEL_TEX_GEN_ALPHA_MS_SGIX 0x818A -#endif - -#ifndef GL_EXT_bgra -#define GL_BGR_EXT 0x80E0 -#define GL_BGRA_EXT 0x80E1 -#endif - -#ifndef GL_SGIX_async -#define GL_ASYNC_MARKER_SGIX 0x8329 -#endif - -#ifndef GL_SGIX_async_pixel -#define GL_ASYNC_TEX_IMAGE_SGIX 0x835C -#define GL_ASYNC_DRAW_PIXELS_SGIX 0x835D -#define GL_ASYNC_READ_PIXELS_SGIX 0x835E -#define GL_MAX_ASYNC_TEX_IMAGE_SGIX 0x835F -#define GL_MAX_ASYNC_DRAW_PIXELS_SGIX 0x8360 -#define GL_MAX_ASYNC_READ_PIXELS_SGIX 0x8361 -#endif - -#ifndef GL_SGIX_async_histogram -#define GL_ASYNC_HISTOGRAM_SGIX 0x832C -#define GL_MAX_ASYNC_HISTOGRAM_SGIX 0x832D -#endif - -#ifndef GL_INTEL_texture_scissor -#endif - -#ifndef GL_INTEL_parallel_arrays -#define GL_PARALLEL_ARRAYS_INTEL 0x83F4 -#define GL_VERTEX_ARRAY_PARALLEL_POINTERS_INTEL 0x83F5 -#define GL_NORMAL_ARRAY_PARALLEL_POINTERS_INTEL 0x83F6 -#define GL_COLOR_ARRAY_PARALLEL_POINTERS_INTEL 0x83F7 -#define GL_TEXTURE_COORD_ARRAY_PARALLEL_POINTERS_INTEL 0x83F8 -#endif - -#ifndef GL_HP_occlusion_test -#define GL_OCCLUSION_TEST_HP 0x8165 -#define GL_OCCLUSION_TEST_RESULT_HP 0x8166 -#endif - -#ifndef GL_EXT_pixel_transform -#define GL_PIXEL_TRANSFORM_2D_EXT 0x8330 -#define GL_PIXEL_MAG_FILTER_EXT 0x8331 -#define GL_PIXEL_MIN_FILTER_EXT 0x8332 -#define GL_PIXEL_CUBIC_WEIGHT_EXT 0x8333 -#define GL_CUBIC_EXT 0x8334 -#define GL_AVERAGE_EXT 0x8335 -#define GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8336 -#define GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT 0x8337 -#define GL_PIXEL_TRANSFORM_2D_MATRIX_EXT 0x8338 -#endif - -#ifndef GL_EXT_pixel_transform_color_table -#endif - -#ifndef GL_EXT_shared_texture_palette -#define GL_SHARED_TEXTURE_PALETTE_EXT 0x81FB -#endif - -#ifndef GL_EXT_separate_specular_color -#define GL_LIGHT_MODEL_COLOR_CONTROL_EXT 0x81F8 -#define GL_SINGLE_COLOR_EXT 0x81F9 -#define GL_SEPARATE_SPECULAR_COLOR_EXT 0x81FA -#endif - -#ifndef GL_EXT_secondary_color -#define GL_COLOR_SUM_EXT 0x8458 -#define GL_CURRENT_SECONDARY_COLOR_EXT 0x8459 -#define GL_SECONDARY_COLOR_ARRAY_SIZE_EXT 0x845A -#define GL_SECONDARY_COLOR_ARRAY_TYPE_EXT 0x845B -#define GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT 0x845C -#define GL_SECONDARY_COLOR_ARRAY_POINTER_EXT 0x845D -#define GL_SECONDARY_COLOR_ARRAY_EXT 0x845E -#endif - -#ifndef GL_EXT_texture_perturb_normal -#define GL_PERTURB_EXT 0x85AE -#define GL_TEXTURE_NORMAL_EXT 0x85AF -#endif - -#ifndef GL_EXT_multi_draw_arrays -#endif - -#ifndef GL_EXT_fog_coord -#define GL_FOG_COORDINATE_SOURCE_EXT 0x8450 -#define GL_FOG_COORDINATE_EXT 0x8451 -#define GL_FRAGMENT_DEPTH_EXT 0x8452 -#define GL_CURRENT_FOG_COORDINATE_EXT 0x8453 -#define GL_FOG_COORDINATE_ARRAY_TYPE_EXT 0x8454 -#define GL_FOG_COORDINATE_ARRAY_STRIDE_EXT 0x8455 -#define GL_FOG_COORDINATE_ARRAY_POINTER_EXT 0x8456 -#define GL_FOG_COORDINATE_ARRAY_EXT 0x8457 -#endif - -#ifndef GL_REND_screen_coordinates -#define GL_SCREEN_COORDINATES_REND 0x8490 -#define GL_INVERTED_SCREEN_W_REND 0x8491 -#endif - -#ifndef GL_EXT_coordinate_frame -#define GL_TANGENT_ARRAY_EXT 0x8439 -#define GL_BINORMAL_ARRAY_EXT 0x843A -#define GL_CURRENT_TANGENT_EXT 0x843B -#define GL_CURRENT_BINORMAL_EXT 0x843C -#define GL_TANGENT_ARRAY_TYPE_EXT 0x843E -#define GL_TANGENT_ARRAY_STRIDE_EXT 0x843F -#define GL_BINORMAL_ARRAY_TYPE_EXT 0x8440 -#define GL_BINORMAL_ARRAY_STRIDE_EXT 0x8441 -#define GL_TANGENT_ARRAY_POINTER_EXT 0x8442 -#define GL_BINORMAL_ARRAY_POINTER_EXT 0x8443 -#define GL_MAP1_TANGENT_EXT 0x8444 -#define GL_MAP2_TANGENT_EXT 0x8445 -#define GL_MAP1_BINORMAL_EXT 0x8446 -#define GL_MAP2_BINORMAL_EXT 0x8447 -#endif - -#ifndef GL_EXT_texture_env_combine -#define GL_COMBINE_EXT 0x8570 -#define GL_COMBINE_RGB_EXT 0x8571 -#define GL_COMBINE_ALPHA_EXT 0x8572 -#define GL_RGB_SCALE_EXT 0x8573 -#define GL_ADD_SIGNED_EXT 0x8574 -#define GL_INTERPOLATE_EXT 0x8575 -#define GL_CONSTANT_EXT 0x8576 -#define GL_PRIMARY_COLOR_EXT 0x8577 -#define GL_PREVIOUS_EXT 0x8578 -#define GL_SOURCE0_RGB_EXT 0x8580 -#define GL_SOURCE1_RGB_EXT 0x8581 -#define GL_SOURCE2_RGB_EXT 0x8582 -#define GL_SOURCE0_ALPHA_EXT 0x8588 -#define GL_SOURCE1_ALPHA_EXT 0x8589 -#define GL_SOURCE2_ALPHA_EXT 0x858A -#define GL_OPERAND0_RGB_EXT 0x8590 -#define GL_OPERAND1_RGB_EXT 0x8591 -#define GL_OPERAND2_RGB_EXT 0x8592 -#define GL_OPERAND0_ALPHA_EXT 0x8598 -#define GL_OPERAND1_ALPHA_EXT 0x8599 -#define GL_OPERAND2_ALPHA_EXT 0x859A -#endif - -#ifndef GL_APPLE_specular_vector -#define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 -#endif - -#ifndef GL_APPLE_transform_hint -#define GL_TRANSFORM_HINT_APPLE 0x85B1 -#endif - -#ifndef GL_SGIX_fog_scale -#define GL_FOG_SCALE_SGIX 0x81FC -#define GL_FOG_SCALE_VALUE_SGIX 0x81FD -#endif - -#ifndef GL_SUNX_constant_data -#define GL_UNPACK_CONSTANT_DATA_SUNX 0x81D5 -#define GL_TEXTURE_CONSTANT_DATA_SUNX 0x81D6 -#endif - -#ifndef GL_SUN_global_alpha -#define GL_GLOBAL_ALPHA_SUN 0x81D9 -#define GL_GLOBAL_ALPHA_FACTOR_SUN 0x81DA -#endif - -#ifndef GL_SUN_triangle_list -#define GL_RESTART_SUN 0x0001 -#define GL_REPLACE_MIDDLE_SUN 0x0002 -#define GL_REPLACE_OLDEST_SUN 0x0003 -#define GL_TRIANGLE_LIST_SUN 0x81D7 -#define GL_REPLACEMENT_CODE_SUN 0x81D8 -#define GL_REPLACEMENT_CODE_ARRAY_SUN 0x85C0 -#define GL_REPLACEMENT_CODE_ARRAY_TYPE_SUN 0x85C1 -#define GL_REPLACEMENT_CODE_ARRAY_STRIDE_SUN 0x85C2 -#define GL_REPLACEMENT_CODE_ARRAY_POINTER_SUN 0x85C3 -#define GL_R1UI_V3F_SUN 0x85C4 -#define GL_R1UI_C4UB_V3F_SUN 0x85C5 -#define GL_R1UI_C3F_V3F_SUN 0x85C6 -#define GL_R1UI_N3F_V3F_SUN 0x85C7 -#define GL_R1UI_C4F_N3F_V3F_SUN 0x85C8 -#define GL_R1UI_T2F_V3F_SUN 0x85C9 -#define GL_R1UI_T2F_N3F_V3F_SUN 0x85CA -#define GL_R1UI_T2F_C4F_N3F_V3F_SUN 0x85CB -#endif - -#ifndef GL_SUN_vertex -#endif - -#ifndef GL_EXT_blend_func_separate -#define GL_BLEND_DST_RGB_EXT 0x80C8 -#define GL_BLEND_SRC_RGB_EXT 0x80C9 -#define GL_BLEND_DST_ALPHA_EXT 0x80CA -#define GL_BLEND_SRC_ALPHA_EXT 0x80CB -#endif - -#ifndef GL_INGR_color_clamp -#define GL_RED_MIN_CLAMP_INGR 0x8560 -#define GL_GREEN_MIN_CLAMP_INGR 0x8561 -#define GL_BLUE_MIN_CLAMP_INGR 0x8562 -#define GL_ALPHA_MIN_CLAMP_INGR 0x8563 -#define GL_RED_MAX_CLAMP_INGR 0x8564 -#define GL_GREEN_MAX_CLAMP_INGR 0x8565 -#define GL_BLUE_MAX_CLAMP_INGR 0x8566 -#define GL_ALPHA_MAX_CLAMP_INGR 0x8567 -#endif - -#ifndef GL_INGR_interlace_read -#define GL_INTERLACE_READ_INGR 0x8568 -#endif - -#ifndef GL_EXT_stencil_wrap -#define GL_INCR_WRAP_EXT 0x8507 -#define GL_DECR_WRAP_EXT 0x8508 -#endif - -#ifndef GL_EXT_422_pixels -#define GL_422_EXT 0x80CC -#define GL_422_REV_EXT 0x80CD -#define GL_422_AVERAGE_EXT 0x80CE -#define GL_422_REV_AVERAGE_EXT 0x80CF -#endif - -#ifndef GL_NV_texgen_reflection -#define GL_NORMAL_MAP_NV 0x8511 -#define GL_REFLECTION_MAP_NV 0x8512 -#endif - -#ifndef GL_EXT_texture_cube_map -#define GL_NORMAL_MAP_EXT 0x8511 -#define GL_REFLECTION_MAP_EXT 0x8512 -#define GL_TEXTURE_CUBE_MAP_EXT 0x8513 -#define GL_TEXTURE_BINDING_CUBE_MAP_EXT 0x8514 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT 0x8515 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT 0x8516 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT 0x8517 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT 0x8518 -#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT 0x8519 -#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT 0x851A -#define GL_PROXY_TEXTURE_CUBE_MAP_EXT 0x851B -#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT 0x851C -#endif - -#ifndef GL_SUN_convolution_border_modes -#define GL_WRAP_BORDER_SUN 0x81D4 -#endif - -#ifndef GL_EXT_texture_env_add -#endif - -#ifndef GL_EXT_texture_lod_bias -#define GL_MAX_TEXTURE_LOD_BIAS_EXT 0x84FD -#define GL_TEXTURE_FILTER_CONTROL_EXT 0x8500 -#define GL_TEXTURE_LOD_BIAS_EXT 0x8501 -#endif - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE -#define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF -#endif - -#ifndef GL_EXT_vertex_weighting -#define GL_MODELVIEW0_STACK_DEPTH_EXT GL_MODELVIEW_STACK_DEPTH -#define GL_MODELVIEW1_STACK_DEPTH_EXT 0x8502 -#define GL_MODELVIEW0_MATRIX_EXT GL_MODELVIEW_MATRIX -#define GL_MODELVIEW1_MATRIX_EXT 0x8506 -#define GL_VERTEX_WEIGHTING_EXT 0x8509 -#define GL_MODELVIEW0_EXT GL_MODELVIEW -#define GL_MODELVIEW1_EXT 0x850A -#define GL_CURRENT_VERTEX_WEIGHT_EXT 0x850B -#define GL_VERTEX_WEIGHT_ARRAY_EXT 0x850C -#define GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT 0x850D -#define GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT 0x850E -#define GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT 0x850F -#define GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT 0x8510 -#endif - -#ifndef GL_NV_light_max_exponent -#define GL_MAX_SHININESS_NV 0x8504 -#define GL_MAX_SPOT_EXPONENT_NV 0x8505 -#endif - -#ifndef GL_NV_vertex_array_range -#define GL_VERTEX_ARRAY_RANGE_NV 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_NV 0x851E -#define GL_VERTEX_ARRAY_RANGE_VALID_NV 0x851F -#define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_NV 0x8520 -#define GL_VERTEX_ARRAY_RANGE_POINTER_NV 0x8521 -#endif - -#ifndef GL_NV_register_combiners -#define GL_REGISTER_COMBINERS_NV 0x8522 -#define GL_VARIABLE_A_NV 0x8523 -#define GL_VARIABLE_B_NV 0x8524 -#define GL_VARIABLE_C_NV 0x8525 -#define GL_VARIABLE_D_NV 0x8526 -#define GL_VARIABLE_E_NV 0x8527 -#define GL_VARIABLE_F_NV 0x8528 -#define GL_VARIABLE_G_NV 0x8529 -#define GL_CONSTANT_COLOR0_NV 0x852A -#define GL_CONSTANT_COLOR1_NV 0x852B -#define GL_PRIMARY_COLOR_NV 0x852C -#define GL_SECONDARY_COLOR_NV 0x852D -#define GL_SPARE0_NV 0x852E -#define GL_SPARE1_NV 0x852F -#define GL_DISCARD_NV 0x8530 -#define GL_E_TIMES_F_NV 0x8531 -#define GL_SPARE0_PLUS_SECONDARY_COLOR_NV 0x8532 -#define GL_UNSIGNED_IDENTITY_NV 0x8536 -#define GL_UNSIGNED_INVERT_NV 0x8537 -#define GL_EXPAND_NORMAL_NV 0x8538 -#define GL_EXPAND_NEGATE_NV 0x8539 -#define GL_HALF_BIAS_NORMAL_NV 0x853A -#define GL_HALF_BIAS_NEGATE_NV 0x853B -#define GL_SIGNED_IDENTITY_NV 0x853C -#define GL_SIGNED_NEGATE_NV 0x853D -#define GL_SCALE_BY_TWO_NV 0x853E -#define GL_SCALE_BY_FOUR_NV 0x853F -#define GL_SCALE_BY_ONE_HALF_NV 0x8540 -#define GL_BIAS_BY_NEGATIVE_ONE_HALF_NV 0x8541 -#define GL_COMBINER_INPUT_NV 0x8542 -#define GL_COMBINER_MAPPING_NV 0x8543 -#define GL_COMBINER_COMPONENT_USAGE_NV 0x8544 -#define GL_COMBINER_AB_DOT_PRODUCT_NV 0x8545 -#define GL_COMBINER_CD_DOT_PRODUCT_NV 0x8546 -#define GL_COMBINER_MUX_SUM_NV 0x8547 -#define GL_COMBINER_SCALE_NV 0x8548 -#define GL_COMBINER_BIAS_NV 0x8549 -#define GL_COMBINER_AB_OUTPUT_NV 0x854A -#define GL_COMBINER_CD_OUTPUT_NV 0x854B -#define GL_COMBINER_SUM_OUTPUT_NV 0x854C -#define GL_MAX_GENERAL_COMBINERS_NV 0x854D -#define GL_NUM_GENERAL_COMBINERS_NV 0x854E -#define GL_COLOR_SUM_CLAMP_NV 0x854F -#define GL_COMBINER0_NV 0x8550 -#define GL_COMBINER1_NV 0x8551 -#define GL_COMBINER2_NV 0x8552 -#define GL_COMBINER3_NV 0x8553 -#define GL_COMBINER4_NV 0x8554 -#define GL_COMBINER5_NV 0x8555 -#define GL_COMBINER6_NV 0x8556 -#define GL_COMBINER7_NV 0x8557 -/* reuse GL_TEXTURE0_ARB */ -/* reuse GL_TEXTURE1_ARB */ -/* reuse GL_ZERO */ -/* reuse GL_NONE */ -/* reuse GL_FOG */ -#endif - -#ifndef GL_NV_fog_distance -#define GL_FOG_DISTANCE_MODE_NV 0x855A -#define GL_EYE_RADIAL_NV 0x855B -#define GL_EYE_PLANE_ABSOLUTE_NV 0x855C -/* reuse GL_EYE_PLANE */ -#endif - -#ifndef GL_NV_texgen_emboss -#define GL_EMBOSS_LIGHT_NV 0x855D -#define GL_EMBOSS_CONSTANT_NV 0x855E -#define GL_EMBOSS_MAP_NV 0x855F -#endif - -#ifndef GL_NV_blend_square -#endif - -#ifndef GL_NV_texture_env_combine4 -#define GL_COMBINE4_NV 0x8503 -#define GL_SOURCE3_RGB_NV 0x8583 -#define GL_SOURCE3_ALPHA_NV 0x858B -#define GL_OPERAND3_RGB_NV 0x8593 -#define GL_OPERAND3_ALPHA_NV 0x859B -#endif - -#ifndef GL_MESA_resize_buffers -#endif - -#ifndef GL_MESA_window_pos -#endif - -#ifndef GL_EXT_texture_compression_s3tc -#define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 -#define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 -#define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 -#define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 -#endif - -#ifndef GL_IBM_cull_vertex -#define GL_CULL_VERTEX_IBM 103050 -#endif - -#ifndef GL_IBM_multimode_draw_arrays -#endif - -#ifndef GL_IBM_vertex_array_lists -#define GL_VERTEX_ARRAY_LIST_IBM 103070 -#define GL_NORMAL_ARRAY_LIST_IBM 103071 -#define GL_COLOR_ARRAY_LIST_IBM 103072 -#define GL_INDEX_ARRAY_LIST_IBM 103073 -#define GL_TEXTURE_COORD_ARRAY_LIST_IBM 103074 -#define GL_EDGE_FLAG_ARRAY_LIST_IBM 103075 -#define GL_FOG_COORDINATE_ARRAY_LIST_IBM 103076 -#define GL_SECONDARY_COLOR_ARRAY_LIST_IBM 103077 -#define GL_VERTEX_ARRAY_LIST_STRIDE_IBM 103080 -#define GL_NORMAL_ARRAY_LIST_STRIDE_IBM 103081 -#define GL_COLOR_ARRAY_LIST_STRIDE_IBM 103082 -#define GL_INDEX_ARRAY_LIST_STRIDE_IBM 103083 -#define GL_TEXTURE_COORD_ARRAY_LIST_STRIDE_IBM 103084 -#define GL_EDGE_FLAG_ARRAY_LIST_STRIDE_IBM 103085 -#define GL_FOG_COORDINATE_ARRAY_LIST_STRIDE_IBM 103086 -#define GL_SECONDARY_COLOR_ARRAY_LIST_STRIDE_IBM 103087 -#endif - -#ifndef GL_SGIX_subsample -#define GL_PACK_SUBSAMPLE_RATE_SGIX 0x85A0 -#define GL_UNPACK_SUBSAMPLE_RATE_SGIX 0x85A1 -#define GL_PIXEL_SUBSAMPLE_4444_SGIX 0x85A2 -#define GL_PIXEL_SUBSAMPLE_2424_SGIX 0x85A3 -#define GL_PIXEL_SUBSAMPLE_4242_SGIX 0x85A4 -#endif - -#ifndef GL_SGIX_ycrcb_subsample -#endif - -#ifndef GL_SGIX_ycrcba -#define GL_YCRCB_SGIX 0x8318 -#define GL_YCRCBA_SGIX 0x8319 -#endif - -#ifndef GL_SGI_depth_pass_instrument -#define GL_DEPTH_PASS_INSTRUMENT_SGIX 0x8310 -#define GL_DEPTH_PASS_INSTRUMENT_COUNTERS_SGIX 0x8311 -#define GL_DEPTH_PASS_INSTRUMENT_MAX_SGIX 0x8312 -#endif - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_COMPRESSED_RGB_FXT1_3DFX 0x86B0 -#define GL_COMPRESSED_RGBA_FXT1_3DFX 0x86B1 -#endif - -#ifndef GL_3DFX_multisample -#define GL_MULTISAMPLE_3DFX 0x86B2 -#define GL_SAMPLE_BUFFERS_3DFX 0x86B3 -#define GL_SAMPLES_3DFX 0x86B4 -#define GL_MULTISAMPLE_BIT_3DFX 0x20000000 -#endif - -#ifndef GL_3DFX_tbuffer -#endif - -#ifndef GL_EXT_multisample -#define GL_MULTISAMPLE_EXT 0x809D -#define GL_SAMPLE_ALPHA_TO_MASK_EXT 0x809E -#define GL_SAMPLE_ALPHA_TO_ONE_EXT 0x809F -#define GL_SAMPLE_MASK_EXT 0x80A0 -#define GL_1PASS_EXT 0x80A1 -#define GL_2PASS_0_EXT 0x80A2 -#define GL_2PASS_1_EXT 0x80A3 -#define GL_4PASS_0_EXT 0x80A4 -#define GL_4PASS_1_EXT 0x80A5 -#define GL_4PASS_2_EXT 0x80A6 -#define GL_4PASS_3_EXT 0x80A7 -#define GL_SAMPLE_BUFFERS_EXT 0x80A8 -#define GL_SAMPLES_EXT 0x80A9 -#define GL_SAMPLE_MASK_VALUE_EXT 0x80AA -#define GL_SAMPLE_MASK_INVERT_EXT 0x80AB -#define GL_SAMPLE_PATTERN_EXT 0x80AC -#define GL_MULTISAMPLE_BIT_EXT 0x20000000 -#endif - -#ifndef GL_SGIX_vertex_preclip -#define GL_VERTEX_PRECLIP_SGIX 0x83EE -#define GL_VERTEX_PRECLIP_HINT_SGIX 0x83EF -#endif - -#ifndef GL_SGIX_convolution_accuracy -#define GL_CONVOLUTION_HINT_SGIX 0x8316 -#endif - -#ifndef GL_SGIX_resample -#define GL_PACK_RESAMPLE_SGIX 0x842C -#define GL_UNPACK_RESAMPLE_SGIX 0x842D -#define GL_RESAMPLE_REPLICATE_SGIX 0x842E -#define GL_RESAMPLE_ZERO_FILL_SGIX 0x842F -#define GL_RESAMPLE_DECIMATE_SGIX 0x8430 -#endif - -#ifndef GL_SGIS_point_line_texgen -#define GL_EYE_DISTANCE_TO_POINT_SGIS 0x81F0 -#define GL_OBJECT_DISTANCE_TO_POINT_SGIS 0x81F1 -#define GL_EYE_DISTANCE_TO_LINE_SGIS 0x81F2 -#define GL_OBJECT_DISTANCE_TO_LINE_SGIS 0x81F3 -#define GL_EYE_POINT_SGIS 0x81F4 -#define GL_OBJECT_POINT_SGIS 0x81F5 -#define GL_EYE_LINE_SGIS 0x81F6 -#define GL_OBJECT_LINE_SGIS 0x81F7 -#endif - -#ifndef GL_SGIS_texture_color_mask -#define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF -#endif - -#ifndef GL_EXT_texture_env_dot3 -#define GL_DOT3_RGB_EXT 0x8740 -#define GL_DOT3_RGBA_EXT 0x8741 -#endif - -#ifndef GL_ATI_texture_mirror_once -#define GL_MIRROR_CLAMP_ATI 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_ATI 0x8743 -#endif - -#ifndef GL_NV_fence -#define GL_ALL_COMPLETED_NV 0x84F2 -#define GL_FENCE_STATUS_NV 0x84F3 -#define GL_FENCE_CONDITION_NV 0x84F4 -#endif - -#ifndef GL_IBM_texture_mirrored_repeat -#define GL_MIRRORED_REPEAT_IBM 0x8370 -#endif - -#ifndef GL_NV_evaluators -#define GL_EVAL_2D_NV 0x86C0 -#define GL_EVAL_TRIANGULAR_2D_NV 0x86C1 -#define GL_MAP_TESSELLATION_NV 0x86C2 -#define GL_MAP_ATTRIB_U_ORDER_NV 0x86C3 -#define GL_MAP_ATTRIB_V_ORDER_NV 0x86C4 -#define GL_EVAL_FRACTIONAL_TESSELLATION_NV 0x86C5 -#define GL_EVAL_VERTEX_ATTRIB0_NV 0x86C6 -#define GL_EVAL_VERTEX_ATTRIB1_NV 0x86C7 -#define GL_EVAL_VERTEX_ATTRIB2_NV 0x86C8 -#define GL_EVAL_VERTEX_ATTRIB3_NV 0x86C9 -#define GL_EVAL_VERTEX_ATTRIB4_NV 0x86CA -#define GL_EVAL_VERTEX_ATTRIB5_NV 0x86CB -#define GL_EVAL_VERTEX_ATTRIB6_NV 0x86CC -#define GL_EVAL_VERTEX_ATTRIB7_NV 0x86CD -#define GL_EVAL_VERTEX_ATTRIB8_NV 0x86CE -#define GL_EVAL_VERTEX_ATTRIB9_NV 0x86CF -#define GL_EVAL_VERTEX_ATTRIB10_NV 0x86D0 -#define GL_EVAL_VERTEX_ATTRIB11_NV 0x86D1 -#define GL_EVAL_VERTEX_ATTRIB12_NV 0x86D2 -#define GL_EVAL_VERTEX_ATTRIB13_NV 0x86D3 -#define GL_EVAL_VERTEX_ATTRIB14_NV 0x86D4 -#define GL_EVAL_VERTEX_ATTRIB15_NV 0x86D5 -#define GL_MAX_MAP_TESSELLATION_NV 0x86D6 -#define GL_MAX_RATIONAL_EVAL_ORDER_NV 0x86D7 -#endif - -#ifndef GL_NV_packed_depth_stencil -#define GL_DEPTH_STENCIL_NV 0x84F9 -#define GL_UNSIGNED_INT_24_8_NV 0x84FA -#endif - -#ifndef GL_NV_register_combiners2 -#define GL_PER_STAGE_CONSTANTS_NV 0x8535 -#endif - -#ifndef GL_NV_texture_compression_vtc -#endif - -#ifndef GL_NV_texture_rectangle -#define GL_TEXTURE_RECTANGLE_NV 0x84F5 -#define GL_TEXTURE_BINDING_RECTANGLE_NV 0x84F6 -#define GL_PROXY_TEXTURE_RECTANGLE_NV 0x84F7 -#define GL_MAX_RECTANGLE_TEXTURE_SIZE_NV 0x84F8 -#endif - -#ifndef GL_NV_texture_shader -#define GL_OFFSET_TEXTURE_RECTANGLE_NV 0x864C -#define GL_OFFSET_TEXTURE_RECTANGLE_SCALE_NV 0x864D -#define GL_DOT_PRODUCT_TEXTURE_RECTANGLE_NV 0x864E -#define GL_RGBA_UNSIGNED_DOT_PRODUCT_MAPPING_NV 0x86D9 -#define GL_UNSIGNED_INT_S8_S8_8_8_NV 0x86DA -#define GL_UNSIGNED_INT_8_8_S8_S8_REV_NV 0x86DB -#define GL_DSDT_MAG_INTENSITY_NV 0x86DC -#define GL_SHADER_CONSISTENT_NV 0x86DD -#define GL_TEXTURE_SHADER_NV 0x86DE -#define GL_SHADER_OPERATION_NV 0x86DF -#define GL_CULL_MODES_NV 0x86E0 -#define GL_OFFSET_TEXTURE_MATRIX_NV 0x86E1 -#define GL_OFFSET_TEXTURE_SCALE_NV 0x86E2 -#define GL_OFFSET_TEXTURE_BIAS_NV 0x86E3 -#define GL_OFFSET_TEXTURE_2D_MATRIX_NV GL_OFFSET_TEXTURE_MATRIX_NV -#define GL_OFFSET_TEXTURE_2D_SCALE_NV GL_OFFSET_TEXTURE_SCALE_NV -#define GL_OFFSET_TEXTURE_2D_BIAS_NV GL_OFFSET_TEXTURE_BIAS_NV -#define GL_PREVIOUS_TEXTURE_INPUT_NV 0x86E4 -#define GL_CONST_EYE_NV 0x86E5 -#define GL_PASS_THROUGH_NV 0x86E6 -#define GL_CULL_FRAGMENT_NV 0x86E7 -#define GL_OFFSET_TEXTURE_2D_NV 0x86E8 -#define GL_DEPENDENT_AR_TEXTURE_2D_NV 0x86E9 -#define GL_DEPENDENT_GB_TEXTURE_2D_NV 0x86EA -#define GL_DOT_PRODUCT_NV 0x86EC -#define GL_DOT_PRODUCT_DEPTH_REPLACE_NV 0x86ED -#define GL_DOT_PRODUCT_TEXTURE_2D_NV 0x86EE -#define GL_DOT_PRODUCT_TEXTURE_CUBE_MAP_NV 0x86F0 -#define GL_DOT_PRODUCT_DIFFUSE_CUBE_MAP_NV 0x86F1 -#define GL_DOT_PRODUCT_REFLECT_CUBE_MAP_NV 0x86F2 -#define GL_DOT_PRODUCT_CONST_EYE_REFLECT_CUBE_MAP_NV 0x86F3 -#define GL_HILO_NV 0x86F4 -#define GL_DSDT_NV 0x86F5 -#define GL_DSDT_MAG_NV 0x86F6 -#define GL_DSDT_MAG_VIB_NV 0x86F7 -#define GL_HILO16_NV 0x86F8 -#define GL_SIGNED_HILO_NV 0x86F9 -#define GL_SIGNED_HILO16_NV 0x86FA -#define GL_SIGNED_RGBA_NV 0x86FB -#define GL_SIGNED_RGBA8_NV 0x86FC -#define GL_SIGNED_RGB_NV 0x86FE -#define GL_SIGNED_RGB8_NV 0x86FF -#define GL_SIGNED_LUMINANCE_NV 0x8701 -#define GL_SIGNED_LUMINANCE8_NV 0x8702 -#define GL_SIGNED_LUMINANCE_ALPHA_NV 0x8703 -#define GL_SIGNED_LUMINANCE8_ALPHA8_NV 0x8704 -#define GL_SIGNED_ALPHA_NV 0x8705 -#define GL_SIGNED_ALPHA8_NV 0x8706 -#define GL_SIGNED_INTENSITY_NV 0x8707 -#define GL_SIGNED_INTENSITY8_NV 0x8708 -#define GL_DSDT8_NV 0x8709 -#define GL_DSDT8_MAG8_NV 0x870A -#define GL_DSDT8_MAG8_INTENSITY8_NV 0x870B -#define GL_SIGNED_RGB_UNSIGNED_ALPHA_NV 0x870C -#define GL_SIGNED_RGB8_UNSIGNED_ALPHA8_NV 0x870D -#define GL_HI_SCALE_NV 0x870E -#define GL_LO_SCALE_NV 0x870F -#define GL_DS_SCALE_NV 0x8710 -#define GL_DT_SCALE_NV 0x8711 -#define GL_MAGNITUDE_SCALE_NV 0x8712 -#define GL_VIBRANCE_SCALE_NV 0x8713 -#define GL_HI_BIAS_NV 0x8714 -#define GL_LO_BIAS_NV 0x8715 -#define GL_DS_BIAS_NV 0x8716 -#define GL_DT_BIAS_NV 0x8717 -#define GL_MAGNITUDE_BIAS_NV 0x8718 -#define GL_VIBRANCE_BIAS_NV 0x8719 -#define GL_TEXTURE_BORDER_VALUES_NV 0x871A -#define GL_TEXTURE_HI_SIZE_NV 0x871B -#define GL_TEXTURE_LO_SIZE_NV 0x871C -#define GL_TEXTURE_DS_SIZE_NV 0x871D -#define GL_TEXTURE_DT_SIZE_NV 0x871E -#define GL_TEXTURE_MAG_SIZE_NV 0x871F -#endif - -#ifndef GL_NV_texture_shader2 -#define GL_DOT_PRODUCT_TEXTURE_3D_NV 0x86EF -#endif - -#ifndef GL_NV_vertex_array_range2 -#define GL_VERTEX_ARRAY_RANGE_WITHOUT_FLUSH_NV 0x8533 -#endif - -#ifndef GL_NV_vertex_program -#define GL_VERTEX_PROGRAM_NV 0x8620 -#define GL_VERTEX_STATE_PROGRAM_NV 0x8621 -#define GL_ATTRIB_ARRAY_SIZE_NV 0x8623 -#define GL_ATTRIB_ARRAY_STRIDE_NV 0x8624 -#define GL_ATTRIB_ARRAY_TYPE_NV 0x8625 -#define GL_CURRENT_ATTRIB_NV 0x8626 -#define GL_PROGRAM_LENGTH_NV 0x8627 -#define GL_PROGRAM_STRING_NV 0x8628 -#define GL_MODELVIEW_PROJECTION_NV 0x8629 -#define GL_IDENTITY_NV 0x862A -#define GL_INVERSE_NV 0x862B -#define GL_TRANSPOSE_NV 0x862C -#define GL_INVERSE_TRANSPOSE_NV 0x862D -#define GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV 0x862E -#define GL_MAX_TRACK_MATRICES_NV 0x862F -#define GL_MATRIX0_NV 0x8630 -#define GL_MATRIX1_NV 0x8631 -#define GL_MATRIX2_NV 0x8632 -#define GL_MATRIX3_NV 0x8633 -#define GL_MATRIX4_NV 0x8634 -#define GL_MATRIX5_NV 0x8635 -#define GL_MATRIX6_NV 0x8636 -#define GL_MATRIX7_NV 0x8637 -#define GL_CURRENT_MATRIX_STACK_DEPTH_NV 0x8640 -#define GL_CURRENT_MATRIX_NV 0x8641 -#define GL_VERTEX_PROGRAM_POINT_SIZE_NV 0x8642 -#define GL_VERTEX_PROGRAM_TWO_SIDE_NV 0x8643 -#define GL_PROGRAM_PARAMETER_NV 0x8644 -#define GL_ATTRIB_ARRAY_POINTER_NV 0x8645 -#define GL_PROGRAM_TARGET_NV 0x8646 -#define GL_PROGRAM_RESIDENT_NV 0x8647 -#define GL_TRACK_MATRIX_NV 0x8648 -#define GL_TRACK_MATRIX_TRANSFORM_NV 0x8649 -#define GL_VERTEX_PROGRAM_BINDING_NV 0x864A -#define GL_PROGRAM_ERROR_POSITION_NV 0x864B -#define GL_VERTEX_ATTRIB_ARRAY0_NV 0x8650 -#define GL_VERTEX_ATTRIB_ARRAY1_NV 0x8651 -#define GL_VERTEX_ATTRIB_ARRAY2_NV 0x8652 -#define GL_VERTEX_ATTRIB_ARRAY3_NV 0x8653 -#define GL_VERTEX_ATTRIB_ARRAY4_NV 0x8654 -#define GL_VERTEX_ATTRIB_ARRAY5_NV 0x8655 -#define GL_VERTEX_ATTRIB_ARRAY6_NV 0x8656 -#define GL_VERTEX_ATTRIB_ARRAY7_NV 0x8657 -#define GL_VERTEX_ATTRIB_ARRAY8_NV 0x8658 -#define GL_VERTEX_ATTRIB_ARRAY9_NV 0x8659 -#define GL_VERTEX_ATTRIB_ARRAY10_NV 0x865A -#define GL_VERTEX_ATTRIB_ARRAY11_NV 0x865B -#define GL_VERTEX_ATTRIB_ARRAY12_NV 0x865C -#define GL_VERTEX_ATTRIB_ARRAY13_NV 0x865D -#define GL_VERTEX_ATTRIB_ARRAY14_NV 0x865E -#define GL_VERTEX_ATTRIB_ARRAY15_NV 0x865F -#define GL_MAP1_VERTEX_ATTRIB0_4_NV 0x8660 -#define GL_MAP1_VERTEX_ATTRIB1_4_NV 0x8661 -#define GL_MAP1_VERTEX_ATTRIB2_4_NV 0x8662 -#define GL_MAP1_VERTEX_ATTRIB3_4_NV 0x8663 -#define GL_MAP1_VERTEX_ATTRIB4_4_NV 0x8664 -#define GL_MAP1_VERTEX_ATTRIB5_4_NV 0x8665 -#define GL_MAP1_VERTEX_ATTRIB6_4_NV 0x8666 -#define GL_MAP1_VERTEX_ATTRIB7_4_NV 0x8667 -#define GL_MAP1_VERTEX_ATTRIB8_4_NV 0x8668 -#define GL_MAP1_VERTEX_ATTRIB9_4_NV 0x8669 -#define GL_MAP1_VERTEX_ATTRIB10_4_NV 0x866A -#define GL_MAP1_VERTEX_ATTRIB11_4_NV 0x866B -#define GL_MAP1_VERTEX_ATTRIB12_4_NV 0x866C -#define GL_MAP1_VERTEX_ATTRIB13_4_NV 0x866D -#define GL_MAP1_VERTEX_ATTRIB14_4_NV 0x866E -#define GL_MAP1_VERTEX_ATTRIB15_4_NV 0x866F -#define GL_MAP2_VERTEX_ATTRIB0_4_NV 0x8670 -#define GL_MAP2_VERTEX_ATTRIB1_4_NV 0x8671 -#define GL_MAP2_VERTEX_ATTRIB2_4_NV 0x8672 -#define GL_MAP2_VERTEX_ATTRIB3_4_NV 0x8673 -#define GL_MAP2_VERTEX_ATTRIB4_4_NV 0x8674 -#define GL_MAP2_VERTEX_ATTRIB5_4_NV 0x8675 -#define GL_MAP2_VERTEX_ATTRIB6_4_NV 0x8676 -#define GL_MAP2_VERTEX_ATTRIB7_4_NV 0x8677 -#define GL_MAP2_VERTEX_ATTRIB8_4_NV 0x8678 -#define GL_MAP2_VERTEX_ATTRIB9_4_NV 0x8679 -#define GL_MAP2_VERTEX_ATTRIB10_4_NV 0x867A -#define GL_MAP2_VERTEX_ATTRIB11_4_NV 0x867B -#define GL_MAP2_VERTEX_ATTRIB12_4_NV 0x867C -#define GL_MAP2_VERTEX_ATTRIB13_4_NV 0x867D -#define GL_MAP2_VERTEX_ATTRIB14_4_NV 0x867E -#define GL_MAP2_VERTEX_ATTRIB15_4_NV 0x867F -#endif - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_TEXTURE_MAX_CLAMP_S_SGIX 0x8369 -#define GL_TEXTURE_MAX_CLAMP_T_SGIX 0x836A -#define GL_TEXTURE_MAX_CLAMP_R_SGIX 0x836B -#endif - -#ifndef GL_SGIX_scalebias_hint -#define GL_SCALEBIAS_HINT_SGIX 0x8322 -#endif - -#ifndef GL_OML_interlace -#define GL_INTERLACE_OML 0x8980 -#define GL_INTERLACE_READ_OML 0x8981 -#endif - -#ifndef GL_OML_subsample -#define GL_FORMAT_SUBSAMPLE_24_24_OML 0x8982 -#define GL_FORMAT_SUBSAMPLE_244_244_OML 0x8983 -#endif - -#ifndef GL_OML_resample -#define GL_PACK_RESAMPLE_OML 0x8984 -#define GL_UNPACK_RESAMPLE_OML 0x8985 -#define GL_RESAMPLE_REPLICATE_OML 0x8986 -#define GL_RESAMPLE_ZERO_FILL_OML 0x8987 -#define GL_RESAMPLE_AVERAGE_OML 0x8988 -#define GL_RESAMPLE_DECIMATE_OML 0x8989 -#endif - -#ifndef GL_NV_copy_depth_to_color -#define GL_DEPTH_STENCIL_TO_RGBA_NV 0x886E -#define GL_DEPTH_STENCIL_TO_BGRA_NV 0x886F -#endif - -#ifndef GL_ATI_envmap_bumpmap -#define GL_BUMP_ROT_MATRIX_ATI 0x8775 -#define GL_BUMP_ROT_MATRIX_SIZE_ATI 0x8776 -#define GL_BUMP_NUM_TEX_UNITS_ATI 0x8777 -#define GL_BUMP_TEX_UNITS_ATI 0x8778 -#define GL_DUDV_ATI 0x8779 -#define GL_DU8DV8_ATI 0x877A -#define GL_BUMP_ENVMAP_ATI 0x877B -#define GL_BUMP_TARGET_ATI 0x877C -#endif - -#ifndef GL_ATI_fragment_shader -#define GL_FRAGMENT_SHADER_ATI 0x8920 -#define GL_REG_0_ATI 0x8921 -#define GL_REG_1_ATI 0x8922 -#define GL_REG_2_ATI 0x8923 -#define GL_REG_3_ATI 0x8924 -#define GL_REG_4_ATI 0x8925 -#define GL_REG_5_ATI 0x8926 -#define GL_REG_6_ATI 0x8927 -#define GL_REG_7_ATI 0x8928 -#define GL_REG_8_ATI 0x8929 -#define GL_REG_9_ATI 0x892A -#define GL_REG_10_ATI 0x892B -#define GL_REG_11_ATI 0x892C -#define GL_REG_12_ATI 0x892D -#define GL_REG_13_ATI 0x892E -#define GL_REG_14_ATI 0x892F -#define GL_REG_15_ATI 0x8930 -#define GL_REG_16_ATI 0x8931 -#define GL_REG_17_ATI 0x8932 -#define GL_REG_18_ATI 0x8933 -#define GL_REG_19_ATI 0x8934 -#define GL_REG_20_ATI 0x8935 -#define GL_REG_21_ATI 0x8936 -#define GL_REG_22_ATI 0x8937 -#define GL_REG_23_ATI 0x8938 -#define GL_REG_24_ATI 0x8939 -#define GL_REG_25_ATI 0x893A -#define GL_REG_26_ATI 0x893B -#define GL_REG_27_ATI 0x893C -#define GL_REG_28_ATI 0x893D -#define GL_REG_29_ATI 0x893E -#define GL_REG_30_ATI 0x893F -#define GL_REG_31_ATI 0x8940 -#define GL_CON_0_ATI 0x8941 -#define GL_CON_1_ATI 0x8942 -#define GL_CON_2_ATI 0x8943 -#define GL_CON_3_ATI 0x8944 -#define GL_CON_4_ATI 0x8945 -#define GL_CON_5_ATI 0x8946 -#define GL_CON_6_ATI 0x8947 -#define GL_CON_7_ATI 0x8948 -#define GL_CON_8_ATI 0x8949 -#define GL_CON_9_ATI 0x894A -#define GL_CON_10_ATI 0x894B -#define GL_CON_11_ATI 0x894C -#define GL_CON_12_ATI 0x894D -#define GL_CON_13_ATI 0x894E -#define GL_CON_14_ATI 0x894F -#define GL_CON_15_ATI 0x8950 -#define GL_CON_16_ATI 0x8951 -#define GL_CON_17_ATI 0x8952 -#define GL_CON_18_ATI 0x8953 -#define GL_CON_19_ATI 0x8954 -#define GL_CON_20_ATI 0x8955 -#define GL_CON_21_ATI 0x8956 -#define GL_CON_22_ATI 0x8957 -#define GL_CON_23_ATI 0x8958 -#define GL_CON_24_ATI 0x8959 -#define GL_CON_25_ATI 0x895A -#define GL_CON_26_ATI 0x895B -#define GL_CON_27_ATI 0x895C -#define GL_CON_28_ATI 0x895D -#define GL_CON_29_ATI 0x895E -#define GL_CON_30_ATI 0x895F -#define GL_CON_31_ATI 0x8960 -#define GL_MOV_ATI 0x8961 -#define GL_ADD_ATI 0x8963 -#define GL_MUL_ATI 0x8964 -#define GL_SUB_ATI 0x8965 -#define GL_DOT3_ATI 0x8966 -#define GL_DOT4_ATI 0x8967 -#define GL_MAD_ATI 0x8968 -#define GL_LERP_ATI 0x8969 -#define GL_CND_ATI 0x896A -#define GL_CND0_ATI 0x896B -#define GL_DOT2_ADD_ATI 0x896C -#define GL_SECONDARY_INTERPOLATOR_ATI 0x896D -#define GL_NUM_FRAGMENT_REGISTERS_ATI 0x896E -#define GL_NUM_FRAGMENT_CONSTANTS_ATI 0x896F -#define GL_NUM_PASSES_ATI 0x8970 -#define GL_NUM_INSTRUCTIONS_PER_PASS_ATI 0x8971 -#define GL_NUM_INSTRUCTIONS_TOTAL_ATI 0x8972 -#define GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI 0x8973 -#define GL_NUM_LOOPBACK_COMPONENTS_ATI 0x8974 -#define GL_COLOR_ALPHA_PAIRING_ATI 0x8975 -#define GL_SWIZZLE_STR_ATI 0x8976 -#define GL_SWIZZLE_STQ_ATI 0x8977 -#define GL_SWIZZLE_STR_DR_ATI 0x8978 -#define GL_SWIZZLE_STQ_DQ_ATI 0x8979 -#define GL_SWIZZLE_STRQ_ATI 0x897A -#define GL_SWIZZLE_STRQ_DQ_ATI 0x897B -#define GL_RED_BIT_ATI 0x00000001 -#define GL_GREEN_BIT_ATI 0x00000002 -#define GL_BLUE_BIT_ATI 0x00000004 -#define GL_2X_BIT_ATI 0x00000001 -#define GL_4X_BIT_ATI 0x00000002 -#define GL_8X_BIT_ATI 0x00000004 -#define GL_HALF_BIT_ATI 0x00000008 -#define GL_QUARTER_BIT_ATI 0x00000010 -#define GL_EIGHTH_BIT_ATI 0x00000020 -#define GL_SATURATE_BIT_ATI 0x00000040 -#define GL_COMP_BIT_ATI 0x00000002 -#define GL_NEGATE_BIT_ATI 0x00000004 -#define GL_BIAS_BIT_ATI 0x00000008 -#endif - -#ifndef GL_ATI_pn_triangles -#define GL_PN_TRIANGLES_ATI 0x87F0 -#define GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F1 -#define GL_PN_TRIANGLES_POINT_MODE_ATI 0x87F2 -#define GL_PN_TRIANGLES_NORMAL_MODE_ATI 0x87F3 -#define GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI 0x87F4 -#define GL_PN_TRIANGLES_POINT_MODE_LINEAR_ATI 0x87F5 -#define GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI 0x87F6 -#define GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI 0x87F7 -#define GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI 0x87F8 -#endif - -#ifndef GL_ATI_vertex_array_object -#define GL_STATIC_ATI 0x8760 -#define GL_DYNAMIC_ATI 0x8761 -#define GL_PRESERVE_ATI 0x8762 -#define GL_DISCARD_ATI 0x8763 -#define GL_OBJECT_BUFFER_SIZE_ATI 0x8764 -#define GL_OBJECT_BUFFER_USAGE_ATI 0x8765 -#define GL_ARRAY_OBJECT_BUFFER_ATI 0x8766 -#define GL_ARRAY_OBJECT_OFFSET_ATI 0x8767 -#endif - -#ifndef GL_EXT_vertex_shader -#define GL_VERTEX_SHADER_EXT 0x8780 -#define GL_VERTEX_SHADER_BINDING_EXT 0x8781 -#define GL_OP_INDEX_EXT 0x8782 -#define GL_OP_NEGATE_EXT 0x8783 -#define GL_OP_DOT3_EXT 0x8784 -#define GL_OP_DOT4_EXT 0x8785 -#define GL_OP_MUL_EXT 0x8786 -#define GL_OP_ADD_EXT 0x8787 -#define GL_OP_MADD_EXT 0x8788 -#define GL_OP_FRAC_EXT 0x8789 -#define GL_OP_MAX_EXT 0x878A -#define GL_OP_MIN_EXT 0x878B -#define GL_OP_SET_GE_EXT 0x878C -#define GL_OP_SET_LT_EXT 0x878D -#define GL_OP_CLAMP_EXT 0x878E -#define GL_OP_FLOOR_EXT 0x878F -#define GL_OP_ROUND_EXT 0x8790 -#define GL_OP_EXP_BASE_2_EXT 0x8791 -#define GL_OP_LOG_BASE_2_EXT 0x8792 -#define GL_OP_POWER_EXT 0x8793 -#define GL_OP_RECIP_EXT 0x8794 -#define GL_OP_RECIP_SQRT_EXT 0x8795 -#define GL_OP_SUB_EXT 0x8796 -#define GL_OP_CROSS_PRODUCT_EXT 0x8797 -#define GL_OP_MULTIPLY_MATRIX_EXT 0x8798 -#define GL_OP_MOV_EXT 0x8799 -#define GL_OUTPUT_VERTEX_EXT 0x879A -#define GL_OUTPUT_COLOR0_EXT 0x879B -#define GL_OUTPUT_COLOR1_EXT 0x879C -#define GL_OUTPUT_TEXTURE_COORD0_EXT 0x879D -#define GL_OUTPUT_TEXTURE_COORD1_EXT 0x879E -#define GL_OUTPUT_TEXTURE_COORD2_EXT 0x879F -#define GL_OUTPUT_TEXTURE_COORD3_EXT 0x87A0 -#define GL_OUTPUT_TEXTURE_COORD4_EXT 0x87A1 -#define GL_OUTPUT_TEXTURE_COORD5_EXT 0x87A2 -#define GL_OUTPUT_TEXTURE_COORD6_EXT 0x87A3 -#define GL_OUTPUT_TEXTURE_COORD7_EXT 0x87A4 -#define GL_OUTPUT_TEXTURE_COORD8_EXT 0x87A5 -#define GL_OUTPUT_TEXTURE_COORD9_EXT 0x87A6 -#define GL_OUTPUT_TEXTURE_COORD10_EXT 0x87A7 -#define GL_OUTPUT_TEXTURE_COORD11_EXT 0x87A8 -#define GL_OUTPUT_TEXTURE_COORD12_EXT 0x87A9 -#define GL_OUTPUT_TEXTURE_COORD13_EXT 0x87AA -#define GL_OUTPUT_TEXTURE_COORD14_EXT 0x87AB -#define GL_OUTPUT_TEXTURE_COORD15_EXT 0x87AC -#define GL_OUTPUT_TEXTURE_COORD16_EXT 0x87AD -#define GL_OUTPUT_TEXTURE_COORD17_EXT 0x87AE -#define GL_OUTPUT_TEXTURE_COORD18_EXT 0x87AF -#define GL_OUTPUT_TEXTURE_COORD19_EXT 0x87B0 -#define GL_OUTPUT_TEXTURE_COORD20_EXT 0x87B1 -#define GL_OUTPUT_TEXTURE_COORD21_EXT 0x87B2 -#define GL_OUTPUT_TEXTURE_COORD22_EXT 0x87B3 -#define GL_OUTPUT_TEXTURE_COORD23_EXT 0x87B4 -#define GL_OUTPUT_TEXTURE_COORD24_EXT 0x87B5 -#define GL_OUTPUT_TEXTURE_COORD25_EXT 0x87B6 -#define GL_OUTPUT_TEXTURE_COORD26_EXT 0x87B7 -#define GL_OUTPUT_TEXTURE_COORD27_EXT 0x87B8 -#define GL_OUTPUT_TEXTURE_COORD28_EXT 0x87B9 -#define GL_OUTPUT_TEXTURE_COORD29_EXT 0x87BA -#define GL_OUTPUT_TEXTURE_COORD30_EXT 0x87BB -#define GL_OUTPUT_TEXTURE_COORD31_EXT 0x87BC -#define GL_OUTPUT_FOG_EXT 0x87BD -#define GL_SCALAR_EXT 0x87BE -#define GL_VECTOR_EXT 0x87BF -#define GL_MATRIX_EXT 0x87C0 -#define GL_VARIANT_EXT 0x87C1 -#define GL_INVARIANT_EXT 0x87C2 -#define GL_LOCAL_CONSTANT_EXT 0x87C3 -#define GL_LOCAL_EXT 0x87C4 -#define GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87C5 -#define GL_MAX_VERTEX_SHADER_VARIANTS_EXT 0x87C6 -#define GL_MAX_VERTEX_SHADER_INVARIANTS_EXT 0x87C7 -#define GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87C8 -#define GL_MAX_VERTEX_SHADER_LOCALS_EXT 0x87C9 -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CA -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT 0x87CB -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87CC -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT 0x87CD -#define GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT 0x87CE -#define GL_VERTEX_SHADER_INSTRUCTIONS_EXT 0x87CF -#define GL_VERTEX_SHADER_VARIANTS_EXT 0x87D0 -#define GL_VERTEX_SHADER_INVARIANTS_EXT 0x87D1 -#define GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT 0x87D2 -#define GL_VERTEX_SHADER_LOCALS_EXT 0x87D3 -#define GL_VERTEX_SHADER_OPTIMIZED_EXT 0x87D4 -#define GL_X_EXT 0x87D5 -#define GL_Y_EXT 0x87D6 -#define GL_Z_EXT 0x87D7 -#define GL_W_EXT 0x87D8 -#define GL_NEGATIVE_X_EXT 0x87D9 -#define GL_NEGATIVE_Y_EXT 0x87DA -#define GL_NEGATIVE_Z_EXT 0x87DB -#define GL_NEGATIVE_W_EXT 0x87DC -#define GL_ZERO_EXT 0x87DD -#define GL_ONE_EXT 0x87DE -#define GL_NEGATIVE_ONE_EXT 0x87DF -#define GL_NORMALIZED_RANGE_EXT 0x87E0 -#define GL_FULL_RANGE_EXT 0x87E1 -#define GL_CURRENT_VERTEX_EXT 0x87E2 -#define GL_MVP_MATRIX_EXT 0x87E3 -#define GL_VARIANT_VALUE_EXT 0x87E4 -#define GL_VARIANT_DATATYPE_EXT 0x87E5 -#define GL_VARIANT_ARRAY_STRIDE_EXT 0x87E6 -#define GL_VARIANT_ARRAY_TYPE_EXT 0x87E7 -#define GL_VARIANT_ARRAY_EXT 0x87E8 -#define GL_VARIANT_ARRAY_POINTER_EXT 0x87E9 -#define GL_INVARIANT_VALUE_EXT 0x87EA -#define GL_INVARIANT_DATATYPE_EXT 0x87EB -#define GL_LOCAL_CONSTANT_VALUE_EXT 0x87EC -#define GL_LOCAL_CONSTANT_DATATYPE_EXT 0x87ED -#endif - -#ifndef GL_ATI_vertex_streams -#define GL_MAX_VERTEX_STREAMS_ATI 0x876B -#define GL_VERTEX_STREAM0_ATI 0x876C -#define GL_VERTEX_STREAM1_ATI 0x876D -#define GL_VERTEX_STREAM2_ATI 0x876E -#define GL_VERTEX_STREAM3_ATI 0x876F -#define GL_VERTEX_STREAM4_ATI 0x8770 -#define GL_VERTEX_STREAM5_ATI 0x8771 -#define GL_VERTEX_STREAM6_ATI 0x8772 -#define GL_VERTEX_STREAM7_ATI 0x8773 -#define GL_VERTEX_SOURCE_ATI 0x8774 -#endif - -#ifndef GL_ATI_element_array -#define GL_ELEMENT_ARRAY_ATI 0x8768 -#define GL_ELEMENT_ARRAY_TYPE_ATI 0x8769 -#define GL_ELEMENT_ARRAY_POINTER_ATI 0x876A -#endif - -#ifndef GL_SUN_mesh_array -#define GL_QUAD_MESH_SUN 0x8614 -#define GL_TRIANGLE_MESH_SUN 0x8615 -#endif - -#ifndef GL_SUN_slice_accum -#define GL_SLICE_ACCUM_SUN 0x85CC -#endif - -#ifndef GL_NV_multisample_filter_hint -#define GL_MULTISAMPLE_FILTER_HINT_NV 0x8534 -#endif - -#ifndef GL_NV_depth_clamp -#define GL_DEPTH_CLAMP_NV 0x864F -#endif - -#ifndef GL_NV_occlusion_query -#define GL_PIXEL_COUNTER_BITS_NV 0x8864 -#define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 -#define GL_PIXEL_COUNT_NV 0x8866 -#define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 -#endif - -#ifndef GL_NV_point_sprite -#define GL_POINT_SPRITE_NV 0x8861 -#define GL_COORD_REPLACE_NV 0x8862 -#define GL_POINT_SPRITE_R_MODE_NV 0x8863 -#endif - -#ifndef GL_NV_texture_shader3 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_NV 0x8850 -#define GL_OFFSET_PROJECTIVE_TEXTURE_2D_SCALE_NV 0x8851 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8852 -#define GL_OFFSET_PROJECTIVE_TEXTURE_RECTANGLE_SCALE_NV 0x8853 -#define GL_OFFSET_HILO_TEXTURE_2D_NV 0x8854 -#define GL_OFFSET_HILO_TEXTURE_RECTANGLE_NV 0x8855 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_2D_NV 0x8856 -#define GL_OFFSET_HILO_PROJECTIVE_TEXTURE_RECTANGLE_NV 0x8857 -#define GL_DEPENDENT_HILO_TEXTURE_2D_NV 0x8858 -#define GL_DEPENDENT_RGB_TEXTURE_3D_NV 0x8859 -#define GL_DEPENDENT_RGB_TEXTURE_CUBE_MAP_NV 0x885A -#define GL_DOT_PRODUCT_PASS_THROUGH_NV 0x885B -#define GL_DOT_PRODUCT_TEXTURE_1D_NV 0x885C -#define GL_DOT_PRODUCT_AFFINE_DEPTH_REPLACE_NV 0x885D -#define GL_HILO8_NV 0x885E -#define GL_SIGNED_HILO8_NV 0x885F -#define GL_FORCE_BLUE_TO_ONE_NV 0x8860 -#endif - -#ifndef GL_NV_vertex_program1_1 -#endif - -#ifndef GL_EXT_shadow_funcs -#endif - -#ifndef GL_EXT_stencil_two_side -#define GL_STENCIL_TEST_TWO_SIDE_EXT 0x8910 -#define GL_ACTIVE_STENCIL_FACE_EXT 0x8911 -#endif - -#ifndef GL_ATI_text_fragment_shader -#define GL_TEXT_FRAGMENT_SHADER_ATI 0x8200 -#endif - -#ifndef GL_APPLE_client_storage -#define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 -#endif - -#ifndef GL_APPLE_element_array -#define GL_ELEMENT_ARRAY_APPLE 0x8A0C -#define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D -#define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E -#endif - -#ifndef GL_APPLE_fence -#define GL_DRAW_PIXELS_APPLE 0x8A0A -#define GL_FENCE_APPLE 0x8A0B -#endif - -#ifndef GL_APPLE_vertex_array_object -#define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 -#endif - -#ifndef GL_APPLE_vertex_array_range -#define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D -#define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E -#define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F -#define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 -#define GL_STORAGE_CLIENT_APPLE 0x85B4 -#define GL_STORAGE_CACHED_APPLE 0x85BE -#define GL_STORAGE_SHARED_APPLE 0x85BF -#endif - -#ifndef GL_APPLE_ycbcr_422 -#define GL_YCBCR_422_APPLE 0x85B9 -#define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB -#endif - -#ifndef GL_S3_s3tc -#define GL_RGB_S3TC 0x83A0 -#define GL_RGB4_S3TC 0x83A1 -#define GL_RGBA_S3TC 0x83A2 -#define GL_RGBA4_S3TC 0x83A3 -#endif - -#ifndef GL_ATI_draw_buffers -#define GL_MAX_DRAW_BUFFERS_ATI 0x8824 -#define GL_DRAW_BUFFER0_ATI 0x8825 -#define GL_DRAW_BUFFER1_ATI 0x8826 -#define GL_DRAW_BUFFER2_ATI 0x8827 -#define GL_DRAW_BUFFER3_ATI 0x8828 -#define GL_DRAW_BUFFER4_ATI 0x8829 -#define GL_DRAW_BUFFER5_ATI 0x882A -#define GL_DRAW_BUFFER6_ATI 0x882B -#define GL_DRAW_BUFFER7_ATI 0x882C -#define GL_DRAW_BUFFER8_ATI 0x882D -#define GL_DRAW_BUFFER9_ATI 0x882E -#define GL_DRAW_BUFFER10_ATI 0x882F -#define GL_DRAW_BUFFER11_ATI 0x8830 -#define GL_DRAW_BUFFER12_ATI 0x8831 -#define GL_DRAW_BUFFER13_ATI 0x8832 -#define GL_DRAW_BUFFER14_ATI 0x8833 -#define GL_DRAW_BUFFER15_ATI 0x8834 -#endif - -#ifndef GL_ATI_pixel_format_float -#define GL_TYPE_RGBA_FLOAT_ATI 0x8820 -#define GL_COLOR_CLEAR_UNCLAMPED_VALUE_ATI 0x8835 -#endif - -#ifndef GL_ATI_texture_env_combine3 -#define GL_MODULATE_ADD_ATI 0x8744 -#define GL_MODULATE_SIGNED_ADD_ATI 0x8745 -#define GL_MODULATE_SUBTRACT_ATI 0x8746 -#endif - -#ifndef GL_ATI_texture_float -#define GL_RGBA_FLOAT32_ATI 0x8814 -#define GL_RGB_FLOAT32_ATI 0x8815 -#define GL_ALPHA_FLOAT32_ATI 0x8816 -#define GL_INTENSITY_FLOAT32_ATI 0x8817 -#define GL_LUMINANCE_FLOAT32_ATI 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_ATI 0x8819 -#define GL_RGBA_FLOAT16_ATI 0x881A -#define GL_RGB_FLOAT16_ATI 0x881B -#define GL_ALPHA_FLOAT16_ATI 0x881C -#define GL_INTENSITY_FLOAT16_ATI 0x881D -#define GL_LUMINANCE_FLOAT16_ATI 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_ATI 0x881F -#endif - -#ifndef GL_NV_float_buffer -#define GL_FLOAT_R_NV 0x8880 -#define GL_FLOAT_RG_NV 0x8881 -#define GL_FLOAT_RGB_NV 0x8882 -#define GL_FLOAT_RGBA_NV 0x8883 -#define GL_FLOAT_R16_NV 0x8884 -#define GL_FLOAT_R32_NV 0x8885 -#define GL_FLOAT_RG16_NV 0x8886 -#define GL_FLOAT_RG32_NV 0x8887 -#define GL_FLOAT_RGB16_NV 0x8888 -#define GL_FLOAT_RGB32_NV 0x8889 -#define GL_FLOAT_RGBA16_NV 0x888A -#define GL_FLOAT_RGBA32_NV 0x888B -#define GL_TEXTURE_FLOAT_COMPONENTS_NV 0x888C -#define GL_FLOAT_CLEAR_COLOR_VALUE_NV 0x888D -#define GL_FLOAT_RGBA_MODE_NV 0x888E -#endif - -#ifndef GL_NV_fragment_program -#define GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV 0x8868 -#define GL_FRAGMENT_PROGRAM_NV 0x8870 -#define GL_MAX_TEXTURE_COORDS_NV 0x8871 -#define GL_MAX_TEXTURE_IMAGE_UNITS_NV 0x8872 -#define GL_FRAGMENT_PROGRAM_BINDING_NV 0x8873 -#define GL_PROGRAM_ERROR_STRING_NV 0x8874 -#endif - -#ifndef GL_NV_half_float -#define GL_HALF_FLOAT_NV 0x140B -#endif - -#ifndef GL_NV_pixel_data_range -#define GL_WRITE_PIXEL_DATA_RANGE_NV 0x8878 -#define GL_READ_PIXEL_DATA_RANGE_NV 0x8879 -#define GL_WRITE_PIXEL_DATA_RANGE_LENGTH_NV 0x887A -#define GL_READ_PIXEL_DATA_RANGE_LENGTH_NV 0x887B -#define GL_WRITE_PIXEL_DATA_RANGE_POINTER_NV 0x887C -#define GL_READ_PIXEL_DATA_RANGE_POINTER_NV 0x887D -#endif - -#ifndef GL_NV_primitive_restart -#define GL_PRIMITIVE_RESTART_NV 0x8558 -#define GL_PRIMITIVE_RESTART_INDEX_NV 0x8559 -#endif - -#ifndef GL_NV_texture_expand_normal -#define GL_TEXTURE_UNSIGNED_REMAP_MODE_NV 0x888F -#endif - -#ifndef GL_NV_vertex_program2 -#endif - -#ifndef GL_ATI_map_object_buffer -#endif - -#ifndef GL_ATI_separate_stencil -#define GL_STENCIL_BACK_FUNC_ATI 0x8800 -#define GL_STENCIL_BACK_FAIL_ATI 0x8801 -#define GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI 0x8802 -#define GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI 0x8803 -#endif - -#ifndef GL_ATI_vertex_attrib_array_object -#endif - -#ifndef GL_OES_read_format -#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A -#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B -#endif - -#ifndef GL_EXT_depth_bounds_test -#define GL_DEPTH_BOUNDS_TEST_EXT 0x8890 -#define GL_DEPTH_BOUNDS_EXT 0x8891 -#endif - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_MIRROR_CLAMP_EXT 0x8742 -#define GL_MIRROR_CLAMP_TO_EDGE_EXT 0x8743 -#define GL_MIRROR_CLAMP_TO_BORDER_EXT 0x8912 -#endif - -#ifndef GL_EXT_blend_equation_separate -#define GL_BLEND_EQUATION_RGB_EXT 0x8009 -#define GL_BLEND_EQUATION_ALPHA_EXT 0x883D -#endif - -#ifndef GL_MESA_pack_invert -#define GL_PACK_INVERT_MESA 0x8758 -#endif - -#ifndef GL_MESA_ycbcr_texture -#define GL_UNSIGNED_SHORT_8_8_MESA 0x85BA -#define GL_UNSIGNED_SHORT_8_8_REV_MESA 0x85BB -#define GL_YCBCR_MESA 0x8757 -#endif - -#ifndef GL_EXT_pixel_buffer_object -#define GL_PIXEL_PACK_BUFFER_EXT 0x88EB -#define GL_PIXEL_UNPACK_BUFFER_EXT 0x88EC -#define GL_PIXEL_PACK_BUFFER_BINDING_EXT 0x88ED -#define GL_PIXEL_UNPACK_BUFFER_BINDING_EXT 0x88EF -#endif - -#ifndef GL_NV_fragment_program_option -#endif - -#ifndef GL_NV_fragment_program2 -#define GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV 0x88F4 -#define GL_MAX_PROGRAM_CALL_DEPTH_NV 0x88F5 -#define GL_MAX_PROGRAM_IF_DEPTH_NV 0x88F6 -#define GL_MAX_PROGRAM_LOOP_DEPTH_NV 0x88F7 -#define GL_MAX_PROGRAM_LOOP_COUNT_NV 0x88F8 -#endif - -#ifndef GL_NV_vertex_program2_option -/* reuse GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */ -/* reuse GL_MAX_PROGRAM_CALL_DEPTH_NV */ -#endif - -#ifndef GL_NV_vertex_program3 -/* reuse GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */ -#endif - -#ifndef GL_EXT_framebuffer_object -#define GL_INVALID_FRAMEBUFFER_OPERATION_EXT 0x0506 -#define GL_MAX_RENDERBUFFER_SIZE_EXT 0x84E8 -#define GL_FRAMEBUFFER_BINDING_EXT 0x8CA6 -#define GL_RENDERBUFFER_BINDING_EXT 0x8CA7 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT 0x8CD0 -#define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT 0x8CD1 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT 0x8CD2 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT 0x8CD3 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT 0x8CD4 -#define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5 -#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT 0x8CD6 -#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT 0x8CD7 -#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT 0x8CD9 -#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT 0x8CDA -#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT 0x8CDB -#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT 0x8CDC -#define GL_FRAMEBUFFER_UNSUPPORTED_EXT 0x8CDD -#define GL_MAX_COLOR_ATTACHMENTS_EXT 0x8CDF -#define GL_COLOR_ATTACHMENT0_EXT 0x8CE0 -#define GL_COLOR_ATTACHMENT1_EXT 0x8CE1 -#define GL_COLOR_ATTACHMENT2_EXT 0x8CE2 -#define GL_COLOR_ATTACHMENT3_EXT 0x8CE3 -#define GL_COLOR_ATTACHMENT4_EXT 0x8CE4 -#define GL_COLOR_ATTACHMENT5_EXT 0x8CE5 -#define GL_COLOR_ATTACHMENT6_EXT 0x8CE6 -#define GL_COLOR_ATTACHMENT7_EXT 0x8CE7 -#define GL_COLOR_ATTACHMENT8_EXT 0x8CE8 -#define GL_COLOR_ATTACHMENT9_EXT 0x8CE9 -#define GL_COLOR_ATTACHMENT10_EXT 0x8CEA -#define GL_COLOR_ATTACHMENT11_EXT 0x8CEB -#define GL_COLOR_ATTACHMENT12_EXT 0x8CEC -#define GL_COLOR_ATTACHMENT13_EXT 0x8CED -#define GL_COLOR_ATTACHMENT14_EXT 0x8CEE -#define GL_COLOR_ATTACHMENT15_EXT 0x8CEF -#define GL_DEPTH_ATTACHMENT_EXT 0x8D00 -#define GL_STENCIL_ATTACHMENT_EXT 0x8D20 -#define GL_FRAMEBUFFER_EXT 0x8D40 -#define GL_RENDERBUFFER_EXT 0x8D41 -#define GL_RENDERBUFFER_WIDTH_EXT 0x8D42 -#define GL_RENDERBUFFER_HEIGHT_EXT 0x8D43 -#define GL_RENDERBUFFER_INTERNAL_FORMAT_EXT 0x8D44 -#define GL_STENCIL_INDEX1_EXT 0x8D46 -#define GL_STENCIL_INDEX4_EXT 0x8D47 -#define GL_STENCIL_INDEX8_EXT 0x8D48 -#define GL_STENCIL_INDEX16_EXT 0x8D49 -#define GL_RENDERBUFFER_RED_SIZE_EXT 0x8D50 -#define GL_RENDERBUFFER_GREEN_SIZE_EXT 0x8D51 -#define GL_RENDERBUFFER_BLUE_SIZE_EXT 0x8D52 -#define GL_RENDERBUFFER_ALPHA_SIZE_EXT 0x8D53 -#define GL_RENDERBUFFER_DEPTH_SIZE_EXT 0x8D54 -#define GL_RENDERBUFFER_STENCIL_SIZE_EXT 0x8D55 -#endif - -#ifndef GL_GREMEDY_string_marker -#endif - -#ifndef GL_EXT_packed_depth_stencil -#define GL_DEPTH_STENCIL_EXT 0x84F9 -#define GL_UNSIGNED_INT_24_8_EXT 0x84FA -#define GL_DEPTH24_STENCIL8_EXT 0x88F0 -#define GL_TEXTURE_STENCIL_SIZE_EXT 0x88F1 -#endif - -#ifndef GL_EXT_stencil_clear_tag -#define GL_STENCIL_TAG_BITS_EXT 0x88F2 -#define GL_STENCIL_CLEAR_TAG_VALUE_EXT 0x88F3 -#endif - -#ifndef GL_EXT_texture_sRGB -#define GL_SRGB_EXT 0x8C40 -#define GL_SRGB8_EXT 0x8C41 -#define GL_SRGB_ALPHA_EXT 0x8C42 -#define GL_SRGB8_ALPHA8_EXT 0x8C43 -#define GL_SLUMINANCE_ALPHA_EXT 0x8C44 -#define GL_SLUMINANCE8_ALPHA8_EXT 0x8C45 -#define GL_SLUMINANCE_EXT 0x8C46 -#define GL_SLUMINANCE8_EXT 0x8C47 -#define GL_COMPRESSED_SRGB_EXT 0x8C48 -#define GL_COMPRESSED_SRGB_ALPHA_EXT 0x8C49 -#define GL_COMPRESSED_SLUMINANCE_EXT 0x8C4A -#define GL_COMPRESSED_SLUMINANCE_ALPHA_EXT 0x8C4B -#define GL_COMPRESSED_SRGB_S3TC_DXT1_EXT 0x8C4C -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT 0x8C4D -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT 0x8C4E -#define GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT 0x8C4F -#endif - -#ifndef GL_EXT_framebuffer_blit -#define GL_READ_FRAMEBUFFER_EXT 0x8CA8 -#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9 -#define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING_EXT -#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA -#endif - -#ifndef GL_EXT_framebuffer_multisample -#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB -#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56 -#define GL_MAX_SAMPLES_EXT 0x8D57 -#endif - -#ifndef GL_MESAX_texture_stack -#define GL_TEXTURE_1D_STACK_MESAX 0x8759 -#define GL_TEXTURE_2D_STACK_MESAX 0x875A -#define GL_PROXY_TEXTURE_1D_STACK_MESAX 0x875B -#define GL_PROXY_TEXTURE_2D_STACK_MESAX 0x875C -#define GL_TEXTURE_1D_STACK_BINDING_MESAX 0x875D -#define GL_TEXTURE_2D_STACK_BINDING_MESAX 0x875E -#endif - -#ifndef GL_EXT_timer_query -#define GL_TIME_ELAPSED_EXT 0x88BF -#endif - -#ifndef GL_EXT_gpu_program_parameters -#endif - -#ifndef GL_APPLE_flush_buffer_range -#define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 -#define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 -#endif - -#ifndef GL_NV_gpu_program4 -#define GL_MIN_PROGRAM_TEXEL_OFFSET_NV 0x8904 -#define GL_MAX_PROGRAM_TEXEL_OFFSET_NV 0x8905 -#define GL_PROGRAM_ATTRIB_COMPONENTS_NV 0x8906 -#define GL_PROGRAM_RESULT_COMPONENTS_NV 0x8907 -#define GL_MAX_PROGRAM_ATTRIB_COMPONENTS_NV 0x8908 -#define GL_MAX_PROGRAM_RESULT_COMPONENTS_NV 0x8909 -#define GL_MAX_PROGRAM_GENERIC_ATTRIBS_NV 0x8DA5 -#define GL_MAX_PROGRAM_GENERIC_RESULTS_NV 0x8DA6 -#endif - -#ifndef GL_NV_geometry_program4 -#define GL_LINES_ADJACENCY_EXT 0x000A -#define GL_LINE_STRIP_ADJACENCY_EXT 0x000B -#define GL_TRIANGLES_ADJACENCY_EXT 0x000C -#define GL_TRIANGLE_STRIP_ADJACENCY_EXT 0x000D -#define GL_GEOMETRY_PROGRAM_NV 0x8C26 -#define GL_MAX_PROGRAM_OUTPUT_VERTICES_NV 0x8C27 -#define GL_MAX_PROGRAM_TOTAL_OUTPUT_COMPONENTS_NV 0x8C28 -#define GL_GEOMETRY_VERTICES_OUT_EXT 0x8DDA -#define GL_GEOMETRY_INPUT_TYPE_EXT 0x8DDB -#define GL_GEOMETRY_OUTPUT_TYPE_EXT 0x8DDC -#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT 0x8C29 -#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT 0x8DA7 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT 0x8DA8 -#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT 0x8DA9 -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT 0x8CD4 -#define GL_PROGRAM_POINT_SIZE_EXT 0x8642 -#endif - -#ifndef GL_EXT_geometry_shader4 -#define GL_GEOMETRY_SHADER_EXT 0x8DD9 -/* reuse GL_GEOMETRY_VERTICES_OUT_EXT */ -/* reuse GL_GEOMETRY_INPUT_TYPE_EXT */ -/* reuse GL_GEOMETRY_OUTPUT_TYPE_EXT */ -/* reuse GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT */ -#define GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT 0x8DDD -#define GL_MAX_VERTEX_VARYING_COMPONENTS_EXT 0x8DDE -#define GL_MAX_VARYING_COMPONENTS_EXT 0x8B4B -#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT 0x8DDF -#define GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT 0x8DE0 -#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT 0x8DE1 -/* reuse GL_LINES_ADJACENCY_EXT */ -/* reuse GL_LINE_STRIP_ADJACENCY_EXT */ -/* reuse GL_TRIANGLES_ADJACENCY_EXT */ -/* reuse GL_TRIANGLE_STRIP_ADJACENCY_EXT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT */ -/* reuse GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT */ -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ -/* reuse GL_PROGRAM_POINT_SIZE_EXT */ -#endif - -#ifndef GL_NV_vertex_program4 -#define GL_VERTEX_ATTRIB_ARRAY_INTEGER_NV 0x88FD -#endif - -#ifndef GL_EXT_gpu_shader4 -#define GL_SAMPLER_1D_ARRAY_EXT 0x8DC0 -#define GL_SAMPLER_2D_ARRAY_EXT 0x8DC1 -#define GL_SAMPLER_BUFFER_EXT 0x8DC2 -#define GL_SAMPLER_1D_ARRAY_SHADOW_EXT 0x8DC3 -#define GL_SAMPLER_2D_ARRAY_SHADOW_EXT 0x8DC4 -#define GL_SAMPLER_CUBE_SHADOW_EXT 0x8DC5 -#define GL_UNSIGNED_INT_VEC2_EXT 0x8DC6 -#define GL_UNSIGNED_INT_VEC3_EXT 0x8DC7 -#define GL_UNSIGNED_INT_VEC4_EXT 0x8DC8 -#define GL_INT_SAMPLER_1D_EXT 0x8DC9 -#define GL_INT_SAMPLER_2D_EXT 0x8DCA -#define GL_INT_SAMPLER_3D_EXT 0x8DCB -#define GL_INT_SAMPLER_CUBE_EXT 0x8DCC -#define GL_INT_SAMPLER_2D_RECT_EXT 0x8DCD -#define GL_INT_SAMPLER_1D_ARRAY_EXT 0x8DCE -#define GL_INT_SAMPLER_2D_ARRAY_EXT 0x8DCF -#define GL_INT_SAMPLER_BUFFER_EXT 0x8DD0 -#define GL_UNSIGNED_INT_SAMPLER_1D_EXT 0x8DD1 -#define GL_UNSIGNED_INT_SAMPLER_2D_EXT 0x8DD2 -#define GL_UNSIGNED_INT_SAMPLER_3D_EXT 0x8DD3 -#define GL_UNSIGNED_INT_SAMPLER_CUBE_EXT 0x8DD4 -#define GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT 0x8DD5 -#define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT 0x8DD6 -#define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT 0x8DD7 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT 0x8DD8 -#endif - -#ifndef GL_EXT_draw_instanced -#endif - -#ifndef GL_EXT_packed_float -#define GL_R11F_G11F_B10F_EXT 0x8C3A -#define GL_UNSIGNED_INT_10F_11F_11F_REV_EXT 0x8C3B -#define GL_RGBA_SIGNED_COMPONENTS_EXT 0x8C3C -#endif - -#ifndef GL_EXT_texture_array -#define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 -#define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 -#define GL_TEXTURE_2D_ARRAY_EXT 0x8C1A -#define GL_PROXY_TEXTURE_2D_ARRAY_EXT 0x8C1B -#define GL_TEXTURE_BINDING_1D_ARRAY_EXT 0x8C1C -#define GL_TEXTURE_BINDING_2D_ARRAY_EXT 0x8C1D -#define GL_MAX_ARRAY_TEXTURE_LAYERS_EXT 0x88FF -#define GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT 0x884E -/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */ -#endif - -#ifndef GL_EXT_texture_buffer_object -#define GL_TEXTURE_BUFFER_EXT 0x8C2A -#define GL_MAX_TEXTURE_BUFFER_SIZE_EXT 0x8C2B -#define GL_TEXTURE_BINDING_BUFFER_EXT 0x8C2C -#define GL_TEXTURE_BUFFER_DATA_STORE_BINDING_EXT 0x8C2D -#define GL_TEXTURE_BUFFER_FORMAT_EXT 0x8C2E -#endif - -#ifndef GL_EXT_texture_compression_latc -#define GL_COMPRESSED_LUMINANCE_LATC1_EXT 0x8C70 -#define GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT 0x8C71 -#define GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT 0x8C72 -#define GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT 0x8C73 -#endif - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_COMPRESSED_RED_RGTC1_EXT 0x8DBB -#define GL_COMPRESSED_SIGNED_RED_RGTC1_EXT 0x8DBC -#define GL_COMPRESSED_RED_GREEN_RGTC2_EXT 0x8DBD -#define GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT 0x8DBE -#endif - -#ifndef GL_EXT_texture_shared_exponent -#define GL_RGB9_E5_EXT 0x8C3D -#define GL_UNSIGNED_INT_5_9_9_9_REV_EXT 0x8C3E -#define GL_TEXTURE_SHARED_SIZE_EXT 0x8C3F -#endif - -#ifndef GL_NV_depth_buffer_float -#define GL_DEPTH_COMPONENT32F_NV 0x8DAB -#define GL_DEPTH32F_STENCIL8_NV 0x8DAC -#define GL_FLOAT_32_UNSIGNED_INT_24_8_REV_NV 0x8DAD -#define GL_DEPTH_BUFFER_FLOAT_MODE_NV 0x8DAF -#endif - -#ifndef GL_NV_fragment_program4 -#endif - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_RENDERBUFFER_COVERAGE_SAMPLES_NV 0x8CAB -#define GL_RENDERBUFFER_COLOR_SAMPLES_NV 0x8E10 -#define GL_MAX_MULTISAMPLE_COVERAGE_MODES_NV 0x8E11 -#define GL_MULTISAMPLE_COVERAGE_MODES_NV 0x8E12 -#endif - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 -#define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA -#endif - -#ifndef GL_NV_geometry_shader4 -#endif - -#ifndef GL_NV_parameter_buffer_object -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_BINDINGS_NV 0x8DA0 -#define GL_MAX_PROGRAM_PARAMETER_BUFFER_SIZE_NV 0x8DA1 -#define GL_VERTEX_PROGRAM_PARAMETER_BUFFER_NV 0x8DA2 -#define GL_GEOMETRY_PROGRAM_PARAMETER_BUFFER_NV 0x8DA3 -#define GL_FRAGMENT_PROGRAM_PARAMETER_BUFFER_NV 0x8DA4 -#endif - -#ifndef GL_EXT_draw_buffers2 -#endif - -#ifndef GL_NV_transform_feedback -#define GL_BACK_PRIMARY_COLOR_NV 0x8C77 -#define GL_BACK_SECONDARY_COLOR_NV 0x8C78 -#define GL_TEXTURE_COORD_NV 0x8C79 -#define GL_CLIP_DISTANCE_NV 0x8C7A -#define GL_VERTEX_ID_NV 0x8C7B -#define GL_PRIMITIVE_ID_NV 0x8C7C -#define GL_GENERIC_ATTRIB_NV 0x8C7D -#define GL_TRANSFORM_FEEDBACK_ATTRIBS_NV 0x8C7E -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_NV 0x8C7F -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_NV 0x8C80 -#define GL_ACTIVE_VARYINGS_NV 0x8C81 -#define GL_ACTIVE_VARYING_MAX_LENGTH_NV 0x8C82 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_NV 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_NV 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_NV 0x8C85 -#define GL_TRANSFORM_FEEDBACK_RECORD_NV 0x8C86 -#define GL_PRIMITIVES_GENERATED_NV 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_NV 0x8C88 -#define GL_RASTERIZER_DISCARD_NV 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_ATTRIBS_NV 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_NV 0x8C8B -#define GL_INTERLEAVED_ATTRIBS_NV 0x8C8C -#define GL_SEPARATE_ATTRIBS_NV 0x8C8D -#define GL_TRANSFORM_FEEDBACK_BUFFER_NV 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_NV 0x8C8F -#define GL_LAYER_NV 0x8DAA -#define GL_NEXT_BUFFER_NV -2 -#define GL_SKIP_COMPONENTS4_NV -3 -#define GL_SKIP_COMPONENTS3_NV -4 -#define GL_SKIP_COMPONENTS2_NV -5 -#define GL_SKIP_COMPONENTS1_NV -6 -#endif - -#ifndef GL_EXT_bindable_uniform -#define GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT 0x8DE2 -#define GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT 0x8DE3 -#define GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT 0x8DE4 -#define GL_MAX_BINDABLE_UNIFORM_SIZE_EXT 0x8DED -#define GL_UNIFORM_BUFFER_EXT 0x8DEE -#define GL_UNIFORM_BUFFER_BINDING_EXT 0x8DEF -#endif - -#ifndef GL_EXT_texture_integer -#define GL_RGBA32UI_EXT 0x8D70 -#define GL_RGB32UI_EXT 0x8D71 -#define GL_ALPHA32UI_EXT 0x8D72 -#define GL_INTENSITY32UI_EXT 0x8D73 -#define GL_LUMINANCE32UI_EXT 0x8D74 -#define GL_LUMINANCE_ALPHA32UI_EXT 0x8D75 -#define GL_RGBA16UI_EXT 0x8D76 -#define GL_RGB16UI_EXT 0x8D77 -#define GL_ALPHA16UI_EXT 0x8D78 -#define GL_INTENSITY16UI_EXT 0x8D79 -#define GL_LUMINANCE16UI_EXT 0x8D7A -#define GL_LUMINANCE_ALPHA16UI_EXT 0x8D7B -#define GL_RGBA8UI_EXT 0x8D7C -#define GL_RGB8UI_EXT 0x8D7D -#define GL_ALPHA8UI_EXT 0x8D7E -#define GL_INTENSITY8UI_EXT 0x8D7F -#define GL_LUMINANCE8UI_EXT 0x8D80 -#define GL_LUMINANCE_ALPHA8UI_EXT 0x8D81 -#define GL_RGBA32I_EXT 0x8D82 -#define GL_RGB32I_EXT 0x8D83 -#define GL_ALPHA32I_EXT 0x8D84 -#define GL_INTENSITY32I_EXT 0x8D85 -#define GL_LUMINANCE32I_EXT 0x8D86 -#define GL_LUMINANCE_ALPHA32I_EXT 0x8D87 -#define GL_RGBA16I_EXT 0x8D88 -#define GL_RGB16I_EXT 0x8D89 -#define GL_ALPHA16I_EXT 0x8D8A -#define GL_INTENSITY16I_EXT 0x8D8B -#define GL_LUMINANCE16I_EXT 0x8D8C -#define GL_LUMINANCE_ALPHA16I_EXT 0x8D8D -#define GL_RGBA8I_EXT 0x8D8E -#define GL_RGB8I_EXT 0x8D8F -#define GL_ALPHA8I_EXT 0x8D90 -#define GL_INTENSITY8I_EXT 0x8D91 -#define GL_LUMINANCE8I_EXT 0x8D92 -#define GL_LUMINANCE_ALPHA8I_EXT 0x8D93 -#define GL_RED_INTEGER_EXT 0x8D94 -#define GL_GREEN_INTEGER_EXT 0x8D95 -#define GL_BLUE_INTEGER_EXT 0x8D96 -#define GL_ALPHA_INTEGER_EXT 0x8D97 -#define GL_RGB_INTEGER_EXT 0x8D98 -#define GL_RGBA_INTEGER_EXT 0x8D99 -#define GL_BGR_INTEGER_EXT 0x8D9A -#define GL_BGRA_INTEGER_EXT 0x8D9B -#define GL_LUMINANCE_INTEGER_EXT 0x8D9C -#define GL_LUMINANCE_ALPHA_INTEGER_EXT 0x8D9D -#define GL_RGBA_INTEGER_MODE_EXT 0x8D9E -#endif - -#ifndef GL_GREMEDY_frame_terminator -#endif - -#ifndef GL_NV_conditional_render -#define GL_QUERY_WAIT_NV 0x8E13 -#define GL_QUERY_NO_WAIT_NV 0x8E14 -#define GL_QUERY_BY_REGION_WAIT_NV 0x8E15 -#define GL_QUERY_BY_REGION_NO_WAIT_NV 0x8E16 -#endif - -#ifndef GL_NV_present_video -#define GL_FRAME_NV 0x8E26 -#define GL_FIELDS_NV 0x8E27 -#define GL_CURRENT_TIME_NV 0x8E28 -#define GL_NUM_FILL_STREAMS_NV 0x8E29 -#define GL_PRESENT_TIME_NV 0x8E2A -#define GL_PRESENT_DURATION_NV 0x8E2B -#endif - -#ifndef GL_EXT_transform_feedback -#define GL_TRANSFORM_FEEDBACK_BUFFER_EXT 0x8C8E -#define GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT 0x8C84 -#define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT 0x8C85 -#define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT 0x8C8F -#define GL_INTERLEAVED_ATTRIBS_EXT 0x8C8C -#define GL_SEPARATE_ATTRIBS_EXT 0x8C8D -#define GL_PRIMITIVES_GENERATED_EXT 0x8C87 -#define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT 0x8C88 -#define GL_RASTERIZER_DISCARD_EXT 0x8C89 -#define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT 0x8C8A -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT 0x8C8B -#define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT 0x8C80 -#define GL_TRANSFORM_FEEDBACK_VARYINGS_EXT 0x8C83 -#define GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT 0x8C7F -#define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT 0x8C76 -#endif - -#ifndef GL_EXT_direct_state_access -#define GL_PROGRAM_MATRIX_EXT 0x8E2D -#define GL_TRANSPOSE_PROGRAM_MATRIX_EXT 0x8E2E -#define GL_PROGRAM_MATRIX_STACK_DEPTH_EXT 0x8E2F -#endif - -#ifndef GL_EXT_vertex_array_bgra -/* reuse GL_BGRA */ -#endif - -#ifndef GL_EXT_texture_swizzle -#define GL_TEXTURE_SWIZZLE_R_EXT 0x8E42 -#define GL_TEXTURE_SWIZZLE_G_EXT 0x8E43 -#define GL_TEXTURE_SWIZZLE_B_EXT 0x8E44 -#define GL_TEXTURE_SWIZZLE_A_EXT 0x8E45 -#define GL_TEXTURE_SWIZZLE_RGBA_EXT 0x8E46 -#endif - -#ifndef GL_NV_explicit_multisample -#define GL_SAMPLE_POSITION_NV 0x8E50 -#define GL_SAMPLE_MASK_NV 0x8E51 -#define GL_SAMPLE_MASK_VALUE_NV 0x8E52 -#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53 -#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54 -#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55 -#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56 -#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57 -#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58 -#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59 -#endif - -#ifndef GL_NV_transform_feedback2 -#define GL_TRANSFORM_FEEDBACK_NV 0x8E22 -#define GL_TRANSFORM_FEEDBACK_BUFFER_PAUSED_NV 0x8E23 -#define GL_TRANSFORM_FEEDBACK_BUFFER_ACTIVE_NV 0x8E24 -#define GL_TRANSFORM_FEEDBACK_BINDING_NV 0x8E25 -#endif - -#ifndef GL_ATI_meminfo -#define GL_VBO_FREE_MEMORY_ATI 0x87FB -#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC -#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD -#endif - -#ifndef GL_AMD_performance_monitor -#define GL_COUNTER_TYPE_AMD 0x8BC0 -#define GL_COUNTER_RANGE_AMD 0x8BC1 -#define GL_UNSIGNED_INT64_AMD 0x8BC2 -#define GL_PERCENTAGE_AMD 0x8BC3 -#define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 -#define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 -#define GL_PERFMON_RESULT_AMD 0x8BC6 -#endif - -#ifndef GL_AMD_texture_texture4 -#endif - -#ifndef GL_AMD_vertex_shader_tesselator -#define GL_SAMPLER_BUFFER_AMD 0x9001 -#define GL_INT_SAMPLER_BUFFER_AMD 0x9002 -#define GL_UNSIGNED_INT_SAMPLER_BUFFER_AMD 0x9003 -#define GL_TESSELLATION_MODE_AMD 0x9004 -#define GL_TESSELLATION_FACTOR_AMD 0x9005 -#define GL_DISCRETE_AMD 0x9006 -#define GL_CONTINUOUS_AMD 0x9007 -#endif - -#ifndef GL_EXT_provoking_vertex -#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT 0x8E4C -#define GL_FIRST_VERTEX_CONVENTION_EXT 0x8E4D -#define GL_LAST_VERTEX_CONVENTION_EXT 0x8E4E -#define GL_PROVOKING_VERTEX_EXT 0x8E4F -#endif - -#ifndef GL_EXT_texture_snorm -#define GL_ALPHA_SNORM 0x9010 -#define GL_LUMINANCE_SNORM 0x9011 -#define GL_LUMINANCE_ALPHA_SNORM 0x9012 -#define GL_INTENSITY_SNORM 0x9013 -#define GL_ALPHA8_SNORM 0x9014 -#define GL_LUMINANCE8_SNORM 0x9015 -#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016 -#define GL_INTENSITY8_SNORM 0x9017 -#define GL_ALPHA16_SNORM 0x9018 -#define GL_LUMINANCE16_SNORM 0x9019 -#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A -#define GL_INTENSITY16_SNORM 0x901B -/* reuse GL_RED_SNORM */ -/* reuse GL_RG_SNORM */ -/* reuse GL_RGB_SNORM */ -/* reuse GL_RGBA_SNORM */ -/* reuse GL_R8_SNORM */ -/* reuse GL_RG8_SNORM */ -/* reuse GL_RGB8_SNORM */ -/* reuse GL_RGBA8_SNORM */ -/* reuse GL_R16_SNORM */ -/* reuse GL_RG16_SNORM */ -/* reuse GL_RGB16_SNORM */ -/* reuse GL_RGBA16_SNORM */ -/* reuse GL_SIGNED_NORMALIZED */ -#endif - -#ifndef GL_AMD_draw_buffers_blend -#endif - -#ifndef GL_APPLE_texture_range -#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 -#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 -#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC -#define GL_STORAGE_PRIVATE_APPLE 0x85BD -/* reuse GL_STORAGE_CACHED_APPLE */ -/* reuse GL_STORAGE_SHARED_APPLE */ -#endif - -#ifndef GL_APPLE_float_pixels -#define GL_HALF_APPLE 0x140B -#define GL_RGBA_FLOAT32_APPLE 0x8814 -#define GL_RGB_FLOAT32_APPLE 0x8815 -#define GL_ALPHA_FLOAT32_APPLE 0x8816 -#define GL_INTENSITY_FLOAT32_APPLE 0x8817 -#define GL_LUMINANCE_FLOAT32_APPLE 0x8818 -#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 -#define GL_RGBA_FLOAT16_APPLE 0x881A -#define GL_RGB_FLOAT16_APPLE 0x881B -#define GL_ALPHA_FLOAT16_APPLE 0x881C -#define GL_INTENSITY_FLOAT16_APPLE 0x881D -#define GL_LUMINANCE_FLOAT16_APPLE 0x881E -#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F -#define GL_COLOR_FLOAT_APPLE 0x8A0F -#endif - -#ifndef GL_APPLE_vertex_program_evaluators -#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 -#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 -#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 -#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 -#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 -#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 -#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 -#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 -#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 -#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 -#endif - -#ifndef GL_APPLE_aux_depth_stencil -#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14 -#endif - -#ifndef GL_APPLE_object_purgeable -#define GL_BUFFER_OBJECT_APPLE 0x85B3 -#define GL_RELEASED_APPLE 0x8A19 -#define GL_VOLATILE_APPLE 0x8A1A -#define GL_RETAINED_APPLE 0x8A1B -#define GL_UNDEFINED_APPLE 0x8A1C -#define GL_PURGEABLE_APPLE 0x8A1D -#endif - -#ifndef GL_APPLE_row_bytes -#define GL_PACK_ROW_BYTES_APPLE 0x8A15 -#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 -#endif - -#ifndef GL_APPLE_rgb_422 -#define GL_RGB_422_APPLE 0x8A1F -/* reuse GL_UNSIGNED_SHORT_8_8_APPLE */ -/* reuse GL_UNSIGNED_SHORT_8_8_REV_APPLE */ -#endif - -#ifndef GL_NV_video_capture -#define GL_VIDEO_BUFFER_NV 0x9020 -#define GL_VIDEO_BUFFER_BINDING_NV 0x9021 -#define GL_FIELD_UPPER_NV 0x9022 -#define GL_FIELD_LOWER_NV 0x9023 -#define GL_NUM_VIDEO_CAPTURE_STREAMS_NV 0x9024 -#define GL_NEXT_VIDEO_CAPTURE_BUFFER_STATUS_NV 0x9025 -#define GL_VIDEO_CAPTURE_TO_422_SUPPORTED_NV 0x9026 -#define GL_LAST_VIDEO_CAPTURE_STATUS_NV 0x9027 -#define GL_VIDEO_BUFFER_PITCH_NV 0x9028 -#define GL_VIDEO_COLOR_CONVERSION_MATRIX_NV 0x9029 -#define GL_VIDEO_COLOR_CONVERSION_MAX_NV 0x902A -#define GL_VIDEO_COLOR_CONVERSION_MIN_NV 0x902B -#define GL_VIDEO_COLOR_CONVERSION_OFFSET_NV 0x902C -#define GL_VIDEO_BUFFER_INTERNAL_FORMAT_NV 0x902D -#define GL_PARTIAL_SUCCESS_NV 0x902E -#define GL_SUCCESS_NV 0x902F -#define GL_FAILURE_NV 0x9030 -#define GL_YCBYCR8_422_NV 0x9031 -#define GL_YCBAYCR8A_4224_NV 0x9032 -#define GL_Z6Y10Z6CB10Z6Y10Z6CR10_422_NV 0x9033 -#define GL_Z6Y10Z6CB10Z6A10Z6Y10Z6CR10Z6A10_4224_NV 0x9034 -#define GL_Z4Y12Z4CB12Z4Y12Z4CR12_422_NV 0x9035 -#define GL_Z4Y12Z4CB12Z4A12Z4Y12Z4CR12Z4A12_4224_NV 0x9036 -#define GL_Z4Y12Z4CB12Z4CR12_444_NV 0x9037 -#define GL_VIDEO_CAPTURE_FRAME_WIDTH_NV 0x9038 -#define GL_VIDEO_CAPTURE_FRAME_HEIGHT_NV 0x9039 -#define GL_VIDEO_CAPTURE_FIELD_UPPER_HEIGHT_NV 0x903A -#define GL_VIDEO_CAPTURE_FIELD_LOWER_HEIGHT_NV 0x903B -#define GL_VIDEO_CAPTURE_SURFACE_ORIGIN_NV 0x903C -#endif - -#ifndef GL_NV_copy_image -#endif - -#ifndef GL_EXT_separate_shader_objects -#define GL_ACTIVE_PROGRAM_EXT 0x8B8D -#endif - -#ifndef GL_NV_parameter_buffer_object2 -#endif - -#ifndef GL_NV_shader_buffer_load -#define GL_BUFFER_GPU_ADDRESS_NV 0x8F1D -#define GL_GPU_ADDRESS_NV 0x8F34 -#define GL_MAX_SHADER_BUFFER_ADDRESS_NV 0x8F35 -#endif - -#ifndef GL_NV_vertex_buffer_unified_memory -#define GL_VERTEX_ATTRIB_ARRAY_UNIFIED_NV 0x8F1E -#define GL_ELEMENT_ARRAY_UNIFIED_NV 0x8F1F -#define GL_VERTEX_ATTRIB_ARRAY_ADDRESS_NV 0x8F20 -#define GL_VERTEX_ARRAY_ADDRESS_NV 0x8F21 -#define GL_NORMAL_ARRAY_ADDRESS_NV 0x8F22 -#define GL_COLOR_ARRAY_ADDRESS_NV 0x8F23 -#define GL_INDEX_ARRAY_ADDRESS_NV 0x8F24 -#define GL_TEXTURE_COORD_ARRAY_ADDRESS_NV 0x8F25 -#define GL_EDGE_FLAG_ARRAY_ADDRESS_NV 0x8F26 -#define GL_SECONDARY_COLOR_ARRAY_ADDRESS_NV 0x8F27 -#define GL_FOG_COORD_ARRAY_ADDRESS_NV 0x8F28 -#define GL_ELEMENT_ARRAY_ADDRESS_NV 0x8F29 -#define GL_VERTEX_ATTRIB_ARRAY_LENGTH_NV 0x8F2A -#define GL_VERTEX_ARRAY_LENGTH_NV 0x8F2B -#define GL_NORMAL_ARRAY_LENGTH_NV 0x8F2C -#define GL_COLOR_ARRAY_LENGTH_NV 0x8F2D -#define GL_INDEX_ARRAY_LENGTH_NV 0x8F2E -#define GL_TEXTURE_COORD_ARRAY_LENGTH_NV 0x8F2F -#define GL_EDGE_FLAG_ARRAY_LENGTH_NV 0x8F30 -#define GL_SECONDARY_COLOR_ARRAY_LENGTH_NV 0x8F31 -#define GL_FOG_COORD_ARRAY_LENGTH_NV 0x8F32 -#define GL_ELEMENT_ARRAY_LENGTH_NV 0x8F33 -#define GL_DRAW_INDIRECT_UNIFIED_NV 0x8F40 -#define GL_DRAW_INDIRECT_ADDRESS_NV 0x8F41 -#define GL_DRAW_INDIRECT_LENGTH_NV 0x8F42 -#endif - -#ifndef GL_NV_texture_barrier -#endif - -#ifndef GL_AMD_shader_stencil_export -#endif - -#ifndef GL_AMD_seamless_cubemap_per_texture -/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */ -#endif - -#ifndef GL_AMD_conservative_depth -#endif - -#ifndef GL_EXT_shader_image_load_store -#define GL_MAX_IMAGE_UNITS_EXT 0x8F38 -#define GL_MAX_COMBINED_IMAGE_UNITS_AND_FRAGMENT_OUTPUTS_EXT 0x8F39 -#define GL_IMAGE_BINDING_NAME_EXT 0x8F3A -#define GL_IMAGE_BINDING_LEVEL_EXT 0x8F3B -#define GL_IMAGE_BINDING_LAYERED_EXT 0x8F3C -#define GL_IMAGE_BINDING_LAYER_EXT 0x8F3D -#define GL_IMAGE_BINDING_ACCESS_EXT 0x8F3E -#define GL_IMAGE_1D_EXT 0x904C -#define GL_IMAGE_2D_EXT 0x904D -#define GL_IMAGE_3D_EXT 0x904E -#define GL_IMAGE_2D_RECT_EXT 0x904F -#define GL_IMAGE_CUBE_EXT 0x9050 -#define GL_IMAGE_BUFFER_EXT 0x9051 -#define GL_IMAGE_1D_ARRAY_EXT 0x9052 -#define GL_IMAGE_2D_ARRAY_EXT 0x9053 -#define GL_IMAGE_CUBE_MAP_ARRAY_EXT 0x9054 -#define GL_IMAGE_2D_MULTISAMPLE_EXT 0x9055 -#define GL_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9056 -#define GL_INT_IMAGE_1D_EXT 0x9057 -#define GL_INT_IMAGE_2D_EXT 0x9058 -#define GL_INT_IMAGE_3D_EXT 0x9059 -#define GL_INT_IMAGE_2D_RECT_EXT 0x905A -#define GL_INT_IMAGE_CUBE_EXT 0x905B -#define GL_INT_IMAGE_BUFFER_EXT 0x905C -#define GL_INT_IMAGE_1D_ARRAY_EXT 0x905D -#define GL_INT_IMAGE_2D_ARRAY_EXT 0x905E -#define GL_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x905F -#define GL_INT_IMAGE_2D_MULTISAMPLE_EXT 0x9060 -#define GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x9061 -#define GL_UNSIGNED_INT_IMAGE_1D_EXT 0x9062 -#define GL_UNSIGNED_INT_IMAGE_2D_EXT 0x9063 -#define GL_UNSIGNED_INT_IMAGE_3D_EXT 0x9064 -#define GL_UNSIGNED_INT_IMAGE_2D_RECT_EXT 0x9065 -#define GL_UNSIGNED_INT_IMAGE_CUBE_EXT 0x9066 -#define GL_UNSIGNED_INT_IMAGE_BUFFER_EXT 0x9067 -#define GL_UNSIGNED_INT_IMAGE_1D_ARRAY_EXT 0x9068 -#define GL_UNSIGNED_INT_IMAGE_2D_ARRAY_EXT 0x9069 -#define GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY_EXT 0x906A -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_EXT 0x906B -#define GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY_EXT 0x906C -#define GL_MAX_IMAGE_SAMPLES_EXT 0x906D -#define GL_IMAGE_BINDING_FORMAT_EXT 0x906E -#define GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT_EXT 0x00000001 -#define GL_ELEMENT_ARRAY_BARRIER_BIT_EXT 0x00000002 -#define GL_UNIFORM_BARRIER_BIT_EXT 0x00000004 -#define GL_TEXTURE_FETCH_BARRIER_BIT_EXT 0x00000008 -#define GL_SHADER_IMAGE_ACCESS_BARRIER_BIT_EXT 0x00000020 -#define GL_COMMAND_BARRIER_BIT_EXT 0x00000040 -#define GL_PIXEL_BUFFER_BARRIER_BIT_EXT 0x00000080 -#define GL_TEXTURE_UPDATE_BARRIER_BIT_EXT 0x00000100 -#define GL_BUFFER_UPDATE_BARRIER_BIT_EXT 0x00000200 -#define GL_FRAMEBUFFER_BARRIER_BIT_EXT 0x00000400 -#define GL_TRANSFORM_FEEDBACK_BARRIER_BIT_EXT 0x00000800 -#define GL_ATOMIC_COUNTER_BARRIER_BIT_EXT 0x00001000 -#define GL_ALL_BARRIER_BITS_EXT 0xFFFFFFFF -#endif - -#ifndef GL_EXT_vertex_attrib_64bit -/* reuse GL_DOUBLE */ -#define GL_DOUBLE_VEC2_EXT 0x8FFC -#define GL_DOUBLE_VEC3_EXT 0x8FFD -#define GL_DOUBLE_VEC4_EXT 0x8FFE -#define GL_DOUBLE_MAT2_EXT 0x8F46 -#define GL_DOUBLE_MAT3_EXT 0x8F47 -#define GL_DOUBLE_MAT4_EXT 0x8F48 -#define GL_DOUBLE_MAT2x3_EXT 0x8F49 -#define GL_DOUBLE_MAT2x4_EXT 0x8F4A -#define GL_DOUBLE_MAT3x2_EXT 0x8F4B -#define GL_DOUBLE_MAT3x4_EXT 0x8F4C -#define GL_DOUBLE_MAT4x2_EXT 0x8F4D -#define GL_DOUBLE_MAT4x3_EXT 0x8F4E -#endif - -#ifndef GL_NV_gpu_program5 -#define GL_MAX_GEOMETRY_PROGRAM_INVOCATIONS_NV 0x8E5A -#define GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5B -#define GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_NV 0x8E5C -#define GL_FRAGMENT_PROGRAM_INTERPOLATION_OFFSET_BITS_NV 0x8E5D -#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5E -#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET_NV 0x8E5F -#define GL_MAX_PROGRAM_SUBROUTINE_PARAMETERS_NV 0x8F44 -#define GL_MAX_PROGRAM_SUBROUTINE_NUM_NV 0x8F45 -#endif - -#ifndef GL_NV_gpu_shader5 -#define GL_INT64_NV 0x140E -#define GL_UNSIGNED_INT64_NV 0x140F -#define GL_INT8_NV 0x8FE0 -#define GL_INT8_VEC2_NV 0x8FE1 -#define GL_INT8_VEC3_NV 0x8FE2 -#define GL_INT8_VEC4_NV 0x8FE3 -#define GL_INT16_NV 0x8FE4 -#define GL_INT16_VEC2_NV 0x8FE5 -#define GL_INT16_VEC3_NV 0x8FE6 -#define GL_INT16_VEC4_NV 0x8FE7 -#define GL_INT64_VEC2_NV 0x8FE9 -#define GL_INT64_VEC3_NV 0x8FEA -#define GL_INT64_VEC4_NV 0x8FEB -#define GL_UNSIGNED_INT8_NV 0x8FEC -#define GL_UNSIGNED_INT8_VEC2_NV 0x8FED -#define GL_UNSIGNED_INT8_VEC3_NV 0x8FEE -#define GL_UNSIGNED_INT8_VEC4_NV 0x8FEF -#define GL_UNSIGNED_INT16_NV 0x8FF0 -#define GL_UNSIGNED_INT16_VEC2_NV 0x8FF1 -#define GL_UNSIGNED_INT16_VEC3_NV 0x8FF2 -#define GL_UNSIGNED_INT16_VEC4_NV 0x8FF3 -#define GL_UNSIGNED_INT64_VEC2_NV 0x8FF5 -#define GL_UNSIGNED_INT64_VEC3_NV 0x8FF6 -#define GL_UNSIGNED_INT64_VEC4_NV 0x8FF7 -#define GL_FLOAT16_NV 0x8FF8 -#define GL_FLOAT16_VEC2_NV 0x8FF9 -#define GL_FLOAT16_VEC3_NV 0x8FFA -#define GL_FLOAT16_VEC4_NV 0x8FFB -/* reuse GL_PATCHES */ -#endif - -#ifndef GL_NV_shader_buffer_store -#define GL_SHADER_GLOBAL_ACCESS_BARRIER_BIT_NV 0x00000010 -/* reuse GL_READ_WRITE */ -/* reuse GL_WRITE_ONLY */ -#endif - -#ifndef GL_NV_tessellation_program5 -#define GL_MAX_PROGRAM_PATCH_ATTRIBS_NV 0x86D8 -#define GL_TESS_CONTROL_PROGRAM_NV 0x891E -#define GL_TESS_EVALUATION_PROGRAM_NV 0x891F -#define GL_TESS_CONTROL_PROGRAM_PARAMETER_BUFFER_NV 0x8C74 -#define GL_TESS_EVALUATION_PROGRAM_PARAMETER_BUFFER_NV 0x8C75 -#endif - -#ifndef GL_NV_vertex_attrib_integer_64bit -/* reuse GL_INT64_NV */ -/* reuse GL_UNSIGNED_INT64_NV */ -#endif - -#ifndef GL_NV_multisample_coverage -#define GL_COVERAGE_SAMPLES_NV 0x80A9 -#define GL_COLOR_SAMPLES_NV 0x8E20 -#endif - -#ifndef GL_AMD_name_gen_delete -#define GL_DATA_BUFFER_AMD 0x9151 -#define GL_PERFORMANCE_MONITOR_AMD 0x9152 -#define GL_QUERY_OBJECT_AMD 0x9153 -#define GL_VERTEX_ARRAY_OBJECT_AMD 0x9154 -#define GL_SAMPLER_OBJECT_AMD 0x9155 -#endif - -#ifndef GL_AMD_debug_output -#define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 -#define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 -#define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 -#define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 -#define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 -#define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 -#define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A -#define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B -#define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C -#define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D -#define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E -#define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F -#define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 -#endif - -#ifndef GL_NV_vdpau_interop -#define GL_SURFACE_STATE_NV 0x86EB -#define GL_SURFACE_REGISTERED_NV 0x86FD -#define GL_SURFACE_MAPPED_NV 0x8700 -#define GL_WRITE_DISCARD_NV 0x88BE -#endif - -#ifndef GL_AMD_transform_feedback3_lines_triangles -#endif - -#ifndef GL_AMD_depth_clamp_separate -#define GL_DEPTH_CLAMP_NEAR_AMD 0x901E -#define GL_DEPTH_CLAMP_FAR_AMD 0x901F -#endif - -#ifndef GL_EXT_texture_sRGB_decode -#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 -#define GL_DECODE_EXT 0x8A49 -#define GL_SKIP_DECODE_EXT 0x8A4A -#endif - -#ifndef GL_NV_texture_multisample -#define GL_TEXTURE_COVERAGE_SAMPLES_NV 0x9045 -#define GL_TEXTURE_COLOR_SAMPLES_NV 0x9046 -#endif - -#ifndef GL_AMD_blend_minmax_factor -#define GL_FACTOR_MIN_AMD 0x901C -#define GL_FACTOR_MAX_AMD 0x901D -#endif - - -/*************************************************************/ - -#include -#ifndef GL_VERSION_2_0 -/* GL type for program/shader text */ -typedef char GLchar; -#endif - -#ifndef GL_VERSION_1_5 -/* GL types for handling large vertex buffer objects */ -typedef ptrdiff_t GLintptr; -typedef ptrdiff_t GLsizeiptr; -#endif - -#ifndef GL_ARB_vertex_buffer_object -/* GL types for handling large vertex buffer objects */ -typedef ptrdiff_t GLintptrARB; -typedef ptrdiff_t GLsizeiptrARB; -#endif - -#ifndef GL_ARB_shader_objects -/* GL types for program/shader text and shader object handles */ -typedef char GLcharARB; -typedef unsigned int GLhandleARB; -#endif - -/* GL type for "half" precision (s10e5) float data in host memory */ -#ifndef GL_ARB_half_float_pixel -typedef unsigned short GLhalfARB; -#endif - -#ifndef GL_NV_half_float -typedef unsigned short GLhalfNV; -#endif - -#ifndef GLEXT_64_TYPES_DEFINED -/* This code block is duplicated in glxext.h, so must be protected */ -#define GLEXT_64_TYPES_DEFINED -/* Define int32_t, int64_t, and uint64_t types for UST/MSC */ -/* (as used in the GL_EXT_timer_query extension). */ -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -#include -#elif defined(__sun__) || defined(__digital__) -#include -#if defined(__STDC__) -#if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; -#else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#endif /* __arch64__ */ -#endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) -#include -#elif defined(__SCO__) || defined(__USLC__) -#include -#elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; -#elif defined(_WIN32) && defined(__GNUC__) -#include -#elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; -#else -/* Fallback if nothing above works */ -#include -#endif -#endif - -#ifndef GL_EXT_timer_query -typedef int64_t GLint64EXT; -typedef uint64_t GLuint64EXT; -#endif - -#ifndef GL_ARB_sync -typedef int64_t GLint64; -typedef uint64_t GLuint64; -typedef struct __GLsync *GLsync; -#endif - -#ifndef GL_ARB_cl_event -/* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */ -struct _cl_context; -struct _cl_event; -#endif - -#ifndef GL_ARB_debug_output -typedef void (APIENTRY *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); -#endif - -#ifndef GL_AMD_debug_output -typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,GLvoid *userParam); -#endif - -#ifndef GL_NV_vdpau_interop -typedef GLintptr GLvdpauSurfaceNV; -#endif - -#ifndef GL_VERSION_1_2 -#define GL_VERSION_1_2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -GLAPI void APIENTRY glBlendEquation (GLenum mode); -GLAPI void APIENTRY glDrawRangeElements (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -GLAPI void APIENTRY glTexImage3D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glCopyTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -typedef void (APIENTRYP PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif - -#ifndef GL_VERSION_1_2_DEPRECATED -#define GL_VERSION_1_2_DEPRECATED 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTable (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -GLAPI void APIENTRY glColorTableParameterfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glColorTableParameteriv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyColorTable (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glGetColorTable (GLenum target, GLenum format, GLenum type, GLvoid *table); -GLAPI void APIENTRY glGetColorTableParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetColorTableParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glColorSubTable (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -GLAPI void APIENTRY glCopyColorSubTable (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glConvolutionFilter1D (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -GLAPI void APIENTRY glConvolutionFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -GLAPI void APIENTRY glConvolutionParameterf (GLenum target, GLenum pname, GLfloat params); -GLAPI void APIENTRY glConvolutionParameterfv (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glConvolutionParameteri (GLenum target, GLenum pname, GLint params); -GLAPI void APIENTRY glConvolutionParameteriv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyConvolutionFilter1D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyConvolutionFilter2D (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetConvolutionFilter (GLenum target, GLenum format, GLenum type, GLvoid *image); -GLAPI void APIENTRY glGetConvolutionParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetConvolutionParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSeparableFilter (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -GLAPI void APIENTRY glSeparableFilter2D (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -GLAPI void APIENTRY glGetHistogram (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -GLAPI void APIENTRY glGetHistogramParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetHistogramParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMinmax (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -GLAPI void APIENTRY glGetMinmaxParameterfv (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMinmaxParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glHistogram (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glMinmax (GLenum target, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glResetHistogram (GLenum target); -GLAPI void APIENTRY glResetMinmax (GLenum target); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXPROC) (GLenum target); -#endif - -#ifndef GL_VERSION_1_3 -#define GL_VERSION_1_3 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTexture (GLenum texture); -GLAPI void APIENTRY glSampleCoverage (GLclampf value, GLboolean invert); -GLAPI void APIENTRY glCompressedTexImage3D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexImage2D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexImage1D (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexSubImage3D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glGetCompressedTexImage (GLenum target, GLint level, GLvoid *img); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img); -#endif - -#ifndef GL_VERSION_1_3_DEPRECATED -#define GL_VERSION_1_3_DEPRECATED 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClientActiveTexture (GLenum texture); -GLAPI void APIENTRY glMultiTexCoord1d (GLenum target, GLdouble s); -GLAPI void APIENTRY glMultiTexCoord1dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord1f (GLenum target, GLfloat s); -GLAPI void APIENTRY glMultiTexCoord1fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord1i (GLenum target, GLint s); -GLAPI void APIENTRY glMultiTexCoord1iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord1s (GLenum target, GLshort s); -GLAPI void APIENTRY glMultiTexCoord1sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord2d (GLenum target, GLdouble s, GLdouble t); -GLAPI void APIENTRY glMultiTexCoord2dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord2f (GLenum target, GLfloat s, GLfloat t); -GLAPI void APIENTRY glMultiTexCoord2fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord2i (GLenum target, GLint s, GLint t); -GLAPI void APIENTRY glMultiTexCoord2iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord2s (GLenum target, GLshort s, GLshort t); -GLAPI void APIENTRY glMultiTexCoord2sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord3d (GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI void APIENTRY glMultiTexCoord3dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord3f (GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI void APIENTRY glMultiTexCoord3fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord3i (GLenum target, GLint s, GLint t, GLint r); -GLAPI void APIENTRY glMultiTexCoord3iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord3s (GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI void APIENTRY glMultiTexCoord3sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord4d (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void APIENTRY glMultiTexCoord4dv (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord4f (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void APIENTRY glMultiTexCoord4fv (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord4i (GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI void APIENTRY glMultiTexCoord4iv (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord4s (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void APIENTRY glMultiTexCoord4sv (GLenum target, const GLshort *v); -GLAPI void APIENTRY glLoadTransposeMatrixf (const GLfloat *m); -GLAPI void APIENTRY glLoadTransposeMatrixd (const GLdouble *m); -GLAPI void APIENTRY glMultTransposeMatrixf (const GLfloat *m); -GLAPI void APIENTRY glMultTransposeMatrixd (const GLdouble *m); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble *m); -#endif - -#ifndef GL_VERSION_1_4 -#define GL_VERSION_1_4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -GLAPI void APIENTRY glMultiDrawArrays (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -GLAPI void APIENTRY glMultiDrawElements (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -GLAPI void APIENTRY glPointParameterf (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfv (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glPointParameteri (GLenum pname, GLint param); -GLAPI void APIENTRY glPointParameteriv (GLenum pname, const GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); -#endif - -#ifndef GL_VERSION_1_4_DEPRECATED -#define GL_VERSION_1_4_DEPRECATED 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogCoordf (GLfloat coord); -GLAPI void APIENTRY glFogCoordfv (const GLfloat *coord); -GLAPI void APIENTRY glFogCoordd (GLdouble coord); -GLAPI void APIENTRY glFogCoorddv (const GLdouble *coord); -GLAPI void APIENTRY glFogCoordPointer (GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glSecondaryColor3b (GLbyte red, GLbyte green, GLbyte blue); -GLAPI void APIENTRY glSecondaryColor3bv (const GLbyte *v); -GLAPI void APIENTRY glSecondaryColor3d (GLdouble red, GLdouble green, GLdouble blue); -GLAPI void APIENTRY glSecondaryColor3dv (const GLdouble *v); -GLAPI void APIENTRY glSecondaryColor3f (GLfloat red, GLfloat green, GLfloat blue); -GLAPI void APIENTRY glSecondaryColor3fv (const GLfloat *v); -GLAPI void APIENTRY glSecondaryColor3i (GLint red, GLint green, GLint blue); -GLAPI void APIENTRY glSecondaryColor3iv (const GLint *v); -GLAPI void APIENTRY glSecondaryColor3s (GLshort red, GLshort green, GLshort blue); -GLAPI void APIENTRY glSecondaryColor3sv (const GLshort *v); -GLAPI void APIENTRY glSecondaryColor3ub (GLubyte red, GLubyte green, GLubyte blue); -GLAPI void APIENTRY glSecondaryColor3ubv (const GLubyte *v); -GLAPI void APIENTRY glSecondaryColor3ui (GLuint red, GLuint green, GLuint blue); -GLAPI void APIENTRY glSecondaryColor3uiv (const GLuint *v); -GLAPI void APIENTRY glSecondaryColor3us (GLushort red, GLushort green, GLushort blue); -GLAPI void APIENTRY glSecondaryColor3usv (const GLushort *v); -GLAPI void APIENTRY glSecondaryColorPointer (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glWindowPos2d (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dv (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2f (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fv (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2i (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2iv (const GLint *v); -GLAPI void APIENTRY glWindowPos2s (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2sv (const GLshort *v); -GLAPI void APIENTRY glWindowPos3d (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dv (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3f (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fv (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3i (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3iv (const GLint *v); -GLAPI void APIENTRY glWindowPos3s (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3sv (const GLshort *v); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFOGCOORDFPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVPROC) (const GLshort *v); -#endif - -#ifndef GL_VERSION_1_5 -#define GL_VERSION_1_5 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueries (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteQueries (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsQuery (GLuint id); -GLAPI void APIENTRY glBeginQuery (GLenum target, GLuint id); -GLAPI void APIENTRY glEndQuery (GLenum target); -GLAPI void APIENTRY glGetQueryiv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectiv (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectuiv (GLuint id, GLenum pname, GLuint *params); -GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer); -GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers); -GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers); -GLAPI GLboolean APIENTRY glIsBuffer (GLuint buffer); -GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); -GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); -GLAPI void APIENTRY glGetBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); -GLAPI GLvoid* APIENTRY glMapBuffer (GLenum target, GLenum access); -GLAPI GLboolean APIENTRY glUnmapBuffer (GLenum target); -GLAPI void APIENTRY glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENQUERIESPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); -typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, GLvoid* *params); -#endif - -#ifndef GL_VERSION_2_0 -#define GL_VERSION_2_0 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparate (GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glDrawBuffers (GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glStencilOpSeparate (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -GLAPI void APIENTRY glStencilFuncSeparate (GLenum face, GLenum func, GLint ref, GLuint mask); -GLAPI void APIENTRY glStencilMaskSeparate (GLenum face, GLuint mask); -GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader); -GLAPI void APIENTRY glBindAttribLocation (GLuint program, GLuint index, const GLchar *name); -GLAPI void APIENTRY glCompileShader (GLuint shader); -GLAPI GLuint APIENTRY glCreateProgram (void); -GLAPI GLuint APIENTRY glCreateShader (GLenum type); -GLAPI void APIENTRY glDeleteProgram (GLuint program); -GLAPI void APIENTRY glDeleteShader (GLuint shader); -GLAPI void APIENTRY glDetachShader (GLuint program, GLuint shader); -GLAPI void APIENTRY glDisableVertexAttribArray (GLuint index); -GLAPI void APIENTRY glEnableVertexAttribArray (GLuint index); -GLAPI void APIENTRY glGetActiveAttrib (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetAttachedShaders (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); -GLAPI GLint APIENTRY glGetAttribLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -GLAPI void APIENTRY glGetShaderSource (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetUniformfv (GLuint program, GLint location, GLfloat *params); -GLAPI void APIENTRY glGetUniformiv (GLuint program, GLint location, GLint *params); -GLAPI void APIENTRY glGetVertexAttribdv (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfv (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribiv (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointerv (GLuint index, GLenum pname, GLvoid* *pointer); -GLAPI GLboolean APIENTRY glIsProgram (GLuint program); -GLAPI GLboolean APIENTRY glIsShader (GLuint shader); -GLAPI void APIENTRY glLinkProgram (GLuint program); -GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); -GLAPI void APIENTRY glUseProgram (GLuint program); -GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0); -GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glUniform1i (GLint location, GLint v0); -GLAPI void APIENTRY glUniform2i (GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glUniform3i (GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glUniform4i (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glUniform1fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform2fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform1iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform2iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform3iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform4iv (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniformMatrix2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glValidateProgram (GLuint program); -GLAPI void APIENTRY glVertexAttrib1d (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1f (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1s (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2d (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2f (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2s (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3f (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3s (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4Nbv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4Niv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4Nsv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4Nub (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4Nubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4Nuiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4Nusv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttrib4bv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4f (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4s (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4usv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribPointer (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEPROC) (GLenum face, GLenum func, GLint ref, GLuint mask); -typedef void (APIENTRYP PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); -typedef void (APIENTRYP PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar *name); -typedef void (APIENTRYP PFNGLCOMPILESHADERPROC) (GLuint shader); -typedef GLuint (APIENTRYP PFNGLCREATEPROGRAMPROC) (void); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROC) (GLenum type); -typedef void (APIENTRYP PFNGLDELETEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLDELETESHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEPROC) (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPROC) (GLuint program); -typedef GLboolean (APIENTRYP PFNGLISSHADERPROC) (GLuint shader); -typedef void (APIENTRYP PFNGLLINKPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); -typedef void (APIENTRYP PFNGLUSEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPROC) (GLuint program); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_VERSION_2_1 -#define GL_VERSION_2_1 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformMatrix2x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix2x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4x2fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3x4fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4x3fv (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -#endif - -#ifndef GL_VERSION_3_0 -#define GL_VERSION_3_0 1 -/* OpenGL 3.0 also reuses entry points from these extensions: */ -/* ARB_framebuffer_object */ -/* ARB_map_buffer_range */ -/* ARB_vertex_array_object */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaski (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -GLAPI void APIENTRY glGetBooleani_v (GLenum target, GLuint index, GLboolean *data); -GLAPI void APIENTRY glGetIntegeri_v (GLenum target, GLuint index, GLint *data); -GLAPI void APIENTRY glEnablei (GLenum target, GLuint index); -GLAPI void APIENTRY glDisablei (GLenum target, GLuint index); -GLAPI GLboolean APIENTRY glIsEnabledi (GLenum target, GLuint index); -GLAPI void APIENTRY glBeginTransformFeedback (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedback (void); -GLAPI void APIENTRY glBindBufferRange (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferBase (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryings (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); -GLAPI void APIENTRY glGetTransformFeedbackVarying (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glClampColor (GLenum target, GLenum clamp); -GLAPI void APIENTRY glBeginConditionalRender (GLuint id, GLenum mode); -GLAPI void APIENTRY glEndConditionalRender (void); -GLAPI void APIENTRY glVertexAttribIPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glGetVertexAttribIiv (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint index, GLenum pname, GLuint *params); -GLAPI void APIENTRY glVertexAttribI1i (GLuint index, GLint x); -GLAPI void APIENTRY glVertexAttribI2i (GLuint index, GLint x, GLint y); -GLAPI void APIENTRY glVertexAttribI3i (GLuint index, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexAttribI4i (GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexAttribI1ui (GLuint index, GLuint x); -GLAPI void APIENTRY glVertexAttribI2ui (GLuint index, GLuint x, GLuint y); -GLAPI void APIENTRY glVertexAttribI3ui (GLuint index, GLuint x, GLuint y, GLuint z); -GLAPI void APIENTRY glVertexAttribI4ui (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glVertexAttribI1iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI2iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI3iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI4iv (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI1uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI2uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI3uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4uiv (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4bv (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttribI4sv (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttribI4ubv (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribI4usv (GLuint index, const GLushort *v); -GLAPI void APIENTRY glGetUniformuiv (GLuint program, GLint location, GLuint *params); -GLAPI void APIENTRY glBindFragDataLocation (GLuint program, GLuint color, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataLocation (GLuint program, const GLchar *name); -GLAPI void APIENTRY glUniform1ui (GLint location, GLuint v0); -GLAPI void APIENTRY glUniform2ui (GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glUniform3ui (GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glUniform4ui (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glUniform1uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform2uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform3uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform4uiv (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glTexParameterIiv (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTexParameterIuiv (GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTexParameterIiv (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTexParameterIuiv (GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glClearBufferiv (GLenum buffer, GLint drawbuffer, const GLint *value); -GLAPI void APIENTRY glClearBufferuiv (GLenum buffer, GLint drawbuffer, const GLuint *value); -GLAPI void APIENTRY glClearBufferfv (GLenum buffer, GLint drawbuffer, const GLfloat *value); -GLAPI void APIENTRY glClearBufferfi (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -GLAPI const GLubyte * APIENTRY glGetStringi (GLenum name, GLuint index); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORMASKIPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (APIENTRYP PFNGLGETBOOLEANI_VPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLENABLEIPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEIPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDIPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value); -typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); -#endif - -#ifndef GL_VERSION_3_1 -#define GL_VERSION_3_1 1 -/* OpenGL 3.1 also reuses entry points from these extensions: */ -/* ARB_copy_buffer */ -/* ARB_uniform_buffer_object */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -GLAPI void APIENTRY glDrawElementsInstanced (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -GLAPI void APIENTRY glTexBuffer (GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glPrimitiveRestartIndex (GLuint index); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index); -#endif - -#ifndef GL_VERSION_3_2 -#define GL_VERSION_3_2 1 -/* OpenGL 3.2 also reuses entry points from these extensions: */ -/* ARB_draw_elements_base_vertex */ -/* ARB_provoking_vertex */ -/* ARB_sync */ -/* ARB_texture_multisample */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetInteger64i_v (GLenum target, GLuint index, GLint64 *data); -GLAPI void APIENTRY glGetBufferParameteri64v (GLenum target, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glFramebufferTexture (GLenum target, GLenum attachment, GLuint texture, GLint level); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -#endif - -#ifndef GL_VERSION_3_3 -#define GL_VERSION_3_3 1 -/* OpenGL 3.3 also reuses entry points from these extensions: */ -/* ARB_blend_func_extended */ -/* ARB_sampler_objects */ -/* ARB_explicit_attrib_location, but it has none */ -/* ARB_occlusion_query2 (no entry points) */ -/* ARB_shader_bit_encoding (no entry points) */ -/* ARB_texture_rgb10_a2ui (no entry points) */ -/* ARB_texture_swizzle (no entry points) */ -/* ARB_timer_query */ -/* ARB_vertex_type_2_10_10_10_rev */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribDivisor (GLuint index, GLuint divisor); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); -#endif - -#ifndef GL_VERSION_4_0 -#define GL_VERSION_4_0 1 -/* OpenGL 4.0 also reuses entry points from these extensions: */ -/* ARB_texture_query_lod (no entry points) */ -/* ARB_draw_indirect */ -/* ARB_gpu_shader5 (no entry points) */ -/* ARB_gpu_shader_fp64 */ -/* ARB_shader_subroutine */ -/* ARB_tessellation_shader */ -/* ARB_texture_buffer_object_rgb32 (no entry points) */ -/* ARB_texture_cube_map_array (no entry points) */ -/* ARB_texture_gather (no entry points) */ -/* ARB_transform_feedback2 */ -/* ARB_transform_feedback3 */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMinSampleShading (GLclampf value); -GLAPI void APIENTRY glBlendEquationi (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparatei (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glBlendFunci (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparatei (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLclampf value); -typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -#endif - -#ifndef GL_VERSION_4_1 -#define GL_VERSION_4_1 1 -/* OpenGL 4.1 also reuses entry points from these extensions: */ -/* ARB_ES2_compatibility */ -/* ARB_get_program_binary */ -/* ARB_separate_shader_objects */ -/* ARB_shader_precision (no entry points) */ -/* ARB_vertex_attrib_64bit */ -/* ARB_viewport_array */ -#endif - -#ifndef GL_ARB_multitexture -#define GL_ARB_multitexture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveTextureARB (GLenum texture); -GLAPI void APIENTRY glClientActiveTextureARB (GLenum texture); -GLAPI void APIENTRY glMultiTexCoord1dARB (GLenum target, GLdouble s); -GLAPI void APIENTRY glMultiTexCoord1dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord1fARB (GLenum target, GLfloat s); -GLAPI void APIENTRY glMultiTexCoord1fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord1iARB (GLenum target, GLint s); -GLAPI void APIENTRY glMultiTexCoord1ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord1sARB (GLenum target, GLshort s); -GLAPI void APIENTRY glMultiTexCoord1svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord2dARB (GLenum target, GLdouble s, GLdouble t); -GLAPI void APIENTRY glMultiTexCoord2dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord2fARB (GLenum target, GLfloat s, GLfloat t); -GLAPI void APIENTRY glMultiTexCoord2fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord2iARB (GLenum target, GLint s, GLint t); -GLAPI void APIENTRY glMultiTexCoord2ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord2sARB (GLenum target, GLshort s, GLshort t); -GLAPI void APIENTRY glMultiTexCoord2svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord3dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r); -GLAPI void APIENTRY glMultiTexCoord3dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord3fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r); -GLAPI void APIENTRY glMultiTexCoord3fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord3iARB (GLenum target, GLint s, GLint t, GLint r); -GLAPI void APIENTRY glMultiTexCoord3ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord3sARB (GLenum target, GLshort s, GLshort t, GLshort r); -GLAPI void APIENTRY glMultiTexCoord3svARB (GLenum target, const GLshort *v); -GLAPI void APIENTRY glMultiTexCoord4dARB (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -GLAPI void APIENTRY glMultiTexCoord4dvARB (GLenum target, const GLdouble *v); -GLAPI void APIENTRY glMultiTexCoord4fARB (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -GLAPI void APIENTRY glMultiTexCoord4fvARB (GLenum target, const GLfloat *v); -GLAPI void APIENTRY glMultiTexCoord4iARB (GLenum target, GLint s, GLint t, GLint r, GLint q); -GLAPI void APIENTRY glMultiTexCoord4ivARB (GLenum target, const GLint *v); -GLAPI void APIENTRY glMultiTexCoord4sARB (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -GLAPI void APIENTRY glMultiTexCoord4svARB (GLenum target, const GLshort *v); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLCLIENTACTIVETEXTUREARBPROC) (GLenum texture); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DARBPROC) (GLenum target, GLdouble s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FARBPROC) (GLenum target, GLfloat s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IARBPROC) (GLenum target, GLint s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SARBPROC) (GLenum target, GLshort s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DARBPROC) (GLenum target, GLdouble s, GLdouble t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IARBPROC) (GLenum target, GLint s, GLint t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SARBPROC) (GLenum target, GLshort s, GLshort t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IARBPROC) (GLenum target, GLint s, GLint t, GLint r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3SVARBPROC) (GLenum target, const GLshort *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DARBPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4DVARBPROC) (GLenum target, const GLdouble *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FARBPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4FVARBPROC) (GLenum target, const GLfloat *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IARBPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4IVARBPROC) (GLenum target, const GLint *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SARBPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4SVARBPROC) (GLenum target, const GLshort *v); -#endif - -#ifndef GL_ARB_transpose_matrix -#define GL_ARB_transpose_matrix 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLoadTransposeMatrixfARB (const GLfloat *m); -GLAPI void APIENTRY glLoadTransposeMatrixdARB (const GLdouble *m); -GLAPI void APIENTRY glMultTransposeMatrixfARB (const GLfloat *m); -GLAPI void APIENTRY glMultTransposeMatrixdARB (const GLdouble *m); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLLOADTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXFARBPROC) (const GLfloat *m); -typedef void (APIENTRYP PFNGLMULTTRANSPOSEMATRIXDARBPROC) (const GLdouble *m); -#endif - -#ifndef GL_ARB_multisample -#define GL_ARB_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleCoverageARB (GLclampf value, GLboolean invert); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLECOVERAGEARBPROC) (GLclampf value, GLboolean invert); -#endif - -#ifndef GL_ARB_texture_env_add -#define GL_ARB_texture_env_add 1 -#endif - -#ifndef GL_ARB_texture_cube_map -#define GL_ARB_texture_cube_map 1 -#endif - -#ifndef GL_ARB_texture_compression -#define GL_ARB_texture_compression 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCompressedTexImage3DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexImage2DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexImage1DARB (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexSubImage3DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexSubImage2DARB (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glCompressedTexSubImage1DARB (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -GLAPI void APIENTRY glGetCompressedTexImageARB (GLenum target, GLint level, GLvoid *img); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DARBPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint level, GLvoid *img); -#endif - -#ifndef GL_ARB_texture_border_clamp -#define GL_ARB_texture_border_clamp 1 -#endif - -#ifndef GL_ARB_point_parameters -#define GL_ARB_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfARB (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvARB (GLenum pname, const GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFARBPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVARBPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_ARB_vertex_blend -#define GL_ARB_vertex_blend 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWeightbvARB (GLint size, const GLbyte *weights); -GLAPI void APIENTRY glWeightsvARB (GLint size, const GLshort *weights); -GLAPI void APIENTRY glWeightivARB (GLint size, const GLint *weights); -GLAPI void APIENTRY glWeightfvARB (GLint size, const GLfloat *weights); -GLAPI void APIENTRY glWeightdvARB (GLint size, const GLdouble *weights); -GLAPI void APIENTRY glWeightubvARB (GLint size, const GLubyte *weights); -GLAPI void APIENTRY glWeightusvARB (GLint size, const GLushort *weights); -GLAPI void APIENTRY glWeightuivARB (GLint size, const GLuint *weights); -GLAPI void APIENTRY glWeightPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glVertexBlendARB (GLint count); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWEIGHTBVARBPROC) (GLint size, const GLbyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTSVARBPROC) (GLint size, const GLshort *weights); -typedef void (APIENTRYP PFNGLWEIGHTIVARBPROC) (GLint size, const GLint *weights); -typedef void (APIENTRYP PFNGLWEIGHTFVARBPROC) (GLint size, const GLfloat *weights); -typedef void (APIENTRYP PFNGLWEIGHTDVARBPROC) (GLint size, const GLdouble *weights); -typedef void (APIENTRYP PFNGLWEIGHTUBVARBPROC) (GLint size, const GLubyte *weights); -typedef void (APIENTRYP PFNGLWEIGHTUSVARBPROC) (GLint size, const GLushort *weights); -typedef void (APIENTRYP PFNGLWEIGHTUIVARBPROC) (GLint size, const GLuint *weights); -typedef void (APIENTRYP PFNGLWEIGHTPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXBLENDARBPROC) (GLint count); -#endif - -#ifndef GL_ARB_matrix_palette -#define GL_ARB_matrix_palette 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCurrentPaletteMatrixARB (GLint index); -GLAPI void APIENTRY glMatrixIndexubvARB (GLint size, const GLubyte *indices); -GLAPI void APIENTRY glMatrixIndexusvARB (GLint size, const GLushort *indices); -GLAPI void APIENTRY glMatrixIndexuivARB (GLint size, const GLuint *indices); -GLAPI void APIENTRY glMatrixIndexPointerARB (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCURRENTPALETTEMATRIXARBPROC) (GLint index); -typedef void (APIENTRYP PFNGLMATRIXINDEXUBVARBPROC) (GLint size, const GLubyte *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUSVARBPROC) (GLint size, const GLushort *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXUIVARBPROC) (GLint size, const GLuint *indices); -typedef void (APIENTRYP PFNGLMATRIXINDEXPOINTERARBPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_ARB_texture_env_combine -#define GL_ARB_texture_env_combine 1 -#endif - -#ifndef GL_ARB_texture_env_crossbar -#define GL_ARB_texture_env_crossbar 1 -#endif - -#ifndef GL_ARB_texture_env_dot3 -#define GL_ARB_texture_env_dot3 1 -#endif - -#ifndef GL_ARB_texture_mirrored_repeat -#define GL_ARB_texture_mirrored_repeat 1 -#endif - -#ifndef GL_ARB_depth_texture -#define GL_ARB_depth_texture 1 -#endif - -#ifndef GL_ARB_shadow -#define GL_ARB_shadow 1 -#endif - -#ifndef GL_ARB_shadow_ambient -#define GL_ARB_shadow_ambient 1 -#endif - -#ifndef GL_ARB_window_pos -#define GL_ARB_window_pos 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dARB (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dvARB (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2fARB (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fvARB (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2iARB (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2ivARB (const GLint *v); -GLAPI void APIENTRY glWindowPos2sARB (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2svARB (const GLshort *v); -GLAPI void APIENTRY glWindowPos3dARB (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dvARB (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3fARB (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fvARB (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3iARB (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3ivARB (const GLint *v); -GLAPI void APIENTRY glWindowPos3sARB (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3svARB (const GLshort *v); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWINDOWPOS2DARBPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FARBPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IARBPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SARBPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVARBPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DARBPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVARBPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FARBPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVARBPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IARBPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVARBPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SARBPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVARBPROC) (const GLshort *v); -#endif - -#ifndef GL_ARB_vertex_program -#define GL_ARB_vertex_program 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttrib1dARB (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1fARB (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1sARB (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2dARB (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2fARB (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2sARB (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3sARB (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4NbvARB (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4NivARB (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4NsvARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4NubARB (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4NubvARB (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4NuivARB (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4NusvARB (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttrib4bvARB (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttrib4dARB (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dvARB (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4fARB (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fvARB (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4ivARB (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttrib4sARB (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4svARB (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubvARB (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttrib4uivARB (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttrib4usvARB (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribPointerARB (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glEnableVertexAttribArrayARB (GLuint index); -GLAPI void APIENTRY glDisableVertexAttribArrayARB (GLuint index); -GLAPI void APIENTRY glProgramStringARB (GLenum target, GLenum format, GLsizei len, const GLvoid *string); -GLAPI void APIENTRY glBindProgramARB (GLenum target, GLuint program); -GLAPI void APIENTRY glDeleteProgramsARB (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glGenProgramsARB (GLsizei n, GLuint *programs); -GLAPI void APIENTRY glProgramEnvParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramEnvParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glProgramEnvParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramEnvParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glProgramLocalParameter4dARB (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramLocalParameter4dvARB (GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glProgramLocalParameter4fARB (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramLocalParameter4fvARB (GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glGetProgramEnvParameterdvARB (GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetProgramEnvParameterfvARB (GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetProgramLocalParameterdvARB (GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetProgramLocalParameterfvARB (GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetProgramivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramStringARB (GLenum target, GLenum pname, GLvoid *string); -GLAPI void APIENTRY glGetVertexAttribdvARB (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfvARB (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribivARB (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointervARB (GLuint index, GLenum pname, GLvoid* *pointer); -GLAPI GLboolean APIENTRY glIsProgramARB (GLuint program); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DARBPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FARBPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SARBPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DARBPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FARBPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SARBPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NBVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NIVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NSVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBARBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4NUSVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4BVARBPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DARBPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVARBPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FARBPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVARBPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4IVARBPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SARBPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVARBPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVARBPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UIVARBPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4USVARBPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERARBPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBARRAYARBPROC) (GLuint index); -typedef void (APIENTRYP PFNGLPROGRAMSTRINGARBPROC) (GLenum target, GLenum format, GLsizei len, const GLvoid *string); -typedef void (APIENTRYP PFNGLBINDPROGRAMARBPROC) (GLenum target, GLuint program); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSARBPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLGENPROGRAMSARBPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DARBPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4DVARBPROC) (GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FARBPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETER4FVARBPROC) (GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC) (GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC) (GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGARBPROC) (GLenum target, GLenum pname, GLvoid *string); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVARBPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVARBPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVARBPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVARBPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMARBPROC) (GLuint program); -#endif - -#ifndef GL_ARB_fragment_program -#define GL_ARB_fragment_program 1 -/* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ -#endif - -#ifndef GL_ARB_vertex_buffer_object -#define GL_ARB_vertex_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindBufferARB (GLenum target, GLuint buffer); -GLAPI void APIENTRY glDeleteBuffersARB (GLsizei n, const GLuint *buffers); -GLAPI void APIENTRY glGenBuffersARB (GLsizei n, GLuint *buffers); -GLAPI GLboolean APIENTRY glIsBufferARB (GLuint buffer); -GLAPI void APIENTRY glBufferDataARB (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); -GLAPI void APIENTRY glBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); -GLAPI void APIENTRY glGetBufferSubDataARB (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); -GLAPI GLvoid* APIENTRY glMapBufferARB (GLenum target, GLenum access); -GLAPI GLboolean APIENTRY glUnmapBufferARB (GLenum target); -GLAPI void APIENTRY glGetBufferParameterivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetBufferPointervARB (GLenum target, GLenum pname, GLvoid* *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDBUFFERARBPROC) (GLenum target, GLuint buffer); -typedef void (APIENTRYP PFNGLDELETEBUFFERSARBPROC) (GLsizei n, const GLuint *buffers); -typedef void (APIENTRYP PFNGLGENBUFFERSARBPROC) (GLsizei n, GLuint *buffers); -typedef GLboolean (APIENTRYP PFNGLISBUFFERARBPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLBUFFERDATAARBPROC) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); -typedef void (APIENTRYP PFNGLBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); -typedef void (APIENTRYP PFNGLGETBUFFERSUBDATAARBPROC) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); -typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERARBPROC) (GLenum target, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPBUFFERARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETBUFFERPOINTERVARBPROC) (GLenum target, GLenum pname, GLvoid* *params); -#endif - -#ifndef GL_ARB_occlusion_query -#define GL_ARB_occlusion_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenQueriesARB (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteQueriesARB (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsQueryARB (GLuint id); -GLAPI void APIENTRY glBeginQueryARB (GLenum target, GLuint id); -GLAPI void APIENTRY glEndQueryARB (GLenum target); -GLAPI void APIENTRY glGetQueryivARB (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectivARB (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetQueryObjectuivARB (GLuint id, GLenum pname, GLuint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENQUERIESARBPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEQUERIESARBPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISQUERYARBPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINQUERYARBPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYARBPROC) (GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYIVARBPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTIVARBPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUIVARBPROC) (GLuint id, GLenum pname, GLuint *params); -#endif - -#ifndef GL_ARB_shader_objects -#define GL_ARB_shader_objects 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteObjectARB (GLhandleARB obj); -GLAPI GLhandleARB APIENTRY glGetHandleARB (GLenum pname); -GLAPI void APIENTRY glDetachObjectARB (GLhandleARB containerObj, GLhandleARB attachedObj); -GLAPI GLhandleARB APIENTRY glCreateShaderObjectARB (GLenum shaderType); -GLAPI void APIENTRY glShaderSourceARB (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); -GLAPI void APIENTRY glCompileShaderARB (GLhandleARB shaderObj); -GLAPI GLhandleARB APIENTRY glCreateProgramObjectARB (void); -GLAPI void APIENTRY glAttachObjectARB (GLhandleARB containerObj, GLhandleARB obj); -GLAPI void APIENTRY glLinkProgramARB (GLhandleARB programObj); -GLAPI void APIENTRY glUseProgramObjectARB (GLhandleARB programObj); -GLAPI void APIENTRY glValidateProgramARB (GLhandleARB programObj); -GLAPI void APIENTRY glUniform1fARB (GLint location, GLfloat v0); -GLAPI void APIENTRY glUniform2fARB (GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glUniform3fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glUniform4fARB (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glUniform1iARB (GLint location, GLint v0); -GLAPI void APIENTRY glUniform2iARB (GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glUniform3iARB (GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glUniform4iARB (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glUniform1fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform2fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform3fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform4fvARB (GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glUniform1ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform2ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform3ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniform4ivARB (GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glUniformMatrix2fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix3fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glUniformMatrix4fvARB (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glGetObjectParameterfvARB (GLhandleARB obj, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetObjectParameterivARB (GLhandleARB obj, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetInfoLogARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); -GLAPI void APIENTRY glGetAttachedObjectsARB (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); -GLAPI GLint APIENTRY glGetUniformLocationARB (GLhandleARB programObj, const GLcharARB *name); -GLAPI void APIENTRY glGetActiveUniformARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -GLAPI void APIENTRY glGetUniformfvARB (GLhandleARB programObj, GLint location, GLfloat *params); -GLAPI void APIENTRY glGetUniformivARB (GLhandleARB programObj, GLint location, GLint *params); -GLAPI void APIENTRY glGetShaderSourceARB (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDELETEOBJECTARBPROC) (GLhandleARB obj); -typedef GLhandleARB (APIENTRYP PFNGLGETHANDLEARBPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLDETACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB attachedObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATESHADEROBJECTARBPROC) (GLenum shaderType); -typedef void (APIENTRYP PFNGLSHADERSOURCEARBPROC) (GLhandleARB shaderObj, GLsizei count, const GLcharARB* *string, const GLint *length); -typedef void (APIENTRYP PFNGLCOMPILESHADERARBPROC) (GLhandleARB shaderObj); -typedef GLhandleARB (APIENTRYP PFNGLCREATEPROGRAMOBJECTARBPROC) (void); -typedef void (APIENTRYP PFNGLATTACHOBJECTARBPROC) (GLhandleARB containerObj, GLhandleARB obj); -typedef void (APIENTRYP PFNGLLINKPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUSEPROGRAMOBJECTARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMARBPROC) (GLhandleARB programObj); -typedef void (APIENTRYP PFNGLUNIFORM1FARBPROC) (GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLUNIFORM2FARBPROC) (GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLUNIFORM3FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLUNIFORM4FARBPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLUNIFORM1IARBPROC) (GLint location, GLint v0); -typedef void (APIENTRYP PFNGLUNIFORM2IARBPROC) (GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLUNIFORM3IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLUNIFORM4IARBPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLUNIFORM1FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM2FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM3FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM4FVARBPROC) (GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORM1IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM2IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM3IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORM4IVARBPROC) (GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4FVARBPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERFVARBPROC) (GLhandleARB obj, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVARBPROC) (GLhandleARB obj, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETINFOLOGARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *infoLog); -typedef void (APIENTRYP PFNGLGETATTACHEDOBJECTSARBPROC) (GLhandleARB containerObj, GLsizei maxCount, GLsizei *count, GLhandleARB *obj); -typedef GLint (APIENTRYP PFNGLGETUNIFORMLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef void (APIENTRYP PFNGLGETUNIFORMFVARBPROC) (GLhandleARB programObj, GLint location, GLfloat *params); -typedef void (APIENTRYP PFNGLGETUNIFORMIVARBPROC) (GLhandleARB programObj, GLint location, GLint *params); -typedef void (APIENTRYP PFNGLGETSHADERSOURCEARBPROC) (GLhandleARB obj, GLsizei maxLength, GLsizei *length, GLcharARB *source); -#endif - -#ifndef GL_ARB_vertex_shader -#define GL_ARB_vertex_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindAttribLocationARB (GLhandleARB programObj, GLuint index, const GLcharARB *name); -GLAPI void APIENTRY glGetActiveAttribARB (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -GLAPI GLint APIENTRY glGetAttribLocationARB (GLhandleARB programObj, const GLcharARB *name); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDATTRIBLOCATIONARBPROC) (GLhandleARB programObj, GLuint index, const GLcharARB *name); -typedef void (APIENTRYP PFNGLGETACTIVEATTRIBARBPROC) (GLhandleARB programObj, GLuint index, GLsizei maxLength, GLsizei *length, GLint *size, GLenum *type, GLcharARB *name); -typedef GLint (APIENTRYP PFNGLGETATTRIBLOCATIONARBPROC) (GLhandleARB programObj, const GLcharARB *name); -#endif - -#ifndef GL_ARB_fragment_shader -#define GL_ARB_fragment_shader 1 -#endif - -#ifndef GL_ARB_shading_language_100 -#define GL_ARB_shading_language_100 1 -#endif - -#ifndef GL_ARB_texture_non_power_of_two -#define GL_ARB_texture_non_power_of_two 1 -#endif - -#ifndef GL_ARB_point_sprite -#define GL_ARB_point_sprite 1 -#endif - -#ifndef GL_ARB_fragment_program_shadow -#define GL_ARB_fragment_program_shadow 1 -#endif - -#ifndef GL_ARB_draw_buffers -#define GL_ARB_draw_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersARB (GLsizei n, const GLenum *bufs); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWBUFFERSARBPROC) (GLsizei n, const GLenum *bufs); -#endif - -#ifndef GL_ARB_texture_rectangle -#define GL_ARB_texture_rectangle 1 -#endif - -#ifndef GL_ARB_color_buffer_float -#define GL_ARB_color_buffer_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClampColorARB (GLenum target, GLenum clamp); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCLAMPCOLORARBPROC) (GLenum target, GLenum clamp); -#endif - -#ifndef GL_ARB_half_float_pixel -#define GL_ARB_half_float_pixel 1 -#endif - -#ifndef GL_ARB_texture_float -#define GL_ARB_texture_float 1 -#endif - -#ifndef GL_ARB_pixel_buffer_object -#define GL_ARB_pixel_buffer_object 1 -#endif - -#ifndef GL_ARB_depth_buffer_float -#define GL_ARB_depth_buffer_float 1 -#endif - -#ifndef GL_ARB_draw_instanced -#define GL_ARB_draw_instanced 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -GLAPI void APIENTRY glDrawElementsInstancedARB (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDARBPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDARBPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -#endif - -#ifndef GL_ARB_framebuffer_object -#define GL_ARB_framebuffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glIsRenderbuffer (GLuint renderbuffer); -GLAPI void APIENTRY glBindRenderbuffer (GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glDeleteRenderbuffers (GLsizei n, const GLuint *renderbuffers); -GLAPI void APIENTRY glGenRenderbuffers (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glRenderbufferStorage (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetRenderbufferParameteriv (GLenum target, GLenum pname, GLint *params); -GLAPI GLboolean APIENTRY glIsFramebuffer (GLuint framebuffer); -GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer); -GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers); -GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers); -GLAPI GLenum APIENTRY glCheckFramebufferStatus (GLenum target); -GLAPI void APIENTRY glFramebufferTexture1D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture3D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glFramebufferRenderbuffer (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetFramebufferAttachmentParameteriv (GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateMipmap (GLenum target); -GLAPI void APIENTRY glBlitFramebuffer (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -GLAPI void APIENTRY glRenderbufferStorageMultisample (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glFramebufferTextureLayer (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPPROC) (GLenum target); -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -#endif - -#ifndef GL_ARB_framebuffer_sRGB -#define GL_ARB_framebuffer_sRGB 1 -#endif - -#ifndef GL_ARB_geometry_shader4 -#define GL_ARB_geometry_shader4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriARB (GLuint program, GLenum pname, GLint value); -GLAPI void APIENTRY glFramebufferTextureARB (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTextureLayerARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glFramebufferTextureFaceARB (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIARBPROC) (GLuint program, GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYERARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEARBPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif - -#ifndef GL_ARB_half_float_vertex -#define GL_ARB_half_float_vertex 1 -#endif - -#ifndef GL_ARB_instanced_arrays -#define GL_ARB_instanced_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribDivisorARB (GLuint index, GLuint divisor); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBDIVISORARBPROC) (GLuint index, GLuint divisor); -#endif - -#ifndef GL_ARB_map_buffer_range -#define GL_ARB_map_buffer_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLvoid* APIENTRY glMapBufferRange (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI void APIENTRY glFlushMappedBufferRange (GLenum target, GLintptr offset, GLsizeiptr length); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLvoid* (APIENTRYP PFNGLMAPBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEPROC) (GLenum target, GLintptr offset, GLsizeiptr length); -#endif - -#ifndef GL_ARB_texture_buffer_object -#define GL_ARB_texture_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferARB (GLenum target, GLenum internalformat, GLuint buffer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXBUFFERARBPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#endif - -#ifndef GL_ARB_texture_compression_rgtc -#define GL_ARB_texture_compression_rgtc 1 -#endif - -#ifndef GL_ARB_texture_rg -#define GL_ARB_texture_rg 1 -#endif - -#ifndef GL_ARB_vertex_array_object -#define GL_ARB_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindVertexArray (GLuint array); -GLAPI void APIENTRY glDeleteVertexArrays (GLsizei n, const GLuint *arrays); -GLAPI void APIENTRY glGenVertexArrays (GLsizei n, GLuint *arrays); -GLAPI GLboolean APIENTRY glIsVertexArray (GLuint array); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYPROC) (GLuint array); -#endif - -#ifndef GL_ARB_uniform_buffer_object -#define GL_ARB_uniform_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetUniformIndices (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices); -GLAPI void APIENTRY glGetActiveUniformsiv (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetActiveUniformName (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); -GLAPI GLuint APIENTRY glGetUniformBlockIndex (GLuint program, const GLchar *uniformBlockName); -GLAPI void APIENTRY glGetActiveUniformBlockiv (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetActiveUniformBlockName (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -GLAPI void APIENTRY glUniformBlockBinding (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETUNIFORMINDICESPROC) (GLuint program, GLsizei uniformCount, const GLchar* *uniformNames, GLuint *uniformIndices); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMSIVPROC) (GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMNAMEPROC) (GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); -typedef GLuint (APIENTRYP PFNGLGETUNIFORMBLOCKINDEXPROC) (GLuint program, const GLchar *uniformBlockName); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKIVPROC) (GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) (GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); -typedef void (APIENTRYP PFNGLUNIFORMBLOCKBINDINGPROC) (GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -#endif - -#ifndef GL_ARB_compatibility -#define GL_ARB_compatibility 1 -#endif - -#ifndef GL_ARB_copy_buffer -#define GL_ARB_copy_buffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyBufferSubData (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -#endif - -#ifndef GL_ARB_shader_texture_lod -#define GL_ARB_shader_texture_lod 1 -#endif - -#ifndef GL_ARB_depth_clamp -#define GL_ARB_depth_clamp 1 -#endif - -#ifndef GL_ARB_draw_elements_base_vertex -#define GL_ARB_draw_elements_base_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); -GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); -GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex); -GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex); -#endif - -#ifndef GL_ARB_fragment_coord_conventions -#define GL_ARB_fragment_coord_conventions 1 -#endif - -#ifndef GL_ARB_provoking_vertex -#define GL_ARB_provoking_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProvokingVertex (GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode); -#endif - -#ifndef GL_ARB_seamless_cube_map -#define GL_ARB_seamless_cube_map 1 -#endif - -#ifndef GL_ARB_sync -#define GL_ARB_sync 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLsync APIENTRY glFenceSync (GLenum condition, GLbitfield flags); -GLAPI GLboolean APIENTRY glIsSync (GLsync sync); -GLAPI void APIENTRY glDeleteSync (GLsync sync); -GLAPI GLenum APIENTRY glClientWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI void APIENTRY glWaitSync (GLsync sync, GLbitfield flags, GLuint64 timeout); -GLAPI void APIENTRY glGetInteger64v (GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetSynciv (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags); -typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync); -typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync); -typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -#endif - -#ifndef GL_ARB_texture_multisample -#define GL_ARB_texture_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage2DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glTexImage3DMultisample (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -GLAPI void APIENTRY glGetMultisamplefv (GLenum pname, GLuint index, GLfloat *val); -GLAPI void APIENTRY glSampleMaski (GLuint index, GLbitfield mask); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val); -typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); -#endif - -#ifndef GL_ARB_vertex_array_bgra -#define GL_ARB_vertex_array_bgra 1 -#endif - -#ifndef GL_ARB_draw_buffers_blend -#define GL_ARB_draw_buffers_blend 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationiARB (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparateiARB (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -GLAPI void APIENTRY glBlendFunciARB (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparateiARB (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONIARBPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIARBPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (APIENTRYP PFNGLBLENDFUNCIARBPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIARBPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -#endif - -#ifndef GL_ARB_sample_shading -#define GL_ARB_sample_shading 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMinSampleShadingARB (GLclampf value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMINSAMPLESHADINGARBPROC) (GLclampf value); -#endif - -#ifndef GL_ARB_texture_cube_map_array -#define GL_ARB_texture_cube_map_array 1 -#endif - -#ifndef GL_ARB_texture_gather -#define GL_ARB_texture_gather 1 -#endif - -#ifndef GL_ARB_texture_query_lod -#define GL_ARB_texture_query_lod 1 -#endif - -#ifndef GL_ARB_shading_language_include -#define GL_ARB_shading_language_include 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glNamedStringARB (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); -GLAPI void APIENTRY glDeleteNamedStringARB (GLint namelen, const GLchar *name); -GLAPI void APIENTRY glCompileShaderIncludeARB (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length); -GLAPI GLboolean APIENTRY glIsNamedStringARB (GLint namelen, const GLchar *name); -GLAPI void APIENTRY glGetNamedStringARB (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); -GLAPI void APIENTRY glGetNamedStringivARB (GLint namelen, const GLchar *name, GLenum pname, GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLNAMEDSTRINGARBPROC) (GLenum type, GLint namelen, const GLchar *name, GLint stringlen, const GLchar *string); -typedef void (APIENTRYP PFNGLDELETENAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); -typedef void (APIENTRYP PFNGLCOMPILESHADERINCLUDEARBPROC) (GLuint shader, GLsizei count, const GLchar* *path, const GLint *length); -typedef GLboolean (APIENTRYP PFNGLISNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name); -typedef void (APIENTRYP PFNGLGETNAMEDSTRINGARBPROC) (GLint namelen, const GLchar *name, GLsizei bufSize, GLint *stringlen, GLchar *string); -typedef void (APIENTRYP PFNGLGETNAMEDSTRINGIVARBPROC) (GLint namelen, const GLchar *name, GLenum pname, GLint *params); -#endif - -#ifndef GL_ARB_texture_compression_bptc -#define GL_ARB_texture_compression_bptc 1 -#endif - -#ifndef GL_ARB_blend_func_extended -#define GL_ARB_blend_func_extended 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindFragDataLocationIndexed (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataIndex (GLuint program, const GLchar *name); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) (GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATAINDEXPROC) (GLuint program, const GLchar *name); -#endif - -#ifndef GL_ARB_explicit_attrib_location -#define GL_ARB_explicit_attrib_location 1 -#endif - -#ifndef GL_ARB_occlusion_query2 -#define GL_ARB_occlusion_query2 1 -#endif - -#ifndef GL_ARB_sampler_objects -#define GL_ARB_sampler_objects 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenSamplers (GLsizei count, GLuint *samplers); -GLAPI void APIENTRY glDeleteSamplers (GLsizei count, const GLuint *samplers); -GLAPI GLboolean APIENTRY glIsSampler (GLuint sampler); -GLAPI void APIENTRY glBindSampler (GLuint unit, GLuint sampler); -GLAPI void APIENTRY glSamplerParameteri (GLuint sampler, GLenum pname, GLint param); -GLAPI void APIENTRY glSamplerParameteriv (GLuint sampler, GLenum pname, const GLint *param); -GLAPI void APIENTRY glSamplerParameterf (GLuint sampler, GLenum pname, GLfloat param); -GLAPI void APIENTRY glSamplerParameterfv (GLuint sampler, GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glSamplerParameterIiv (GLuint sampler, GLenum pname, const GLint *param); -GLAPI void APIENTRY glSamplerParameterIuiv (GLuint sampler, GLenum pname, const GLuint *param); -GLAPI void APIENTRY glGetSamplerParameteriv (GLuint sampler, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSamplerParameterIiv (GLuint sampler, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSamplerParameterfv (GLuint sampler, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetSamplerParameterIuiv (GLuint sampler, GLenum pname, GLuint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENSAMPLERSPROC) (GLsizei count, GLuint *samplers); -typedef void (APIENTRYP PFNGLDELETESAMPLERSPROC) (GLsizei count, const GLuint *samplers); -typedef GLboolean (APIENTRYP PFNGLISSAMPLERPROC) (GLuint sampler); -typedef void (APIENTRYP PFNGLBINDSAMPLERPROC) (GLuint unit, GLuint sampler); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIPROC) (GLuint sampler, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFPROC) (GLuint sampler, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, const GLuint *param); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIVPROC) (GLuint sampler, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIIVPROC) (GLuint sampler, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERFVPROC) (GLuint sampler, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETSAMPLERPARAMETERIUIVPROC) (GLuint sampler, GLenum pname, GLuint *params); -#endif - -#ifndef GL_ARB_texture_rgb10_a2ui -#define GL_ARB_texture_rgb10_a2ui 1 -#endif - -#ifndef GL_ARB_texture_swizzle -#define GL_ARB_texture_swizzle 1 -#endif - -#ifndef GL_ARB_timer_query -#define GL_ARB_timer_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glQueryCounter (GLuint id, GLenum target); -GLAPI void APIENTRY glGetQueryObjecti64v (GLuint id, GLenum pname, GLint64 *params); -GLAPI void APIENTRY glGetQueryObjectui64v (GLuint id, GLenum pname, GLuint64 *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64 *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64 *params); -#endif - -#ifndef GL_ARB_vertex_type_2_10_10_10_rev -#define GL_ARB_vertex_type_2_10_10_10_rev 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexP2ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP2uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glVertexP3ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP3uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glVertexP4ui (GLenum type, GLuint value); -GLAPI void APIENTRY glVertexP4uiv (GLenum type, const GLuint *value); -GLAPI void APIENTRY glTexCoordP1ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP1uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP2ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP2uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP3ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP3uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glTexCoordP4ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glTexCoordP4uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP1ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP1uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP2ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP2uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP3ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP3uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glMultiTexCoordP4ui (GLenum texture, GLenum type, GLuint coords); -GLAPI void APIENTRY glMultiTexCoordP4uiv (GLenum texture, GLenum type, const GLuint *coords); -GLAPI void APIENTRY glNormalP3ui (GLenum type, GLuint coords); -GLAPI void APIENTRY glNormalP3uiv (GLenum type, const GLuint *coords); -GLAPI void APIENTRY glColorP3ui (GLenum type, GLuint color); -GLAPI void APIENTRY glColorP3uiv (GLenum type, const GLuint *color); -GLAPI void APIENTRY glColorP4ui (GLenum type, GLuint color); -GLAPI void APIENTRY glColorP4uiv (GLenum type, const GLuint *color); -GLAPI void APIENTRY glSecondaryColorP3ui (GLenum type, GLuint color); -GLAPI void APIENTRY glSecondaryColorP3uiv (GLenum type, const GLuint *color); -GLAPI void APIENTRY glVertexAttribP1ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP1uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP2ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP2uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP3ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP3uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -GLAPI void APIENTRY glVertexAttribP4ui (GLuint index, GLenum type, GLboolean normalized, GLuint value); -GLAPI void APIENTRY glVertexAttribP4uiv (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXP2UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP2UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXP3UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP3UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXP4UIPROC) (GLenum type, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXP4UIVPROC) (GLenum type, const GLuint *value); -typedef void (APIENTRYP PFNGLTEXCOORDP1UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP1UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP2UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP2UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP3UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP3UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLTEXCOORDP4UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLTEXCOORDP4UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP1UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP2UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP3UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIPROC) (GLenum texture, GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLMULTITEXCOORDP4UIVPROC) (GLenum texture, GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLNORMALP3UIPROC) (GLenum type, GLuint coords); -typedef void (APIENTRYP PFNGLNORMALP3UIVPROC) (GLenum type, const GLuint *coords); -typedef void (APIENTRYP PFNGLCOLORP3UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLCOLORP3UIVPROC) (GLenum type, const GLuint *color); -typedef void (APIENTRYP PFNGLCOLORP4UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLCOLORP4UIVPROC) (GLenum type, const GLuint *color); -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIPROC) (GLenum type, GLuint color); -typedef void (APIENTRYP PFNGLSECONDARYCOLORP3UIVPROC) (GLenum type, const GLuint *color); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP1UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP2UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP3UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIPROC) (GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (APIENTRYP PFNGLVERTEXATTRIBP4UIVPROC) (GLuint index, GLenum type, GLboolean normalized, const GLuint *value); -#endif - -#ifndef GL_ARB_draw_indirect -#define GL_ARB_draw_indirect 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysIndirect (GLenum mode, const GLvoid *indirect); -GLAPI void APIENTRY glDrawElementsIndirect (GLenum mode, GLenum type, const GLvoid *indirect); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWARRAYSINDIRECTPROC) (GLenum mode, const GLvoid *indirect); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINDIRECTPROC) (GLenum mode, GLenum type, const GLvoid *indirect); -#endif - -#ifndef GL_ARB_gpu_shader5 -#define GL_ARB_gpu_shader5 1 -#endif - -#ifndef GL_ARB_gpu_shader_fp64 -#define GL_ARB_gpu_shader_fp64 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniform1d (GLint location, GLdouble x); -GLAPI void APIENTRY glUniform2d (GLint location, GLdouble x, GLdouble y); -GLAPI void APIENTRY glUniform3d (GLint location, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glUniform4d (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glUniform1dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform2dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform3dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniform4dv (GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix2x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix3x4dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4x2dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glUniformMatrix4x3dv (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glGetUniformdv (GLuint program, GLint location, GLdouble *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUNIFORM1DPROC) (GLint location, GLdouble x); -typedef void (APIENTRYP PFNGLUNIFORM2DPROC) (GLint location, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLUNIFORM3DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLUNIFORM4DPROC) (GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLUNIFORM1DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM2DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM3DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORM4DVPROC) (GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX2X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX3X4DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X2DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLUNIFORMMATRIX4X3DVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLGETUNIFORMDVPROC) (GLuint program, GLint location, GLdouble *params); -#endif - -#ifndef GL_ARB_shader_subroutine -#define GL_ARB_shader_subroutine 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLint APIENTRY glGetSubroutineUniformLocation (GLuint program, GLenum shadertype, const GLchar *name); -GLAPI GLuint APIENTRY glGetSubroutineIndex (GLuint program, GLenum shadertype, const GLchar *name); -GLAPI void APIENTRY glGetActiveSubroutineUniformiv (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); -GLAPI void APIENTRY glGetActiveSubroutineUniformName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glGetActiveSubroutineName (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -GLAPI void APIENTRY glUniformSubroutinesuiv (GLenum shadertype, GLsizei count, const GLuint *indices); -GLAPI void APIENTRY glGetUniformSubroutineuiv (GLenum shadertype, GLint location, GLuint *params); -GLAPI void APIENTRY glGetProgramStageiv (GLuint program, GLenum shadertype, GLenum pname, GLint *values); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLint (APIENTRYP PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) (GLuint program, GLenum shadertype, const GLchar *name); -typedef GLuint (APIENTRYP PFNGLGETSUBROUTINEINDEXPROC) (GLuint program, GLenum shadertype, const GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) (GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVESUBROUTINENAMEPROC) (GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORMSUBROUTINESUIVPROC) (GLenum shadertype, GLsizei count, const GLuint *indices); -typedef void (APIENTRYP PFNGLGETUNIFORMSUBROUTINEUIVPROC) (GLenum shadertype, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTAGEIVPROC) (GLuint program, GLenum shadertype, GLenum pname, GLint *values); -#endif - -#ifndef GL_ARB_tessellation_shader -#define GL_ARB_tessellation_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPatchParameteri (GLenum pname, GLint value); -GLAPI void APIENTRY glPatchParameterfv (GLenum pname, const GLfloat *values); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPATCHPARAMETERIPROC) (GLenum pname, GLint value); -typedef void (APIENTRYP PFNGLPATCHPARAMETERFVPROC) (GLenum pname, const GLfloat *values); -#endif - -#ifndef GL_ARB_texture_buffer_object_rgb32 -#define GL_ARB_texture_buffer_object_rgb32 1 -#endif - -#ifndef GL_ARB_transform_feedback2 -#define GL_ARB_transform_feedback2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindTransformFeedback (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteTransformFeedbacks (GLsizei n, const GLuint *ids); -GLAPI void APIENTRY glGenTransformFeedbacks (GLsizei n, GLuint *ids); -GLAPI GLboolean APIENTRY glIsTransformFeedback (GLuint id); -GLAPI void APIENTRY glPauseTransformFeedback (void); -GLAPI void APIENTRY glResumeTransformFeedback (void); -GLAPI void APIENTRY glDrawTransformFeedback (GLenum mode, GLuint id); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSPROC) (GLsizei n, const GLuint *ids); -typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKPROC) (GLuint id); -typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKPROC) (void); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKPROC) (GLenum mode, GLuint id); -#endif - -#ifndef GL_ARB_transform_feedback3 -#define GL_ARB_transform_feedback3 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawTransformFeedbackStream (GLenum mode, GLuint id, GLuint stream); -GLAPI void APIENTRY glBeginQueryIndexed (GLenum target, GLuint index, GLuint id); -GLAPI void APIENTRY glEndQueryIndexed (GLenum target, GLuint index); -GLAPI void APIENTRY glGetQueryIndexediv (GLenum target, GLuint index, GLenum pname, GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) (GLenum mode, GLuint id, GLuint stream); -typedef void (APIENTRYP PFNGLBEGINQUERYINDEXEDPROC) (GLenum target, GLuint index, GLuint id); -typedef void (APIENTRYP PFNGLENDQUERYINDEXEDPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLGETQUERYINDEXEDIVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); -#endif - -#ifndef GL_ARB_ES2_compatibility -#define GL_ARB_ES2_compatibility 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReleaseShaderCompiler (void); -GLAPI void APIENTRY glShaderBinary (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); -GLAPI void APIENTRY glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); -GLAPI void APIENTRY glDepthRangef (GLclampf n, GLclampf f); -GLAPI void APIENTRY glClearDepthf (GLclampf d); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRELEASESHADERCOMPILERPROC) (void); -typedef void (APIENTRYP PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); -typedef void (APIENTRYP PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); -typedef void (APIENTRYP PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f); -typedef void (APIENTRYP PFNGLCLEARDEPTHFPROC) (GLclampf d); -#endif - -#ifndef GL_ARB_get_program_binary -#define GL_ARB_get_program_binary 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetProgramBinary (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); -GLAPI void APIENTRY glProgramBinary (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length); -GLAPI void APIENTRY glProgramParameteri (GLuint program, GLenum pname, GLint value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETPROGRAMBINARYPROC) (GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, GLvoid *binary); -typedef void (APIENTRYP PFNGLPROGRAMBINARYPROC) (GLuint program, GLenum binaryFormat, const GLvoid *binary, GLsizei length); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value); -#endif - -#ifndef GL_ARB_separate_shader_objects -#define GL_ARB_separate_shader_objects 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUseProgramStages (GLuint pipeline, GLbitfield stages, GLuint program); -GLAPI void APIENTRY glActiveShaderProgram (GLuint pipeline, GLuint program); -GLAPI GLuint APIENTRY glCreateShaderProgramv (GLenum type, GLsizei count, const GLchar* *strings); -GLAPI void APIENTRY glBindProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glDeleteProgramPipelines (GLsizei n, const GLuint *pipelines); -GLAPI void APIENTRY glGenProgramPipelines (GLsizei n, GLuint *pipelines); -GLAPI GLboolean APIENTRY glIsProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glGetProgramPipelineiv (GLuint pipeline, GLenum pname, GLint *params); -GLAPI void APIENTRY glProgramUniform1i (GLuint program, GLint location, GLint v0); -GLAPI void APIENTRY glProgramUniform1iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform1f (GLuint program, GLint location, GLfloat v0); -GLAPI void APIENTRY glProgramUniform1fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform1d (GLuint program, GLint location, GLdouble v0); -GLAPI void APIENTRY glProgramUniform1dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform1ui (GLuint program, GLint location, GLuint v0); -GLAPI void APIENTRY glProgramUniform1uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform2i (GLuint program, GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glProgramUniform2iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform2f (GLuint program, GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glProgramUniform2fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform2d (GLuint program, GLint location, GLdouble v0, GLdouble v1); -GLAPI void APIENTRY glProgramUniform2dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform2ui (GLuint program, GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glProgramUniform2uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform3i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glProgramUniform3iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform3f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glProgramUniform3fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform3d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); -GLAPI void APIENTRY glProgramUniform3dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform3ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glProgramUniform3uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform4i (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glProgramUniform4iv (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform4f (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glProgramUniform4fv (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform4d (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); -GLAPI void APIENTRY glProgramUniform4dv (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform4ui (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glProgramUniform4uiv (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniformMatrix2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3fv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3dv (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glValidateProgramPipeline (GLuint pipeline); -GLAPI void APIENTRY glGetProgramPipelineInfoLog (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUSEPROGRAMSTAGESPROC) (GLuint pipeline, GLbitfield stages, GLuint program); -typedef void (APIENTRYP PFNGLACTIVESHADERPROGRAMPROC) (GLuint pipeline, GLuint program); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMVPROC) (GLenum type, GLsizei count, const GLchar* *strings); -typedef void (APIENTRYP PFNGLBINDPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLDELETEPROGRAMPIPELINESPROC) (GLsizei n, const GLuint *pipelines); -typedef void (APIENTRYP PFNGLGENPROGRAMPIPELINESPROC) (GLsizei n, GLuint *pipelines); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEIVPROC) (GLuint pipeline, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IPROC) (GLuint program, GLint location, GLint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DPROC) (GLuint program, GLint location, GLdouble v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIPROC) (GLuint program, GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DPROC) (GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLVALIDATEPROGRAMPIPELINEPROC) (GLuint pipeline); -typedef void (APIENTRYP PFNGLGETPROGRAMPIPELINEINFOLOGPROC) (GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); -#endif - -#ifndef GL_ARB_vertex_attrib_64bit -#define GL_ARB_vertex_attrib_64bit 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribL1d (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttribL2d (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttribL3d (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttribL4d (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttribL1dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL2dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL3dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL4dv (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribLPointer (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glGetVertexAttribLdv (GLuint index, GLenum pname, GLdouble *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVPROC) (GLuint index, GLenum pname, GLdouble *params); -#endif - -#ifndef GL_ARB_viewport_array -#define GL_ARB_viewport_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glViewportArrayv (GLuint first, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glViewportIndexedf (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -GLAPI void APIENTRY glViewportIndexedfv (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glScissorArrayv (GLuint first, GLsizei count, const GLint *v); -GLAPI void APIENTRY glScissorIndexed (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -GLAPI void APIENTRY glScissorIndexedv (GLuint index, const GLint *v); -GLAPI void APIENTRY glDepthRangeArrayv (GLuint first, GLsizei count, const GLclampd *v); -GLAPI void APIENTRY glDepthRangeIndexed (GLuint index, GLclampd n, GLclampd f); -GLAPI void APIENTRY glGetFloati_v (GLenum target, GLuint index, GLfloat *data); -GLAPI void APIENTRY glGetDoublei_v (GLenum target, GLuint index, GLdouble *data); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVIEWPORTARRAYVPROC) (GLuint first, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -typedef void (APIENTRYP PFNGLVIEWPORTINDEXEDFVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLSCISSORARRAYVPROC) (GLuint first, GLsizei count, const GLint *v); -typedef void (APIENTRYP PFNGLSCISSORINDEXEDPROC) (GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLSCISSORINDEXEDVPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLDEPTHRANGEARRAYVPROC) (GLuint first, GLsizei count, const GLclampd *v); -typedef void (APIENTRYP PFNGLDEPTHRANGEINDEXEDPROC) (GLuint index, GLclampd n, GLclampd f); -typedef void (APIENTRYP PFNGLGETFLOATI_VPROC) (GLenum target, GLuint index, GLfloat *data); -typedef void (APIENTRYP PFNGLGETDOUBLEI_VPROC) (GLenum target, GLuint index, GLdouble *data); -#endif - -#ifndef GL_ARB_cl_event -#define GL_ARB_cl_event 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLsync APIENTRY glCreateSyncFromCLeventARB (struct _cl_context * context, struct _cl_event * event, GLbitfield flags); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLsync (APIENTRYP PFNGLCREATESYNCFROMCLEVENTARBPROC) (struct _cl_context * context, struct _cl_event * event, GLbitfield flags); -#endif - -#ifndef GL_ARB_debug_output -#define GL_ARB_debug_output 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDebugMessageControlARB (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI void APIENTRY glDebugMessageInsertARB (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -GLAPI void APIENTRY glDebugMessageCallbackARB (GLDEBUGPROCARB callback, const GLvoid *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLogARB (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const GLvoid *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); -#endif - -#ifndef GL_ARB_robustness -#define GL_ARB_robustness 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLenum APIENTRY glGetGraphicsResetStatusARB (void); -GLAPI void APIENTRY glGetnMapdvARB (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -GLAPI void APIENTRY glGetnMapfvARB (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -GLAPI void APIENTRY glGetnMapivARB (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -GLAPI void APIENTRY glGetnPixelMapfvARB (GLenum map, GLsizei bufSize, GLfloat *values); -GLAPI void APIENTRY glGetnPixelMapuivARB (GLenum map, GLsizei bufSize, GLuint *values); -GLAPI void APIENTRY glGetnPixelMapusvARB (GLenum map, GLsizei bufSize, GLushort *values); -GLAPI void APIENTRY glGetnPolygonStippleARB (GLsizei bufSize, GLubyte *pattern); -GLAPI void APIENTRY glGetnColorTableARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table); -GLAPI void APIENTRY glGetnConvolutionFilterARB (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image); -GLAPI void APIENTRY glGetnSeparableFilterARB (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span); -GLAPI void APIENTRY glGetnHistogramARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); -GLAPI void APIENTRY glGetnMinmaxARB (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); -GLAPI void APIENTRY glGetnTexImageARB (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img); -GLAPI void APIENTRY glReadnPixelsARB (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); -GLAPI void APIENTRY glGetnCompressedTexImageARB (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img); -GLAPI void APIENTRY glGetnUniformfvARB (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -GLAPI void APIENTRY glGetnUniformivARB (GLuint program, GLint location, GLsizei bufSize, GLint *params); -GLAPI void APIENTRY glGetnUniformuivARB (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -GLAPI void APIENTRY glGetnUniformdvARB (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLenum (APIENTRYP PFNGLGETGRAPHICSRESETSTATUSARBPROC) (void); -typedef void (APIENTRYP PFNGLGETNMAPDVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); -typedef void (APIENTRYP PFNGLGETNMAPFVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); -typedef void (APIENTRYP PFNGLGETNMAPIVARBPROC) (GLenum target, GLenum query, GLsizei bufSize, GLint *v); -typedef void (APIENTRYP PFNGLGETNPIXELMAPFVARBPROC) (GLenum map, GLsizei bufSize, GLfloat *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUIVARBPROC) (GLenum map, GLsizei bufSize, GLuint *values); -typedef void (APIENTRYP PFNGLGETNPIXELMAPUSVARBPROC) (GLenum map, GLsizei bufSize, GLushort *values); -typedef void (APIENTRYP PFNGLGETNPOLYGONSTIPPLEARBPROC) (GLsizei bufSize, GLubyte *pattern); -typedef void (APIENTRYP PFNGLGETNCOLORTABLEARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *table); -typedef void (APIENTRYP PFNGLGETNCONVOLUTIONFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei bufSize, GLvoid *image); -typedef void (APIENTRYP PFNGLGETNSEPARABLEFILTERARBPROC) (GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, GLvoid *row, GLsizei columnBufSize, GLvoid *column, GLvoid *span); -typedef void (APIENTRYP PFNGLGETNHISTOGRAMARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); -typedef void (APIENTRYP PFNGLGETNMINMAXARBPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, GLvoid *values); -typedef void (APIENTRYP PFNGLGETNTEXIMAGEARBPROC) (GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, GLvoid *img); -typedef void (APIENTRYP PFNGLREADNPIXELSARBPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, GLvoid *data); -typedef void (APIENTRYP PFNGLGETNCOMPRESSEDTEXIMAGEARBPROC) (GLenum target, GLint lod, GLsizei bufSize, GLvoid *img); -typedef void (APIENTRYP PFNGLGETNUNIFORMFVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMUIVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint *params); -typedef void (APIENTRYP PFNGLGETNUNIFORMDVARBPROC) (GLuint program, GLint location, GLsizei bufSize, GLdouble *params); -#endif - -#ifndef GL_ARB_shader_stencil_export -#define GL_ARB_shader_stencil_export 1 -#endif - -#ifndef GL_EXT_abgr -#define GL_EXT_abgr 1 -#endif - -#ifndef GL_EXT_blend_color -#define GL_EXT_blend_color 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendColorEXT (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDCOLOREXTPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); -#endif - -#ifndef GL_EXT_polygon_offset -#define GL_EXT_polygon_offset 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPolygonOffsetEXT (GLfloat factor, GLfloat bias); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOLYGONOFFSETEXTPROC) (GLfloat factor, GLfloat bias); -#endif - -#ifndef GL_EXT_texture -#define GL_EXT_texture 1 -#endif - -#ifndef GL_EXT_texture3D -#define GL_EXT_texture3D 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage3DEXT (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXIMAGE3DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_SGIS_texture_filter4 -#define GL_SGIS_texture_filter4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetTexFilterFuncSGIS (GLenum target, GLenum filter, GLfloat *weights); -GLAPI void APIENTRY glTexFilterFuncSGIS (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLfloat *weights); -typedef void (APIENTRYP PFNGLTEXFILTERFUNCSGISPROC) (GLenum target, GLenum filter, GLsizei n, const GLfloat *weights); -#endif - -#ifndef GL_EXT_subtexture -#define GL_EXT_subtexture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_EXT_copy_texture -#define GL_EXT_copy_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyTexImage1DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyTexImage2DEXT (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyTexSubImage1DEXT (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTexSubImage2DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glCopyTexSubImage3DEXT (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE1DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXIMAGE2DEXTPROC) (GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE1DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE2DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLCOPYTEXSUBIMAGE3DEXTPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -#endif - -#ifndef GL_EXT_histogram -#define GL_EXT_histogram 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetHistogramEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -GLAPI void APIENTRY glGetHistogramParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetHistogramParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMinmaxEXT (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -GLAPI void APIENTRY glGetMinmaxParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMinmaxParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glHistogramEXT (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glMinmaxEXT (GLenum target, GLenum internalformat, GLboolean sink); -GLAPI void APIENTRY glResetHistogramEXT (GLenum target); -GLAPI void APIENTRY glResetMinmaxEXT (GLenum target); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETHISTOGRAMEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETHISTOGRAMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMINMAXEXTPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMINMAXPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLHISTOGRAMEXTPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLMINMAXEXTPROC) (GLenum target, GLenum internalformat, GLboolean sink); -typedef void (APIENTRYP PFNGLRESETHISTOGRAMEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLRESETMINMAXEXTPROC) (GLenum target); -#endif - -#ifndef GL_EXT_convolution -#define GL_EXT_convolution 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -GLAPI void APIENTRY glConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -GLAPI void APIENTRY glConvolutionParameterfEXT (GLenum target, GLenum pname, GLfloat params); -GLAPI void APIENTRY glConvolutionParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glConvolutionParameteriEXT (GLenum target, GLenum pname, GLint params); -GLAPI void APIENTRY glConvolutionParameterivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyConvolutionFilter1DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyConvolutionFilter2DEXT (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetConvolutionFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *image); -GLAPI void APIENTRY glGetConvolutionParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetConvolutionParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetSeparableFilterEXT (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -GLAPI void APIENTRY glSeparableFilter2DEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint params); -typedef void (APIENTRYP PFNGLCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER1DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYCONVOLUTIONFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCONVOLUTIONPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETSEPARABLEFILTEREXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); -typedef void (APIENTRYP PFNGLSEPARABLEFILTER2DEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); -#endif - -#ifndef GL_SGI_color_matrix -#define GL_SGI_color_matrix 1 -#endif - -#ifndef GL_SGI_color_table -#define GL_SGI_color_table 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableSGI (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -GLAPI void APIENTRY glColorTableParameterfvSGI (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glColorTableParameterivSGI (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glCopyColorTableSGI (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glGetColorTableSGI (GLenum target, GLenum format, GLenum type, GLvoid *table); -GLAPI void APIENTRY glGetColorTableParameterfvSGI (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetColorTableParameterivSGI (GLenum target, GLenum pname, GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOPYCOLORTABLESGIPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLGETCOLORTABLESGIPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVSGIPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVSGIPROC) (GLenum target, GLenum pname, GLint *params); -#endif - -#ifndef GL_SGIX_pixel_texture -#define GL_SGIX_pixel_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenSGIX (GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTEXGENSGIXPROC) (GLenum mode); -#endif - -#ifndef GL_SGIS_pixel_texture -#define GL_SGIS_pixel_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTexGenParameteriSGIS (GLenum pname, GLint param); -GLAPI void APIENTRY glPixelTexGenParameterivSGIS (GLenum pname, const GLint *params); -GLAPI void APIENTRY glPixelTexGenParameterfSGIS (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPixelTexGenParameterfvSGIS (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetPixelTexGenParameterivSGIS (GLenum pname, GLint *params); -GLAPI void APIENTRY glGetPixelTexGenParameterfvSGIS (GLenum pname, GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERISGISPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERIVSGISPROC) (GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPIXELTEXGENPARAMETERFVSGISPROC) (GLenum pname, GLfloat *params); -#endif - -#ifndef GL_SGIS_texture4D -#define GL_SGIS_texture4D 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage4DSGIS (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glTexSubImage4DSGIS (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXIMAGE4DSGISPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXSUBIMAGE4DSGISPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint woffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei size4d, GLenum format, GLenum type, const GLvoid *pixels); -#endif - -#ifndef GL_SGI_texture_color_table -#define GL_SGI_texture_color_table 1 -#endif - -#ifndef GL_EXT_cmyka -#define GL_EXT_cmyka 1 -#endif - -#ifndef GL_EXT_texture_object -#define GL_EXT_texture_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreTexturesResidentEXT (GLsizei n, const GLuint *textures, GLboolean *residences); -GLAPI void APIENTRY glBindTextureEXT (GLenum target, GLuint texture); -GLAPI void APIENTRY glDeleteTexturesEXT (GLsizei n, const GLuint *textures); -GLAPI void APIENTRY glGenTexturesEXT (GLsizei n, GLuint *textures); -GLAPI GLboolean APIENTRY glIsTextureEXT (GLuint texture); -GLAPI void APIENTRY glPrioritizeTexturesEXT (GLsizei n, const GLuint *textures, const GLclampf *priorities); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLARETEXTURESRESIDENTEXTPROC) (GLsizei n, const GLuint *textures, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDTEXTUREEXTPROC) (GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLDELETETEXTURESEXTPROC) (GLsizei n, const GLuint *textures); -typedef void (APIENTRYP PFNGLGENTEXTURESEXTPROC) (GLsizei n, GLuint *textures); -typedef GLboolean (APIENTRYP PFNGLISTEXTUREEXTPROC) (GLuint texture); -typedef void (APIENTRYP PFNGLPRIORITIZETEXTURESEXTPROC) (GLsizei n, const GLuint *textures, const GLclampf *priorities); -#endif - -#ifndef GL_SGIS_detail_texture -#define GL_SGIS_detail_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDetailTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetDetailTexFuncSGIS (GLenum target, GLfloat *points); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDETAILTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETDETAILTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#endif - -#ifndef GL_SGIS_sharpen_texture -#define GL_SGIS_sharpen_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSharpenTexFuncSGIS (GLenum target, GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetSharpenTexFuncSGIS (GLenum target, GLfloat *points); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSHARPENTEXFUNCSGISPROC) (GLenum target, GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETSHARPENTEXFUNCSGISPROC) (GLenum target, GLfloat *points); -#endif - -#ifndef GL_EXT_packed_pixels -#define GL_EXT_packed_pixels 1 -#endif - -#ifndef GL_SGIS_texture_lod -#define GL_SGIS_texture_lod 1 -#endif - -#ifndef GL_SGIS_multisample -#define GL_SGIS_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskSGIS (GLclampf value, GLboolean invert); -GLAPI void APIENTRY glSamplePatternSGIS (GLenum pattern); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLEMASKSGISPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNSGISPROC) (GLenum pattern); -#endif - -#ifndef GL_EXT_rescale_normal -#define GL_EXT_rescale_normal 1 -#endif - -#ifndef GL_EXT_vertex_array -#define GL_EXT_vertex_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glArrayElementEXT (GLint i); -GLAPI void APIENTRY glColorPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -GLAPI void APIENTRY glDrawArraysEXT (GLenum mode, GLint first, GLsizei count); -GLAPI void APIENTRY glEdgeFlagPointerEXT (GLsizei stride, GLsizei count, const GLboolean *pointer); -GLAPI void APIENTRY glGetPointervEXT (GLenum pname, GLvoid* *params); -GLAPI void APIENTRY glIndexPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -GLAPI void APIENTRY glNormalPointerEXT (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -GLAPI void APIENTRY glTexCoordPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -GLAPI void APIENTRY glVertexPointerEXT (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLARRAYELEMENTEXTPROC) (GLint i); -typedef void (APIENTRYP PFNGLCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWARRAYSEXTPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTEREXTPROC) (GLsizei stride, GLsizei count, const GLboolean *pointer); -typedef void (APIENTRYP PFNGLGETPOINTERVEXTPROC) (GLenum pname, GLvoid* *params); -typedef void (APIENTRYP PFNGLINDEXPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_misc_attribute -#define GL_EXT_misc_attribute 1 -#endif - -#ifndef GL_SGIS_generate_mipmap -#define GL_SGIS_generate_mipmap 1 -#endif - -#ifndef GL_SGIX_clipmap -#define GL_SGIX_clipmap 1 -#endif - -#ifndef GL_SGIX_shadow -#define GL_SGIX_shadow 1 -#endif - -#ifndef GL_SGIS_texture_edge_clamp -#define GL_SGIS_texture_edge_clamp 1 -#endif - -#ifndef GL_SGIS_texture_border_clamp -#define GL_SGIS_texture_border_clamp 1 -#endif - -#ifndef GL_EXT_blend_minmax -#define GL_EXT_blend_minmax 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationEXT (GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONEXTPROC) (GLenum mode); -#endif - -#ifndef GL_EXT_blend_subtract -#define GL_EXT_blend_subtract 1 -#endif - -#ifndef GL_EXT_blend_logic_op -#define GL_EXT_blend_logic_op 1 -#endif - -#ifndef GL_SGIX_interlace -#define GL_SGIX_interlace 1 -#endif - -#ifndef GL_SGIX_pixel_tiles -#define GL_SGIX_pixel_tiles 1 -#endif - -#ifndef GL_SGIX_texture_select -#define GL_SGIX_texture_select 1 -#endif - -#ifndef GL_SGIX_sprite -#define GL_SGIX_sprite 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSpriteParameterfSGIX (GLenum pname, GLfloat param); -GLAPI void APIENTRY glSpriteParameterfvSGIX (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glSpriteParameteriSGIX (GLenum pname, GLint param); -GLAPI void APIENTRY glSpriteParameterivSGIX (GLenum pname, const GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLSPRITEPARAMETERIVSGIXPROC) (GLenum pname, const GLint *params); -#endif - -#ifndef GL_SGIX_texture_multi_buffer -#define GL_SGIX_texture_multi_buffer 1 -#endif - -#ifndef GL_EXT_point_parameters -#define GL_EXT_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfEXT (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvEXT (GLenum pname, const GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFEXTPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVEXTPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_SGIS_point_parameters -#define GL_SGIS_point_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameterfSGIS (GLenum pname, GLfloat param); -GLAPI void APIENTRY glPointParameterfvSGIS (GLenum pname, const GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERFSGISPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERFVSGISPROC) (GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_SGIX_instruments -#define GL_SGIX_instruments 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLint APIENTRY glGetInstrumentsSGIX (void); -GLAPI void APIENTRY glInstrumentsBufferSGIX (GLsizei size, GLint *buffer); -GLAPI GLint APIENTRY glPollInstrumentsSGIX (GLint *marker_p); -GLAPI void APIENTRY glReadInstrumentsSGIX (GLint marker); -GLAPI void APIENTRY glStartInstrumentsSGIX (void); -GLAPI void APIENTRY glStopInstrumentsSGIX (GLint marker); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLint (APIENTRYP PFNGLGETINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLINSTRUMENTSBUFFERSGIXPROC) (GLsizei size, GLint *buffer); -typedef GLint (APIENTRYP PFNGLPOLLINSTRUMENTSSGIXPROC) (GLint *marker_p); -typedef void (APIENTRYP PFNGLREADINSTRUMENTSSGIXPROC) (GLint marker); -typedef void (APIENTRYP PFNGLSTARTINSTRUMENTSSGIXPROC) (void); -typedef void (APIENTRYP PFNGLSTOPINSTRUMENTSSGIXPROC) (GLint marker); -#endif - -#ifndef GL_SGIX_texture_scale_bias -#define GL_SGIX_texture_scale_bias 1 -#endif - -#ifndef GL_SGIX_framezoom -#define GL_SGIX_framezoom 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameZoomSGIX (GLint factor); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFRAMEZOOMSGIXPROC) (GLint factor); -#endif - -#ifndef GL_SGIX_tag_sample_buffer -#define GL_SGIX_tag_sample_buffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTagSampleBufferSGIX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTAGSAMPLEBUFFERSGIXPROC) (void); -#endif - -#ifndef GL_SGIX_polynomial_ffd -#define GL_SGIX_polynomial_ffd 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeformationMap3dSGIX (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); -GLAPI void APIENTRY glDeformationMap3fSGIX (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); -GLAPI void APIENTRY glDeformSGIX (GLbitfield mask); -GLAPI void APIENTRY glLoadIdentityDeformationMapSGIX (GLbitfield mask); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3DSGIXPROC) (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble w1, GLdouble w2, GLint wstride, GLint worder, const GLdouble *points); -typedef void (APIENTRYP PFNGLDEFORMATIONMAP3FSGIXPROC) (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat w1, GLfloat w2, GLint wstride, GLint worder, const GLfloat *points); -typedef void (APIENTRYP PFNGLDEFORMSGIXPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLLOADIDENTITYDEFORMATIONMAPSGIXPROC) (GLbitfield mask); -#endif - -#ifndef GL_SGIX_reference_plane -#define GL_SGIX_reference_plane 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReferencePlaneSGIX (const GLdouble *equation); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLREFERENCEPLANESGIXPROC) (const GLdouble *equation); -#endif - -#ifndef GL_SGIX_flush_raster -#define GL_SGIX_flush_raster 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushRasterSGIX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFLUSHRASTERSGIXPROC) (void); -#endif - -#ifndef GL_SGIX_depth_texture -#define GL_SGIX_depth_texture 1 -#endif - -#ifndef GL_SGIS_fog_function -#define GL_SGIS_fog_function 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogFuncSGIS (GLsizei n, const GLfloat *points); -GLAPI void APIENTRY glGetFogFuncSGIS (GLfloat *points); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFOGFUNCSGISPROC) (GLsizei n, const GLfloat *points); -typedef void (APIENTRYP PFNGLGETFOGFUNCSGISPROC) (GLfloat *points); -#endif - -#ifndef GL_SGIX_fog_offset -#define GL_SGIX_fog_offset 1 -#endif - -#ifndef GL_HP_image_transform -#define GL_HP_image_transform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glImageTransformParameteriHP (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glImageTransformParameterfHP (GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glImageTransformParameterivHP (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glImageTransformParameterfvHP (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetImageTransformParameterivHP (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetImageTransformParameterfvHP (GLenum target, GLenum pname, GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIHPPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFHPPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERIVHPPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETIMAGETRANSFORMPARAMETERFVHPPROC) (GLenum target, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_HP_convolution_border_modes -#define GL_HP_convolution_border_modes 1 -#endif - -#ifndef GL_SGIX_texture_add_env -#define GL_SGIX_texture_add_env 1 -#endif - -#ifndef GL_EXT_color_subtable -#define GL_EXT_color_subtable 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorSubTableEXT (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -GLAPI void APIENTRY glCopyColorSubTableEXT (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); -typedef void (APIENTRYP PFNGLCOPYCOLORSUBTABLEEXTPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); -#endif - -#ifndef GL_PGI_vertex_hints -#define GL_PGI_vertex_hints 1 -#endif - -#ifndef GL_PGI_misc_hints -#define GL_PGI_misc_hints 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glHintPGI (GLenum target, GLint mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLHINTPGIPROC) (GLenum target, GLint mode); -#endif - -#ifndef GL_EXT_paletted_texture -#define GL_EXT_paletted_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorTableEXT (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -GLAPI void APIENTRY glGetColorTableEXT (GLenum target, GLenum format, GLenum type, GLvoid *data); -GLAPI void APIENTRY glGetColorTableParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetColorTableParameterfvEXT (GLenum target, GLenum pname, GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORTABLEEXTPROC) (GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); -typedef void (APIENTRYP PFNGLGETCOLORTABLEEXTPROC) (GLenum target, GLenum format, GLenum type, GLvoid *data); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOLORTABLEPARAMETERFVEXTPROC) (GLenum target, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_EXT_clip_volume_hint -#define GL_EXT_clip_volume_hint 1 -#endif - -#ifndef GL_SGIX_list_priority -#define GL_SGIX_list_priority 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetListParameterfvSGIX (GLuint list, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetListParameterivSGIX (GLuint list, GLenum pname, GLint *params); -GLAPI void APIENTRY glListParameterfSGIX (GLuint list, GLenum pname, GLfloat param); -GLAPI void APIENTRY glListParameterfvSGIX (GLuint list, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glListParameteriSGIX (GLuint list, GLenum pname, GLint param); -GLAPI void APIENTRY glListParameterivSGIX (GLuint list, GLenum pname, const GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERFSGIXPROC) (GLuint list, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLLISTPARAMETERFVSGIXPROC) (GLuint list, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLLISTPARAMETERISGIXPROC) (GLuint list, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLLISTPARAMETERIVSGIXPROC) (GLuint list, GLenum pname, const GLint *params); -#endif - -#ifndef GL_SGIX_ir_instrument1 -#define GL_SGIX_ir_instrument1 1 -#endif - -#ifndef GL_SGIX_calligraphic_fragment -#define GL_SGIX_calligraphic_fragment 1 -#endif - -#ifndef GL_SGIX_texture_lod_bias -#define GL_SGIX_texture_lod_bias 1 -#endif - -#ifndef GL_SGIX_shadow_ambient -#define GL_SGIX_shadow_ambient 1 -#endif - -#ifndef GL_EXT_index_texture -#define GL_EXT_index_texture 1 -#endif - -#ifndef GL_EXT_index_material -#define GL_EXT_index_material 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexMaterialEXT (GLenum face, GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLINDEXMATERIALEXTPROC) (GLenum face, GLenum mode); -#endif - -#ifndef GL_EXT_index_func -#define GL_EXT_index_func 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIndexFuncEXT (GLenum func, GLclampf ref); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLINDEXFUNCEXTPROC) (GLenum func, GLclampf ref); -#endif - -#ifndef GL_EXT_index_array_formats -#define GL_EXT_index_array_formats 1 -#endif - -#ifndef GL_EXT_compiled_vertex_array -#define GL_EXT_compiled_vertex_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glLockArraysEXT (GLint first, GLsizei count); -GLAPI void APIENTRY glUnlockArraysEXT (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLLOCKARRAYSEXTPROC) (GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLUNLOCKARRAYSEXTPROC) (void); -#endif - -#ifndef GL_EXT_cull_vertex -#define GL_EXT_cull_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCullParameterdvEXT (GLenum pname, GLdouble *params); -GLAPI void APIENTRY glCullParameterfvEXT (GLenum pname, GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCULLPARAMETERDVEXTPROC) (GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLCULLPARAMETERFVEXTPROC) (GLenum pname, GLfloat *params); -#endif - -#ifndef GL_SGIX_ycrcb -#define GL_SGIX_ycrcb 1 -#endif - -#ifndef GL_SGIX_fragment_lighting -#define GL_SGIX_fragment_lighting 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFragmentColorMaterialSGIX (GLenum face, GLenum mode); -GLAPI void APIENTRY glFragmentLightfSGIX (GLenum light, GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentLightfvSGIX (GLenum light, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentLightiSGIX (GLenum light, GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentLightivSGIX (GLenum light, GLenum pname, const GLint *params); -GLAPI void APIENTRY glFragmentLightModelfSGIX (GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentLightModelfvSGIX (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentLightModeliSGIX (GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentLightModelivSGIX (GLenum pname, const GLint *params); -GLAPI void APIENTRY glFragmentMaterialfSGIX (GLenum face, GLenum pname, GLfloat param); -GLAPI void APIENTRY glFragmentMaterialfvSGIX (GLenum face, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glFragmentMaterialiSGIX (GLenum face, GLenum pname, GLint param); -GLAPI void APIENTRY glFragmentMaterialivSGIX (GLenum face, GLenum pname, const GLint *params); -GLAPI void APIENTRY glGetFragmentLightfvSGIX (GLenum light, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFragmentLightivSGIX (GLenum light, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetFragmentMaterialfvSGIX (GLenum face, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFragmentMaterialivSGIX (GLenum face, GLenum pname, GLint *params); -GLAPI void APIENTRY glLightEnviSGIX (GLenum pname, GLint param); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFRAGMENTCOLORMATERIALSGIXPROC) (GLenum face, GLenum mode); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFSGIXPROC) (GLenum light, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTISGIXPROC) (GLenum light, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFSGIXPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELFVSGIXPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELISGIXPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTLIGHTMODELIVSGIXPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFSGIXPROC) (GLenum face, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALISGIXPROC) (GLenum face, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTFVSGIXPROC) (GLenum light, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTLIGHTIVSGIXPROC) (GLenum light, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALFVSGIXPROC) (GLenum face, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFRAGMENTMATERIALIVSGIXPROC) (GLenum face, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLLIGHTENVISGIXPROC) (GLenum pname, GLint param); -#endif - -#ifndef GL_IBM_rasterpos_clip -#define GL_IBM_rasterpos_clip 1 -#endif - -#ifndef GL_HP_texture_lighting -#define GL_HP_texture_lighting 1 -#endif - -#ifndef GL_EXT_draw_range_elements -#define GL_EXT_draw_range_elements 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawRangeElementsEXT (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSEXTPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); -#endif - -#ifndef GL_WIN_phong_shading -#define GL_WIN_phong_shading 1 -#endif - -#ifndef GL_WIN_specular_fog -#define GL_WIN_specular_fog 1 -#endif - -#ifndef GL_EXT_light_texture -#define GL_EXT_light_texture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glApplyTextureEXT (GLenum mode); -GLAPI void APIENTRY glTextureLightEXT (GLenum pname); -GLAPI void APIENTRY glTextureMaterialEXT (GLenum face, GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLAPPLYTEXTUREEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLTEXTURELIGHTEXTPROC) (GLenum pname); -typedef void (APIENTRYP PFNGLTEXTUREMATERIALEXTPROC) (GLenum face, GLenum mode); -#endif - -#ifndef GL_SGIX_blend_alpha_minmax -#define GL_SGIX_blend_alpha_minmax 1 -#endif - -#ifndef GL_EXT_bgra -#define GL_EXT_bgra 1 -#endif - -#ifndef GL_SGIX_async -#define GL_SGIX_async 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glAsyncMarkerSGIX (GLuint marker); -GLAPI GLint APIENTRY glFinishAsyncSGIX (GLuint *markerp); -GLAPI GLint APIENTRY glPollAsyncSGIX (GLuint *markerp); -GLAPI GLuint APIENTRY glGenAsyncMarkersSGIX (GLsizei range); -GLAPI void APIENTRY glDeleteAsyncMarkersSGIX (GLuint marker, GLsizei range); -GLAPI GLboolean APIENTRY glIsAsyncMarkerSGIX (GLuint marker); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLASYNCMARKERSGIXPROC) (GLuint marker); -typedef GLint (APIENTRYP PFNGLFINISHASYNCSGIXPROC) (GLuint *markerp); -typedef GLint (APIENTRYP PFNGLPOLLASYNCSGIXPROC) (GLuint *markerp); -typedef GLuint (APIENTRYP PFNGLGENASYNCMARKERSSGIXPROC) (GLsizei range); -typedef void (APIENTRYP PFNGLDELETEASYNCMARKERSSGIXPROC) (GLuint marker, GLsizei range); -typedef GLboolean (APIENTRYP PFNGLISASYNCMARKERSGIXPROC) (GLuint marker); -#endif - -#ifndef GL_SGIX_async_pixel -#define GL_SGIX_async_pixel 1 -#endif - -#ifndef GL_SGIX_async_histogram -#define GL_SGIX_async_histogram 1 -#endif - -#ifndef GL_INTEL_parallel_arrays -#define GL_INTEL_parallel_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer); -GLAPI void APIENTRY glNormalPointervINTEL (GLenum type, const GLvoid* *pointer); -GLAPI void APIENTRY glColorPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer); -GLAPI void APIENTRY glTexCoordPointervINTEL (GLint size, GLenum type, const GLvoid* *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLNORMALPOINTERVINTELPROC) (GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLCOLORPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERVINTELPROC) (GLint size, GLenum type, const GLvoid* *pointer); -#endif - -#ifndef GL_HP_occlusion_test -#define GL_HP_occlusion_test 1 -#endif - -#ifndef GL_EXT_pixel_transform -#define GL_EXT_pixel_transform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelTransformParameteriEXT (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glPixelTransformParameterfEXT (GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glPixelTransformParameterivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glPixelTransformParameterfvEXT (GLenum target, GLenum pname, const GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIEXTPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFEXTPROC) (GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLPIXELTRANSFORMPARAMETERFVEXTPROC) (GLenum target, GLenum pname, const GLfloat *params); -#endif - -#ifndef GL_EXT_pixel_transform_color_table -#define GL_EXT_pixel_transform_color_table 1 -#endif - -#ifndef GL_EXT_shared_texture_palette -#define GL_EXT_shared_texture_palette 1 -#endif - -#ifndef GL_EXT_separate_specular_color -#define GL_EXT_separate_specular_color 1 -#endif - -#ifndef GL_EXT_secondary_color -#define GL_EXT_secondary_color 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSecondaryColor3bEXT (GLbyte red, GLbyte green, GLbyte blue); -GLAPI void APIENTRY glSecondaryColor3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glSecondaryColor3dEXT (GLdouble red, GLdouble green, GLdouble blue); -GLAPI void APIENTRY glSecondaryColor3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glSecondaryColor3fEXT (GLfloat red, GLfloat green, GLfloat blue); -GLAPI void APIENTRY glSecondaryColor3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glSecondaryColor3iEXT (GLint red, GLint green, GLint blue); -GLAPI void APIENTRY glSecondaryColor3ivEXT (const GLint *v); -GLAPI void APIENTRY glSecondaryColor3sEXT (GLshort red, GLshort green, GLshort blue); -GLAPI void APIENTRY glSecondaryColor3svEXT (const GLshort *v); -GLAPI void APIENTRY glSecondaryColor3ubEXT (GLubyte red, GLubyte green, GLubyte blue); -GLAPI void APIENTRY glSecondaryColor3ubvEXT (const GLubyte *v); -GLAPI void APIENTRY glSecondaryColor3uiEXT (GLuint red, GLuint green, GLuint blue); -GLAPI void APIENTRY glSecondaryColor3uivEXT (const GLuint *v); -GLAPI void APIENTRY glSecondaryColor3usEXT (GLushort red, GLushort green, GLushort blue); -GLAPI void APIENTRY glSecondaryColor3usvEXT (const GLushort *v); -GLAPI void APIENTRY glSecondaryColorPointerEXT (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BEXTPROC) (GLbyte red, GLbyte green, GLbyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DEXTPROC) (GLdouble red, GLdouble green, GLdouble blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FEXTPROC) (GLfloat red, GLfloat green, GLfloat blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IEXTPROC) (GLint red, GLint green, GLint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SEXTPROC) (GLshort red, GLshort green, GLshort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBEXTPROC) (GLubyte red, GLubyte green, GLubyte blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UBVEXTPROC) (const GLubyte *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIEXTPROC) (GLuint red, GLuint green, GLuint blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3UIVEXTPROC) (const GLuint *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USEXTPROC) (GLushort red, GLushort green, GLushort blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3USVEXTPROC) (const GLushort *v); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTEREXTPROC) (GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_texture_perturb_normal -#define GL_EXT_texture_perturb_normal 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureNormalEXT (GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXTURENORMALEXTPROC) (GLenum mode); -#endif - -#ifndef GL_EXT_multi_draw_arrays -#define GL_EXT_multi_draw_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiDrawArraysEXT (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -GLAPI void APIENTRY glMultiDrawElementsEXT (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMULTIDRAWARRAYSEXTPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSEXTPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); -#endif - -#ifndef GL_EXT_fog_coord -#define GL_EXT_fog_coord 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFogCoordfEXT (GLfloat coord); -GLAPI void APIENTRY glFogCoordfvEXT (const GLfloat *coord); -GLAPI void APIENTRY glFogCoorddEXT (GLdouble coord); -GLAPI void APIENTRY glFogCoorddvEXT (const GLdouble *coord); -GLAPI void APIENTRY glFogCoordPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFOGCOORDFEXTPROC) (GLfloat coord); -typedef void (APIENTRYP PFNGLFOGCOORDFVEXTPROC) (const GLfloat *coord); -typedef void (APIENTRYP PFNGLFOGCOORDDEXTPROC) (GLdouble coord); -typedef void (APIENTRYP PFNGLFOGCOORDDVEXTPROC) (const GLdouble *coord); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_REND_screen_coordinates -#define GL_REND_screen_coordinates 1 -#endif - -#ifndef GL_EXT_coordinate_frame -#define GL_EXT_coordinate_frame 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTangent3bEXT (GLbyte tx, GLbyte ty, GLbyte tz); -GLAPI void APIENTRY glTangent3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glTangent3dEXT (GLdouble tx, GLdouble ty, GLdouble tz); -GLAPI void APIENTRY glTangent3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glTangent3fEXT (GLfloat tx, GLfloat ty, GLfloat tz); -GLAPI void APIENTRY glTangent3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glTangent3iEXT (GLint tx, GLint ty, GLint tz); -GLAPI void APIENTRY glTangent3ivEXT (const GLint *v); -GLAPI void APIENTRY glTangent3sEXT (GLshort tx, GLshort ty, GLshort tz); -GLAPI void APIENTRY glTangent3svEXT (const GLshort *v); -GLAPI void APIENTRY glBinormal3bEXT (GLbyte bx, GLbyte by, GLbyte bz); -GLAPI void APIENTRY glBinormal3bvEXT (const GLbyte *v); -GLAPI void APIENTRY glBinormal3dEXT (GLdouble bx, GLdouble by, GLdouble bz); -GLAPI void APIENTRY glBinormal3dvEXT (const GLdouble *v); -GLAPI void APIENTRY glBinormal3fEXT (GLfloat bx, GLfloat by, GLfloat bz); -GLAPI void APIENTRY glBinormal3fvEXT (const GLfloat *v); -GLAPI void APIENTRY glBinormal3iEXT (GLint bx, GLint by, GLint bz); -GLAPI void APIENTRY glBinormal3ivEXT (const GLint *v); -GLAPI void APIENTRY glBinormal3sEXT (GLshort bx, GLshort by, GLshort bz); -GLAPI void APIENTRY glBinormal3svEXT (const GLshort *v); -GLAPI void APIENTRY glTangentPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glBinormalPointerEXT (GLenum type, GLsizei stride, const GLvoid *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTANGENT3BEXTPROC) (GLbyte tx, GLbyte ty, GLbyte tz); -typedef void (APIENTRYP PFNGLTANGENT3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLTANGENT3DEXTPROC) (GLdouble tx, GLdouble ty, GLdouble tz); -typedef void (APIENTRYP PFNGLTANGENT3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLTANGENT3FEXTPROC) (GLfloat tx, GLfloat ty, GLfloat tz); -typedef void (APIENTRYP PFNGLTANGENT3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLTANGENT3IEXTPROC) (GLint tx, GLint ty, GLint tz); -typedef void (APIENTRYP PFNGLTANGENT3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLTANGENT3SEXTPROC) (GLshort tx, GLshort ty, GLshort tz); -typedef void (APIENTRYP PFNGLTANGENT3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLBINORMAL3BEXTPROC) (GLbyte bx, GLbyte by, GLbyte bz); -typedef void (APIENTRYP PFNGLBINORMAL3BVEXTPROC) (const GLbyte *v); -typedef void (APIENTRYP PFNGLBINORMAL3DEXTPROC) (GLdouble bx, GLdouble by, GLdouble bz); -typedef void (APIENTRYP PFNGLBINORMAL3DVEXTPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLBINORMAL3FEXTPROC) (GLfloat bx, GLfloat by, GLfloat bz); -typedef void (APIENTRYP PFNGLBINORMAL3FVEXTPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLBINORMAL3IEXTPROC) (GLint bx, GLint by, GLint bz); -typedef void (APIENTRYP PFNGLBINORMAL3IVEXTPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLBINORMAL3SEXTPROC) (GLshort bx, GLshort by, GLshort bz); -typedef void (APIENTRYP PFNGLBINORMAL3SVEXTPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLTANGENTPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLBINORMALPOINTEREXTPROC) (GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_EXT_texture_env_combine -#define GL_EXT_texture_env_combine 1 -#endif - -#ifndef GL_APPLE_specular_vector -#define GL_APPLE_specular_vector 1 -#endif - -#ifndef GL_APPLE_transform_hint -#define GL_APPLE_transform_hint 1 -#endif - -#ifndef GL_SGIX_fog_scale -#define GL_SGIX_fog_scale 1 -#endif - -#ifndef GL_SUNX_constant_data -#define GL_SUNX_constant_data 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFinishTextureSUNX (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFINISHTEXTURESUNXPROC) (void); -#endif - -#ifndef GL_SUN_global_alpha -#define GL_SUN_global_alpha 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGlobalAlphaFactorbSUN (GLbyte factor); -GLAPI void APIENTRY glGlobalAlphaFactorsSUN (GLshort factor); -GLAPI void APIENTRY glGlobalAlphaFactoriSUN (GLint factor); -GLAPI void APIENTRY glGlobalAlphaFactorfSUN (GLfloat factor); -GLAPI void APIENTRY glGlobalAlphaFactordSUN (GLdouble factor); -GLAPI void APIENTRY glGlobalAlphaFactorubSUN (GLubyte factor); -GLAPI void APIENTRY glGlobalAlphaFactorusSUN (GLushort factor); -GLAPI void APIENTRY glGlobalAlphaFactoruiSUN (GLuint factor); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORBSUNPROC) (GLbyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORSSUNPROC) (GLshort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORISUNPROC) (GLint factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORFSUNPROC) (GLfloat factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORDSUNPROC) (GLdouble factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUBSUNPROC) (GLubyte factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUSSUNPROC) (GLushort factor); -typedef void (APIENTRYP PFNGLGLOBALALPHAFACTORUISUNPROC) (GLuint factor); -#endif - -#ifndef GL_SUN_triangle_list -#define GL_SUN_triangle_list 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glReplacementCodeuiSUN (GLuint code); -GLAPI void APIENTRY glReplacementCodeusSUN (GLushort code); -GLAPI void APIENTRY glReplacementCodeubSUN (GLubyte code); -GLAPI void APIENTRY glReplacementCodeuivSUN (const GLuint *code); -GLAPI void APIENTRY glReplacementCodeusvSUN (const GLushort *code); -GLAPI void APIENTRY glReplacementCodeubvSUN (const GLubyte *code); -GLAPI void APIENTRY glReplacementCodePointerSUN (GLenum type, GLsizei stride, const GLvoid* *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUISUNPROC) (GLuint code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSSUNPROC) (GLushort code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBSUNPROC) (GLubyte code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVSUNPROC) (const GLuint *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUSVSUNPROC) (const GLushort *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUBVSUNPROC) (const GLubyte *code); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEPOINTERSUNPROC) (GLenum type, GLsizei stride, const GLvoid* *pointer); -#endif - -#ifndef GL_SUN_vertex -#define GL_SUN_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColor4ubVertex2fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -GLAPI void APIENTRY glColor4ubVertex2fvSUN (const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glColor4ubVertex3fSUN (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor4ubVertex3fvSUN (const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glColor3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor3fVertex3fvSUN (const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glNormal3fVertex3fSUN (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glNormal3fVertex3fvSUN (const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glColor4fNormal3fVertex3fSUN (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glColor4fNormal3fVertex3fvSUN (const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fVertex3fSUN (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fVertex3fvSUN (const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glTexCoord4fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glTexCoord4fVertex4fvSUN (const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fSUN (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor4ubVertex3fvSUN (const GLfloat *tc, const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fSUN (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glTexCoord2fColor4fNormal3fVertex3fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fSUN (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glTexCoord4fColor4fNormal3fVertex4fvSUN (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiVertex3fSUN (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiVertex3fvSUN (const GLuint *rc, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fSUN (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor4ubVertex3fvSUN (const GLuint *rc, const GLubyte *c, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fSUN (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX2FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FSUNPROC) (GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4UBVERTEX3FVSUNPROC) (const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FSUNPROC) (GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4UBVERTEX3FVSUNPROC) (const GLfloat *tc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLTEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FSUNPROC) (GLfloat s, GLfloat t, GLfloat p, GLfloat q, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLTEXCOORD4FCOLOR4FNORMAL3FVERTEX4FVSUNPROC) (const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FSUNPROC) (GLuint rc, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUIVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FSUNPROC) (GLuint rc, GLubyte r, GLubyte g, GLubyte b, GLubyte a, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4UBVERTEX3FVSUNPROC) (const GLuint *rc, const GLubyte *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUINORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUICOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *n, const GLfloat *v); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FSUNPROC) (GLuint rc, GLfloat s, GLfloat t, GLfloat r, GLfloat g, GLfloat b, GLfloat a, GLfloat nx, GLfloat ny, GLfloat nz, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLREPLACEMENTCODEUITEXCOORD2FCOLOR4FNORMAL3FVERTEX3FVSUNPROC) (const GLuint *rc, const GLfloat *tc, const GLfloat *c, const GLfloat *n, const GLfloat *v); -#endif - -#ifndef GL_EXT_blend_func_separate -#define GL_EXT_blend_func_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateEXT (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEEXTPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif - -#ifndef GL_INGR_blend_func_separate -#define GL_INGR_blend_func_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncSeparateINGR (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINGRPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -#endif - -#ifndef GL_INGR_color_clamp -#define GL_INGR_color_clamp 1 -#endif - -#ifndef GL_INGR_interlace_read -#define GL_INGR_interlace_read 1 -#endif - -#ifndef GL_EXT_stencil_wrap -#define GL_EXT_stencil_wrap 1 -#endif - -#ifndef GL_EXT_422_pixels -#define GL_EXT_422_pixels 1 -#endif - -#ifndef GL_NV_texgen_reflection -#define GL_NV_texgen_reflection 1 -#endif - -#ifndef GL_SUN_convolution_border_modes -#define GL_SUN_convolution_border_modes 1 -#endif - -#ifndef GL_EXT_texture_env_add -#define GL_EXT_texture_env_add 1 -#endif - -#ifndef GL_EXT_texture_lod_bias -#define GL_EXT_texture_lod_bias 1 -#endif - -#ifndef GL_EXT_texture_filter_anisotropic -#define GL_EXT_texture_filter_anisotropic 1 -#endif - -#ifndef GL_EXT_vertex_weighting -#define GL_EXT_vertex_weighting 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexWeightfEXT (GLfloat weight); -GLAPI void APIENTRY glVertexWeightfvEXT (const GLfloat *weight); -GLAPI void APIENTRY glVertexWeightPointerEXT (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFEXTPROC) (GLfloat weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTFVEXTPROC) (const GLfloat *weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTPOINTEREXTPROC) (GLsizei size, GLenum type, GLsizei stride, const GLvoid *pointer); -#endif - -#ifndef GL_NV_light_max_exponent -#define GL_NV_light_max_exponent 1 -#endif - -#ifndef GL_NV_vertex_array_range -#define GL_NV_vertex_array_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFlushVertexArrayRangeNV (void); -GLAPI void APIENTRY glVertexArrayRangeNV (GLsizei length, const GLvoid *pointer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGENVPROC) (void); -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGENVPROC) (GLsizei length, const GLvoid *pointer); -#endif - -#ifndef GL_NV_register_combiners -#define GL_NV_register_combiners 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerParameterfvNV (GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glCombinerParameterfNV (GLenum pname, GLfloat param); -GLAPI void APIENTRY glCombinerParameterivNV (GLenum pname, const GLint *params); -GLAPI void APIENTRY glCombinerParameteriNV (GLenum pname, GLint param); -GLAPI void APIENTRY glCombinerInputNV (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -GLAPI void APIENTRY glCombinerOutputNV (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -GLAPI void APIENTRY glFinalCombinerInputNV (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -GLAPI void APIENTRY glGetCombinerInputParameterfvNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetCombinerInputParameterivNV (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetCombinerOutputParameterfvNV (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetCombinerOutputParameterivNV (GLenum stage, GLenum portion, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetFinalCombinerInputParameterfvNV (GLenum variable, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetFinalCombinerInputParameterivNV (GLenum variable, GLenum pname, GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFVNVPROC) (GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERFNVPROC) (GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLCOMBINERPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLCOMBINERINPUTNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLCOMBINEROUTPUTNVPROC) (GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); -typedef void (APIENTRYP PFNGLFINALCOMBINERINPUTNVPROC) (GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERINPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERFVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINEROUTPUTPARAMETERIVNVPROC) (GLenum stage, GLenum portion, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERFVNVPROC) (GLenum variable, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETFINALCOMBINERINPUTPARAMETERIVNVPROC) (GLenum variable, GLenum pname, GLint *params); -#endif - -#ifndef GL_NV_fog_distance -#define GL_NV_fog_distance 1 -#endif - -#ifndef GL_NV_texgen_emboss -#define GL_NV_texgen_emboss 1 -#endif - -#ifndef GL_NV_blend_square -#define GL_NV_blend_square 1 -#endif - -#ifndef GL_NV_texture_env_combine4 -#define GL_NV_texture_env_combine4 1 -#endif - -#ifndef GL_MESA_resize_buffers -#define GL_MESA_resize_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glResizeBuffersMESA (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRESIZEBUFFERSMESAPROC) (void); -#endif - -#ifndef GL_MESA_window_pos -#define GL_MESA_window_pos 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glWindowPos2dMESA (GLdouble x, GLdouble y); -GLAPI void APIENTRY glWindowPos2dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos2fMESA (GLfloat x, GLfloat y); -GLAPI void APIENTRY glWindowPos2fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos2iMESA (GLint x, GLint y); -GLAPI void APIENTRY glWindowPos2ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos2sMESA (GLshort x, GLshort y); -GLAPI void APIENTRY glWindowPos2svMESA (const GLshort *v); -GLAPI void APIENTRY glWindowPos3dMESA (GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glWindowPos3dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos3fMESA (GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glWindowPos3fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos3iMESA (GLint x, GLint y, GLint z); -GLAPI void APIENTRY glWindowPos3ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos3sMESA (GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glWindowPos3svMESA (const GLshort *v); -GLAPI void APIENTRY glWindowPos4dMESA (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glWindowPos4dvMESA (const GLdouble *v); -GLAPI void APIENTRY glWindowPos4fMESA (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glWindowPos4fvMESA (const GLfloat *v); -GLAPI void APIENTRY glWindowPos4iMESA (GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glWindowPos4ivMESA (const GLint *v); -GLAPI void APIENTRY glWindowPos4sMESA (GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glWindowPos4svMESA (const GLshort *v); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLWINDOWPOS2DMESAPROC) (GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLWINDOWPOS2DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2FMESAPROC) (GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLWINDOWPOS2FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2IMESAPROC) (GLint x, GLint y); -typedef void (APIENTRYP PFNGLWINDOWPOS2IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS2SMESAPROC) (GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLWINDOWPOS2SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3DMESAPROC) (GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLWINDOWPOS3DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3FMESAPROC) (GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLWINDOWPOS3FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3IMESAPROC) (GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLWINDOWPOS3IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS3SMESAPROC) (GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLWINDOWPOS3SVMESAPROC) (const GLshort *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4DMESAPROC) (GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLWINDOWPOS4DVMESAPROC) (const GLdouble *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4FMESAPROC) (GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLWINDOWPOS4FVMESAPROC) (const GLfloat *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4IMESAPROC) (GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLWINDOWPOS4IVMESAPROC) (const GLint *v); -typedef void (APIENTRYP PFNGLWINDOWPOS4SMESAPROC) (GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLWINDOWPOS4SVMESAPROC) (const GLshort *v); -#endif - -#ifndef GL_IBM_cull_vertex -#define GL_IBM_cull_vertex 1 -#endif - -#ifndef GL_IBM_multimode_draw_arrays -#define GL_IBM_multimode_draw_arrays 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMultiModeDrawArraysIBM (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -GLAPI void APIENTRY glMultiModeDrawElementsIBM (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMULTIMODEDRAWARRAYSIBMPROC) (const GLenum *mode, const GLint *first, const GLsizei *count, GLsizei primcount, GLint modestride); -typedef void (APIENTRYP PFNGLMULTIMODEDRAWELEMENTSIBMPROC) (const GLenum *mode, const GLsizei *count, GLenum type, const GLvoid* const *indices, GLsizei primcount, GLint modestride); -#endif - -#ifndef GL_IBM_vertex_array_lists -#define GL_IBM_vertex_array_lists 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -GLAPI void APIENTRY glSecondaryColorPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -GLAPI void APIENTRY glEdgeFlagPointerListIBM (GLint stride, const GLboolean* *pointer, GLint ptrstride); -GLAPI void APIENTRY glFogCoordPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -GLAPI void APIENTRY glIndexPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -GLAPI void APIENTRY glNormalPointerListIBM (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -GLAPI void APIENTRY glTexCoordPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -GLAPI void APIENTRY glVertexPointerListIBM (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLSECONDARYCOLORPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLEDGEFLAGPOINTERLISTIBMPROC) (GLint stride, const GLboolean* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLFOGCOORDPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLINDEXPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLNORMALPOINTERLISTIBMPROC) (GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLTEXCOORDPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -typedef void (APIENTRYP PFNGLVERTEXPOINTERLISTIBMPROC) (GLint size, GLenum type, GLint stride, const GLvoid* *pointer, GLint ptrstride); -#endif - -#ifndef GL_SGIX_subsample -#define GL_SGIX_subsample 1 -#endif - -#ifndef GL_SGIX_ycrcba -#define GL_SGIX_ycrcba 1 -#endif - -#ifndef GL_SGIX_ycrcb_subsample -#define GL_SGIX_ycrcb_subsample 1 -#endif - -#ifndef GL_SGIX_depth_pass_instrument -#define GL_SGIX_depth_pass_instrument 1 -#endif - -#ifndef GL_3DFX_texture_compression_FXT1 -#define GL_3DFX_texture_compression_FXT1 1 -#endif - -#ifndef GL_3DFX_multisample -#define GL_3DFX_multisample 1 -#endif - -#ifndef GL_3DFX_tbuffer -#define GL_3DFX_tbuffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTbufferMask3DFX (GLuint mask); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTBUFFERMASK3DFXPROC) (GLuint mask); -#endif - -#ifndef GL_EXT_multisample -#define GL_EXT_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glSampleMaskEXT (GLclampf value, GLboolean invert); -GLAPI void APIENTRY glSamplePatternEXT (GLenum pattern); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSAMPLEMASKEXTPROC) (GLclampf value, GLboolean invert); -typedef void (APIENTRYP PFNGLSAMPLEPATTERNEXTPROC) (GLenum pattern); -#endif - -#ifndef GL_SGIX_vertex_preclip -#define GL_SGIX_vertex_preclip 1 -#endif - -#ifndef GL_SGIX_convolution_accuracy -#define GL_SGIX_convolution_accuracy 1 -#endif - -#ifndef GL_SGIX_resample -#define GL_SGIX_resample 1 -#endif - -#ifndef GL_SGIS_point_line_texgen -#define GL_SGIS_point_line_texgen 1 -#endif - -#ifndef GL_SGIS_texture_color_mask -#define GL_SGIS_texture_color_mask 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureColorMaskSGIS (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -#endif - -#ifndef GL_SGIX_igloo_interface -#define GL_SGIX_igloo_interface 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glIglooInterfaceSGIX (GLenum pname, const GLvoid *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLIGLOOINTERFACESGIXPROC) (GLenum pname, const GLvoid *params); -#endif - -#ifndef GL_EXT_texture_env_dot3 -#define GL_EXT_texture_env_dot3 1 -#endif - -#ifndef GL_ATI_texture_mirror_once -#define GL_ATI_texture_mirror_once 1 -#endif - -#ifndef GL_NV_fence -#define GL_NV_fence 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDeleteFencesNV (GLsizei n, const GLuint *fences); -GLAPI void APIENTRY glGenFencesNV (GLsizei n, GLuint *fences); -GLAPI GLboolean APIENTRY glIsFenceNV (GLuint fence); -GLAPI GLboolean APIENTRY glTestFenceNV (GLuint fence); -GLAPI void APIENTRY glGetFenceivNV (GLuint fence, GLenum pname, GLint *params); -GLAPI void APIENTRY glFinishFenceNV (GLuint fence); -GLAPI void APIENTRY glSetFenceNV (GLuint fence, GLenum condition); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDELETEFENCESNVPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLGENFENCESNVPROC) (GLsizei n, GLuint *fences); -typedef GLboolean (APIENTRYP PFNGLISFENCENVPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLGETFENCEIVNVPROC) (GLuint fence, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFINISHFENCENVPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLSETFENCENVPROC) (GLuint fence, GLenum condition); -#endif - -#ifndef GL_NV_evaluators -#define GL_NV_evaluators 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); -GLAPI void APIENTRY glMapParameterivNV (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMapParameterfvNV (GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetMapControlPointsNV (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); -GLAPI void APIENTRY glGetMapParameterivNV (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMapParameterfvNV (GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMapAttribParameterivNV (GLenum target, GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMapAttribParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glEvalMapsNV (GLenum target, GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLint uorder, GLint vorder, GLboolean packed, const GLvoid *points); -typedef void (APIENTRYP PFNGLMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPCONTROLPOINTSNVPROC) (GLenum target, GLuint index, GLenum type, GLsizei ustride, GLsizei vstride, GLboolean packed, GLvoid *points); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERIVNVPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPPARAMETERFVNVPROC) (GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERIVNVPROC) (GLenum target, GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMAPATTRIBPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLEVALMAPSNVPROC) (GLenum target, GLenum mode); -#endif - -#ifndef GL_NV_packed_depth_stencil -#define GL_NV_packed_depth_stencil 1 -#endif - -#ifndef GL_NV_register_combiners2 -#define GL_NV_register_combiners2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCombinerStageParameterfvNV (GLenum stage, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glGetCombinerStageParameterfvNV (GLenum stage, GLenum pname, GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETCOMBINERSTAGEPARAMETERFVNVPROC) (GLenum stage, GLenum pname, GLfloat *params); -#endif - -#ifndef GL_NV_texture_compression_vtc -#define GL_NV_texture_compression_vtc 1 -#endif - -#ifndef GL_NV_texture_rectangle -#define GL_NV_texture_rectangle 1 -#endif - -#ifndef GL_NV_texture_shader -#define GL_NV_texture_shader 1 -#endif - -#ifndef GL_NV_texture_shader2 -#define GL_NV_texture_shader2 1 -#endif - -#ifndef GL_NV_vertex_array_range2 -#define GL_NV_vertex_array_range2 1 -#endif - -#ifndef GL_NV_vertex_program -#define GL_NV_vertex_program 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glAreProgramsResidentNV (GLsizei n, const GLuint *programs, GLboolean *residences); -GLAPI void APIENTRY glBindProgramNV (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteProgramsNV (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glExecuteProgramNV (GLenum target, GLuint id, const GLfloat *params); -GLAPI void APIENTRY glGenProgramsNV (GLsizei n, GLuint *programs); -GLAPI void APIENTRY glGetProgramParameterdvNV (GLenum target, GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetProgramParameterfvNV (GLenum target, GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetProgramivNV (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetProgramStringNV (GLuint id, GLenum pname, GLubyte *program); -GLAPI void APIENTRY glGetTrackMatrixivNV (GLenum target, GLuint address, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribdvNV (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetVertexAttribfvNV (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribivNV (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribPointervNV (GLuint index, GLenum pname, GLvoid* *pointer); -GLAPI GLboolean APIENTRY glIsProgramNV (GLuint id); -GLAPI void APIENTRY glLoadProgramNV (GLenum target, GLuint id, GLsizei len, const GLubyte *program); -GLAPI void APIENTRY glProgramParameter4dNV (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramParameter4dvNV (GLenum target, GLuint index, const GLdouble *v); -GLAPI void APIENTRY glProgramParameter4fNV (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramParameter4fvNV (GLenum target, GLuint index, const GLfloat *v); -GLAPI void APIENTRY glProgramParameters4dvNV (GLenum target, GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glProgramParameters4fvNV (GLenum target, GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glRequestResidentProgramsNV (GLsizei n, const GLuint *programs); -GLAPI void APIENTRY glTrackMatrixNV (GLenum target, GLuint address, GLenum matrix, GLenum transform); -GLAPI void APIENTRY glVertexAttribPointerNV (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glVertexAttrib1dNV (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttrib1dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib1fNV (GLuint index, GLfloat x); -GLAPI void APIENTRY glVertexAttrib1fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib1sNV (GLuint index, GLshort x); -GLAPI void APIENTRY glVertexAttrib1svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib2dNV (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttrib2dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib2fNV (GLuint index, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexAttrib2fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib2sNV (GLuint index, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexAttrib2svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib3dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttrib3dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib3fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexAttrib3fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib3sNV (GLuint index, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexAttrib3svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4dNV (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttrib4dvNV (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttrib4fNV (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexAttrib4fvNV (GLuint index, const GLfloat *v); -GLAPI void APIENTRY glVertexAttrib4sNV (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexAttrib4svNV (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttrib4ubNV (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -GLAPI void APIENTRY glVertexAttrib4ubvNV (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribs1dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs1fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs1svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs2dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs2fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs2svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs3dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs3fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs3svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs4dvNV (GLuint index, GLsizei count, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribs4fvNV (GLuint index, GLsizei count, const GLfloat *v); -GLAPI void APIENTRY glVertexAttribs4svNV (GLuint index, GLsizei count, const GLshort *v); -GLAPI void APIENTRY glVertexAttribs4ubvNV (GLuint index, GLsizei count, const GLubyte *v); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLAREPROGRAMSRESIDENTNVPROC) (GLsizei n, const GLuint *programs, GLboolean *residences); -typedef void (APIENTRYP PFNGLBINDPROGRAMNVPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETEPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLEXECUTEPROGRAMNVPROC) (GLenum target, GLuint id, const GLfloat *params); -typedef void (APIENTRYP PFNGLGENPROGRAMSNVPROC) (GLsizei n, GLuint *programs); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERDVNVPROC) (GLenum target, GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETPROGRAMPARAMETERFVNVPROC) (GLenum target, GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSTRINGNVPROC) (GLuint id, GLenum pname, GLubyte *program); -typedef void (APIENTRYP PFNGLGETTRACKMATRIXIVNVPROC) (GLenum target, GLuint address, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBDVNVPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBFVNVPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIVNVPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBPOINTERVNVPROC) (GLuint index, GLenum pname, GLvoid* *pointer); -typedef GLboolean (APIENTRYP PFNGLISPROGRAMNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLLOADPROGRAMNVPROC) (GLenum target, GLuint id, GLsizei len, const GLubyte *program); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DNVPROC) (GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4DVNVPROC) (GLenum target, GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FNVPROC) (GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETER4FVNVPROC) (GLenum target, GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4DVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERS4FVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLREQUESTRESIDENTPROGRAMSNVPROC) (GLsizei n, const GLuint *programs); -typedef void (APIENTRYP PFNGLTRACKMATRIXNVPROC) (GLenum target, GLuint address, GLenum matrix, GLenum transform); -typedef void (APIENTRYP PFNGLVERTEXATTRIBPOINTERNVPROC) (GLuint index, GLint fsize, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DNVPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FNVPROC) (GLuint index, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SNVPROC) (GLuint index, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DNVPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FNVPROC) (GLuint index, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SNVPROC) (GLuint index, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DNVPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4DVNVPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FNVPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4FVNVPROC) (GLuint index, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SNVPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4SVNVPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBNVPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4UBVNVPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4DVNVPROC) (GLuint index, GLsizei count, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4FVNVPROC) (GLuint index, GLsizei count, const GLfloat *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4SVNVPROC) (GLuint index, GLsizei count, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4UBVNVPROC) (GLuint index, GLsizei count, const GLubyte *v); -#endif - -#ifndef GL_SGIX_texture_coordinate_clamp -#define GL_SGIX_texture_coordinate_clamp 1 -#endif - -#ifndef GL_SGIX_scalebias_hint -#define GL_SGIX_scalebias_hint 1 -#endif - -#ifndef GL_OML_interlace -#define GL_OML_interlace 1 -#endif - -#ifndef GL_OML_subsample -#define GL_OML_subsample 1 -#endif - -#ifndef GL_OML_resample -#define GL_OML_resample 1 -#endif - -#ifndef GL_NV_copy_depth_to_color -#define GL_NV_copy_depth_to_color 1 -#endif - -#ifndef GL_ATI_envmap_bumpmap -#define GL_ATI_envmap_bumpmap 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBumpParameterivATI (GLenum pname, const GLint *param); -GLAPI void APIENTRY glTexBumpParameterfvATI (GLenum pname, const GLfloat *param); -GLAPI void APIENTRY glGetTexBumpParameterivATI (GLenum pname, GLint *param); -GLAPI void APIENTRY glGetTexBumpParameterfvATI (GLenum pname, GLfloat *param); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERIVATIPROC) (GLenum pname, const GLint *param); -typedef void (APIENTRYP PFNGLTEXBUMPPARAMETERFVATIPROC) (GLenum pname, const GLfloat *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERIVATIPROC) (GLenum pname, GLint *param); -typedef void (APIENTRYP PFNGLGETTEXBUMPPARAMETERFVATIPROC) (GLenum pname, GLfloat *param); -#endif - -#ifndef GL_ATI_fragment_shader -#define GL_ATI_fragment_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glGenFragmentShadersATI (GLuint range); -GLAPI void APIENTRY glBindFragmentShaderATI (GLuint id); -GLAPI void APIENTRY glDeleteFragmentShaderATI (GLuint id); -GLAPI void APIENTRY glBeginFragmentShaderATI (void); -GLAPI void APIENTRY glEndFragmentShaderATI (void); -GLAPI void APIENTRY glPassTexCoordATI (GLuint dst, GLuint coord, GLenum swizzle); -GLAPI void APIENTRY glSampleMapATI (GLuint dst, GLuint interp, GLenum swizzle); -GLAPI void APIENTRY glColorFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -GLAPI void APIENTRY glColorFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -GLAPI void APIENTRY glColorFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -GLAPI void APIENTRY glAlphaFragmentOp1ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -GLAPI void APIENTRY glAlphaFragmentOp2ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -GLAPI void APIENTRY glAlphaFragmentOp3ATI (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -GLAPI void APIENTRY glSetFragmentShaderConstantATI (GLuint dst, const GLfloat *value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLuint (APIENTRYP PFNGLGENFRAGMENTSHADERSATIPROC) (GLuint range); -typedef void (APIENTRYP PFNGLBINDFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDELETEFRAGMENTSHADERATIPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLENDFRAGMENTSHADERATIPROC) (void); -typedef void (APIENTRYP PFNGLPASSTEXCOORDATIPROC) (GLuint dst, GLuint coord, GLenum swizzle); -typedef void (APIENTRYP PFNGLSAMPLEMAPATIPROC) (GLuint dst, GLuint interp, GLenum swizzle); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLCOLORFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP1ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP2ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); -typedef void (APIENTRYP PFNGLALPHAFRAGMENTOP3ATIPROC) (GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); -typedef void (APIENTRYP PFNGLSETFRAGMENTSHADERCONSTANTATIPROC) (GLuint dst, const GLfloat *value); -#endif - -#ifndef GL_ATI_pn_triangles -#define GL_ATI_pn_triangles 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPNTrianglesiATI (GLenum pname, GLint param); -GLAPI void APIENTRY glPNTrianglesfATI (GLenum pname, GLfloat param); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPNTRIANGLESIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPNTRIANGLESFATIPROC) (GLenum pname, GLfloat param); -#endif - -#ifndef GL_ATI_vertex_array_object -#define GL_ATI_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLuint APIENTRY glNewObjectBufferATI (GLsizei size, const GLvoid *pointer, GLenum usage); -GLAPI GLboolean APIENTRY glIsObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glUpdateObjectBufferATI (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); -GLAPI void APIENTRY glGetObjectBufferfvATI (GLuint buffer, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetObjectBufferivATI (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glFreeObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glArrayObjectATI (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetArrayObjectfvATI (GLenum array, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetArrayObjectivATI (GLenum array, GLenum pname, GLint *params); -GLAPI void APIENTRY glVariantArrayObjectATI (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetVariantArrayObjectfvATI (GLuint id, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVariantArrayObjectivATI (GLuint id, GLenum pname, GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLuint (APIENTRYP PFNGLNEWOBJECTBUFFERATIPROC) (GLsizei size, const GLvoid *pointer, GLenum usage); -typedef GLboolean (APIENTRYP PFNGLISOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUPDATEOBJECTBUFFERATIPROC) (GLuint buffer, GLuint offset, GLsizei size, const GLvoid *pointer, GLenum preserve); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERFVATIPROC) (GLuint buffer, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETOBJECTBUFFERIVATIPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLFREEOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLARRAYOBJECTATIPROC) (GLenum array, GLint size, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTFVATIPROC) (GLenum array, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETARRAYOBJECTIVATIPROC) (GLenum array, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLVARIANTARRAYOBJECTATIPROC) (GLuint id, GLenum type, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTFVATIPROC) (GLuint id, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVARIANTARRAYOBJECTIVATIPROC) (GLuint id, GLenum pname, GLint *params); -#endif - -#ifndef GL_EXT_vertex_shader -#define GL_EXT_vertex_shader 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginVertexShaderEXT (void); -GLAPI void APIENTRY glEndVertexShaderEXT (void); -GLAPI void APIENTRY glBindVertexShaderEXT (GLuint id); -GLAPI GLuint APIENTRY glGenVertexShadersEXT (GLuint range); -GLAPI void APIENTRY glDeleteVertexShaderEXT (GLuint id); -GLAPI void APIENTRY glShaderOp1EXT (GLenum op, GLuint res, GLuint arg1); -GLAPI void APIENTRY glShaderOp2EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -GLAPI void APIENTRY glShaderOp3EXT (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -GLAPI void APIENTRY glSwizzleEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -GLAPI void APIENTRY glWriteMaskEXT (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -GLAPI void APIENTRY glInsertComponentEXT (GLuint res, GLuint src, GLuint num); -GLAPI void APIENTRY glExtractComponentEXT (GLuint res, GLuint src, GLuint num); -GLAPI GLuint APIENTRY glGenSymbolsEXT (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); -GLAPI void APIENTRY glSetInvariantEXT (GLuint id, GLenum type, const GLvoid *addr); -GLAPI void APIENTRY glSetLocalConstantEXT (GLuint id, GLenum type, const GLvoid *addr); -GLAPI void APIENTRY glVariantbvEXT (GLuint id, const GLbyte *addr); -GLAPI void APIENTRY glVariantsvEXT (GLuint id, const GLshort *addr); -GLAPI void APIENTRY glVariantivEXT (GLuint id, const GLint *addr); -GLAPI void APIENTRY glVariantfvEXT (GLuint id, const GLfloat *addr); -GLAPI void APIENTRY glVariantdvEXT (GLuint id, const GLdouble *addr); -GLAPI void APIENTRY glVariantubvEXT (GLuint id, const GLubyte *addr); -GLAPI void APIENTRY glVariantusvEXT (GLuint id, const GLushort *addr); -GLAPI void APIENTRY glVariantuivEXT (GLuint id, const GLuint *addr); -GLAPI void APIENTRY glVariantPointerEXT (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); -GLAPI void APIENTRY glEnableVariantClientStateEXT (GLuint id); -GLAPI void APIENTRY glDisableVariantClientStateEXT (GLuint id); -GLAPI GLuint APIENTRY glBindLightParameterEXT (GLenum light, GLenum value); -GLAPI GLuint APIENTRY glBindMaterialParameterEXT (GLenum face, GLenum value); -GLAPI GLuint APIENTRY glBindTexGenParameterEXT (GLenum unit, GLenum coord, GLenum value); -GLAPI GLuint APIENTRY glBindTextureUnitParameterEXT (GLenum unit, GLenum value); -GLAPI GLuint APIENTRY glBindParameterEXT (GLenum value); -GLAPI GLboolean APIENTRY glIsVariantEnabledEXT (GLuint id, GLenum cap); -GLAPI void APIENTRY glGetVariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetVariantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetVariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -GLAPI void APIENTRY glGetVariantPointervEXT (GLuint id, GLenum value, GLvoid* *data); -GLAPI void APIENTRY glGetInvariantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetInvariantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetInvariantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -GLAPI void APIENTRY glGetLocalConstantBooleanvEXT (GLuint id, GLenum value, GLboolean *data); -GLAPI void APIENTRY glGetLocalConstantIntegervEXT (GLuint id, GLenum value, GLint *data); -GLAPI void APIENTRY glGetLocalConstantFloatvEXT (GLuint id, GLenum value, GLfloat *data); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLENDVERTEXSHADEREXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDVERTEXSHADEREXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLGENVERTEXSHADERSEXTPROC) (GLuint range); -typedef void (APIENTRYP PFNGLDELETEVERTEXSHADEREXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLSHADEROP1EXTPROC) (GLenum op, GLuint res, GLuint arg1); -typedef void (APIENTRYP PFNGLSHADEROP2EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2); -typedef void (APIENTRYP PFNGLSHADEROP3EXTPROC) (GLenum op, GLuint res, GLuint arg1, GLuint arg2, GLuint arg3); -typedef void (APIENTRYP PFNGLSWIZZLEEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLWRITEMASKEXTPROC) (GLuint res, GLuint in, GLenum outX, GLenum outY, GLenum outZ, GLenum outW); -typedef void (APIENTRYP PFNGLINSERTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef void (APIENTRYP PFNGLEXTRACTCOMPONENTEXTPROC) (GLuint res, GLuint src, GLuint num); -typedef GLuint (APIENTRYP PFNGLGENSYMBOLSEXTPROC) (GLenum datatype, GLenum storagetype, GLenum range, GLuint components); -typedef void (APIENTRYP PFNGLSETINVARIANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); -typedef void (APIENTRYP PFNGLSETLOCALCONSTANTEXTPROC) (GLuint id, GLenum type, const GLvoid *addr); -typedef void (APIENTRYP PFNGLVARIANTBVEXTPROC) (GLuint id, const GLbyte *addr); -typedef void (APIENTRYP PFNGLVARIANTSVEXTPROC) (GLuint id, const GLshort *addr); -typedef void (APIENTRYP PFNGLVARIANTIVEXTPROC) (GLuint id, const GLint *addr); -typedef void (APIENTRYP PFNGLVARIANTFVEXTPROC) (GLuint id, const GLfloat *addr); -typedef void (APIENTRYP PFNGLVARIANTDVEXTPROC) (GLuint id, const GLdouble *addr); -typedef void (APIENTRYP PFNGLVARIANTUBVEXTPROC) (GLuint id, const GLubyte *addr); -typedef void (APIENTRYP PFNGLVARIANTUSVEXTPROC) (GLuint id, const GLushort *addr); -typedef void (APIENTRYP PFNGLVARIANTUIVEXTPROC) (GLuint id, const GLuint *addr); -typedef void (APIENTRYP PFNGLVARIANTPOINTEREXTPROC) (GLuint id, GLenum type, GLuint stride, const GLvoid *addr); -typedef void (APIENTRYP PFNGLENABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef void (APIENTRYP PFNGLDISABLEVARIANTCLIENTSTATEEXTPROC) (GLuint id); -typedef GLuint (APIENTRYP PFNGLBINDLIGHTPARAMETEREXTPROC) (GLenum light, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDMATERIALPARAMETEREXTPROC) (GLenum face, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXGENPARAMETEREXTPROC) (GLenum unit, GLenum coord, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDTEXTUREUNITPARAMETEREXTPROC) (GLenum unit, GLenum value); -typedef GLuint (APIENTRYP PFNGLBINDPARAMETEREXTPROC) (GLenum value); -typedef GLboolean (APIENTRYP PFNGLISVARIANTENABLEDEXTPROC) (GLuint id, GLenum cap); -typedef void (APIENTRYP PFNGLGETVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETVARIANTPOINTERVEXTPROC) (GLuint id, GLenum value, GLvoid* *data); -typedef void (APIENTRYP PFNGLGETINVARIANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINVARIANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETINVARIANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTBOOLEANVEXTPROC) (GLuint id, GLenum value, GLboolean *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTINTEGERVEXTPROC) (GLuint id, GLenum value, GLint *data); -typedef void (APIENTRYP PFNGLGETLOCALCONSTANTFLOATVEXTPROC) (GLuint id, GLenum value, GLfloat *data); -#endif - -#ifndef GL_ATI_vertex_streams -#define GL_ATI_vertex_streams 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexStream1sATI (GLenum stream, GLshort x); -GLAPI void APIENTRY glVertexStream1svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream1iATI (GLenum stream, GLint x); -GLAPI void APIENTRY glVertexStream1ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream1fATI (GLenum stream, GLfloat x); -GLAPI void APIENTRY glVertexStream1fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream1dATI (GLenum stream, GLdouble x); -GLAPI void APIENTRY glVertexStream1dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream2sATI (GLenum stream, GLshort x, GLshort y); -GLAPI void APIENTRY glVertexStream2svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream2iATI (GLenum stream, GLint x, GLint y); -GLAPI void APIENTRY glVertexStream2ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream2fATI (GLenum stream, GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertexStream2fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream2dATI (GLenum stream, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexStream2dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream3sATI (GLenum stream, GLshort x, GLshort y, GLshort z); -GLAPI void APIENTRY glVertexStream3svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream3iATI (GLenum stream, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexStream3ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream3fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glVertexStream3fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream3dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexStream3dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glVertexStream4sATI (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -GLAPI void APIENTRY glVertexStream4svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glVertexStream4iATI (GLenum stream, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexStream4ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glVertexStream4fATI (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glVertexStream4fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glVertexStream4dATI (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexStream4dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glNormalStream3bATI (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); -GLAPI void APIENTRY glNormalStream3bvATI (GLenum stream, const GLbyte *coords); -GLAPI void APIENTRY glNormalStream3sATI (GLenum stream, GLshort nx, GLshort ny, GLshort nz); -GLAPI void APIENTRY glNormalStream3svATI (GLenum stream, const GLshort *coords); -GLAPI void APIENTRY glNormalStream3iATI (GLenum stream, GLint nx, GLint ny, GLint nz); -GLAPI void APIENTRY glNormalStream3ivATI (GLenum stream, const GLint *coords); -GLAPI void APIENTRY glNormalStream3fATI (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); -GLAPI void APIENTRY glNormalStream3fvATI (GLenum stream, const GLfloat *coords); -GLAPI void APIENTRY glNormalStream3dATI (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); -GLAPI void APIENTRY glNormalStream3dvATI (GLenum stream, const GLdouble *coords); -GLAPI void APIENTRY glClientActiveVertexStreamATI (GLenum stream); -GLAPI void APIENTRY glVertexBlendEnviATI (GLenum pname, GLint param); -GLAPI void APIENTRY glVertexBlendEnvfATI (GLenum pname, GLfloat param); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SATIPROC) (GLenum stream, GLshort x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IATIPROC) (GLenum stream, GLint x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FATIPROC) (GLenum stream, GLfloat x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DATIPROC) (GLenum stream, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXSTREAM1DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SATIPROC) (GLenum stream, GLshort x, GLshort y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IATIPROC) (GLenum stream, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FATIPROC) (GLenum stream, GLfloat x, GLfloat y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DATIPROC) (GLenum stream, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXSTREAM2DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IATIPROC) (GLenum stream, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SATIPROC) (GLenum stream, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IATIPROC) (GLenum stream, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FATIPROC) (GLenum stream, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DATIPROC) (GLenum stream, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXSTREAM4DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BATIPROC) (GLenum stream, GLbyte nx, GLbyte ny, GLbyte nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3BVATIPROC) (GLenum stream, const GLbyte *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SATIPROC) (GLenum stream, GLshort nx, GLshort ny, GLshort nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3SVATIPROC) (GLenum stream, const GLshort *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IATIPROC) (GLenum stream, GLint nx, GLint ny, GLint nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3IVATIPROC) (GLenum stream, const GLint *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FATIPROC) (GLenum stream, GLfloat nx, GLfloat ny, GLfloat nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3FVATIPROC) (GLenum stream, const GLfloat *coords); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DATIPROC) (GLenum stream, GLdouble nx, GLdouble ny, GLdouble nz); -typedef void (APIENTRYP PFNGLNORMALSTREAM3DVATIPROC) (GLenum stream, const GLdouble *coords); -typedef void (APIENTRYP PFNGLCLIENTACTIVEVERTEXSTREAMATIPROC) (GLenum stream); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVIATIPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLVERTEXBLENDENVFATIPROC) (GLenum pname, GLfloat param); -#endif - -#ifndef GL_ATI_element_array -#define GL_ATI_element_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerATI (GLenum type, const GLvoid *pointer); -GLAPI void APIENTRY glDrawElementArrayATI (GLenum mode, GLsizei count); -GLAPI void APIENTRY glDrawRangeElementArrayATI (GLenum mode, GLuint start, GLuint end, GLsizei count); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLELEMENTPOINTERATIPROC) (GLenum type, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYATIPROC) (GLenum mode, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYATIPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count); -#endif - -#ifndef GL_SUN_mesh_array -#define GL_SUN_mesh_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawMeshArraysSUN (GLenum mode, GLint first, GLsizei count, GLsizei width); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWMESHARRAYSSUNPROC) (GLenum mode, GLint first, GLsizei count, GLsizei width); -#endif - -#ifndef GL_SUN_slice_accum -#define GL_SUN_slice_accum 1 -#endif - -#ifndef GL_NV_multisample_filter_hint -#define GL_NV_multisample_filter_hint 1 -#endif - -#ifndef GL_NV_depth_clamp -#define GL_NV_depth_clamp 1 -#endif - -#ifndef GL_NV_occlusion_query -#define GL_NV_occlusion_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenOcclusionQueriesNV (GLsizei n, GLuint *ids); -GLAPI void APIENTRY glDeleteOcclusionQueriesNV (GLsizei n, const GLuint *ids); -GLAPI GLboolean APIENTRY glIsOcclusionQueryNV (GLuint id); -GLAPI void APIENTRY glBeginOcclusionQueryNV (GLuint id); -GLAPI void APIENTRY glEndOcclusionQueryNV (void); -GLAPI void APIENTRY glGetOcclusionQueryivNV (GLuint id, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetOcclusionQueryuivNV (GLuint id, GLenum pname, GLuint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENOCCLUSIONQUERIESNVPROC) (GLsizei n, GLuint *ids); -typedef void (APIENTRYP PFNGLDELETEOCCLUSIONQUERIESNVPROC) (GLsizei n, const GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLBEGINOCCLUSIONQUERYNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLENDOCCLUSIONQUERYNVPROC) (void); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYIVNVPROC) (GLuint id, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETOCCLUSIONQUERYUIVNVPROC) (GLuint id, GLenum pname, GLuint *params); -#endif - -#ifndef GL_NV_point_sprite -#define GL_NV_point_sprite 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPointParameteriNV (GLenum pname, GLint param); -GLAPI void APIENTRY glPointParameterivNV (GLenum pname, const GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPOINTPARAMETERINVPROC) (GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLPOINTPARAMETERIVNVPROC) (GLenum pname, const GLint *params); -#endif - -#ifndef GL_NV_texture_shader3 -#define GL_NV_texture_shader3 1 -#endif - -#ifndef GL_NV_vertex_program1_1 -#define GL_NV_vertex_program1_1 1 -#endif - -#ifndef GL_EXT_shadow_funcs -#define GL_EXT_shadow_funcs 1 -#endif - -#ifndef GL_EXT_stencil_two_side -#define GL_EXT_stencil_two_side 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glActiveStencilFaceEXT (GLenum face); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLACTIVESTENCILFACEEXTPROC) (GLenum face); -#endif - -#ifndef GL_ATI_text_fragment_shader -#define GL_ATI_text_fragment_shader 1 -#endif - -#ifndef GL_APPLE_client_storage -#define GL_APPLE_client_storage 1 -#endif - -#ifndef GL_APPLE_element_array -#define GL_APPLE_element_array 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glElementPointerAPPLE (GLenum type, const GLvoid *pointer); -GLAPI void APIENTRY glDrawElementArrayAPPLE (GLenum mode, GLint first, GLsizei count); -GLAPI void APIENTRY glDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -GLAPI void APIENTRY glMultiDrawElementArrayAPPLE (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -GLAPI void APIENTRY glMultiDrawRangeElementArrayAPPLE (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); -typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); -typedef void (APIENTRYP PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); -#endif - -#ifndef GL_APPLE_fence -#define GL_APPLE_fence 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenFencesAPPLE (GLsizei n, GLuint *fences); -GLAPI void APIENTRY glDeleteFencesAPPLE (GLsizei n, const GLuint *fences); -GLAPI void APIENTRY glSetFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glIsFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glTestFenceAPPLE (GLuint fence); -GLAPI void APIENTRY glFinishFenceAPPLE (GLuint fence); -GLAPI GLboolean APIENTRY glTestObjectAPPLE (GLenum object, GLuint name); -GLAPI void APIENTRY glFinishObjectAPPLE (GLenum object, GLint name); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint *fences); -typedef void (APIENTRYP PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint *fences); -typedef void (APIENTRYP PFNGLSETFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLISFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTFENCEAPPLEPROC) (GLuint fence); -typedef void (APIENTRYP PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); -typedef GLboolean (APIENTRYP PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); -typedef void (APIENTRYP PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); -#endif - -#ifndef GL_APPLE_vertex_array_object -#define GL_APPLE_vertex_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindVertexArrayAPPLE (GLuint array); -GLAPI void APIENTRY glDeleteVertexArraysAPPLE (GLsizei n, const GLuint *arrays); -GLAPI void APIENTRY glGenVertexArraysAPPLE (GLsizei n, GLuint *arrays); -GLAPI GLboolean APIENTRY glIsVertexArrayAPPLE (GLuint array); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); -typedef void (APIENTRYP PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint *arrays); -typedef void (APIENTRYP PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, GLuint *arrays); -typedef GLboolean (APIENTRYP PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); -#endif - -#ifndef GL_APPLE_vertex_array_range -#define GL_APPLE_vertex_array_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer); -GLAPI void APIENTRY glFlushVertexArrayRangeAPPLE (GLsizei length, GLvoid *pointer); -GLAPI void APIENTRY glVertexArrayParameteriAPPLE (GLenum pname, GLint param); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); -#endif - -#ifndef GL_APPLE_ycbcr_422 -#define GL_APPLE_ycbcr_422 1 -#endif - -#ifndef GL_S3_s3tc -#define GL_S3_s3tc 1 -#endif - -#ifndef GL_ATI_draw_buffers -#define GL_ATI_draw_buffers 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawBuffersATI (GLsizei n, const GLenum *bufs); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWBUFFERSATIPROC) (GLsizei n, const GLenum *bufs); -#endif - -#ifndef GL_ATI_pixel_format_float -#define GL_ATI_pixel_format_float 1 -/* This is really a WGL extension, but defines some associated GL enums. - * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. - */ -#endif - -#ifndef GL_ATI_texture_env_combine3 -#define GL_ATI_texture_env_combine3 1 -#endif - -#ifndef GL_ATI_texture_float -#define GL_ATI_texture_float 1 -#endif - -#ifndef GL_NV_float_buffer -#define GL_NV_float_buffer 1 -#endif - -#ifndef GL_NV_fragment_program -#define GL_NV_fragment_program 1 -/* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramNamedParameter4fNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glProgramNamedParameter4dNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramNamedParameter4fvNV (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); -GLAPI void APIENTRY glProgramNamedParameter4dvNV (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); -GLAPI void APIENTRY glGetProgramNamedParameterfvNV (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); -GLAPI void APIENTRY glGetProgramNamedParameterdvNV (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4FVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLfloat *v); -typedef void (APIENTRYP PFNGLPROGRAMNAMEDPARAMETER4DVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, const GLdouble *v); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERFVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLfloat *params); -typedef void (APIENTRYP PFNGLGETPROGRAMNAMEDPARAMETERDVNVPROC) (GLuint id, GLsizei len, const GLubyte *name, GLdouble *params); -#endif - -#ifndef GL_NV_half_float -#define GL_NV_half_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertex2hNV (GLhalfNV x, GLhalfNV y); -GLAPI void APIENTRY glVertex2hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertex3hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z); -GLAPI void APIENTRY glVertex3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertex4hNV (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -GLAPI void APIENTRY glVertex4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glNormal3hNV (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); -GLAPI void APIENTRY glNormal3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -GLAPI void APIENTRY glColor3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glColor4hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); -GLAPI void APIENTRY glColor4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord1hNV (GLhalfNV s); -GLAPI void APIENTRY glTexCoord1hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord2hNV (GLhalfNV s, GLhalfNV t); -GLAPI void APIENTRY glTexCoord2hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord3hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r); -GLAPI void APIENTRY glTexCoord3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glTexCoord4hNV (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -GLAPI void APIENTRY glTexCoord4hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord1hNV (GLenum target, GLhalfNV s); -GLAPI void APIENTRY glMultiTexCoord1hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord2hNV (GLenum target, GLhalfNV s, GLhalfNV t); -GLAPI void APIENTRY glMultiTexCoord2hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord3hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); -GLAPI void APIENTRY glMultiTexCoord3hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glMultiTexCoord4hNV (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -GLAPI void APIENTRY glMultiTexCoord4hvNV (GLenum target, const GLhalfNV *v); -GLAPI void APIENTRY glFogCoordhNV (GLhalfNV fog); -GLAPI void APIENTRY glFogCoordhvNV (const GLhalfNV *fog); -GLAPI void APIENTRY glSecondaryColor3hNV (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -GLAPI void APIENTRY glSecondaryColor3hvNV (const GLhalfNV *v); -GLAPI void APIENTRY glVertexWeighthNV (GLhalfNV weight); -GLAPI void APIENTRY glVertexWeighthvNV (const GLhalfNV *weight); -GLAPI void APIENTRY glVertexAttrib1hNV (GLuint index, GLhalfNV x); -GLAPI void APIENTRY glVertexAttrib1hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib2hNV (GLuint index, GLhalfNV x, GLhalfNV y); -GLAPI void APIENTRY glVertexAttrib2hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib3hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); -GLAPI void APIENTRY glVertexAttrib3hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttrib4hNV (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -GLAPI void APIENTRY glVertexAttrib4hvNV (GLuint index, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs1hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs2hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs3hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -GLAPI void APIENTRY glVertexAttribs4hvNV (GLuint index, GLsizei n, const GLhalfNV *v); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEX2HNVPROC) (GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEX2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX3HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEX3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEX4HNVPROC) (GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEX4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLNORMAL3HNVPROC) (GLhalfNV nx, GLhalfNV ny, GLhalfNV nz); -typedef void (APIENTRYP PFNGLNORMAL3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLCOLOR4HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue, GLhalfNV alpha); -typedef void (APIENTRYP PFNGLCOLOR4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD1HNVPROC) (GLhalfNV s); -typedef void (APIENTRYP PFNGLTEXCOORD1HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD2HNVPROC) (GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLTEXCOORD2HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD3HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLTEXCOORD3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLTEXCOORD4HNVPROC) (GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLTEXCOORD4HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HNVPROC) (GLenum target, GLhalfNV s); -typedef void (APIENTRYP PFNGLMULTITEXCOORD1HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t); -typedef void (APIENTRYP PFNGLMULTITEXCOORD2HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r); -typedef void (APIENTRYP PFNGLMULTITEXCOORD3HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HNVPROC) (GLenum target, GLhalfNV s, GLhalfNV t, GLhalfNV r, GLhalfNV q); -typedef void (APIENTRYP PFNGLMULTITEXCOORD4HVNVPROC) (GLenum target, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLFOGCOORDHNVPROC) (GLhalfNV fog); -typedef void (APIENTRYP PFNGLFOGCOORDHVNVPROC) (const GLhalfNV *fog); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HNVPROC) (GLhalfNV red, GLhalfNV green, GLhalfNV blue); -typedef void (APIENTRYP PFNGLSECONDARYCOLOR3HVNVPROC) (const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHNVPROC) (GLhalfNV weight); -typedef void (APIENTRYP PFNGLVERTEXWEIGHTHVNVPROC) (const GLhalfNV *weight); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HNVPROC) (GLuint index, GLhalfNV x); -typedef void (APIENTRYP PFNGLVERTEXATTRIB1HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y); -typedef void (APIENTRYP PFNGLVERTEXATTRIB2HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z); -typedef void (APIENTRYP PFNGLVERTEXATTRIB3HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HNVPROC) (GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w); -typedef void (APIENTRYP PFNGLVERTEXATTRIB4HVNVPROC) (GLuint index, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS1HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS2HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS3HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBS4HVNVPROC) (GLuint index, GLsizei n, const GLhalfNV *v); -#endif - -#ifndef GL_NV_pixel_data_range -#define GL_NV_pixel_data_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPixelDataRangeNV (GLenum target, GLsizei length, GLvoid *pointer); -GLAPI void APIENTRY glFlushPixelDataRangeNV (GLenum target); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPIXELDATARANGENVPROC) (GLenum target, GLsizei length, GLvoid *pointer); -typedef void (APIENTRYP PFNGLFLUSHPIXELDATARANGENVPROC) (GLenum target); -#endif - -#ifndef GL_NV_primitive_restart -#define GL_NV_primitive_restart 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPrimitiveRestartNV (void); -GLAPI void APIENTRY glPrimitiveRestartIndexNV (GLuint index); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTNVPROC) (void); -typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXNVPROC) (GLuint index); -#endif - -#ifndef GL_NV_texture_expand_normal -#define GL_NV_texture_expand_normal 1 -#endif - -#ifndef GL_NV_vertex_program2 -#define GL_NV_vertex_program2 1 -#endif - -#ifndef GL_ATI_map_object_buffer -#define GL_ATI_map_object_buffer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLvoid* APIENTRY glMapObjectBufferATI (GLuint buffer); -GLAPI void APIENTRY glUnmapObjectBufferATI (GLuint buffer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLvoid* (APIENTRYP PFNGLMAPOBJECTBUFFERATIPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLUNMAPOBJECTBUFFERATIPROC) (GLuint buffer); -#endif - -#ifndef GL_ATI_separate_stencil -#define GL_ATI_separate_stencil 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilOpSeparateATI (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -GLAPI void APIENTRY glStencilFuncSeparateATI (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTENCILOPSEPARATEATIPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (APIENTRYP PFNGLSTENCILFUNCSEPARATEATIPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); -#endif - -#ifndef GL_ATI_vertex_attrib_array_object -#define GL_ATI_vertex_attrib_array_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribArrayObjectATI (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); -GLAPI void APIENTRY glGetVertexAttribArrayObjectfvATI (GLuint index, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVertexAttribArrayObjectivATI (GLuint index, GLenum pname, GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBARRAYOBJECTATIPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, GLuint buffer, GLuint offset); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTFVATIPROC) (GLuint index, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBARRAYOBJECTIVATIPROC) (GLuint index, GLenum pname, GLint *params); -#endif - -#ifndef GL_OES_read_format -#define GL_OES_read_format 1 -#endif - -#ifndef GL_EXT_depth_bounds_test -#define GL_EXT_depth_bounds_test 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthBoundsEXT (GLclampd zmin, GLclampd zmax); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEPTHBOUNDSEXTPROC) (GLclampd zmin, GLclampd zmax); -#endif - -#ifndef GL_EXT_texture_mirror_clamp -#define GL_EXT_texture_mirror_clamp 1 -#endif - -#ifndef GL_EXT_blend_equation_separate -#define GL_EXT_blend_equation_separate 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendEquationSeparateEXT (GLenum modeRGB, GLenum modeAlpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEEXTPROC) (GLenum modeRGB, GLenum modeAlpha); -#endif - -#ifndef GL_MESA_pack_invert -#define GL_MESA_pack_invert 1 -#endif - -#ifndef GL_MESA_ycbcr_texture -#define GL_MESA_ycbcr_texture 1 -#endif - -#ifndef GL_EXT_pixel_buffer_object -#define GL_EXT_pixel_buffer_object 1 -#endif - -#ifndef GL_NV_fragment_program_option -#define GL_NV_fragment_program_option 1 -#endif - -#ifndef GL_NV_fragment_program2 -#define GL_NV_fragment_program2 1 -#endif - -#ifndef GL_NV_vertex_program2_option -#define GL_NV_vertex_program2_option 1 -#endif - -#ifndef GL_NV_vertex_program3 -#define GL_NV_vertex_program3 1 -#endif - -#ifndef GL_EXT_framebuffer_object -#define GL_EXT_framebuffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLboolean APIENTRY glIsRenderbufferEXT (GLuint renderbuffer); -GLAPI void APIENTRY glBindRenderbufferEXT (GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glDeleteRenderbuffersEXT (GLsizei n, const GLuint *renderbuffers); -GLAPI void APIENTRY glGenRenderbuffersEXT (GLsizei n, GLuint *renderbuffers); -GLAPI void APIENTRY glRenderbufferStorageEXT (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetRenderbufferParameterivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI GLboolean APIENTRY glIsFramebufferEXT (GLuint framebuffer); -GLAPI void APIENTRY glBindFramebufferEXT (GLenum target, GLuint framebuffer); -GLAPI void APIENTRY glDeleteFramebuffersEXT (GLsizei n, const GLuint *framebuffers); -GLAPI void APIENTRY glGenFramebuffersEXT (GLsizei n, GLuint *framebuffers); -GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT (GLenum target); -GLAPI void APIENTRY glFramebufferTexture1DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture2DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTexture3DEXT (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glFramebufferRenderbufferEXT (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetFramebufferAttachmentParameterivEXT (GLenum target, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateMipmapEXT (GLenum target); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLboolean (APIENTRYP PFNGLISRENDERBUFFEREXTPROC) (GLuint renderbuffer); -typedef void (APIENTRYP PFNGLBINDRENDERBUFFEREXTPROC) (GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLDELETERENDERBUFFERSEXTPROC) (GLsizei n, const GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLGENRENDERBUFFERSEXTPROC) (GLsizei n, GLuint *renderbuffers); -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEEXTPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef GLboolean (APIENTRYP PFNGLISFRAMEBUFFEREXTPROC) (GLuint framebuffer); -typedef void (APIENTRYP PFNGLBINDFRAMEBUFFEREXTPROC) (GLenum target, GLuint framebuffer); -typedef void (APIENTRYP PFNGLDELETEFRAMEBUFFERSEXTPROC) (GLsizei n, const GLuint *framebuffers); -typedef void (APIENTRYP PFNGLGENFRAMEBUFFERSEXTPROC) (GLsizei n, GLuint *framebuffers); -typedef GLenum (APIENTRYP PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC) (GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE1DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE2DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURE3DEXTPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLenum target, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATEMIPMAPEXTPROC) (GLenum target); -#endif - -#ifndef GL_GREMEDY_string_marker -#define GL_GREMEDY_string_marker 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStringMarkerGREMEDY (GLsizei len, const GLvoid *string); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTRINGMARKERGREMEDYPROC) (GLsizei len, const GLvoid *string); -#endif - -#ifndef GL_EXT_packed_depth_stencil -#define GL_EXT_packed_depth_stencil 1 -#endif - -#ifndef GL_EXT_stencil_clear_tag -#define GL_EXT_stencil_clear_tag 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glStencilClearTagEXT (GLsizei stencilTagBits, GLuint stencilClearTag); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLSTENCILCLEARTAGEXTPROC) (GLsizei stencilTagBits, GLuint stencilClearTag); -#endif - -#ifndef GL_EXT_texture_sRGB -#define GL_EXT_texture_sRGB 1 -#endif - -#ifndef GL_EXT_framebuffer_blit -#define GL_EXT_framebuffer_blit 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLITFRAMEBUFFEREXTPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif - -#ifndef GL_EXT_framebuffer_multisample -#define GL_EXT_framebuffer_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -#endif - -#ifndef GL_MESAX_texture_stack -#define GL_MESAX_texture_stack 1 -#endif - -#ifndef GL_EXT_timer_query -#define GL_EXT_timer_query 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetQueryObjecti64vEXT (GLuint id, GLenum pname, GLint64EXT *params); -GLAPI void APIENTRY glGetQueryObjectui64vEXT (GLuint id, GLenum pname, GLuint64EXT *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETQUERYOBJECTI64VEXTPROC) (GLuint id, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETQUERYOBJECTUI64VEXTPROC) (GLuint id, GLenum pname, GLuint64EXT *params); -#endif - -#ifndef GL_EXT_gpu_program_parameters -#define GL_EXT_gpu_program_parameters 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramEnvParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glProgramLocalParameters4fvEXT (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLenum target, GLuint index, GLsizei count, const GLfloat *params); -#endif - -#ifndef GL_APPLE_flush_buffer_range -#define GL_APPLE_flush_buffer_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferParameteriAPPLE (GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glFlushMappedBufferRangeAPPLE (GLenum target, GLintptr offset, GLsizeiptr size); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); -#endif - -#ifndef GL_NV_gpu_program4 -#define GL_NV_gpu_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramLocalParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glProgramLocalParameterI4ivNV (GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glProgramLocalParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramLocalParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glProgramLocalParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glProgramLocalParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glProgramEnvParameterI4iNV (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glProgramEnvParameterI4ivNV (GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glProgramEnvParametersI4ivNV (GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramEnvParameterI4uiNV (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glProgramEnvParameterI4uivNV (GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glProgramEnvParametersI4uivNV (GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetProgramLocalParameterIivNV (GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetProgramLocalParameterIuivNV (GLenum target, GLuint index, GLuint *params); -GLAPI void APIENTRY glGetProgramEnvParameterIivNV (GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetProgramEnvParameterIuivNV (GLenum target, GLuint index, GLuint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMLOCALPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4INVPROC) (GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4IVNVPROC) (GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4IVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UINVPROC) (GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERI4UIVNVPROC) (GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMENVPARAMETERSI4UIVNVPROC) (GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMLOCALPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIIVNVPROC) (GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMENVPARAMETERIUIVNVPROC) (GLenum target, GLuint index, GLuint *params); -#endif - -#ifndef GL_NV_geometry_program4 -#define GL_NV_geometry_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramVertexLimitNV (GLenum target, GLint limit); -GLAPI void APIENTRY glFramebufferTextureEXT (GLenum target, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glFramebufferTextureLayerEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glFramebufferTextureFaceEXT (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMVERTEXLIMITNVPROC) (GLenum target, GLint limit); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEEXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face); -#endif - -#ifndef GL_EXT_geometry_shader4 -#define GL_EXT_geometry_shader4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramParameteriEXT (GLuint program, GLenum pname, GLint value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIEXTPROC) (GLuint program, GLenum pname, GLint value); -#endif - -#ifndef GL_NV_vertex_program4 -#define GL_NV_vertex_program4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribI1iEXT (GLuint index, GLint x); -GLAPI void APIENTRY glVertexAttribI2iEXT (GLuint index, GLint x, GLint y); -GLAPI void APIENTRY glVertexAttribI3iEXT (GLuint index, GLint x, GLint y, GLint z); -GLAPI void APIENTRY glVertexAttribI4iEXT (GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glVertexAttribI1uiEXT (GLuint index, GLuint x); -GLAPI void APIENTRY glVertexAttribI2uiEXT (GLuint index, GLuint x, GLuint y); -GLAPI void APIENTRY glVertexAttribI3uiEXT (GLuint index, GLuint x, GLuint y, GLuint z); -GLAPI void APIENTRY glVertexAttribI4uiEXT (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glVertexAttribI1ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI2ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI3ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI4ivEXT (GLuint index, const GLint *v); -GLAPI void APIENTRY glVertexAttribI1uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI2uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI3uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4uivEXT (GLuint index, const GLuint *v); -GLAPI void APIENTRY glVertexAttribI4bvEXT (GLuint index, const GLbyte *v); -GLAPI void APIENTRY glVertexAttribI4svEXT (GLuint index, const GLshort *v); -GLAPI void APIENTRY glVertexAttribI4ubvEXT (GLuint index, const GLubyte *v); -GLAPI void APIENTRY glVertexAttribI4usvEXT (GLuint index, const GLushort *v); -GLAPI void APIENTRY glVertexAttribIPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glGetVertexAttribIivEXT (GLuint index, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVertexAttribIuivEXT (GLuint index, GLenum pname, GLuint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IEXTPROC) (GLuint index, GLint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IEXTPROC) (GLuint index, GLint x, GLint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IEXTPROC) (GLuint index, GLint x, GLint y, GLint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IEXTPROC) (GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIEXTPROC) (GLuint index, GLuint x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIEXTPROC) (GLuint index, GLuint x, GLuint y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIEXTPROC) (GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4IVEXTPROC) (GLuint index, const GLint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI1UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI2UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI3UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UIVEXTPROC) (GLuint index, const GLuint *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVEXTPROC) (GLuint index, const GLbyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVEXTPROC) (GLuint index, const GLshort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVEXTPROC) (GLuint index, const GLubyte *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVEXTPROC) (GLuint index, const GLushort *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVEXTPROC) (GLuint index, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVEXTPROC) (GLuint index, GLenum pname, GLuint *params); -#endif - -#ifndef GL_EXT_gpu_shader4 -#define GL_EXT_gpu_shader4 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetUniformuivEXT (GLuint program, GLint location, GLuint *params); -GLAPI void APIENTRY glBindFragDataLocationEXT (GLuint program, GLuint color, const GLchar *name); -GLAPI GLint APIENTRY glGetFragDataLocationEXT (GLuint program, const GLchar *name); -GLAPI void APIENTRY glUniform1uiEXT (GLint location, GLuint v0); -GLAPI void APIENTRY glUniform2uiEXT (GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glUniform3uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glUniform4uiEXT (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glUniform1uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform2uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform3uivEXT (GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glUniform4uivEXT (GLint location, GLsizei count, const GLuint *value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETUNIFORMUIVEXTPROC) (GLuint program, GLint location, GLuint *params); -typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONEXTPROC) (GLuint program, GLuint color, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONEXTPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLUNIFORM1UIEXTPROC) (GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLUNIFORM2UIEXTPROC) (GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLUNIFORM3UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLUNIFORM4UIEXTPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLUNIFORM1UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM2UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM3UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLUNIFORM4UIVEXTPROC) (GLint location, GLsizei count, const GLuint *value); -#endif - -#ifndef GL_EXT_draw_instanced -#define GL_EXT_draw_instanced 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -GLAPI void APIENTRY glDrawElementsInstancedEXT (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDRAWARRAYSINSTANCEDEXTPROC) (GLenum mode, GLint start, GLsizei count, GLsizei primcount); -typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDEXTPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); -#endif - -#ifndef GL_EXT_packed_float -#define GL_EXT_packed_float 1 -#endif - -#ifndef GL_EXT_texture_array -#define GL_EXT_texture_array 1 -#endif - -#ifndef GL_EXT_texture_buffer_object -#define GL_EXT_texture_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexBufferEXT (GLenum target, GLenum internalformat, GLuint buffer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXBUFFEREXTPROC) (GLenum target, GLenum internalformat, GLuint buffer); -#endif - -#ifndef GL_EXT_texture_compression_latc -#define GL_EXT_texture_compression_latc 1 -#endif - -#ifndef GL_EXT_texture_compression_rgtc -#define GL_EXT_texture_compression_rgtc 1 -#endif - -#ifndef GL_EXT_texture_shared_exponent -#define GL_EXT_texture_shared_exponent 1 -#endif - -#ifndef GL_NV_depth_buffer_float -#define GL_NV_depth_buffer_float 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDepthRangedNV (GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glClearDepthdNV (GLdouble depth); -GLAPI void APIENTRY glDepthBoundsdNV (GLdouble zmin, GLdouble zmax); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEPTHRANGEDNVPROC) (GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLCLEARDEPTHDNVPROC) (GLdouble depth); -typedef void (APIENTRYP PFNGLDEPTHBOUNDSDNVPROC) (GLdouble zmin, GLdouble zmax); -#endif - -#ifndef GL_NV_fragment_program4 -#define GL_NV_fragment_program4 1 -#endif - -#ifndef GL_NV_framebuffer_multisample_coverage -#define GL_NV_framebuffer_multisample_coverage 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glRenderbufferStorageMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -#endif - -#ifndef GL_EXT_framebuffer_sRGB -#define GL_EXT_framebuffer_sRGB 1 -#endif - -#ifndef GL_NV_geometry_shader4 -#define GL_NV_geometry_shader4 1 -#endif - -#ifndef GL_NV_parameter_buffer_object -#define GL_NV_parameter_buffer_object 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramBufferParametersfvNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glProgramBufferParametersIivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glProgramBufferParametersIuivNV (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSFVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLPROGRAMBUFFERPARAMETERSIUIVNVPROC) (GLenum target, GLuint buffer, GLuint index, GLsizei count, const GLuint *params); -#endif - -#ifndef GL_EXT_draw_buffers2 -#define GL_EXT_draw_buffers2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glColorMaskIndexedEXT (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -GLAPI void APIENTRY glGetBooleanIndexedvEXT (GLenum target, GLuint index, GLboolean *data); -GLAPI void APIENTRY glGetIntegerIndexedvEXT (GLenum target, GLuint index, GLint *data); -GLAPI void APIENTRY glEnableIndexedEXT (GLenum target, GLuint index); -GLAPI void APIENTRY glDisableIndexedEXT (GLenum target, GLuint index); -GLAPI GLboolean APIENTRY glIsEnabledIndexedEXT (GLenum target, GLuint index); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (APIENTRYP PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum target, GLuint index, GLboolean *data); -typedef void (APIENTRYP PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLint *data); -typedef void (APIENTRYP PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef void (APIENTRYP PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); -typedef GLboolean (APIENTRYP PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); -#endif - -#ifndef GL_NV_transform_feedback -#define GL_NV_transform_feedback 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackNV (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedbackNV (void); -GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint count, const GLint *attribs, GLenum bufferMode); -GLAPI void APIENTRY glBindBufferRangeNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferOffsetNV (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -GLAPI void APIENTRY glBindBufferBaseNV (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -GLAPI void APIENTRY glActiveVaryingNV (GLuint program, const GLchar *name); -GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint program, const GLchar *name); -GLAPI void APIENTRY glGetActiveVaryingNV (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -GLAPI void APIENTRY glGetTransformFeedbackVaryingNV (GLuint program, GLuint index, GLint *location); -GLAPI void APIENTRY glTransformFeedbackStreamAttribsNV (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKNVPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, const GLint *attribs, GLenum bufferMode); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode); -typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name); -typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name); -typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGNVPROC) (GLuint program, GLuint index, GLint *location); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKSTREAMATTRIBSNVPROC) (GLsizei count, const GLint *attribs, GLsizei nbuffers, const GLint *bufstreams, GLenum bufferMode); -#endif - -#ifndef GL_EXT_bindable_uniform -#define GL_EXT_bindable_uniform 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniformBufferEXT (GLuint program, GLint location, GLuint buffer); -GLAPI GLint APIENTRY glGetUniformBufferSizeEXT (GLuint program, GLint location); -GLAPI GLintptr APIENTRY glGetUniformOffsetEXT (GLuint program, GLint location); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUNIFORMBUFFEREXTPROC) (GLuint program, GLint location, GLuint buffer); -typedef GLint (APIENTRYP PFNGLGETUNIFORMBUFFERSIZEEXTPROC) (GLuint program, GLint location); -typedef GLintptr (APIENTRYP PFNGLGETUNIFORMOFFSETEXTPROC) (GLuint program, GLint location); -#endif - -#ifndef GL_EXT_texture_integer -#define GL_EXT_texture_integer 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexParameterIivEXT (GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTexParameterIuivEXT (GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTexParameterIivEXT (GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTexParameterIuivEXT (GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glClearColorIiEXT (GLint red, GLint green, GLint blue, GLint alpha); -GLAPI void APIENTRY glClearColorIuiEXT (GLuint red, GLuint green, GLuint blue, GLuint alpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVEXTPROC) (GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVEXTPROC) (GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLCLEARCOLORIIEXTPROC) (GLint red, GLint green, GLint blue, GLint alpha); -typedef void (APIENTRYP PFNGLCLEARCOLORIUIEXTPROC) (GLuint red, GLuint green, GLuint blue, GLuint alpha); -#endif - -#ifndef GL_GREMEDY_frame_terminator -#define GL_GREMEDY_frame_terminator 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glFrameTerminatorGREMEDY (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLFRAMETERMINATORGREMEDYPROC) (void); -#endif - -#ifndef GL_NV_conditional_render -#define GL_NV_conditional_render 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginConditionalRenderNV (GLuint id, GLenum mode); -GLAPI void APIENTRY glEndConditionalRenderNV (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINCONDITIONALRENDERNVPROC) (GLuint id, GLenum mode); -typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERNVPROC) (void); -#endif - -#ifndef GL_NV_present_video -#define GL_NV_present_video 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glPresentFrameKeyedNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); -GLAPI void APIENTRY glPresentFrameDualFillNV (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); -GLAPI void APIENTRY glGetVideoivNV (GLuint video_slot, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideouivNV (GLuint video_slot, GLenum pname, GLuint *params); -GLAPI void APIENTRY glGetVideoi64vNV (GLuint video_slot, GLenum pname, GLint64EXT *params); -GLAPI void APIENTRY glGetVideoui64vNV (GLuint video_slot, GLenum pname, GLuint64EXT *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPRESENTFRAMEKEYEDNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLuint key0, GLenum target1, GLuint fill1, GLuint key1); -typedef void (APIENTRYP PFNGLPRESENTFRAMEDUALFILLNVPROC) (GLuint video_slot, GLuint64EXT minPresentTime, GLuint beginPresentTimeId, GLuint presentDurationId, GLenum type, GLenum target0, GLuint fill0, GLenum target1, GLuint fill1, GLenum target2, GLuint fill2, GLenum target3, GLuint fill3); -typedef void (APIENTRYP PFNGLGETVIDEOIVNVPROC) (GLuint video_slot, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOUIVNVPROC) (GLuint video_slot, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLGETVIDEOI64VNVPROC) (GLuint video_slot, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETVIDEOUI64VNVPROC) (GLuint video_slot, GLenum pname, GLuint64EXT *params); -#endif - -#ifndef GL_EXT_transform_feedback -#define GL_EXT_transform_feedback 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginTransformFeedbackEXT (GLenum primitiveMode); -GLAPI void APIENTRY glEndTransformFeedbackEXT (void); -GLAPI void APIENTRY glBindBufferRangeEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -GLAPI void APIENTRY glBindBufferOffsetEXT (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -GLAPI void APIENTRY glBindBufferBaseEXT (GLenum target, GLuint index, GLuint buffer); -GLAPI void APIENTRY glTransformFeedbackVaryingsEXT (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); -GLAPI void APIENTRY glGetTransformFeedbackVaryingEXT (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINTRANSFORMFEEDBACKEXTPROC) (GLenum primitiveMode); -typedef void (APIENTRYP PFNGLENDTRANSFORMFEEDBACKEXTPROC) (void); -typedef void (APIENTRYP PFNGLBINDBUFFERRANGEEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETEXTPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); -typedef void (APIENTRYP PFNGLBINDBUFFERBASEEXTPROC) (GLenum target, GLuint index, GLuint buffer); -typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSEXTPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); -typedef void (APIENTRYP PFNGLGETTRANSFORMFEEDBACKVARYINGEXTPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); -#endif - -#ifndef GL_EXT_direct_state_access -#define GL_EXT_direct_state_access 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glClientAttribDefaultEXT (GLbitfield mask); -GLAPI void APIENTRY glPushClientAttribDefaultEXT (GLbitfield mask); -GLAPI void APIENTRY glMatrixLoadfEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoaddEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixMultfEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultdEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixLoadIdentityEXT (GLenum mode); -GLAPI void APIENTRY glMatrixRotatefEXT (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixRotatedEXT (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixScalefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixScaledEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixTranslatefEXT (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -GLAPI void APIENTRY glMatrixTranslatedEXT (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glMatrixFrustumEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glMatrixOrthoEXT (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -GLAPI void APIENTRY glMatrixPopEXT (GLenum mode); -GLAPI void APIENTRY glMatrixPushEXT (GLenum mode); -GLAPI void APIENTRY glMatrixLoadTransposefEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixLoadTransposedEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glMatrixMultTransposefEXT (GLenum mode, const GLfloat *m); -GLAPI void APIENTRY glMatrixMultTransposedEXT (GLenum mode, const GLdouble *m); -GLAPI void APIENTRY glTextureParameterfEXT (GLuint texture, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glTextureParameteriEXT (GLuint texture, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glCopyTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetTextureImageEXT (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -GLAPI void APIENTRY glGetTextureParameterfvEXT (GLuint texture, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureParameterivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureLevelParameterfvEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetTextureLevelParameterivEXT (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glCopyTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glMultiTexParameterfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexParameteriEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glCopyMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -GLAPI void APIENTRY glCopyMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -GLAPI void APIENTRY glCopyMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -GLAPI void APIENTRY glCopyMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetMultiTexImageEXT (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -GLAPI void APIENTRY glGetMultiTexParameterfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexParameterivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexLevelParameterfvEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexLevelParameterivEXT (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); -GLAPI void APIENTRY glMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -GLAPI void APIENTRY glCopyMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -GLAPI void APIENTRY glBindMultiTextureEXT (GLenum texunit, GLenum target, GLuint texture); -GLAPI void APIENTRY glEnableClientStateIndexedEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glDisableClientStateIndexedEXT (GLenum array, GLuint index); -GLAPI void APIENTRY glMultiTexCoordPointerEXT (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glMultiTexEnvfEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexEnviEXT (GLenum texunit, GLenum target, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexGendEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -GLAPI void APIENTRY glMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); -GLAPI void APIENTRY glMultiTexGenfEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -GLAPI void APIENTRY glMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glMultiTexGeniEXT (GLenum texunit, GLenum coord, GLenum pname, GLint param); -GLAPI void APIENTRY glMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); -GLAPI void APIENTRY glGetMultiTexEnvfvEXT (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexEnvivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexGendvEXT (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glGetMultiTexGenfvEXT (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetMultiTexGenivEXT (GLenum texunit, GLenum coord, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetFloatIndexedvEXT (GLenum target, GLuint index, GLfloat *data); -GLAPI void APIENTRY glGetDoubleIndexedvEXT (GLenum target, GLuint index, GLdouble *data); -GLAPI void APIENTRY glGetPointerIndexedvEXT (GLenum target, GLuint index, GLvoid* *data); -GLAPI void APIENTRY glCompressedTextureImage3DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedTextureImage2DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedTextureImage1DEXT (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedTextureSubImage3DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedTextureSubImage2DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedTextureSubImage1DEXT (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glGetCompressedTextureImageEXT (GLuint texture, GLenum target, GLint lod, GLvoid *img); -GLAPI void APIENTRY glCompressedMultiTexImage3DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedMultiTexImage2DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedMultiTexImage1DEXT (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage3DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage2DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glCompressedMultiTexSubImage1DEXT (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); -GLAPI void APIENTRY glGetCompressedMultiTexImageEXT (GLenum texunit, GLenum target, GLint lod, GLvoid *img); -GLAPI void APIENTRY glNamedProgramStringEXT (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string); -GLAPI void APIENTRY glNamedProgramLocalParameter4dEXT (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glNamedProgramLocalParameter4dvEXT (GLuint program, GLenum target, GLuint index, const GLdouble *params); -GLAPI void APIENTRY glNamedProgramLocalParameter4fEXT (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -GLAPI void APIENTRY glNamedProgramLocalParameter4fvEXT (GLuint program, GLenum target, GLuint index, const GLfloat *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterdvEXT (GLuint program, GLenum target, GLuint index, GLdouble *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterfvEXT (GLuint program, GLenum target, GLuint index, GLfloat *params); -GLAPI void APIENTRY glGetNamedProgramivEXT (GLuint program, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedProgramStringEXT (GLuint program, GLenum target, GLenum pname, GLvoid *string); -GLAPI void APIENTRY glNamedProgramLocalParameters4fvEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); -GLAPI void APIENTRY glNamedProgramLocalParameterI4iEXT (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -GLAPI void APIENTRY glNamedProgramLocalParameterI4ivEXT (GLuint program, GLenum target, GLuint index, const GLint *params); -GLAPI void APIENTRY glNamedProgramLocalParametersI4ivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); -GLAPI void APIENTRY glNamedProgramLocalParameterI4uiEXT (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -GLAPI void APIENTRY glNamedProgramLocalParameterI4uivEXT (GLuint program, GLenum target, GLuint index, const GLuint *params); -GLAPI void APIENTRY glNamedProgramLocalParametersI4uivEXT (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterIivEXT (GLuint program, GLenum target, GLuint index, GLint *params); -GLAPI void APIENTRY glGetNamedProgramLocalParameterIuivEXT (GLuint program, GLenum target, GLuint index, GLuint *params); -GLAPI void APIENTRY glTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetTextureParameterIivEXT (GLuint texture, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetTextureParameterIuivEXT (GLuint texture, GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -GLAPI void APIENTRY glMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); -GLAPI void APIENTRY glGetMultiTexParameterIivEXT (GLenum texunit, GLenum target, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetMultiTexParameterIuivEXT (GLenum texunit, GLenum target, GLenum pname, GLuint *params); -GLAPI void APIENTRY glProgramUniform1fEXT (GLuint program, GLint location, GLfloat v0); -GLAPI void APIENTRY glProgramUniform2fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1); -GLAPI void APIENTRY glProgramUniform3fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -GLAPI void APIENTRY glProgramUniform4fEXT (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -GLAPI void APIENTRY glProgramUniform1iEXT (GLuint program, GLint location, GLint v0); -GLAPI void APIENTRY glProgramUniform2iEXT (GLuint program, GLint location, GLint v0, GLint v1); -GLAPI void APIENTRY glProgramUniform3iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -GLAPI void APIENTRY glProgramUniform4iEXT (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -GLAPI void APIENTRY glProgramUniform1fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform2fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform3fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform4fvEXT (GLuint program, GLint location, GLsizei count, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform1ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform2ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform3ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniform4ivEXT (GLuint program, GLint location, GLsizei count, const GLint *value); -GLAPI void APIENTRY glProgramUniformMatrix2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3fvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -GLAPI void APIENTRY glProgramUniform1uiEXT (GLuint program, GLint location, GLuint v0); -GLAPI void APIENTRY glProgramUniform2uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1); -GLAPI void APIENTRY glProgramUniform3uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -GLAPI void APIENTRY glProgramUniform4uiEXT (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -GLAPI void APIENTRY glProgramUniform1uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform2uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform3uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glProgramUniform4uivEXT (GLuint program, GLint location, GLsizei count, const GLuint *value); -GLAPI void APIENTRY glNamedBufferDataEXT (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage); -GLAPI void APIENTRY glNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data); -GLAPI GLvoid* APIENTRY glMapNamedBufferEXT (GLuint buffer, GLenum access); -GLAPI GLboolean APIENTRY glUnmapNamedBufferEXT (GLuint buffer); -GLAPI GLvoid* APIENTRY glMapNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -GLAPI void APIENTRY glFlushMappedNamedBufferRangeEXT (GLuint buffer, GLintptr offset, GLsizeiptr length); -GLAPI void APIENTRY glNamedCopyBufferSubDataEXT (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -GLAPI void APIENTRY glGetNamedBufferParameterivEXT (GLuint buffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetNamedBufferPointervEXT (GLuint buffer, GLenum pname, GLvoid* *params); -GLAPI void APIENTRY glGetNamedBufferSubDataEXT (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data); -GLAPI void APIENTRY glTextureBufferEXT (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glMultiTexBufferEXT (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -GLAPI void APIENTRY glNamedRenderbufferStorageEXT (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glGetNamedRenderbufferParameterivEXT (GLuint renderbuffer, GLenum pname, GLint *params); -GLAPI GLenum APIENTRY glCheckNamedFramebufferStatusEXT (GLuint framebuffer, GLenum target); -GLAPI void APIENTRY glNamedFramebufferTexture1DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTexture2DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTexture3DEXT (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -GLAPI void APIENTRY glNamedFramebufferRenderbufferEXT (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -GLAPI void APIENTRY glGetNamedFramebufferAttachmentParameterivEXT (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -GLAPI void APIENTRY glGenerateTextureMipmapEXT (GLuint texture, GLenum target); -GLAPI void APIENTRY glGenerateMultiTexMipmapEXT (GLenum texunit, GLenum target); -GLAPI void APIENTRY glFramebufferDrawBufferEXT (GLuint framebuffer, GLenum mode); -GLAPI void APIENTRY glFramebufferDrawBuffersEXT (GLuint framebuffer, GLsizei n, const GLenum *bufs); -GLAPI void APIENTRY glFramebufferReadBufferEXT (GLuint framebuffer, GLenum mode); -GLAPI void APIENTRY glGetFramebufferParameterivEXT (GLuint framebuffer, GLenum pname, GLint *params); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleEXT (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glNamedRenderbufferStorageMultisampleCoverageEXT (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -GLAPI void APIENTRY glNamedFramebufferTextureEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -GLAPI void APIENTRY glNamedFramebufferTextureLayerEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -GLAPI void APIENTRY glNamedFramebufferTextureFaceEXT (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -GLAPI void APIENTRY glTextureRenderbufferEXT (GLuint texture, GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glMultiTexRenderbufferEXT (GLenum texunit, GLenum target, GLuint renderbuffer); -GLAPI void APIENTRY glProgramUniform1dEXT (GLuint program, GLint location, GLdouble x); -GLAPI void APIENTRY glProgramUniform2dEXT (GLuint program, GLint location, GLdouble x, GLdouble y); -GLAPI void APIENTRY glProgramUniform3dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glProgramUniform4dEXT (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glProgramUniform1dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform2dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform3dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniform4dvEXT (GLuint program, GLint location, GLsizei count, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix2x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix3x4dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x2dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -GLAPI void APIENTRY glProgramUniformMatrix4x3dvEXT (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLPUSHCLIENTATTRIBDEFAULTEXTPROC) (GLbitfield mask); -typedef void (APIENTRYP PFNGLMATRIXLOADFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXMULTFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXLOADIDENTITYEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXROTATEFEXTPROC) (GLenum mode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXROTATEDEXTPROC) (GLenum mode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXSCALEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXSCALEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXTRANSLATEFEXTPROC) (GLenum mode, GLfloat x, GLfloat y, GLfloat z); -typedef void (APIENTRYP PFNGLMATRIXTRANSLATEDEXTPROC) (GLenum mode, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLMATRIXFRUSTUMEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLMATRIXORTHOEXTPROC) (GLenum mode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (APIENTRYP PFNGLMATRIXPOPEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXPUSHEXTPROC) (GLenum mode); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXLOADTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEFEXTPROC) (GLenum mode, const GLfloat *m); -typedef void (APIENTRYP PFNGLMATRIXMULTTRANSPOSEDEXTPROC) (GLenum mode, const GLdouble *m); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERFVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETTEXTURELEVELPARAMETERIVEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (APIENTRYP PFNGLCOPYMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERFVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXLEVELPARAMETERIVEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); -typedef void (APIENTRYP PFNGLCOPYMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLBINDMULTITEXTUREEXTPROC) (GLenum texunit, GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLENABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLDISABLECLIENTSTATEINDEXEDEXTPROC) (GLenum array, GLuint index); -typedef void (APIENTRYP PFNGLMULTITEXCOORDPOINTEREXTPROC) (GLenum texunit, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLMULTITEXENVFEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXENVIEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXGENDEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble param); -typedef void (APIENTRYP PFNGLMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params); -typedef void (APIENTRYP PFNGLMULTITEXGENFEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat param); -typedef void (APIENTRYP PFNGLMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLMULTITEXGENIEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint param); -typedef void (APIENTRYP PFNGLMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXENVFVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXENVIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENDVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENFVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETMULTITEXGENIVEXTPROC) (GLenum texunit, GLenum coord, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETFLOATINDEXEDVEXTPROC) (GLenum target, GLuint index, GLfloat *data); -typedef void (APIENTRYP PFNGLGETDOUBLEINDEXEDVEXTPROC) (GLenum target, GLuint index, GLdouble *data); -typedef void (APIENTRYP PFNGLGETPOINTERINDEXEDVEXTPROC) (GLenum target, GLuint index, GLvoid* *data); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTUREIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE3DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE2DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDTEXTURESUBIMAGE1DEXTPROC) (GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXTUREIMAGEEXTPROC) (GLuint texture, GLenum target, GLint lod, GLvoid *img); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE3DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE2DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLCOMPRESSEDMULTITEXSUBIMAGE1DEXTPROC) (GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *bits); -typedef void (APIENTRYP PFNGLGETCOMPRESSEDMULTITEXIMAGEEXTPROC) (GLenum texunit, GLenum target, GLint lod, GLvoid *img); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid *string); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4DVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLdouble *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETER4FVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLfloat *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERDVEXTPROC) (GLuint program, GLenum target, GLuint index, GLdouble *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERFVEXTPROC) (GLuint program, GLenum target, GLuint index, GLfloat *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMIVEXTPROC) (GLuint program, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMSTRINGEXTPROC) (GLuint program, GLenum target, GLenum pname, GLvoid *string); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERS4FVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLfloat *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IEXTPROC) (GLuint program, GLenum target, GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4IVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, const GLuint *params); -typedef void (APIENTRYP PFNGLNAMEDPROGRAMLOCALPARAMETERSI4UIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDPROGRAMLOCALPARAMETERIUIVEXTPROC) (GLuint program, GLenum target, GLuint index, GLuint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETTEXTUREPARAMETERIUIVEXTPROC) (GLuint texture, GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, const GLuint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETMULTITEXPARAMETERIUIVEXTPROC) (GLenum texunit, GLenum target, GLenum pname, GLuint *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FEXTPROC) (GLuint program, GLint location, GLfloat v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FEXTPROC) (GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IEXTPROC) (GLuint program, GLint location, GLint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IEXTPROC) (GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4FVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4IVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3FVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIEXTPROC) (GLuint program, GLint location, GLuint v0); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIEXTPROC) (GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UIVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLuint *value); -typedef void (APIENTRYP PFNGLNAMEDBUFFERDATAEXTPROC) (GLuint buffer, GLsizeiptr size, const GLvoid *data, GLenum usage); -typedef void (APIENTRYP PFNGLNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const GLvoid *data); -typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFEREXTPROC) (GLuint buffer, GLenum access); -typedef GLboolean (APIENTRYP PFNGLUNMAPNAMEDBUFFEREXTPROC) (GLuint buffer); -typedef GLvoid* (APIENTRYP PFNGLMAPNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (APIENTRYP PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (APIENTRYP PFNGLNAMEDCOPYBUFFERSUBDATAEXTPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERIVEXTPROC) (GLuint buffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPOINTERVEXTPROC) (GLuint buffer, GLenum pname, GLvoid* *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERSUBDATAEXTPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, GLvoid *data); -typedef void (APIENTRYP PFNGLTEXTUREBUFFEREXTPROC) (GLuint texture, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLMULTITEXBUFFEREXTPROC) (GLenum texunit, GLenum target, GLenum internalformat, GLuint buffer); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEEXTPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLGETNAMEDRENDERBUFFERPARAMETERIVEXTPROC) (GLuint renderbuffer, GLenum pname, GLint *params); -typedef GLenum (APIENTRYP PFNGLCHECKNAMEDFRAMEBUFFERSTATUSEXTPROC) (GLuint framebuffer, GLenum target); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE1DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE2DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURE3DEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERRENDERBUFFEREXTPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGENERATETEXTUREMIPMAPEXTPROC) (GLuint texture, GLenum target); -typedef void (APIENTRYP PFNGLGENERATEMULTITEXMIPMAPEXTPROC) (GLenum texunit, GLenum target); -typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (APIENTRYP PFNGLFRAMEBUFFERDRAWBUFFERSEXTPROC) (GLuint framebuffer, GLsizei n, const GLenum *bufs); -typedef void (APIENTRYP PFNGLFRAMEBUFFERREADBUFFEREXTPROC) (GLuint framebuffer, GLenum mode); -typedef void (APIENTRYP PFNGLGETFRAMEBUFFERPARAMETERIVEXTPROC) (GLuint framebuffer, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLECOVERAGEEXTPROC) (GLuint renderbuffer, GLsizei coverageSamples, GLsizei colorSamples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTURELAYEREXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (APIENTRYP PFNGLNAMEDFRAMEBUFFERTEXTUREFACEEXTPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLenum face); -typedef void (APIENTRYP PFNGLTEXTURERENDERBUFFEREXTPROC) (GLuint texture, GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLMULTITEXRENDERBUFFEREXTPROC) (GLenum texunit, GLenum target, GLuint renderbuffer); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DEXTPROC) (GLuint program, GLint location, GLdouble x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DEXTPROC) (GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4DVEXTPROC) (GLuint program, GLint location, GLsizei count, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX2X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX3X4DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X2DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMMATRIX4X3DVEXTPROC) (GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); -#endif - -#ifndef GL_EXT_vertex_array_bgra -#define GL_EXT_vertex_array_bgra 1 -#endif - -#ifndef GL_EXT_texture_swizzle -#define GL_EXT_texture_swizzle 1 -#endif - -#ifndef GL_NV_explicit_multisample -#define GL_NV_explicit_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetMultisamplefvNV (GLenum pname, GLuint index, GLfloat *val); -GLAPI void APIENTRY glSampleMaskIndexedNV (GLuint index, GLbitfield mask); -GLAPI void APIENTRY glTexRenderbufferNV (GLenum target, GLuint renderbuffer); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVNVPROC) (GLenum pname, GLuint index, GLfloat *val); -typedef void (APIENTRYP PFNGLSAMPLEMASKINDEXEDNVPROC) (GLuint index, GLbitfield mask); -typedef void (APIENTRYP PFNGLTEXRENDERBUFFERNVPROC) (GLenum target, GLuint renderbuffer); -#endif - -#ifndef GL_NV_transform_feedback2 -#define GL_NV_transform_feedback2 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindTransformFeedbackNV (GLenum target, GLuint id); -GLAPI void APIENTRY glDeleteTransformFeedbacksNV (GLsizei n, const GLuint *ids); -GLAPI void APIENTRY glGenTransformFeedbacksNV (GLsizei n, GLuint *ids); -GLAPI GLboolean APIENTRY glIsTransformFeedbackNV (GLuint id); -GLAPI void APIENTRY glPauseTransformFeedbackNV (void); -GLAPI void APIENTRY glResumeTransformFeedbackNV (void); -GLAPI void APIENTRY glDrawTransformFeedbackNV (GLenum mode, GLuint id); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDTRANSFORMFEEDBACKNVPROC) (GLenum target, GLuint id); -typedef void (APIENTRYP PFNGLDELETETRANSFORMFEEDBACKSNVPROC) (GLsizei n, const GLuint *ids); -typedef void (APIENTRYP PFNGLGENTRANSFORMFEEDBACKSNVPROC) (GLsizei n, GLuint *ids); -typedef GLboolean (APIENTRYP PFNGLISTRANSFORMFEEDBACKNVPROC) (GLuint id); -typedef void (APIENTRYP PFNGLPAUSETRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLRESUMETRANSFORMFEEDBACKNVPROC) (void); -typedef void (APIENTRYP PFNGLDRAWTRANSFORMFEEDBACKNVPROC) (GLenum mode, GLuint id); -#endif - -#ifndef GL_ATI_meminfo -#define GL_ATI_meminfo 1 -#endif - -#ifndef GL_AMD_performance_monitor -#define GL_AMD_performance_monitor 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGetPerfMonitorGroupsAMD (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -GLAPI void APIENTRY glGetPerfMonitorCountersAMD (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -GLAPI void APIENTRY glGetPerfMonitorGroupStringAMD (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -GLAPI void APIENTRY glGetPerfMonitorCounterStringAMD (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -GLAPI void APIENTRY glGetPerfMonitorCounterInfoAMD (GLuint group, GLuint counter, GLenum pname, GLvoid *data); -GLAPI void APIENTRY glGenPerfMonitorsAMD (GLsizei n, GLuint *monitors); -GLAPI void APIENTRY glDeletePerfMonitorsAMD (GLsizei n, GLuint *monitors); -GLAPI void APIENTRY glSelectPerfMonitorCountersAMD (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); -GLAPI void APIENTRY glBeginPerfMonitorAMD (GLuint monitor); -GLAPI void APIENTRY glEndPerfMonitorAMD (GLuint monitor); -GLAPI void APIENTRY glGetPerfMonitorCounterDataAMD (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint *numGroups, GLsizei groupsSize, GLuint *groups); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint *numCounters, GLint *maxActiveCounters, GLsizei counterSize, GLuint *counters); -typedef void (APIENTRYP PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei *length, GLchar *groupString); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei *length, GLchar *counterString); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, GLvoid *data); -typedef void (APIENTRYP PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (APIENTRYP PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint *monitors); -typedef void (APIENTRYP PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint *counterList); -typedef void (APIENTRYP PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); -typedef void (APIENTRYP PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); -typedef void (APIENTRYP PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint *data, GLint *bytesWritten); -#endif - -#ifndef GL_AMD_texture_texture4 -#define GL_AMD_texture_texture4 1 -#endif - -#ifndef GL_AMD_vertex_shader_tesselator -#define GL_AMD_vertex_shader_tesselator 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTessellationFactorAMD (GLfloat factor); -GLAPI void APIENTRY glTessellationModeAMD (GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTESSELLATIONFACTORAMDPROC) (GLfloat factor); -typedef void (APIENTRYP PFNGLTESSELLATIONMODEAMDPROC) (GLenum mode); -#endif - -#ifndef GL_EXT_provoking_vertex -#define GL_EXT_provoking_vertex 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProvokingVertexEXT (GLenum mode); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode); -#endif - -#ifndef GL_EXT_texture_snorm -#define GL_EXT_texture_snorm 1 -#endif - -#ifndef GL_AMD_draw_buffers_blend -#define GL_AMD_draw_buffers_blend 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint buf, GLenum src, GLenum dst); -GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint buf, GLenum mode); -GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst); -typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode); -typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); -#endif - -#ifndef GL_APPLE_texture_range -#define GL_APPLE_texture_range 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureRangeAPPLE (GLenum target, GLsizei length, const GLvoid *pointer); -GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum target, GLenum pname, GLvoid* *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid* *params); -#endif - -#ifndef GL_APPLE_float_pixels -#define GL_APPLE_float_pixels 1 -#endif - -#ifndef GL_APPLE_vertex_program_evaluators -#define GL_APPLE_vertex_program_evaluators 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint index, GLenum pname); -GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint index, GLenum pname); -GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint index, GLenum pname); -GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); -typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); -typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); -typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); -#endif - -#ifndef GL_APPLE_aux_depth_stencil -#define GL_APPLE_aux_depth_stencil 1 -#endif - -#ifndef GL_APPLE_object_purgeable -#define GL_APPLE_object_purgeable 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); -GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum objectType, GLuint name, GLenum option); -GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum objectType, GLuint name, GLenum pname, GLint *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); -typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); -typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params); -#endif - -#ifndef GL_APPLE_row_bytes -#define GL_APPLE_row_bytes 1 -#endif - -#ifndef GL_APPLE_rgb_422 -#define GL_APPLE_rgb_422 1 -#endif - -#ifndef GL_NV_video_capture -#define GL_NV_video_capture 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBeginVideoCaptureNV (GLuint video_capture_slot); -GLAPI void APIENTRY glBindVideoCaptureStreamBufferNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); -GLAPI void APIENTRY glBindVideoCaptureStreamTextureNV (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); -GLAPI void APIENTRY glEndVideoCaptureNV (GLuint video_capture_slot); -GLAPI void APIENTRY glGetVideoCaptureivNV (GLuint video_capture_slot, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideoCaptureStreamivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); -GLAPI void APIENTRY glGetVideoCaptureStreamfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); -GLAPI void APIENTRY glGetVideoCaptureStreamdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); -GLAPI GLenum APIENTRY glVideoCaptureNV (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); -GLAPI void APIENTRY glVideoCaptureStreamParameterivNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); -GLAPI void APIENTRY glVideoCaptureStreamParameterfvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); -GLAPI void APIENTRY glVideoCaptureStreamParameterdvNV (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBEGINVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMBUFFERNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLintptrARB offset); -typedef void (APIENTRYP PFNGLBINDVIDEOCAPTURESTREAMTEXTURENVPROC) (GLuint video_capture_slot, GLuint stream, GLenum frame_region, GLenum target, GLuint texture); -typedef void (APIENTRYP PFNGLENDVIDEOCAPTURENVPROC) (GLuint video_capture_slot); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTUREIVNVPROC) (GLuint video_capture_slot, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLint *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLfloat *params); -typedef void (APIENTRYP PFNGLGETVIDEOCAPTURESTREAMDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, GLdouble *params); -typedef GLenum (APIENTRYP PFNGLVIDEOCAPTURENVPROC) (GLuint video_capture_slot, GLuint *sequence_num, GLuint64EXT *capture_time); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERIVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLint *params); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERFVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLfloat *params); -typedef void (APIENTRYP PFNGLVIDEOCAPTURESTREAMPARAMETERDVNVPROC) (GLuint video_capture_slot, GLuint stream, GLenum pname, const GLdouble *params); -#endif - -#ifndef GL_NV_copy_image -#define GL_NV_copy_image 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glCopyImageSubDataNV (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLCOPYIMAGESUBDATANVPROC) (GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif - -#ifndef GL_EXT_separate_shader_objects -#define GL_EXT_separate_shader_objects 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUseShaderProgramEXT (GLenum type, GLuint program); -GLAPI void APIENTRY glActiveProgramEXT (GLuint program); -GLAPI GLuint APIENTRY glCreateShaderProgramEXT (GLenum type, const GLchar *string); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUSESHADERPROGRAMEXTPROC) (GLenum type, GLuint program); -typedef void (APIENTRYP PFNGLACTIVEPROGRAMEXTPROC) (GLuint program); -typedef GLuint (APIENTRYP PFNGLCREATESHADERPROGRAMEXTPROC) (GLenum type, const GLchar *string); -#endif - -#ifndef GL_NV_parameter_buffer_object2 -#define GL_NV_parameter_buffer_object2 1 -#endif - -#ifndef GL_NV_shader_buffer_load -#define GL_NV_shader_buffer_load 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glMakeBufferResidentNV (GLenum target, GLenum access); -GLAPI void APIENTRY glMakeBufferNonResidentNV (GLenum target); -GLAPI GLboolean APIENTRY glIsBufferResidentNV (GLenum target); -GLAPI void APIENTRY glMakeNamedBufferResidentNV (GLuint buffer, GLenum access); -GLAPI void APIENTRY glMakeNamedBufferNonResidentNV (GLuint buffer); -GLAPI GLboolean APIENTRY glIsNamedBufferResidentNV (GLuint buffer); -GLAPI void APIENTRY glGetBufferParameterui64vNV (GLenum target, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glGetNamedBufferParameterui64vNV (GLuint buffer, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glGetIntegerui64vNV (GLenum value, GLuint64EXT *result); -GLAPI void APIENTRY glUniformui64NV (GLint location, GLuint64EXT value); -GLAPI void APIENTRY glUniformui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glGetUniformui64vNV (GLuint program, GLint location, GLuint64EXT *params); -GLAPI void APIENTRY glProgramUniformui64NV (GLuint program, GLint location, GLuint64EXT value); -GLAPI void APIENTRY glProgramUniformui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLMAKEBUFFERRESIDENTNVPROC) (GLenum target, GLenum access); -typedef void (APIENTRYP PFNGLMAKEBUFFERNONRESIDENTNVPROC) (GLenum target); -typedef GLboolean (APIENTRYP PFNGLISBUFFERRESIDENTNVPROC) (GLenum target); -typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERRESIDENTNVPROC) (GLuint buffer, GLenum access); -typedef void (APIENTRYP PFNGLMAKENAMEDBUFFERNONRESIDENTNVPROC) (GLuint buffer); -typedef GLboolean (APIENTRYP PFNGLISNAMEDBUFFERRESIDENTNVPROC) (GLuint buffer); -typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERUI64VNVPROC) (GLenum target, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLGETNAMEDBUFFERPARAMETERUI64VNVPROC) (GLuint buffer, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLGETINTEGERUI64VNVPROC) (GLenum value, GLuint64EXT *result); -typedef void (APIENTRYP PFNGLUNIFORMUI64NVPROC) (GLint location, GLuint64EXT value); -typedef void (APIENTRYP PFNGLUNIFORMUI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLGETUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64NVPROC) (GLuint program, GLint location, GLuint64EXT value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORMUI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#endif - -#ifndef GL_NV_vertex_buffer_unified_memory -#define GL_NV_vertex_buffer_unified_memory 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBufferAddressRangeNV (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); -GLAPI void APIENTRY glVertexFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glNormalFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glColorFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glIndexFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glTexCoordFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glEdgeFlagFormatNV (GLsizei stride); -GLAPI void APIENTRY glSecondaryColorFormatNV (GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glFogCoordFormatNV (GLenum type, GLsizei stride); -GLAPI void APIENTRY glVertexAttribFormatNV (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); -GLAPI void APIENTRY glVertexAttribIFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); -GLAPI void APIENTRY glGetIntegerui64i_vNV (GLenum value, GLuint index, GLuint64EXT *result); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBUFFERADDRESSRANGENVPROC) (GLenum pname, GLuint index, GLuint64EXT address, GLsizeiptr length); -typedef void (APIENTRYP PFNGLVERTEXFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLNORMALFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLINDEXFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLTEXCOORDFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLEDGEFLAGFORMATNVPROC) (GLsizei stride); -typedef void (APIENTRYP PFNGLSECONDARYCOLORFORMATNVPROC) (GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLFOGCOORDFORMATNVPROC) (GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXATTRIBFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride); -typedef void (APIENTRYP PFNGLVERTEXATTRIBIFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); -typedef void (APIENTRYP PFNGLGETINTEGERUI64I_VNVPROC) (GLenum value, GLuint index, GLuint64EXT *result); -#endif - -#ifndef GL_NV_texture_barrier -#define GL_NV_texture_barrier 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTextureBarrierNV (void); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXTUREBARRIERNVPROC) (void); -#endif - -#ifndef GL_AMD_shader_stencil_export -#define GL_AMD_shader_stencil_export 1 -#endif - -#ifndef GL_AMD_seamless_cubemap_per_texture -#define GL_AMD_seamless_cubemap_per_texture 1 -#endif - -#ifndef GL_AMD_conservative_depth -#define GL_AMD_conservative_depth 1 -#endif - -#ifndef GL_EXT_shader_image_load_store -#define GL_EXT_shader_image_load_store 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glBindImageTextureEXT (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); -GLAPI void APIENTRY glMemoryBarrierEXT (GLbitfield barriers); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLBINDIMAGETEXTUREEXTPROC) (GLuint index, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLint format); -typedef void (APIENTRYP PFNGLMEMORYBARRIEREXTPROC) (GLbitfield barriers); -#endif - -#ifndef GL_EXT_vertex_attrib_64bit -#define GL_EXT_vertex_attrib_64bit 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribL1dEXT (GLuint index, GLdouble x); -GLAPI void APIENTRY glVertexAttribL2dEXT (GLuint index, GLdouble x, GLdouble y); -GLAPI void APIENTRY glVertexAttribL3dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z); -GLAPI void APIENTRY glVertexAttribL4dEXT (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -GLAPI void APIENTRY glVertexAttribL1dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL2dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL3dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribL4dvEXT (GLuint index, const GLdouble *v); -GLAPI void APIENTRY glVertexAttribLPointerEXT (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glGetVertexAttribLdvEXT (GLuint index, GLenum pname, GLdouble *params); -GLAPI void APIENTRY glVertexArrayVertexAttribLOffsetEXT (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DEXTPROC) (GLuint index, GLdouble x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DEXTPROC) (GLuint index, GLdouble x, GLdouble y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DEXTPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4DVEXTPROC) (GLuint index, const GLdouble *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLPOINTEREXTPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLDVEXTPROC) (GLuint index, GLenum pname, GLdouble *params); -typedef void (APIENTRYP PFNGLVERTEXARRAYVERTEXATTRIBLOFFSETEXTPROC) (GLuint vaobj, GLuint buffer, GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); -#endif - -#ifndef GL_NV_gpu_program5 -#define GL_NV_gpu_program5 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glProgramSubroutineParametersuivNV (GLenum target, GLsizei count, const GLuint *params); -GLAPI void APIENTRY glGetProgramSubroutineParameteruivNV (GLenum target, GLuint index, GLuint *param); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLPROGRAMSUBROUTINEPARAMETERSUIVNVPROC) (GLenum target, GLsizei count, const GLuint *params); -typedef void (APIENTRYP PFNGLGETPROGRAMSUBROUTINEPARAMETERUIVNVPROC) (GLenum target, GLuint index, GLuint *param); -#endif - -#ifndef GL_NV_gpu_shader5 -#define GL_NV_gpu_shader5 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glUniform1i64NV (GLint location, GLint64EXT x); -GLAPI void APIENTRY glUniform2i64NV (GLint location, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glUniform3i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glUniform4i64NV (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glUniform1i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform2i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform3i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform4i64vNV (GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glUniform1ui64NV (GLint location, GLuint64EXT x); -GLAPI void APIENTRY glUniform2ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glUniform3ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glUniform4ui64NV (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glUniform1ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform2ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform3ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glUniform4ui64vNV (GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glGetUniformi64vNV (GLuint program, GLint location, GLint64EXT *params); -GLAPI void APIENTRY glProgramUniform1i64NV (GLuint program, GLint location, GLint64EXT x); -GLAPI void APIENTRY glProgramUniform2i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glProgramUniform3i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glProgramUniform4i64NV (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glProgramUniform1i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform2i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform3i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform4i64vNV (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -GLAPI void APIENTRY glProgramUniform1ui64NV (GLuint program, GLint location, GLuint64EXT x); -GLAPI void APIENTRY glProgramUniform2ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glProgramUniform3ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glProgramUniform4ui64NV (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glProgramUniform1ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform2ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform3ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -GLAPI void APIENTRY glProgramUniform4ui64vNV (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLUNIFORM1I64NVPROC) (GLint location, GLint64EXT x); -typedef void (APIENTRYP PFNGLUNIFORM2I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLUNIFORM3I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLUNIFORM4I64NVPROC) (GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLUNIFORM1I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM2I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM3I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM4I64VNVPROC) (GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM1UI64NVPROC) (GLint location, GLuint64EXT x); -typedef void (APIENTRYP PFNGLUNIFORM2UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLUNIFORM3UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLUNIFORM4UI64NVPROC) (GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLUNIFORM1UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM2UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM3UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLUNIFORM4UI64VNVPROC) (GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLGETUNIFORMI64VNVPROC) (GLuint program, GLint location, GLint64EXT *params); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64NVPROC) (GLuint program, GLint location, GLint64EXT x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64NVPROC) (GLuint program, GLint location, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4I64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64NVPROC) (GLuint program, GLint location, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM1UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM2UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM3UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -typedef void (APIENTRYP PFNGLPROGRAMUNIFORM4UI64VNVPROC) (GLuint program, GLint location, GLsizei count, const GLuint64EXT *value); -#endif - -#ifndef GL_NV_shader_buffer_store -#define GL_NV_shader_buffer_store 1 -#endif - -#ifndef GL_NV_tessellation_program5 -#define GL_NV_tessellation_program5 1 -#endif - -#ifndef GL_NV_vertex_attrib_integer_64bit -#define GL_NV_vertex_attrib_integer_64bit 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVertexAttribL1i64NV (GLuint index, GLint64EXT x); -GLAPI void APIENTRY glVertexAttribL2i64NV (GLuint index, GLint64EXT x, GLint64EXT y); -GLAPI void APIENTRY glVertexAttribL3i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); -GLAPI void APIENTRY glVertexAttribL4i64NV (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -GLAPI void APIENTRY glVertexAttribL1i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL2i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL3i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL4i64vNV (GLuint index, const GLint64EXT *v); -GLAPI void APIENTRY glVertexAttribL1ui64NV (GLuint index, GLuint64EXT x); -GLAPI void APIENTRY glVertexAttribL2ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y); -GLAPI void APIENTRY glVertexAttribL3ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -GLAPI void APIENTRY glVertexAttribL4ui64NV (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -GLAPI void APIENTRY glVertexAttribL1ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL2ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL3ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glVertexAttribL4ui64vNV (GLuint index, const GLuint64EXT *v); -GLAPI void APIENTRY glGetVertexAttribLi64vNV (GLuint index, GLenum pname, GLint64EXT *params); -GLAPI void APIENTRY glGetVertexAttribLui64vNV (GLuint index, GLenum pname, GLuint64EXT *params); -GLAPI void APIENTRY glVertexAttribLFormatNV (GLuint index, GLint size, GLenum type, GLsizei stride); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64NVPROC) (GLuint index, GLint64EXT x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64NVPROC) (GLuint index, GLint64EXT x, GLint64EXT y, GLint64EXT z, GLint64EXT w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4I64VNVPROC) (GLuint index, const GLint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64NVPROC) (GLuint index, GLuint64EXT x); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64NVPROC) (GLuint index, GLuint64EXT x, GLuint64EXT y, GLuint64EXT z, GLuint64EXT w); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL1UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL2UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL3UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLVERTEXATTRIBL4UI64VNVPROC) (GLuint index, const GLuint64EXT *v); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLI64VNVPROC) (GLuint index, GLenum pname, GLint64EXT *params); -typedef void (APIENTRYP PFNGLGETVERTEXATTRIBLUI64VNVPROC) (GLuint index, GLenum pname, GLuint64EXT *params); -typedef void (APIENTRYP PFNGLVERTEXATTRIBLFORMATNVPROC) (GLuint index, GLint size, GLenum type, GLsizei stride); -#endif - -#ifndef GL_NV_multisample_coverage -#define GL_NV_multisample_coverage 1 -#endif - -#ifndef GL_AMD_name_gen_delete -#define GL_AMD_name_gen_delete 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glGenNamesAMD (GLenum identifier, GLuint num, GLuint *names); -GLAPI void APIENTRY glDeleteNamesAMD (GLenum identifier, GLuint num, const GLuint *names); -GLAPI GLboolean APIENTRY glIsNameAMD (GLenum identifier, GLuint name); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLGENNAMESAMDPROC) (GLenum identifier, GLuint num, GLuint *names); -typedef void (APIENTRYP PFNGLDELETENAMESAMDPROC) (GLenum identifier, GLuint num, const GLuint *names); -typedef GLboolean (APIENTRYP PFNGLISNAMEAMDPROC) (GLenum identifier, GLuint name); -#endif - -#ifndef GL_AMD_debug_output -#define GL_AMD_debug_output 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glDebugMessageEnableAMD (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -GLAPI void APIENTRY glDebugMessageInsertAMD (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); -GLAPI void APIENTRY glDebugMessageCallbackAMD (GLDEBUGPROCAMD callback, GLvoid *userParam); -GLAPI GLuint APIENTRY glGetDebugMessageLogAMD (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); -typedef void (APIENTRYP PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); -typedef void (APIENTRYP PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, GLvoid *userParam); -typedef GLuint (APIENTRYP PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); -#endif - -#ifndef GL_NV_vdpau_interop -#define GL_NV_vdpau_interop 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glVDPAUInitNV (const GLvoid *vdpDevice, const GLvoid *getProcAddress); -GLAPI void APIENTRY glVDPAUFiniNV (void); -GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterVideoSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -GLAPI GLvdpauSurfaceNV APIENTRY glVDPAURegisterOutputSurfaceNV (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -GLAPI void APIENTRY glVDPAUIsSurfaceNV (GLvdpauSurfaceNV surface); -GLAPI void APIENTRY glVDPAUUnregisterSurfaceNV (GLvdpauSurfaceNV surface); -GLAPI void APIENTRY glVDPAUGetSurfaceivNV (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -GLAPI void APIENTRY glVDPAUSurfaceAccessNV (GLvdpauSurfaceNV surface, GLenum access); -GLAPI void APIENTRY glVDPAUMapSurfacesNV (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); -GLAPI void APIENTRY glVDPAUUnmapSurfacesNV (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLVDPAUINITNVPROC) (const GLvoid *vdpDevice, const GLvoid *getProcAddress); -typedef void (APIENTRYP PFNGLVDPAUFININVPROC) (void); -typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTERVIDEOSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -typedef GLvdpauSurfaceNV (APIENTRYP PFNGLVDPAUREGISTEROUTPUTSURFACENVPROC) (GLvoid *vdpSurface, GLenum target, GLsizei numTextureNames, const GLuint *textureNames); -typedef void (APIENTRYP PFNGLVDPAUISSURFACENVPROC) (GLvdpauSurfaceNV surface); -typedef void (APIENTRYP PFNGLVDPAUUNREGISTERSURFACENVPROC) (GLvdpauSurfaceNV surface); -typedef void (APIENTRYP PFNGLVDPAUGETSURFACEIVNVPROC) (GLvdpauSurfaceNV surface, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); -typedef void (APIENTRYP PFNGLVDPAUSURFACEACCESSNVPROC) (GLvdpauSurfaceNV surface, GLenum access); -typedef void (APIENTRYP PFNGLVDPAUMAPSURFACESNVPROC) (GLsizei numSurfaces, const GLvdpauSurfaceNV *surfaces); -typedef void (APIENTRYP PFNGLVDPAUUNMAPSURFACESNVPROC) (GLsizei numSurface, const GLvdpauSurfaceNV *surfaces); -#endif - -#ifndef GL_AMD_transform_feedback3_lines_triangles -#define GL_AMD_transform_feedback3_lines_triangles 1 -#endif - -#ifndef GL_AMD_depth_clamp_separate -#define GL_AMD_depth_clamp_separate 1 -#endif - -#ifndef GL_EXT_texture_sRGB_decode -#define GL_EXT_texture_sRGB_decode 1 -#endif - -#ifndef GL_NV_texture_multisample -#define GL_NV_texture_multisample 1 -#ifdef GL_GLEXT_PROTOTYPES -GLAPI void APIENTRY glTexImage2DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTexImage3DMultisampleCoverageNV (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage2DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage3DMultisampleNV (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage2DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -GLAPI void APIENTRY glTextureImage3DMultisampleCoverageNV (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -#endif /* GL_GLEXT_PROTOTYPES */ -typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLENVPROC) (GLuint texture, GLenum target, GLsizei samples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE2DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLboolean fixedSampleLocations); -typedef void (APIENTRYP PFNGLTEXTUREIMAGE3DMULTISAMPLECOVERAGENVPROC) (GLuint texture, GLenum target, GLsizei coverageSamples, GLsizei colorSamples, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedSampleLocations); -#endif - -#ifndef GL_AMD_blend_minmax_factor -#define GL_AMD_blend_minmax_factor 1 -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/3rdParty/glext/GL/wglext.h b/3rdParty/glext/GL/wglext.h deleted file mode 100644 index 9d2d232..0000000 --- a/3rdParty/glext/GL/wglext.h +++ /dev/null @@ -1,929 +0,0 @@ -#ifndef __wglext_h_ -#define __wglext_h_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* -** Copyright (c) 2007-2010 The Khronos Group Inc. -** -** Permission is hereby granted, free of charge, to any person obtaining a -** copy of this software and/or associated documentation files (the -** "Materials"), to deal in the Materials without restriction, including -** without limitation the rights to use, copy, modify, merge, publish, -** distribute, sublicense, and/or sell copies of the Materials, and to -** permit persons to whom the Materials are furnished to do so, subject to -** the following conditions: -** -** The above copyright notice and this permission notice shall be included -** in all copies or substantial portions of the Materials. -** -** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. -*/ - -/* Function declaration macros - to move into glplatform.h */ - -#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) -#define WIN32_LEAN_AND_MEAN 1 -#include -#endif - -#ifndef APIENTRY -#define APIENTRY -#endif -#ifndef APIENTRYP -#define APIENTRYP APIENTRY * -#endif -#ifndef GLAPI -#define GLAPI extern -#endif - -/*************************************************************/ - -/* Header file version number */ -/* wglext.h last updated 2011/04/13 */ -/* Current version at http://www.opengl.org/registry/ */ -#define WGL_WGLEXT_VERSION 23 - -#ifndef WGL_ARB_buffer_region -#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 -#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 -#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 -#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 -#endif - -#ifndef WGL_ARB_multisample -#define WGL_SAMPLE_BUFFERS_ARB 0x2041 -#define WGL_SAMPLES_ARB 0x2042 -#endif - -#ifndef WGL_ARB_extensions_string -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 -#define WGL_DRAW_TO_WINDOW_ARB 0x2001 -#define WGL_DRAW_TO_BITMAP_ARB 0x2002 -#define WGL_ACCELERATION_ARB 0x2003 -#define WGL_NEED_PALETTE_ARB 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 -#define WGL_SWAP_METHOD_ARB 0x2007 -#define WGL_NUMBER_OVERLAYS_ARB 0x2008 -#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 -#define WGL_TRANSPARENT_ARB 0x200A -#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 -#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 -#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 -#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A -#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B -#define WGL_SHARE_DEPTH_ARB 0x200C -#define WGL_SHARE_STENCIL_ARB 0x200D -#define WGL_SHARE_ACCUM_ARB 0x200E -#define WGL_SUPPORT_GDI_ARB 0x200F -#define WGL_SUPPORT_OPENGL_ARB 0x2010 -#define WGL_DOUBLE_BUFFER_ARB 0x2011 -#define WGL_STEREO_ARB 0x2012 -#define WGL_PIXEL_TYPE_ARB 0x2013 -#define WGL_COLOR_BITS_ARB 0x2014 -#define WGL_RED_BITS_ARB 0x2015 -#define WGL_RED_SHIFT_ARB 0x2016 -#define WGL_GREEN_BITS_ARB 0x2017 -#define WGL_GREEN_SHIFT_ARB 0x2018 -#define WGL_BLUE_BITS_ARB 0x2019 -#define WGL_BLUE_SHIFT_ARB 0x201A -#define WGL_ALPHA_BITS_ARB 0x201B -#define WGL_ALPHA_SHIFT_ARB 0x201C -#define WGL_ACCUM_BITS_ARB 0x201D -#define WGL_ACCUM_RED_BITS_ARB 0x201E -#define WGL_ACCUM_GREEN_BITS_ARB 0x201F -#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 -#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 -#define WGL_DEPTH_BITS_ARB 0x2022 -#define WGL_STENCIL_BITS_ARB 0x2023 -#define WGL_AUX_BUFFERS_ARB 0x2024 -#define WGL_NO_ACCELERATION_ARB 0x2025 -#define WGL_GENERIC_ACCELERATION_ARB 0x2026 -#define WGL_FULL_ACCELERATION_ARB 0x2027 -#define WGL_SWAP_EXCHANGE_ARB 0x2028 -#define WGL_SWAP_COPY_ARB 0x2029 -#define WGL_SWAP_UNDEFINED_ARB 0x202A -#define WGL_TYPE_RGBA_ARB 0x202B -#define WGL_TYPE_COLORINDEX_ARB 0x202C -#endif - -#ifndef WGL_ARB_make_current_read -#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 -#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 -#endif - -#ifndef WGL_ARB_pbuffer -#define WGL_DRAW_TO_PBUFFER_ARB 0x202D -#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E -#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 -#define WGL_PBUFFER_LARGEST_ARB 0x2033 -#define WGL_PBUFFER_WIDTH_ARB 0x2034 -#define WGL_PBUFFER_HEIGHT_ARB 0x2035 -#define WGL_PBUFFER_LOST_ARB 0x2036 -#endif - -#ifndef WGL_ARB_render_texture -#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 -#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 -#define WGL_TEXTURE_FORMAT_ARB 0x2072 -#define WGL_TEXTURE_TARGET_ARB 0x2073 -#define WGL_MIPMAP_TEXTURE_ARB 0x2074 -#define WGL_TEXTURE_RGB_ARB 0x2075 -#define WGL_TEXTURE_RGBA_ARB 0x2076 -#define WGL_NO_TEXTURE_ARB 0x2077 -#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 -#define WGL_TEXTURE_1D_ARB 0x2079 -#define WGL_TEXTURE_2D_ARB 0x207A -#define WGL_MIPMAP_LEVEL_ARB 0x207B -#define WGL_CUBE_MAP_FACE_ARB 0x207C -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 -#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 -#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 -#define WGL_FRONT_LEFT_ARB 0x2083 -#define WGL_FRONT_RIGHT_ARB 0x2084 -#define WGL_BACK_LEFT_ARB 0x2085 -#define WGL_BACK_RIGHT_ARB 0x2086 -#define WGL_AUX0_ARB 0x2087 -#define WGL_AUX1_ARB 0x2088 -#define WGL_AUX2_ARB 0x2089 -#define WGL_AUX3_ARB 0x208A -#define WGL_AUX4_ARB 0x208B -#define WGL_AUX5_ARB 0x208C -#define WGL_AUX6_ARB 0x208D -#define WGL_AUX7_ARB 0x208E -#define WGL_AUX8_ARB 0x208F -#define WGL_AUX9_ARB 0x2090 -#endif - -#ifndef WGL_ARB_pixel_format_float -#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 -#endif - -#ifndef WGL_ARB_framebuffer_sRGB -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 -#endif - -#ifndef WGL_ARB_create_context -#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 -#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 -#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 -#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 -#define WGL_CONTEXT_FLAGS_ARB 0x2094 -#define ERROR_INVALID_VERSION_ARB 0x2095 -#endif - -#ifndef WGL_ARB_create_context_profile -#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 -#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 -#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 -#define ERROR_INVALID_PROFILE_ARB 0x2096 -#endif - -#ifndef WGL_ARB_create_context_robustness -#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 -#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 -#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 -#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 -#endif - -#ifndef WGL_EXT_make_current_read -#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 -#endif - -#ifndef WGL_EXT_pixel_format -#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 -#define WGL_DRAW_TO_WINDOW_EXT 0x2001 -#define WGL_DRAW_TO_BITMAP_EXT 0x2002 -#define WGL_ACCELERATION_EXT 0x2003 -#define WGL_NEED_PALETTE_EXT 0x2004 -#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 -#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 -#define WGL_SWAP_METHOD_EXT 0x2007 -#define WGL_NUMBER_OVERLAYS_EXT 0x2008 -#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 -#define WGL_TRANSPARENT_EXT 0x200A -#define WGL_TRANSPARENT_VALUE_EXT 0x200B -#define WGL_SHARE_DEPTH_EXT 0x200C -#define WGL_SHARE_STENCIL_EXT 0x200D -#define WGL_SHARE_ACCUM_EXT 0x200E -#define WGL_SUPPORT_GDI_EXT 0x200F -#define WGL_SUPPORT_OPENGL_EXT 0x2010 -#define WGL_DOUBLE_BUFFER_EXT 0x2011 -#define WGL_STEREO_EXT 0x2012 -#define WGL_PIXEL_TYPE_EXT 0x2013 -#define WGL_COLOR_BITS_EXT 0x2014 -#define WGL_RED_BITS_EXT 0x2015 -#define WGL_RED_SHIFT_EXT 0x2016 -#define WGL_GREEN_BITS_EXT 0x2017 -#define WGL_GREEN_SHIFT_EXT 0x2018 -#define WGL_BLUE_BITS_EXT 0x2019 -#define WGL_BLUE_SHIFT_EXT 0x201A -#define WGL_ALPHA_BITS_EXT 0x201B -#define WGL_ALPHA_SHIFT_EXT 0x201C -#define WGL_ACCUM_BITS_EXT 0x201D -#define WGL_ACCUM_RED_BITS_EXT 0x201E -#define WGL_ACCUM_GREEN_BITS_EXT 0x201F -#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 -#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 -#define WGL_DEPTH_BITS_EXT 0x2022 -#define WGL_STENCIL_BITS_EXT 0x2023 -#define WGL_AUX_BUFFERS_EXT 0x2024 -#define WGL_NO_ACCELERATION_EXT 0x2025 -#define WGL_GENERIC_ACCELERATION_EXT 0x2026 -#define WGL_FULL_ACCELERATION_EXT 0x2027 -#define WGL_SWAP_EXCHANGE_EXT 0x2028 -#define WGL_SWAP_COPY_EXT 0x2029 -#define WGL_SWAP_UNDEFINED_EXT 0x202A -#define WGL_TYPE_RGBA_EXT 0x202B -#define WGL_TYPE_COLORINDEX_EXT 0x202C -#endif - -#ifndef WGL_EXT_pbuffer -#define WGL_DRAW_TO_PBUFFER_EXT 0x202D -#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E -#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F -#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 -#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 -#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 -#define WGL_PBUFFER_LARGEST_EXT 0x2033 -#define WGL_PBUFFER_WIDTH_EXT 0x2034 -#define WGL_PBUFFER_HEIGHT_EXT 0x2035 -#endif - -#ifndef WGL_EXT_depth_float -#define WGL_DEPTH_FLOAT_EXT 0x2040 -#endif - -#ifndef WGL_3DFX_multisample -#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 -#define WGL_SAMPLES_3DFX 0x2061 -#endif - -#ifndef WGL_EXT_multisample -#define WGL_SAMPLE_BUFFERS_EXT 0x2041 -#define WGL_SAMPLES_EXT 0x2042 -#endif - -#ifndef WGL_I3D_digital_video_control -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 -#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 -#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 -#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 -#endif - -#ifndef WGL_I3D_gamma -#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E -#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F -#endif - -#ifndef WGL_I3D_genlock -#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 -#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 -#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 -#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 -#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 -#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 -#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A -#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B -#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C -#endif - -#ifndef WGL_I3D_image_buffer -#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 -#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 -#endif - -#ifndef WGL_I3D_swap_frame_lock -#endif - -#ifndef WGL_NV_render_depth_texture -#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 -#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 -#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 -#define WGL_DEPTH_COMPONENT_NV 0x20A7 -#endif - -#ifndef WGL_NV_render_texture_rectangle -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 -#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 -#endif - -#ifndef WGL_ATI_pixel_format_float -#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 -#endif - -#ifndef WGL_NV_float_buffer -#define WGL_FLOAT_COMPONENTS_NV 0x20B0 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 -#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 -#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 -#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 -#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 -#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 -#endif - -#ifndef WGL_3DL_stereo_control -#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 -#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 -#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 -#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 -#endif - -#ifndef WGL_EXT_pixel_format_packed_float -#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 -#endif - -#ifndef WGL_EXT_framebuffer_sRGB -#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 -#endif - -#ifndef WGL_NV_present_video -#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 -#endif - -#ifndef WGL_NV_video_out -#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 -#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 -#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 -#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 -#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 -#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 -#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 -#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 -#define WGL_VIDEO_OUT_FRAME 0x20C8 -#define WGL_VIDEO_OUT_FIELD_1 0x20C9 -#define WGL_VIDEO_OUT_FIELD_2 0x20CA -#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB -#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC -#endif - -#ifndef WGL_NV_swap_group -#endif - -#ifndef WGL_NV_gpu_affinity -#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 -#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 -#endif - -#ifndef WGL_AMD_gpu_association -#define WGL_GPU_VENDOR_AMD 0x1F00 -#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 -#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 -#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 -#define WGL_GPU_RAM_AMD 0x21A3 -#define WGL_GPU_CLOCK_AMD 0x21A4 -#define WGL_GPU_NUM_PIPES_AMD 0x21A5 -#define WGL_GPU_NUM_SIMD_AMD 0x21A6 -#define WGL_GPU_NUM_RB_AMD 0x21A7 -#define WGL_GPU_NUM_SPI_AMD 0x21A8 -#endif - -#ifndef WGL_NV_video_capture -#define WGL_UNIQUE_ID_NV 0x20CE -#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF -#endif - -#ifndef WGL_NV_copy_image -#endif - -#ifndef WGL_NV_multisample_coverage -#define WGL_COVERAGE_SAMPLES_NV 0x2042 -#define WGL_COLOR_SAMPLES_NV 0x20B9 -#endif - -#ifndef WGL_EXT_create_context_es2_profile -#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004 -#endif - -#ifndef WGL_NV_DX_interop -#define WGL_ACCESS_READ_ONLY_NV 0x00000000 -#define WGL_ACCESS_READ_WRITE_NV 0x00000001 -#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002 -#endif - - -/*************************************************************/ - -#ifndef WGL_ARB_pbuffer -DECLARE_HANDLE(HPBUFFERARB); -#endif -#ifndef WGL_EXT_pbuffer -DECLARE_HANDLE(HPBUFFEREXT); -#endif -#ifndef WGL_NV_present_video -DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); -#endif -#ifndef WGL_NV_video_output -DECLARE_HANDLE(HPVIDEODEV); -#endif -#ifndef WGL_NV_gpu_affinity -DECLARE_HANDLE(HPGPUNV); -DECLARE_HANDLE(HGPUNV); - -typedef struct _GPU_DEVICE { - DWORD cb; - CHAR DeviceName[32]; - CHAR DeviceString[128]; - DWORD Flags; - RECT rcVirtualScreen; -} GPU_DEVICE, *PGPU_DEVICE; -#endif -#ifndef WGL_NV_video_capture -DECLARE_HANDLE(HVIDEOINPUTDEVICENV); -#endif - -#ifndef WGL_ARB_buffer_region -#define WGL_ARB_buffer_region 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType); -extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion); -extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height); -extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); -typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); -typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); -typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); -#endif - -#ifndef WGL_ARB_multisample -#define WGL_ARB_multisample 1 -#endif - -#ifndef WGL_ARB_extensions_string -#define WGL_ARB_extensions_string 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern const char * WINAPI wglGetExtensionsStringARB (HDC hdc); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); -#endif - -#ifndef WGL_ARB_pixel_format -#define WGL_ARB_pixel_format 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -extern BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - -#ifndef WGL_ARB_make_current_read -#define WGL_ARB_make_current_read 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -extern HDC WINAPI wglGetCurrentReadDCARB (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); -#endif - -#ifndef WGL_ARB_pbuffer -#define WGL_ARB_pbuffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer); -extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC); -extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer); -extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -#endif - -#ifndef WGL_ARB_render_texture -#define WGL_ARB_render_texture 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); -extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer); -extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); -typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); -#endif - -#ifndef WGL_ARB_pixel_format_float -#define WGL_ARB_pixel_format_float 1 -#endif - -#ifndef WGL_ARB_framebuffer_sRGB -#define WGL_ARB_framebuffer_sRGB 1 -#endif - -#ifndef WGL_ARB_create_context -#define WGL_ARB_create_context 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); -#endif - -#ifndef WGL_ARB_create_context_profile -#define WGL_ARB_create_context_profile 1 -#endif - -#ifndef WGL_ARB_create_context_robustness -#define WGL_ARB_create_context_robustness 1 -#endif - -#ifndef WGL_EXT_display_color_table -#define WGL_EXT_display_color_table 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id); -extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length); -extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id); -extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); -typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); -typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); -#endif - -#ifndef WGL_EXT_extensions_string -#define WGL_EXT_extensions_string 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern const char * WINAPI wglGetExtensionsStringEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); -#endif - -#ifndef WGL_EXT_make_current_read -#define WGL_EXT_make_current_read 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -extern HDC WINAPI wglGetCurrentReadDCEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); -#endif - -#ifndef WGL_EXT_pbuffer -#define WGL_EXT_pbuffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer); -extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC); -extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer); -extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); -typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); -typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); -typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); -#endif - -#ifndef WGL_EXT_pixel_format -#define WGL_EXT_pixel_format 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -extern BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); -typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); -typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -#endif - -#ifndef WGL_EXT_swap_control -#define WGL_EXT_swap_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglSwapIntervalEXT (int interval); -extern int WINAPI wglGetSwapIntervalEXT (void); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); -typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); -#endif - -#ifndef WGL_EXT_depth_float -#define WGL_EXT_depth_float 1 -#endif - -#ifndef WGL_NV_vertex_array_range -#define WGL_NV_vertex_array_range 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern void* WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -extern void WINAPI wglFreeMemoryNV (void *pointer); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); -typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); -#endif - -#ifndef WGL_3DFX_multisample -#define WGL_3DFX_multisample 1 -#endif - -#ifndef WGL_EXT_multisample -#define WGL_EXT_multisample 1 -#endif - -#ifndef WGL_OML_sync_control -#define WGL_OML_sync_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -extern BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator); -extern INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -extern BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -extern BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); -typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); -typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); -typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); -#endif - -#ifndef WGL_I3D_digital_video_control -#define WGL_I3D_digital_video_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue); -extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -#endif - -#ifndef WGL_I3D_gamma -#define WGL_I3D_gamma 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue); -extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue); -extern BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -extern BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); -typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); -typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); -#endif - -#ifndef WGL_I3D_genlock -#define WGL_I3D_genlock 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglEnableGenlockI3D (HDC hDC); -extern BOOL WINAPI wglDisableGenlockI3D (HDC hDC); -extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag); -extern BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource); -extern BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource); -extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge); -extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge); -extern BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate); -extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate); -extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay); -extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay); -extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); -typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); -typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); -typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); -typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); -typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); -#endif - -#ifndef WGL_I3D_image_buffer -#define WGL_I3D_image_buffer 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags); -extern BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress); -extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); -typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); -typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); -typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); -#endif - -#ifndef WGL_I3D_swap_frame_lock -#define WGL_I3D_swap_frame_lock 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglEnableFrameLockI3D (void); -extern BOOL WINAPI wglDisableFrameLockI3D (void); -extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag); -extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); -#endif - -#ifndef WGL_I3D_swap_frame_usage -#define WGL_I3D_swap_frame_usage 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetFrameUsageI3D (float *pUsage); -extern BOOL WINAPI wglBeginFrameTrackingI3D (void); -extern BOOL WINAPI wglEndFrameTrackingI3D (void); -extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); -typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); -#endif - -#ifndef WGL_ATI_pixel_format_float -#define WGL_ATI_pixel_format_float 1 -#endif - -#ifndef WGL_NV_float_buffer -#define WGL_NV_float_buffer 1 -#endif - -#ifndef WGL_3DL_stereo_control -#define WGL_3DL_stereo_control 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); -#endif - -#ifndef WGL_EXT_pixel_format_packed_float -#define WGL_EXT_pixel_format_packed_float 1 -#endif - -#ifndef WGL_EXT_framebuffer_sRGB -#define WGL_EXT_framebuffer_sRGB 1 -#endif - -#ifndef WGL_NV_present_video -#define WGL_NV_present_video 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); -extern BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); -extern BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); -typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); -typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); -#endif - -#ifndef WGL_NV_video_output -#define WGL_NV_video_output 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); -extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice); -extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer); -extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); -extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); -typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); -typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); -typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); -#endif - -#ifndef WGL_NV_swap_group -#define WGL_NV_swap_group 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group); -extern BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier); -extern BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier); -extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); -extern BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count); -extern BOOL WINAPI wglResetFrameCountNV (HDC hDC); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); -typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); -typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); -typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); -typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); -typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); -#endif - -#ifndef WGL_NV_gpu_affinity -#define WGL_NV_gpu_affinity 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu); -extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList); -extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -extern BOOL WINAPI wglDeleteDCNV (HDC hdc); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); -typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); -typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); -typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); -typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); -#endif - -#ifndef WGL_AMD_gpu_association -#define WGL_AMD_gpu_association 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids); -extern INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data); -extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc); -extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id); -extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList); -extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc); -extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc); -extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void); -extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids); -typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data); -typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); -typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList); -typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); -typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); -typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); -typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -#endif - -#ifndef WGL_NV_video_capture -#define WGL_NV_video_capture 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -extern UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); -extern BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -extern BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); -extern BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); -typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); -typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); -typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); -#endif - -#ifndef WGL_NV_copy_image -#define WGL_NV_copy_image 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -#endif - -#ifndef WGL_NV_multisample_coverage -#define WGL_NV_multisample_coverage 1 -#endif - -#ifndef WGL_NV_DX_interop -#define WGL_NV_DX_interop 1 -#ifdef WGL_WGLEXT_PROTOTYPES -extern BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle); -extern HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice); -extern BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice); -extern HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); -extern BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject); -extern BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access); -extern BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); -extern BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects); -#endif /* WGL_WGLEXT_PROTOTYPES */ -typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle); -typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice); -typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); -typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); -typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); -typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); -typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects); -#endif - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/LibOVR/Include/Extras/OVR_Math.h b/LibOVR/Include/Extras/OVR_Math.h new file mode 100644 index 0000000..91f0b07 --- /dev/null +++ b/LibOVR/Include/Extras/OVR_Math.h @@ -0,0 +1,3663 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Math.h +Content : Implementation of 3D primitives such as vectors, matrices. +Created : September 4, 2012 +Authors : Andrew Reisse, Michael Antonov, Steve LaValle, + Anna Yershova, Max Katsev, Dov Katz + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Math_h +#define OVR_Math_h + + +// This file is intended to be independent of the rest of LibOVR and LibOVRKernel and thus +// has no #include dependencies on either. + +#include +#include +#include +#include +#include +#include +#include "../OVR_CAPI.h" // Currently required due to a dependence on the ovrFovPort_ declaration. + +#if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable: 4127) // conditional expression is constant +#endif + + +#if defined(_MSC_VER) + #define OVRMath_sprintf sprintf_s +#else + #define OVRMath_sprintf snprintf +#endif + + +//------------------------------------------------------------------------------------- +// ***** OVR_MATH_ASSERT +// +// Independent debug break implementation for OVR_Math.h. + +#if !defined(OVR_MATH_DEBUG_BREAK) + #if defined(_DEBUG) + #if defined(_MSC_VER) + #define OVR_MATH_DEBUG_BREAK __debugbreak() + #else + #define OVR_MATH_DEBUG_BREAK __builtin_trap() + #endif + #else + #define OVR_MATH_DEBUG_BREAK ((void)0) + #endif +#endif + + +//------------------------------------------------------------------------------------- +// ***** OVR_MATH_ASSERT +// +// Independent OVR_MATH_ASSERT implementation for OVR_Math.h. + +#if !defined(OVR_MATH_ASSERT) + #if defined(_DEBUG) + #define OVR_MATH_ASSERT(p) if (!(p)) { OVR_MATH_DEBUG_BREAK; } + #else + #define OVR_MATH_ASSERT(p) ((void)0) + #endif +#endif + + +//------------------------------------------------------------------------------------- +// ***** OVR_MATH_STATIC_ASSERT +// +// Independent OVR_MATH_ASSERT implementation for OVR_Math.h. + +#if !defined(OVR_MATH_STATIC_ASSERT) + #if defined(__cplusplus) && ((defined(_MSC_VER) && (defined(_MSC_VER) >= 1600)) || defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)) + #define OVR_MATH_STATIC_ASSERT static_assert + #else + #if !defined(OVR_SA_UNUSED) + #if defined(__GNUC__) || defined(__clang__) + #define OVR_SA_UNUSED __attribute__((unused)) + #else + #define OVR_SA_UNUSED + #endif + #define OVR_SA_PASTE(a,b) a##b + #define OVR_SA_HELP(a,b) OVR_SA_PASTE(a,b) + #endif + + #define OVR_MATH_STATIC_ASSERT(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED + #endif +#endif + + + +namespace OVR { + +template +const T OVRMath_Min(const T a, const T b) +{ return (a < b) ? a : b; } + +template +const T OVRMath_Max(const T a, const T b) +{ return (b < a) ? a : b; } + +template +void OVRMath_Swap(T& a, T& b) +{ T temp(a); a = b; b = temp; } + + +//------------------------------------------------------------------------------------- +// ***** Constants for 3D world/axis definitions. + +// Definitions of axes for coordinate and rotation conversions. +enum Axis +{ + Axis_X = 0, Axis_Y = 1, Axis_Z = 2 +}; + +// RotateDirection describes the rotation direction around an axis, interpreted as follows: +// CW - Clockwise while looking "down" from positive axis towards the origin. +// CCW - Counter-clockwise while looking from the positive axis towards the origin, +// which is in the negative axis direction. +// CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate +// system defines Y up, X right, and Z back (pointing out from the screen). In this +// system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane. +enum RotateDirection +{ + Rotate_CCW = 1, + Rotate_CW = -1 +}; + +// Constants for right handed and left handed coordinate systems +enum HandedSystem +{ + Handed_R = 1, Handed_L = -1 +}; + +// AxisDirection describes which way the coordinate axis points. Used by WorldAxes. +enum AxisDirection +{ + Axis_Up = 2, + Axis_Down = -2, + Axis_Right = 1, + Axis_Left = -1, + Axis_In = 3, + Axis_Out = -3 +}; + +struct WorldAxes +{ + AxisDirection XAxis, YAxis, ZAxis; + + WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z) + : XAxis(x), YAxis(y), ZAxis(z) + { OVR_MATH_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));} +}; + +} // namespace OVR + + +//------------------------------------------------------------------------------------// +// ***** C Compatibility Types + +// These declarations are used to support conversion between C types used in +// LibOVR C interfaces and their C++ versions. As an example, they allow passing +// Vector3f into a function that expects ovrVector3f. + +typedef struct ovrQuatf_ ovrQuatf; +typedef struct ovrQuatd_ ovrQuatd; +typedef struct ovrSizei_ ovrSizei; +typedef struct ovrSizef_ ovrSizef; +typedef struct ovrSized_ ovrSized; +typedef struct ovrRecti_ ovrRecti; +typedef struct ovrVector2i_ ovrVector2i; +typedef struct ovrVector2f_ ovrVector2f; +typedef struct ovrVector2d_ ovrVector2d; +typedef struct ovrVector3f_ ovrVector3f; +typedef struct ovrVector3d_ ovrVector3d; +typedef struct ovrVector4f_ ovrVector4f; +typedef struct ovrVector4d_ ovrVector4d; +typedef struct ovrMatrix2f_ ovrMatrix2f; +typedef struct ovrMatrix2d_ ovrMatrix2d; +typedef struct ovrMatrix3f_ ovrMatrix3f; +typedef struct ovrMatrix3d_ ovrMatrix3d; +typedef struct ovrMatrix4f_ ovrMatrix4f; +typedef struct ovrMatrix4d_ ovrMatrix4d; +typedef struct ovrPosef_ ovrPosef; +typedef struct ovrPosed_ ovrPosed; +typedef struct ovrPoseStatef_ ovrPoseStatef; +typedef struct ovrPoseStated_ ovrPoseStated; + +namespace OVR { + +// Forward-declare our templates. +template class Quat; +template class Size; +template class Rect; +template class Vector2; +template class Vector3; +template class Vector4; +template class Matrix3; +template class Matrix4; +template class Pose; +template class PoseState; + +// CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class. +template +struct CompatibleTypes +{ + // Declaration here seems necessary for MSVC; specializations are + // used instead. + typedef struct {} Type; +}; + +// Specializations providing CompatibleTypes::Type value. +template<> struct CompatibleTypes > { typedef ovrQuatf Type; }; +template<> struct CompatibleTypes > { typedef ovrQuatd Type; }; +template<> struct CompatibleTypes > { typedef ovrMatrix3f Type; }; +template<> struct CompatibleTypes > { typedef ovrMatrix3d Type; }; +template<> struct CompatibleTypes > { typedef ovrMatrix4f Type; }; +template<> struct CompatibleTypes > { typedef ovrMatrix4d Type; }; +template<> struct CompatibleTypes > { typedef ovrSizei Type; }; +template<> struct CompatibleTypes > { typedef ovrSizef Type; }; +template<> struct CompatibleTypes > { typedef ovrSized Type; }; +template<> struct CompatibleTypes > { typedef ovrRecti Type; }; +template<> struct CompatibleTypes > { typedef ovrVector2i Type; }; +template<> struct CompatibleTypes > { typedef ovrVector2f Type; }; +template<> struct CompatibleTypes > { typedef ovrVector2d Type; }; +template<> struct CompatibleTypes > { typedef ovrVector3f Type; }; +template<> struct CompatibleTypes > { typedef ovrVector3d Type; }; +template<> struct CompatibleTypes > { typedef ovrVector4f Type; }; +template<> struct CompatibleTypes > { typedef ovrVector4d Type; }; +template<> struct CompatibleTypes > { typedef ovrPosef Type; }; +template<> struct CompatibleTypes > { typedef ovrPosed Type; }; + +//------------------------------------------------------------------------------------// +// ***** Math +// +// Math class contains constants and functions. This class is a template specialized +// per type, with Math and Math being distinct. +template +class Math +{ +public: + // By default, support explicit conversion to float. This allows Vector2 to + // compile, for example. + typedef float OtherFloatType; + + static int Tolerance() { return 0; } // Default value so integer types compile +}; + + +//------------------------------------------------------------------------------------// +// ***** double constants +#define MATH_DOUBLE_PI 3.14159265358979323846 +#define MATH_DOUBLE_TWOPI (2*MATH_DOUBLE_PI) +#define MATH_DOUBLE_PIOVER2 (0.5*MATH_DOUBLE_PI) +#define MATH_DOUBLE_PIOVER4 (0.25*MATH_DOUBLE_PI) +#define MATH_FLOAT_MAXVALUE (FLT_MAX) + +#define MATH_DOUBLE_RADTODEGREEFACTOR (360.0 / MATH_DOUBLE_TWOPI) +#define MATH_DOUBLE_DEGREETORADFACTOR (MATH_DOUBLE_TWOPI / 360.0) + +#define MATH_DOUBLE_E 2.71828182845904523536 +#define MATH_DOUBLE_LOG2E 1.44269504088896340736 +#define MATH_DOUBLE_LOG10E 0.434294481903251827651 +#define MATH_DOUBLE_LN2 0.693147180559945309417 +#define MATH_DOUBLE_LN10 2.30258509299404568402 + +#define MATH_DOUBLE_SQRT2 1.41421356237309504880 +#define MATH_DOUBLE_SQRT1_2 0.707106781186547524401 + +#define MATH_DOUBLE_TOLERANCE 1e-12 // a default number for value equality tolerance: about 4096*Epsilon; +#define MATH_DOUBLE_SINGULARITYRADIUS 1e-12 // about 1-cos(.0001 degree), for gimbal lock numerical problems + +//------------------------------------------------------------------------------------// +// ***** float constants +#define MATH_FLOAT_PI float(MATH_DOUBLE_PI) +#define MATH_FLOAT_TWOPI float(MATH_DOUBLE_TWOPI) +#define MATH_FLOAT_PIOVER2 float(MATH_DOUBLE_PIOVER2) +#define MATH_FLOAT_PIOVER4 float(MATH_DOUBLE_PIOVER4) + +#define MATH_FLOAT_RADTODEGREEFACTOR float(MATH_DOUBLE_RADTODEGREEFACTOR) +#define MATH_FLOAT_DEGREETORADFACTOR float(MATH_DOUBLE_DEGREETORADFACTOR) + +#define MATH_FLOAT_E float(MATH_DOUBLE_E) +#define MATH_FLOAT_LOG2E float(MATH_DOUBLE_LOG2E) +#define MATH_FLOAT_LOG10E float(MATH_DOUBLE_LOG10E) +#define MATH_FLOAT_LN2 float(MATH_DOUBLE_LN2) +#define MATH_FLOAT_LN10 float(MATH_DOUBLE_LN10) + +#define MATH_FLOAT_SQRT2 float(MATH_DOUBLE_SQRT2) +#define MATH_FLOAT_SQRT1_2 float(MATH_DOUBLE_SQRT1_2) + +#define MATH_FLOAT_TOLERANCE 1e-5f // a default number for value equality tolerance: 1e-5, about 64*EPSILON; +#define MATH_FLOAT_SINGULARITYRADIUS 1e-7f // about 1-cos(.025 degree), for gimbal lock numerical problems + + + +// Single-precision Math constants class. +template<> +class Math +{ +public: + typedef double OtherFloatType; + + static inline float Tolerance() { return MATH_FLOAT_TOLERANCE; }; // a default number for value equality tolerance + static inline float SingularityRadius() { return MATH_FLOAT_SINGULARITYRADIUS; }; // for gimbal lock numerical problems +}; + +// Double-precision Math constants class +template<> +class Math +{ +public: + typedef float OtherFloatType; + + static inline double Tolerance() { return MATH_DOUBLE_TOLERANCE; }; // a default number for value equality tolerance + static inline double SingularityRadius() { return MATH_DOUBLE_SINGULARITYRADIUS; }; // for gimbal lock numerical problems +}; + +typedef Math Mathf; +typedef Math Mathd; + +// Conversion functions between degrees and radians +// (non-templated to ensure passing int arguments causes warning) +inline float RadToDegree(float rad) { return rad * MATH_FLOAT_RADTODEGREEFACTOR; } +inline double RadToDegree(double rad) { return rad * MATH_DOUBLE_RADTODEGREEFACTOR; } + +inline float DegreeToRad(float deg) { return deg * MATH_FLOAT_DEGREETORADFACTOR; } +inline double DegreeToRad(double deg) { return deg * MATH_DOUBLE_DEGREETORADFACTOR; } + +// Square function +template +inline T Sqr(T x) { return x*x; } + +// Sign: returns 0 if x == 0, -1 if x < 0, and 1 if x > 0 +template +inline T Sign(T x) { return (x != T(0)) ? (x < T(0) ? T(-1) : T(1)) : T(0); } + +// Numerically stable acos function +inline float Acos(float x) { return (x > 1.0f) ? 0.0f : (x < -1.0f) ? MATH_FLOAT_PI : acos(x); } +inline double Acos(double x) { return (x > 1.0) ? 0.0 : (x < -1.0) ? MATH_DOUBLE_PI : acos(x); } + +// Numerically stable asin function +inline float Asin(float x) { return (x > 1.0f) ? MATH_FLOAT_PIOVER2 : (x < -1.0f) ? -MATH_FLOAT_PIOVER2 : asin(x); } +inline double Asin(double x) { return (x > 1.0) ? MATH_DOUBLE_PIOVER2 : (x < -1.0) ? -MATH_DOUBLE_PIOVER2 : asin(x); } + +#if defined(_MSC_VER) + inline int isnan(double x) { return ::_isnan(x); } +#elif !defined(isnan) // Some libraries #define isnan. + inline int isnan(double x) { return ::isnan(x); } +#endif + +template +class Quat; + + +//------------------------------------------------------------------------------------- +// ***** Vector2<> + +// Vector2f (Vector2d) represents a 2-dimensional vector or point in space, +// consisting of coordinates x and y + +template +class Vector2 +{ +public: + typedef T ElementType; + static const size_t ElementCount = 2; + + T x, y; + + Vector2() : x(0), y(0) { } + Vector2(T x_, T y_) : x(x_), y(y_) { } + explicit Vector2(T s) : x(s), y(s) { } + explicit Vector2(const Vector2::OtherFloatType> &src) + : x((T)src.x), y((T)src.y) { } + + static Vector2 Zero() { return Vector2(0, 0); } + + // C-interop support. + typedef typename CompatibleTypes >::Type CompatibleType; + + Vector2(const CompatibleType& s) : x(s.x), y(s.y) { } + + operator const CompatibleType& () const + { + OVR_MATH_STATIC_ASSERT(sizeof(Vector2) == sizeof(CompatibleType), "sizeof(Vector2) failure"); + return reinterpret_cast(*this); + } + + + bool operator== (const Vector2& b) const { return x == b.x && y == b.y; } + bool operator!= (const Vector2& b) const { return x != b.x || y != b.y; } + + Vector2 operator+ (const Vector2& b) const { return Vector2(x + b.x, y + b.y); } + Vector2& operator+= (const Vector2& b) { x += b.x; y += b.y; return *this; } + Vector2 operator- (const Vector2& b) const { return Vector2(x - b.x, y - b.y); } + Vector2& operator-= (const Vector2& b) { x -= b.x; y -= b.y; return *this; } + Vector2 operator- () const { return Vector2(-x, -y); } + + // Scalar multiplication/division scales vector. + Vector2 operator* (T s) const { return Vector2(x*s, y*s); } + Vector2& operator*= (T s) { x *= s; y *= s; return *this; } + + Vector2 operator/ (T s) const { T rcp = T(1)/s; + return Vector2(x*rcp, y*rcp); } + Vector2& operator/= (T s) { T rcp = T(1)/s; + x *= rcp; y *= rcp; + return *this; } + + static Vector2 Min(const Vector2& a, const Vector2& b) { return Vector2((a.x < b.x) ? a.x : b.x, + (a.y < b.y) ? a.y : b.y); } + static Vector2 Max(const Vector2& a, const Vector2& b) { return Vector2((a.x > b.x) ? a.x : b.x, + (a.y > b.y) ? a.y : b.y); } + + // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. + bool Compare(const Vector2&b, T tolerance =Math::Tolerance()) + { + return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance); + } + + // Access element by index + T& operator[] (int idx) + { + OVR_MATH_ASSERT(0 <= idx && idx < 2); + return *(&x + idx); + } + const T& operator[] (int idx) const + { + OVR_MATH_ASSERT(0 <= idx && idx < 2); + return *(&x + idx); + } + + // Entry-wise product of two vectors + Vector2 EntrywiseMultiply(const Vector2& b) const { return Vector2(x * b.x, y * b.y);} + + + // Multiply and divide operators do entry-wise math. Used Dot() for dot product. + Vector2 operator* (const Vector2& b) const { return Vector2(x * b.x, y * b.y); } + Vector2 operator/ (const Vector2& b) const { return Vector2(x / b.x, y / b.y); } + + // Dot product + // Used to calculate angle q between two vectors among other things, + // as (A dot B) = |a||b|cos(q). + T Dot(const Vector2& b) const { return x*b.x + y*b.y; } + + // Returns the angle from this vector to b, in radians. + T Angle(const Vector2& b) const + { + T div = LengthSq()*b.LengthSq(); + OVR_MATH_ASSERT(div != T(0)); + T result = Acos((this->Dot(b))/sqrt(div)); + return result; + } + + // Return Length of the vector squared. + T LengthSq() const { return (x * x + y * y); } + + // Return vector length. + T Length() const { return sqrt(LengthSq()); } + + // Returns squared distance between two points represented by vectors. + T DistanceSq(const Vector2& b) const { return (*this - b).LengthSq(); } + + // Returns distance between two points represented by vectors. + T Distance(const Vector2& b) const { return (*this - b).Length(); } + + // Determine if this a unit vector. + bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math::Tolerance(); } + + // Normalize, convention vector length to 1. + void Normalize() + { + T s = Length(); + if (s != 0) + s = T(1) / s; + *this *= s; + } + + // Returns normalized (unit) version of the vector without modifying itself. + Vector2 Normalized() const + { + T s = Length(); + if (s != 0) + s = T(1) / s; + return *this * s; + } + + // Linearly interpolates from this vector to another. + // Factor should be between 0.0 and 1.0, with 0 giving full value to this. + Vector2 Lerp(const Vector2& b, T f) const { return *this*(T(1) - f) + b*f; } + + // Projects this vector onto the argument; in other words, + // A.Project(B) returns projection of vector A onto B. + Vector2 ProjectTo(const Vector2& b) const + { + T l2 = b.LengthSq(); + OVR_MATH_ASSERT(l2 != T(0)); + return b * ( Dot(b) / l2 ); + } + + // returns true if vector b is clockwise from this vector + bool IsClockwise(const Vector2& b) const + { + return (x * b.y - y * b.x) < 0; + } +}; + + +typedef Vector2 Vector2f; +typedef Vector2 Vector2d; +typedef Vector2 Vector2i; + +typedef Vector2 Point2f; +typedef Vector2 Point2d; +typedef Vector2 Point2i; + +//------------------------------------------------------------------------------------- +// ***** Vector3<> - 3D vector of {x, y, z} + +// +// Vector3f (Vector3d) represents a 3-dimensional vector or point in space, +// consisting of coordinates x, y and z. + +template +class Vector3 +{ +public: + typedef T ElementType; + static const size_t ElementCount = 3; + + T x, y, z; + + // FIXME: default initialization of a vector class can be very expensive in a full-blown + // application. A few hundred thousand vector constructions is not unlikely and can add + // up to milliseconds of time on processors like the PS3 PPU. + Vector3() : x(0), y(0), z(0) { } + Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { } + explicit Vector3(T s) : x(s), y(s), z(s) { } + explicit Vector3(const Vector3::OtherFloatType> &src) + : x((T)src.x), y((T)src.y), z((T)src.z) { } + + static Vector3 Zero() { return Vector3(0, 0, 0); } + + // C-interop support. + typedef typename CompatibleTypes >::Type CompatibleType; + + Vector3(const CompatibleType& s) : x(s.x), y(s.y), z(s.z) { } + + operator const CompatibleType& () const + { + OVR_MATH_STATIC_ASSERT(sizeof(Vector3) == sizeof(CompatibleType), "sizeof(Vector3) failure"); + return reinterpret_cast(*this); + } + + bool operator== (const Vector3& b) const { return x == b.x && y == b.y && z == b.z; } + bool operator!= (const Vector3& b) const { return x != b.x || y != b.y || z != b.z; } + + Vector3 operator+ (const Vector3& b) const { return Vector3(x + b.x, y + b.y, z + b.z); } + Vector3& operator+= (const Vector3& b) { x += b.x; y += b.y; z += b.z; return *this; } + Vector3 operator- (const Vector3& b) const { return Vector3(x - b.x, y - b.y, z - b.z); } + Vector3& operator-= (const Vector3& b) { x -= b.x; y -= b.y; z -= b.z; return *this; } + Vector3 operator- () const { return Vector3(-x, -y, -z); } + + // Scalar multiplication/division scales vector. + Vector3 operator* (T s) const { return Vector3(x*s, y*s, z*s); } + Vector3& operator*= (T s) { x *= s; y *= s; z *= s; return *this; } + + Vector3 operator/ (T s) const { T rcp = T(1)/s; + return Vector3(x*rcp, y*rcp, z*rcp); } + Vector3& operator/= (T s) { T rcp = T(1)/s; + x *= rcp; y *= rcp; z *= rcp; + return *this; } + + static Vector3 Min(const Vector3& a, const Vector3& b) + { + return Vector3((a.x < b.x) ? a.x : b.x, + (a.y < b.y) ? a.y : b.y, + (a.z < b.z) ? a.z : b.z); + } + static Vector3 Max(const Vector3& a, const Vector3& b) + { + return Vector3((a.x > b.x) ? a.x : b.x, + (a.y > b.y) ? a.y : b.y, + (a.z > b.z) ? a.z : b.z); + } + + // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. + bool IsEqual(const Vector3&b, T tolerance = Math::Tolerance()) + { + return (fabs(b.x-x) < tolerance) && + (fabs(b.y-y) < tolerance) && + (fabs(b.z-z) < tolerance); + } + + T& operator[] (int idx) + { + OVR_MATH_ASSERT(0 <= idx && idx < 3); + return *(&x + idx); + } + + const T& operator[] (int idx) const + { + OVR_MATH_ASSERT(0 <= idx && idx < 3); + return *(&x + idx); + } + + // Entrywise product of two vectors + Vector3 EntrywiseMultiply(const Vector3& b) const { return Vector3(x * b.x, + y * b.y, + z * b.z);} + + // Multiply and divide operators do entry-wise math + Vector3 operator* (const Vector3& b) const { return Vector3(x * b.x, + y * b.y, + z * b.z); } + + Vector3 operator/ (const Vector3& b) const { return Vector3(x / b.x, + y / b.y, + z / b.z); } + + + // Dot product + // Used to calculate angle q between two vectors among other things, + // as (A dot B) = |a||b|cos(q). + T Dot(const Vector3& b) const { return x*b.x + y*b.y + z*b.z; } + + // Compute cross product, which generates a normal vector. + // Direction vector can be determined by right-hand rule: Pointing index finder in + // direction a and middle finger in direction b, thumb will point in a.Cross(b). + Vector3 Cross(const Vector3& b) const { return Vector3(y*b.z - z*b.y, + z*b.x - x*b.z, + x*b.y - y*b.x); } + + // Returns the angle from this vector to b, in radians. + T Angle(const Vector3& b) const + { + T div = LengthSq()*b.LengthSq(); + OVR_MATH_ASSERT(div != T(0)); + T result = Acos((this->Dot(b))/sqrt(div)); + return result; + } + + // Return Length of the vector squared. + T LengthSq() const { return (x * x + y * y + z * z); } + + // Return vector length. + T Length() const { return sqrt(LengthSq()); } + + // Returns squared distance between two points represented by vectors. + T DistanceSq(Vector3 const& b) const { return (*this - b).LengthSq(); } + + // Returns distance between two points represented by vectors. + T Distance(Vector3 const& b) const { return (*this - b).Length(); } + + bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math::Tolerance(); } + + // Normalize, convention vector length to 1. + void Normalize() + { + T s = Length(); + if (s != 0) + s = T(1) / s; + *this *= s; + } + + // Returns normalized (unit) version of the vector without modifying itself. + Vector3 Normalized() const + { + T s = Length(); + if (s != 0) + s = T(1) / s; + return *this * s; + } + + // Linearly interpolates from this vector to another. + // Factor should be between 0.0 and 1.0, with 0 giving full value to this. + Vector3 Lerp(const Vector3& b, T f) const { return *this*(T(1) - f) + b*f; } + + // Projects this vector onto the argument; in other words, + // A.Project(B) returns projection of vector A onto B. + Vector3 ProjectTo(const Vector3& b) const + { + T l2 = b.LengthSq(); + OVR_MATH_ASSERT(l2 != T(0)); + return b * ( Dot(b) / l2 ); + } + + // Projects this vector onto a plane defined by a normal vector + Vector3 ProjectToPlane(const Vector3& normal) const { return *this - this->ProjectTo(normal); } +}; + +typedef Vector3 Vector3f; +typedef Vector3 Vector3d; +typedef Vector3 Vector3i; + +OVR_MATH_STATIC_ASSERT((sizeof(Vector3f) == 3*sizeof(float)), "sizeof(Vector3f) failure"); +OVR_MATH_STATIC_ASSERT((sizeof(Vector3d) == 3*sizeof(double)), "sizeof(Vector3d) failure"); +OVR_MATH_STATIC_ASSERT((sizeof(Vector3i) == 3*sizeof(int32_t)), "sizeof(Vector3i) failure"); + +typedef Vector3 Point3f; +typedef Vector3 Point3d; +typedef Vector3 Point3i; + + +//------------------------------------------------------------------------------------- +// ***** Vector4<> - 4D vector of {x, y, z, w} + +// +// Vector4f (Vector4d) represents a 3-dimensional vector or point in space, +// consisting of coordinates x, y, z and w. + +template +class Vector4 +{ +public: + typedef T ElementType; + static const size_t ElementCount = 4; + + T x, y, z, w; + + // FIXME: default initialization of a vector class can be very expensive in a full-blown + // application. A few hundred thousand vector constructions is not unlikely and can add + // up to milliseconds of time on processors like the PS3 PPU. + Vector4() : x(0), y(0), z(0), w(0) { } + Vector4(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { } + explicit Vector4(T s) : x(s), y(s), z(s), w(s) { } + explicit Vector4(const Vector3& v, const float w_=1) : x(v.x), y(v.y), z(v.z), w(w_) { } + explicit Vector4(const Vector4::OtherFloatType> &src) + : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { } + + static Vector4 Zero() { return Vector4(0, 0, 0, 0); } + + // C-interop support. + typedef typename CompatibleTypes< Vector4 >::Type CompatibleType; + + Vector4(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } + + operator const CompatibleType& () const + { + OVR_MATH_STATIC_ASSERT(sizeof(Vector4) == sizeof(CompatibleType), "sizeof(Vector4) failure"); + return reinterpret_cast(*this); + } + + Vector4& operator= (const Vector3& other) { x=other.x; y=other.y; z=other.z; w=1; return *this; } + bool operator== (const Vector4& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; } + bool operator!= (const Vector4& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; } + + Vector4 operator+ (const Vector4& b) const { return Vector4(x + b.x, y + b.y, z + b.z, w + b.w); } + Vector4& operator+= (const Vector4& b) { x += b.x; y += b.y; z += b.z; w += b.w; return *this; } + Vector4 operator- (const Vector4& b) const { return Vector4(x - b.x, y - b.y, z - b.z, w - b.w); } + Vector4& operator-= (const Vector4& b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; return *this; } + Vector4 operator- () const { return Vector4(-x, -y, -z, -w); } + + // Scalar multiplication/division scales vector. + Vector4 operator* (T s) const { return Vector4(x*s, y*s, z*s, w*s); } + Vector4& operator*= (T s) { x *= s; y *= s; z *= s; w *= s;return *this; } + + Vector4 operator/ (T s) const { T rcp = T(1)/s; + return Vector4(x*rcp, y*rcp, z*rcp, w*rcp); } + Vector4& operator/= (T s) { T rcp = T(1)/s; + x *= rcp; y *= rcp; z *= rcp; w *= rcp; + return *this; } + + static Vector4 Min(const Vector4& a, const Vector4& b) + { + return Vector4((a.x < b.x) ? a.x : b.x, + (a.y < b.y) ? a.y : b.y, + (a.z < b.z) ? a.z : b.z, + (a.w < b.w) ? a.w : b.w); + } + static Vector4 Max(const Vector4& a, const Vector4& b) + { + return Vector4((a.x > b.x) ? a.x : b.x, + (a.y > b.y) ? a.y : b.y, + (a.z > b.z) ? a.z : b.z, + (a.w > b.w) ? a.w : b.w); + } + + // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. + bool Compare(const Vector4&b, T tolerance = Math::Tolerance()) + { + return (fabs(b.x-x) < tolerance) && + (fabs(b.y-y) < tolerance) && + (fabs(b.z-z) < tolerance) && + (fabs(b.w-w) < tolerance); + } + + T& operator[] (int idx) + { + OVR_MATH_ASSERT(0 <= idx && idx < 4); + return *(&x + idx); + } + + const T& operator[] (int idx) const + { + OVR_MATH_ASSERT(0 <= idx && idx < 4); + return *(&x + idx); + } + + // Entry wise product of two vectors + Vector4 EntrywiseMultiply(const Vector4& b) const { return Vector4(x * b.x, + y * b.y, + z * b.z);} + + // Multiply and divide operators do entry-wise math + Vector4 operator* (const Vector4& b) const { return Vector4(x * b.x, + y * b.y, + z * b.z, + w * b.w); } + + Vector4 operator/ (const Vector4& b) const { return Vector4(x / b.x, + y / b.y, + z / b.z, + w / b.w); } + + + // Dot product + T Dot(const Vector4& b) const { return x*b.x + y*b.y + z*b.z + w*b.w; } + + // Return Length of the vector squared. + T LengthSq() const { return (x * x + y * y + z * z + w * w); } + + // Return vector length. + T Length() const { return sqrt(LengthSq()); } + + bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math::Tolerance(); } + + // Normalize, convention vector length to 1. + void Normalize() + { + T s = Length(); + if (s != 0) + s = T(1) / s; + *this *= s; + } + + // Returns normalized (unit) version of the vector without modifying itself. + Vector4 Normalized() const + { + T s = Length(); + if (s != 0) + s = T(1) / s; + return *this * s; + } +}; + +typedef Vector4 Vector4f; +typedef Vector4 Vector4d; +typedef Vector4 Vector4i; + + +//------------------------------------------------------------------------------------- +// ***** Bounds3 + +// Bounds class used to describe a 3D axis aligned bounding box. + +template +class Bounds3 +{ +public: + Vector3 b[2]; + + Bounds3() + { + } + + Bounds3( const Vector3 & mins, const Vector3 & maxs ) +{ + b[0] = mins; + b[1] = maxs; + } + + void Clear() + { + b[0].x = b[0].y = b[0].z = Math::MaxValue; + b[1].x = b[1].y = b[1].z = -Math::MaxValue; + } + + void AddPoint( const Vector3 & v ) + { + b[0].x = (b[0].x < v.x ? b[0].x : v.x); + b[0].y = (b[0].y < v.y ? b[0].y : v.y); + b[0].z = (b[0].z < v.z ? b[0].z : v.z); + b[1].x = (v.x < b[1].x ? b[1].x : v.x); + b[1].y = (v.y < b[1].y ? b[1].y : v.y); + b[1].z = (v.z < b[1].z ? b[1].z : v.z); + } + + const Vector3 & GetMins() const { return b[0]; } + const Vector3 & GetMaxs() const { return b[1]; } + + Vector3 & GetMins() { return b[0]; } + Vector3 & GetMaxs() { return b[1]; } +}; + +typedef Bounds3 Bounds3f; +typedef Bounds3 Bounds3d; + + +//------------------------------------------------------------------------------------- +// ***** Size + +// Size class represents 2D size with Width, Height components. +// Used to describe distentions of render targets, etc. + +template +class Size +{ +public: + T w, h; + + Size() : w(0), h(0) { } + Size(T w_, T h_) : w(w_), h(h_) { } + explicit Size(T s) : w(s), h(s) { } + explicit Size(const Size::OtherFloatType> &src) + : w((T)src.w), h((T)src.h) { } + + // C-interop support. + typedef typename CompatibleTypes >::Type CompatibleType; + + Size(const CompatibleType& s) : w(s.w), h(s.h) { } + + operator const CompatibleType& () const + { + OVR_MATH_STATIC_ASSERT(sizeof(Size) == sizeof(CompatibleType), "sizeof(Size) failure"); + return reinterpret_cast(*this); + } + + bool operator== (const Size& b) const { return w == b.w && h == b.h; } + bool operator!= (const Size& b) const { return w != b.w || h != b.h; } + + Size operator+ (const Size& b) const { return Size(w + b.w, h + b.h); } + Size& operator+= (const Size& b) { w += b.w; h += b.h; return *this; } + Size operator- (const Size& b) const { return Size(w - b.w, h - b.h); } + Size& operator-= (const Size& b) { w -= b.w; h -= b.h; return *this; } + Size operator- () const { return Size(-w, -h); } + Size operator* (const Size& b) const { return Size(w * b.w, h * b.h); } + Size& operator*= (const Size& b) { w *= b.w; h *= b.h; return *this; } + Size operator/ (const Size& b) const { return Size(w / b.w, h / b.h); } + Size& operator/= (const Size& b) { w /= b.w; h /= b.h; return *this; } + + // Scalar multiplication/division scales both components. + Size operator* (T s) const { return Size(w*s, h*s); } + Size& operator*= (T s) { w *= s; h *= s; return *this; } + Size operator/ (T s) const { return Size(w/s, h/s); } + Size& operator/= (T s) { w /= s; h /= s; return *this; } + + static Size Min(const Size& a, const Size& b) { return Size((a.w < b.w) ? a.w : b.w, + (a.h < b.h) ? a.h : b.h); } + static Size Max(const Size& a, const Size& b) { return Size((a.w > b.w) ? a.w : b.w, + (a.h > b.h) ? a.h : b.h); } + + T Area() const { return w * h; } + + inline Vector2 ToVector() const { return Vector2(w, h); } +}; + + +typedef Size Sizei; +typedef Size Sizeu; +typedef Size Sizef; +typedef Size Sized; + + + +//----------------------------------------------------------------------------------- +// ***** Rect + +// Rect describes a rectangular area for rendering, that includes position and size. +template +class Rect +{ +public: + T x, y; + T w, h; + + Rect() { } + Rect(T x1, T y1, T w1, T h1) : x(x1), y(y1), w(w1), h(h1) { } + Rect(const Vector2& pos, const Size& sz) : x(pos.x), y(pos.y), w(sz.w), h(sz.h) { } + Rect(const Size& sz) : x(0), y(0), w(sz.w), h(sz.h) { } + + // C-interop support. + typedef typename CompatibleTypes >::Type CompatibleType; + + Rect(const CompatibleType& s) : x(s.Pos.x), y(s.Pos.y), w(s.Size.w), h(s.Size.h) { } + + operator const CompatibleType& () const + { + OVR_MATH_STATIC_ASSERT(sizeof(Rect) == sizeof(CompatibleType), "sizeof(Rect) failure"); + return reinterpret_cast(*this); + } + + Vector2 GetPos() const { return Vector2(x, y); } + Size GetSize() const { return Size(w, h); } + void SetPos(const Vector2& pos) { x = pos.x; y = pos.y; } + void SetSize(const Size& sz) { w = sz.w; h = sz.h; } + + bool operator == (const Rect& vp) const + { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); } + bool operator != (const Rect& vp) const + { return !operator == (vp); } +}; + +typedef Rect Recti; + + +//-------------------------------------------------------------------------------------// +// ***** Quat +// +// Quatf represents a quaternion class used for rotations. +// +// Quaternion multiplications are done in right-to-left order, to match the +// behavior of matrices. + + +template +class Quat +{ +public: + typedef T ElementType; + static const size_t ElementCount = 4; + + // x,y,z = axis*sin(angle), w = cos(angle) + T x, y, z, w; + + Quat() : x(0), y(0), z(0), w(1) { } + Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { } + explicit Quat(const Quat::OtherFloatType> &src) + : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { } + + typedef typename CompatibleTypes >::Type CompatibleType; + + // C-interop support. + Quat(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } + + operator CompatibleType () const + { + CompatibleType result; + result.x = x; + result.y = y; + result.z = z; + result.w = w; + return result; + } + + // Constructs quaternion for rotation around the axis by an angle. + Quat(const Vector3& axis, T angle) + { + // Make sure we don't divide by zero. + if (axis.LengthSq() == 0) + { + // Assert if the axis is zero, but the angle isn't + OVR_MATH_ASSERT(angle == 0); + x = 0; y = 0; z = 0; w = 1; + return; + } + + Vector3 unitAxis = axis.Normalized(); + T sinHalfAngle = sin(angle * T(0.5)); + + w = cos(angle * T(0.5)); + x = unitAxis.x * sinHalfAngle; + y = unitAxis.y * sinHalfAngle; + z = unitAxis.z * sinHalfAngle; + } + + // Constructs quaternion for rotation around one of the coordinate axis by an angle. + Quat(Axis A, T angle, RotateDirection d = Rotate_CCW, HandedSystem s = Handed_R) + { + T sinHalfAngle = s * d *sin(angle * T(0.5)); + T v[3]; + v[0] = v[1] = v[2] = T(0); + v[A] = sinHalfAngle; + + w = cos(angle * T(0.5)); + x = v[0]; + y = v[1]; + z = v[2]; + } + + // Explicit identity for clairity, saves ambiguity at callsite about Quat() + // being initialized or not. + static Quat Identity() { return Quat(0, 0, 0, 1); } + + // Compute axis and angle from quaternion + void GetAxisAngle(Vector3* axis, T* angle) const + { + if ( x*x + y*y + z*z > Math::Tolerance() * Math::Tolerance() ) { + *axis = Vector3(x, y, z).Normalized(); + *angle = 2 * Acos(w); + if (*angle > ((T)MATH_DOUBLE_PI)) // Reduce the magnitude of the angle, if necessary + { + *angle = ((T)MATH_DOUBLE_TWOPI) - *angle; + *axis = *axis * (-1); + } + } + else + { + *axis = Vector3(1, 0, 0); + *angle= 0; + } + } + + // Convert a quaternion to a rotation vector, also known as + // Rodrigues vector, AxisAngle vector, SORA vector, exponential map. + // A rotation vector describes a rotation about an axis: + // the axis of rotation is the vector normalized, + // the angle of rotation is the magnitude of the vector. + Vector3 ToRotationVector() const + { + T s = T(0); + T sinHalfAngle = sqrt(x*x + y*y + z*z); + if (sinHalfAngle > T(0)) + { + T cosHalfAngle = w; + T halfAngle = atan2(sinHalfAngle, cosHalfAngle); + + // Ensure minimum rotation magnitude + if (cosHalfAngle < 0) + halfAngle -= T(MATH_DOUBLE_PI); + + s = T(2) * (halfAngle / sinHalfAngle); + } + return Vector3(x*s, y*s, z*s); + } + + // Faster version of the above, optimized for use with small rotations, where rotation angle ~= sin(angle) + inline OVR::Vector3 FastToRotationVector() const + { + T s; + T sinHalfSquared = x*x + y*y + z*z; + if (sinHalfSquared < T(.0037)) // =~ sin(7/2 degrees)^2 + { + // Max rotation magnitude error is (1 - 2*halfAngle/sin(halfAngle)) = -.0044 radians (.06%) at 7 degrees rotation + s = T(2); + } + else + { + T sinHalfAngle = sqrt(sinHalfSquared); + T cosHalfAngle = w; + T halfAngle = atan2(sinHalfAngle, cosHalfAngle); + + // Ensure minimum rotation magnitude + if (cosHalfAngle < 0) + halfAngle -= T(MATH_DOUBLE_PI); + + s = T(2) * halfAngle / sinHalfAngle; + } + return Vector3(x*s, y*s, z*s); + } + + // Given a rotation vector of form unitRotationAxis * angle, + // returns the equivalent quaternion (unitRotationAxis * sin(angle), cos(Angle)). + static Quat FromRotationVector(const Vector3& v) + { + T angleSquared = v.LengthSq(); + T s = T(0); + T c = T(1); + if (angleSquared > T(0)) + { + T angle = sqrt(angleSquared); + s = sin(angle * T(0.5)) / angle; // normalize + c = cos(angle * T(0.5)); + } + return Quat(s*v.x, s*v.y, s*v.z, c); + } + + // Faster version of above, optimized for use with small rotation magnitudes, where rotation angle =~ sin(angle). + // If normalize is false, small-angle quaternions are returned un-normalized. + inline static Quat FastFromRotationVector(const OVR::Vector3& v, bool normalize = true) + { + T s, c; + T angleSquared = v.LengthSq(); + if (angleSquared < T(0.0076)) // =~ (5 degrees*pi/180)^2 + { + s = T(0.5); + c = T(1.0); + // Max rotation magnitude error (after normalization) is about .0031 degrees at 5 degrees, or .06% + if (normalize && angleSquared > 0) + { + T invLen = T(1) / sqrt(s * angleSquared + c); // normalize + s = s * invLen; + c = c * invLen; + } + } + else + { + T angle = sqrt(angleSquared); + s = sin(angle * T(0.5)) / angle; + c = cos(angle * T(0.5)); + } + return Quat(s*v.x, s*v.y, s*v.z, c); + } + + // Constructs the quaternion from a rotation matrix + explicit Quat(const Matrix4& m) + { + T trace = m.M[0][0] + m.M[1][1] + m.M[2][2]; + + // In almost all cases, the first part is executed. + // However, if the trace is not positive, the other + // cases arise. + if (trace > T(0)) + { + T s = sqrt(trace + T(1)) * T(2); // s=4*qw + w = T(0.25) * s; + x = (m.M[2][1] - m.M[1][2]) / s; + y = (m.M[0][2] - m.M[2][0]) / s; + z = (m.M[1][0] - m.M[0][1]) / s; + } + else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2])) + { + T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2); + w = (m.M[2][1] - m.M[1][2]) / s; + x = T(0.25) * s; + y = (m.M[0][1] + m.M[1][0]) / s; + z = (m.M[2][0] + m.M[0][2]) / s; + } + else if (m.M[1][1] > m.M[2][2]) + { + T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy + w = (m.M[0][2] - m.M[2][0]) / s; + x = (m.M[0][1] + m.M[1][0]) / s; + y = T(0.25) * s; + z = (m.M[1][2] + m.M[2][1]) / s; + } + else + { + T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz + w = (m.M[1][0] - m.M[0][1]) / s; + x = (m.M[0][2] + m.M[2][0]) / s; + y = (m.M[1][2] + m.M[2][1]) / s; + z = T(0.25) * s; + } + } + + // Constructs the quaternion from a rotation matrix + explicit Quat(const Matrix3& m) + { + T trace = m.M[0][0] + m.M[1][1] + m.M[2][2]; + + // In almost all cases, the first part is executed. + // However, if the trace is not positive, the other + // cases arise. + if (trace > T(0)) + { + T s = sqrt(trace + T(1)) * T(2); // s=4*qw + w = T(0.25) * s; + x = (m.M[2][1] - m.M[1][2]) / s; + y = (m.M[0][2] - m.M[2][0]) / s; + z = (m.M[1][0] - m.M[0][1]) / s; + } + else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2])) + { + T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2); + w = (m.M[2][1] - m.M[1][2]) / s; + x = T(0.25) * s; + y = (m.M[0][1] + m.M[1][0]) / s; + z = (m.M[2][0] + m.M[0][2]) / s; + } + else if (m.M[1][1] > m.M[2][2]) + { + T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy + w = (m.M[0][2] - m.M[2][0]) / s; + x = (m.M[0][1] + m.M[1][0]) / s; + y = T(0.25) * s; + z = (m.M[1][2] + m.M[2][1]) / s; + } + else + { + T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz + w = (m.M[1][0] - m.M[0][1]) / s; + x = (m.M[0][2] + m.M[2][0]) / s; + y = (m.M[1][2] + m.M[2][1]) / s; + z = T(0.25) * s; + } + } + + bool operator== (const Quat& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; } + bool operator!= (const Quat& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; } + + Quat operator+ (const Quat& b) const { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); } + Quat& operator+= (const Quat& b) { w += b.w; x += b.x; y += b.y; z += b.z; return *this; } + Quat operator- (const Quat& b) const { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); } + Quat& operator-= (const Quat& b) { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; } + + Quat operator* (T s) const { return Quat(x * s, y * s, z * s, w * s); } + Quat& operator*= (T s) { w *= s; x *= s; y *= s; z *= s; return *this; } + Quat operator/ (T s) const { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); } + Quat& operator/= (T s) { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; } + + // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. + bool IsEqual(const Quat&b, T tolerance = Math::Tolerance()) + { + return Abs(Dot(b)) >= 1 - tolerance; + } + + static T Abs(const T v) { return (v >= 0) ? v : -v; } + + // Get Imaginary part vector + Vector3 Imag() const { return Vector3(x,y,z); } + + // Get quaternion length. + T Length() const { return sqrt(LengthSq()); } + + // Get quaternion length squared. + T LengthSq() const { return (x * x + y * y + z * z + w * w); } + + // Simple Euclidean distance in R^4 (not SLERP distance, but at least respects Haar measure) + T Distance(const Quat& q) const + { + T d1 = (*this - q).Length(); + T d2 = (*this + q).Length(); // Antipodal point check + return (d1 < d2) ? d1 : d2; + } + + T DistanceSq(const Quat& q) const + { + T d1 = (*this - q).LengthSq(); + T d2 = (*this + q).LengthSq(); // Antipodal point check + return (d1 < d2) ? d1 : d2; + } + + T Dot(const Quat& q) const + { + return x * q.x + y * q.y + z * q.z + w * q.w; + } + + // Angle between two quaternions in radians + T Angle(const Quat& q) const + { + return 2 * Acos(Abs(Dot(q))); + } + + // Normalize + bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math::Tolerance(); } + + void Normalize() + { + T s = Length(); + if (s != 0) + s = T(1) / s; + *this *= s; + } + + Quat Normalized() const + { + T s = Length(); + if (s != 0) + s = T(1) / s; + return *this * s; + } + + inline void EnsureSameHemisphere(const Quat& o) + { + if (Dot(o) < T(0)) + { + x = -x; + y = -y; + z = -z; + w = -w; + } + } + + // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized. + Quat Conj() const { return Quat(-x, -y, -z, w); } + + // Quaternion multiplication. Combines quaternion rotations, performing the one on the + // right hand side first. + Quat operator* (const Quat& b) const { return Quat(w * b.x + x * b.w + y * b.z - z * b.y, + w * b.y - x * b.z + y * b.w + z * b.x, + w * b.z + x * b.y - y * b.x + z * b.w, + w * b.w - x * b.x - y * b.y - z * b.z); } + const Quat& operator*= (const Quat& b) { *this = *this * b; return *this; } + + // + // this^p normalized; same as rotating by this p times. + Quat PowNormalized(T p) const + { + Vector3 v; + T a; + GetAxisAngle(&v, &a); + return Quat(v, a * p); + } + + // Compute quaternion that rotates v into alignTo: alignTo = Quat::Align(alignTo, v).Rotate(v). + // NOTE: alignTo and v must be normalized. + static Quat Align(const Vector3& alignTo, const Vector3& v) + { + Vector3 bisector = (v + alignTo); + bisector.Normalize(); + T cosHalfAngle = v.Dot(bisector); // 0..1 + if (cosHalfAngle > T(0)) + { + Vector3 imag = v.Cross(bisector); + return Quat(imag.x, imag.y, imag.z, cosHalfAngle); + } + else + { + // cosHalfAngle == 0: a 180 degree rotation. + // sinHalfAngle == 1, rotation axis is any axis perpendicular + // to alignTo. Choose axis to include largest magnitude components + if (fabs(v.x) > fabs(v.y)) + { + // x or z is max magnitude component + // = Cross(v, (0,1,0)).Normalized(); + T invLen = sqrt(v.x*v.x + v.z*v.z); + if (invLen > T(0)) + invLen = T(1) / invLen; + return Quat(-v.z*invLen, 0, v.x*invLen, 0); + } + else + { + // y or z is max magnitude component + // = Cross(v, (1,0,0)).Normalized(); + T invLen = sqrt(v.y*v.y + v.z*v.z); + if (invLen > T(0)) + invLen = T(1) / invLen; + return Quat(0, v.z*invLen, -v.y*invLen, 0); + } + } + } + + // Normalized linear interpolation of quaternions + Quat Lerp(const Quat& b, T s) const + { + return (*this * (T(1) - s) + b * (Dot(b) < 0 ? -s : s)).Normalized(); + } + + // Normalized linear interpolation of quaternions + // WARNING, POSSIBLE BUG: This function doesn't work like Lerp() for other classes! + // If f is 1, then full value is given to *this, not "other" like other Lerp() functions + Quat Nlerp(const Quat& other, T a) + { + T sign = (Dot(other) >= 0) ? 1 : -1; + return (*this * sign * a + other * (1-a)).Normalized(); + } + + // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise, + // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1. + Vector3 Rotate(const Vector3& v) const + { + // rv = q * (v,0) * q' + // Same as rv = v + real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2); + + // uv = 2 * Imag().Cross(v); + T uvx = T(2) * (y*v.z - z*v.y); + T uvy = T(2) * (z*v.x - x*v.z); + T uvz = T(2) * (x*v.y - y*v.x); + + // return v + Real()*uv + Imag().Cross(uv); + return Vector3(v.x + w*uvx + y*uvz - z*uvy, + v.y + w*uvy + z*uvx - x*uvz, + v.z + w*uvz + x*uvy - y*uvx); + } + + // Rotation by inverse of *this + Vector3 InverseRotate(const Vector3& v) const + { + // rv = q' * (v,0) * q + // Same as rv = v + real * cross(-imag,v)*2 + cross(-imag, cross(-imag,v)*2); + // or rv = v - real * cross(imag,v)*2 + cross(imag, cross(imag,v)*2); + + // uv = 2 * Imag().Cross(v); + T uvx = T(2) * (y*v.z - z*v.y); + T uvy = T(2) * (z*v.x - x*v.z); + T uvz = T(2) * (x*v.y - y*v.x); + + // return v - Real()*uv + Imag().Cross(uv); + return Vector3(v.x - w*uvx + y*uvz - z*uvy, + v.y - w*uvy + z*uvx - x*uvz, + v.z - w*uvz + x*uvy - y*uvx); + } + + // Inversed quaternion rotates in the opposite direction. + Quat Inverted() const + { + return Quat(-x, -y, -z, w); + } + + Quat Inverse() const + { + return Quat(-x, -y, -z, w); + } + + // Sets this quaternion to the one rotates in the opposite direction. + void Invert() + { + *this = Quat(-x, -y, -z, w); + } + + // Time integration of constant angular velocity over dt + Quat TimeIntegrate(Vector3 angularVelocity, T dt) const + { + // solution is: this * exp( omega*dt/2 ); FromRotationVector(v) gives exp(v*.5). + return (*this * FastFromRotationVector(angularVelocity * dt, false)).Normalized(); + } + + // Time integration of constant angular acceleration and velocity over dt + // These are the first two terms of the "Magnus expansion" of the solution + // + // o = o * exp( W=(W1 + W2 + W3+...) * 0.5 ); + // + // omega1 = (omega + omegaDot*dt) + // W1 = (omega + omega1)*dt/2 + // W2 = cross(omega, omega1)/12*dt^2 % (= -cross(omega_dot, omega)/12*dt^3) + // Terms 3 and beyond are vanishingly small: + // W3 = cross(omega_dot, cross(omega_dot, omega))/240*dt^5 + Quat TimeIntegrate(Vector3 angularVelocity, Vector3 angularAcceleration, T dt, T dtAcceleration) const + { + (void)dtAcceleration; + + const Vector3& omega = angularVelocity; + const Vector3& omegaDot = angularAcceleration; + + Vector3 omega1 = (omega + omegaDot * dtAcceleration); + Vector3 W = T(0.5)*dt*((omega + omega1) / T(2) + omega.Cross(omega1)*(dt * T(1)/T(12))); + + // FromRotationVector(v) is exp(v*.5) + return (*this * FastFromRotationVector(W, false)).Normalized(); + } + + // Decompose rotation into three rotations: + // roll radians about Z axis, then pitch radians about X axis, then yaw radians about Y axis. + // Call with nullptr if a return value is not needed. + void GetYawPitchRoll(T* yaw, T* pitch, T* roll) const + { + return GetEulerAngles(yaw, pitch, roll, Rotate_CCW, Handed_R); + } + + // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of + // axis rotations and the specified coordinate system. Right-handed coordinate system + // is the default, with CCW rotations while looking in the negative axis direction. + // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned. + // Rotation order is c, b, a: + // rotation c around axis A3 + // is followed by rotation b around axis A2 + // is followed by rotation a around axis A1 + // rotations are CCW or CW (D) in LH or RH coordinate system (S) + // + template + void GetEulerAngles(T *a, T *b, T *c) const + { + OVR_MATH_STATIC_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); + + T Q[3] = { x, y, z }; //Quaternion components x,y,z + + T ww = w*w; + T Q11 = Q[A1]*Q[A1]; + T Q22 = Q[A2]*Q[A2]; + T Q33 = Q[A3]*Q[A3]; + + T psign = T(-1); + // Determine whether even permutation + if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) + psign = T(1); + + T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]); + + T singularityRadius = Math::SingularityRadius(); + if (s2 < T(-1) + singularityRadius) + { // South pole singularity + if (a) *a = T(0); + if (b) *b = -S*D*((T)MATH_DOUBLE_PIOVER2); + if (c) *c = S*D*atan2(T(2)*(psign*Q[A1] * Q[A2] + w*Q[A3]), ww + Q22 - Q11 - Q33 ); + } + else if (s2 > T(1) - singularityRadius) + { // North pole singularity + if (a) *a = T(0); + if (b) *b = S*D*((T)MATH_DOUBLE_PIOVER2); + if (c) *c = S*D*atan2(T(2)*(psign*Q[A1] * Q[A2] + w*Q[A3]), ww + Q22 - Q11 - Q33); + } + else + { + if (a) *a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2] * Q[A3]), ww + Q33 - Q11 - Q22); + if (b) *b = S*D*asin(s2); + if (c) *c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1] * Q[A2]), ww + Q11 - Q22 - Q33); + } + } + + template + void GetEulerAngles(T *a, T *b, T *c) const + { GetEulerAngles(a, b, c); } + + template + void GetEulerAngles(T *a, T *b, T *c) const + { GetEulerAngles(a, b, c); } + + // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of + // axis rotations and the specified coordinate system. Right-handed coordinate system + // is the default, with CCW rotations while looking in the negative axis direction. + // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned. + // rotation a around axis A1 + // is followed by rotation b around axis A2 + // is followed by rotation c around axis A1 + // Rotations are CCW or CW (D) in LH or RH coordinate system (S) + template + void GetEulerAnglesABA(T *a, T *b, T *c) const + { + OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2"); + + T Q[3] = {x, y, z}; // Quaternion components + + // Determine the missing axis that was not supplied + int m = 3 - A1 - A2; + + T ww = w*w; + T Q11 = Q[A1]*Q[A1]; + T Q22 = Q[A2]*Q[A2]; + T Qmm = Q[m]*Q[m]; + + T psign = T(-1); + if ((A1 + 1) % 3 == A2) // Determine whether even permutation + { + psign = T(1); + } + + T c2 = ww + Q11 - Q22 - Qmm; + if (c2 < T(-1) + Math::SingularityRadius) + { // South pole singularity + if (a) *a = T(0); + if (b) *b = S*D*((T)MATH_DOUBLE_PI); + if (c) *c = S*D*atan2(T(2)*(w*Q[A1] - psign*Q[A2] * Q[m]), + ww + Q22 - Q11 - Qmm); + } + else if (c2 > T(1) - Math::SingularityRadius) + { // North pole singularity + if (a) *a = T(0); + if (b) *b = T(0); + if (c) *c = S*D*atan2(T(2)*(w*Q[A1] - psign*Q[A2] * Q[m]), + ww + Q22 - Q11 - Qmm); + } + else + { + if (a) *a = S*D*atan2(psign*w*Q[m] + Q[A1] * Q[A2], + w*Q[A2] -psign*Q[A1]*Q[m]); + if (b) *b = S*D*acos(c2); + if (c) *c = S*D*atan2(-psign*w*Q[m] + Q[A1] * Q[A2], + w*Q[A2] + psign*Q[A1]*Q[m]); + } + } +}; + +typedef Quat Quatf; +typedef Quat Quatd; + +OVR_MATH_STATIC_ASSERT((sizeof(Quatf) == 4*sizeof(float)), "sizeof(Quatf) failure"); +OVR_MATH_STATIC_ASSERT((sizeof(Quatd) == 4*sizeof(double)), "sizeof(Quatd) failure"); + +//------------------------------------------------------------------------------------- +// ***** Pose + +// Position and orientation combined. + +template +class Pose +{ +public: + typedef typename CompatibleTypes >::Type CompatibleType; + + Pose() { } + Pose(const Quat& orientation, const Vector3& pos) + : Rotation(orientation), Translation(pos) { } + Pose(const Pose& s) + : Rotation(s.Rotation), Translation(s.Translation) { } + Pose(const Matrix3& R, const Vector3& t) + : Rotation((Quat)R), Translation(t) { } + Pose(const CompatibleType& s) + : Rotation(s.Orientation), Translation(s.Position) { } + explicit Pose(const Pose::OtherFloatType> &s) + : Rotation(s.Rotation), Translation(s.Translation) { } + + static Pose Identity() { return Pose(Quat(0, 0, 0, 1), Vector3(0, 0, 0)); } + + void SetIdentity() { Rotation = Quat(0, 0, 0, 1); Translation = Vector3(0, 0, 0); } + + bool IsEqual(const Pose&b, T tolerance = Math::Tolerance()) + { + return Translation.IsEqual(b.Translation, tolerance) && Rotation.IsEqual(b.Rotation, tolerance); + } + + operator typename CompatibleTypes >::Type () const + { + typename CompatibleTypes >::Type result; + result.Orientation = Rotation; + result.Position = Translation; + return result; + } + + Quat Rotation; + Vector3 Translation; + + OVR_MATH_STATIC_ASSERT((sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float)), "(sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float))"); + + void ToArray(T* arr) const + { + T temp[7] = { Rotation.x, Rotation.y, Rotation.z, Rotation.w, Translation.x, Translation.y, Translation.z }; + for (int i = 0; i < 7; i++) arr[i] = temp[i]; + } + + static Pose FromArray(const T* v) + { + Quat rotation(v[0], v[1], v[2], v[3]); + Vector3 translation(v[4], v[5], v[6]); + return Pose(rotation, translation); + } + + Vector3 Rotate(const Vector3& v) const + { + return Rotation.Rotate(v); + } + + Vector3 InverseRotate(const Vector3& v) const + { + return Rotation.InverseRotate(v); + } + + Vector3 Translate(const Vector3& v) const + { + return v + Translation; + } + + Vector3 Transform(const Vector3& v) const + { + return Rotate(v) + Translation; + } + + Vector3 InverseTransform(const Vector3& v) const + { + return InverseRotate(v - Translation); + } + + + Vector3 Apply(const Vector3& v) const + { + return Transform(v); + } + + Pose operator*(const Pose& other) const + { + return Pose(Rotation * other.Rotation, Apply(other.Translation)); + } + + Pose Inverted() const + { + Quat inv = Rotation.Inverted(); + return Pose(inv, inv.Rotate(-Translation)); + } + + Pose TimeIntegrate(const Vector3& linearVelocity, const Vector3& angularVelocity, T dt) const + { + return Pose( + (Rotation * Quat::FastFromRotationVector(angularVelocity * dt, false)).Normalized(), + Translation + linearVelocity * dt); + } + + Pose TimeIntegrate(const Vector3& linearVelocity, const Vector3& linearAcceleration, + const Vector3& angularVelocity, const Vector3& angularAcceleration, + T dt, T dtAcceleration) const + { + return Pose(Rotation.TimeIntegrate(angularVelocity, angularAcceleration, dt, dtAcceleration), + Translation + linearVelocity*dt + linearAcceleration*dt*dt / T(2)); + } +}; + +typedef Pose Posef; +typedef Pose Posed; + +OVR_MATH_STATIC_ASSERT((sizeof(Posed) == sizeof(Quatd) + sizeof(Vector3d)), "sizeof(Posed) failure"); +OVR_MATH_STATIC_ASSERT((sizeof(Posef) == sizeof(Quatf) + sizeof(Vector3f)), "sizeof(Posef) failure"); + + +//------------------------------------------------------------------------------------- +// ***** Matrix4 +// +// Matrix4 is a 4x4 matrix used for 3d transformations and projections. +// Translation stored in the last column. +// The matrix is stored in row-major order in memory, meaning that values +// of the first row are stored before the next one. +// +// The arrangement of the matrix is chosen to be in Right-Handed +// coordinate system and counterclockwise rotations when looking down +// the axis +// +// Transformation Order: +// - Transformations are applied from right to left, so the expression +// M1 * M2 * M3 * V means that the vector V is transformed by M3 first, +// followed by M2 and M1. +// +// Coordinate system: Right Handed +// +// Rotations: Counterclockwise when looking down the axis. All angles are in radians. +// +// | sx 01 02 tx | // First column (sx, 10, 20): Axis X basis vector. +// | 10 sy 12 ty | // Second column (01, sy, 21): Axis Y basis vector. +// | 20 21 sz tz | // Third columnt (02, 12, sz): Axis Z basis vector. +// | 30 31 32 33 | +// +// The basis vectors are first three columns. + +template +class Matrix4 +{ +public: + typedef T ElementType; + static const size_t Dimension = 4; + + T M[4][4]; + + enum NoInitType { NoInit }; + + // Construct with no memory initialization. + Matrix4(NoInitType) { } + + // By default, we construct identity matrix. + Matrix4() + { + M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1; + M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0; + M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0; + M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0; + } + + Matrix4(T m11, T m12, T m13, T m14, + T m21, T m22, T m23, T m24, + T m31, T m32, T m33, T m34, + T m41, T m42, T m43, T m44) + { + M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14; + M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24; + M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34; + M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44; + } + + Matrix4(T m11, T m12, T m13, + T m21, T m22, T m23, + T m31, T m32, T m33) + { + M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = 0; + M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = 0; + M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = 0; + M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; + } + + explicit Matrix4(const Matrix3& m) + { + M[0][0] = m.M[0][0]; M[0][1] = m.M[0][1]; M[0][2] = m.M[0][2]; M[0][3] = 0; + M[1][0] = m.M[1][0]; M[1][1] = m.M[1][1]; M[1][2] = m.M[1][2]; M[1][3] = 0; + M[2][0] = m.M[2][0]; M[2][1] = m.M[2][1]; M[2][2] = m.M[2][2]; M[2][3] = 0; + M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; + } + + explicit Matrix4(const Quat& q) + { + T ww = q.w*q.w; + T xx = q.x*q.x; + T yy = q.y*q.y; + T zz = q.z*q.z; + + M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); M[0][3] = 0; + M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x); M[1][3] = 0; + M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz; M[2][3] = 0; + M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; + } + + explicit Matrix4(const Pose& p) + { + Matrix4 result(p.Rotation); + result.SetTranslation(p.Translation); + *this = result; + } + + + // C-interop support + explicit Matrix4(const Matrix4::OtherFloatType> &src) + { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] = (T)src.M[i][j]; + } + + // C-interop support. + Matrix4(const typename CompatibleTypes >::Type& s) + { + OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix4), "sizeof(s) == sizeof(Matrix4)"); + memcpy(M, s.M, sizeof(M)); + } + + operator typename CompatibleTypes >::Type () const + { + typename CompatibleTypes >::Type result; + OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)"); + memcpy(result.M, M, sizeof(M)); + return result; + } + + void ToString(char* dest, size_t destsize) const + { + size_t pos = 0; + for (int r=0; r<4; r++) + { + for (int c=0; c<4; c++) + { + pos += OVRMath_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]); + } + } + } + + static Matrix4 FromString(const char* src) + { + Matrix4 result; + if (src) + { + for (int r = 0; r < 4; r++) + { + for (int c = 0; c < 4; c++) + { + result.M[r][c] = (T)atof(src); + while (*src && *src != ' ') + { + src++; + } + while (*src && *src == ' ') + { + src++; + } + } + } + } + return result; + } + + static Matrix4 Identity() { return Matrix4(); } + + void SetIdentity() + { + M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1; + M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0; + M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0; + M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0; + } + + void SetXBasis(const Vector3f & v) + { + M[0][0] = v.x; + M[1][0] = v.y; + M[2][0] = v.z; + } + Vector3f GetXBasis() const + { + return Vector3f(M[0][0], M[1][0], M[2][0]); + } + + void SetYBasis(const Vector3f & v) + { + M[0][1] = v.x; + M[1][1] = v.y; + M[2][1] = v.z; + } + Vector3f GetYBasis() const + { + return Vector3f(M[0][1], M[1][1], M[2][1]); + } + + void SetZBasis(const Vector3f & v) + { + M[0][2] = v.x; + M[1][2] = v.y; + M[2][2] = v.z; + } + Vector3f GetZBasis() const + { + return Vector3f(M[0][2], M[1][2], M[2][2]); + } + + bool operator== (const Matrix4& b) const + { + bool isEqual = true; + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + isEqual &= (M[i][j] == b.M[i][j]); + + return isEqual; + } + + Matrix4 operator+ (const Matrix4& b) const + { + Matrix4 result(*this); + result += b; + return result; + } + + Matrix4& operator+= (const Matrix4& b) + { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] += b.M[i][j]; + return *this; + } + + Matrix4 operator- (const Matrix4& b) const + { + Matrix4 result(*this); + result -= b; + return result; + } + + Matrix4& operator-= (const Matrix4& b) + { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] -= b.M[i][j]; + return *this; + } + + // Multiplies two matrices into destination with minimum copying. + static Matrix4& Multiply(Matrix4* d, const Matrix4& a, const Matrix4& b) + { + OVR_MATH_ASSERT((d != &a) && (d != &b)); + int i = 0; + do { + d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0] + a.M[i][3] * b.M[3][0]; + d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1] + a.M[i][3] * b.M[3][1]; + d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2] + a.M[i][3] * b.M[3][2]; + d->M[i][3] = a.M[i][0] * b.M[0][3] + a.M[i][1] * b.M[1][3] + a.M[i][2] * b.M[2][3] + a.M[i][3] * b.M[3][3]; + } while((++i) < 4); + + return *d; + } + + Matrix4 operator* (const Matrix4& b) const + { + Matrix4 result(Matrix4::NoInit); + Multiply(&result, *this, b); + return result; + } + + Matrix4& operator*= (const Matrix4& b) + { + return Multiply(this, Matrix4(*this), b); + } + + Matrix4 operator* (T s) const + { + Matrix4 result(*this); + result *= s; + return result; + } + + Matrix4& operator*= (T s) + { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] *= s; + return *this; + } + + + Matrix4 operator/ (T s) const + { + Matrix4 result(*this); + result /= s; + return result; + } + + Matrix4& operator/= (T s) + { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + M[i][j] /= s; + return *this; + } + + Vector3 Transform(const Vector3& v) const + { + const T rcpW = 1.0f / (M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3]); + return Vector3((M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3]) * rcpW, + (M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3]) * rcpW, + (M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]) * rcpW); + } + + Vector4 Transform(const Vector4& v) const + { + return Vector4(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3] * v.w, + M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3] * v.w, + M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3] * v.w, + M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3] * v.w); + } + + Matrix4 Transposed() const + { + return Matrix4(M[0][0], M[1][0], M[2][0], M[3][0], + M[0][1], M[1][1], M[2][1], M[3][1], + M[0][2], M[1][2], M[2][2], M[3][2], + M[0][3], M[1][3], M[2][3], M[3][3]); + } + + void Transpose() + { + *this = Transposed(); + } + + + T SubDet (const size_t* rows, const size_t* cols) const + { + return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]]) + - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]]) + + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]); + } + + T Cofactor(size_t I, size_t J) const + { + const size_t indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}}; + return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]); + } + + T Determinant() const + { + return M[0][0] * Cofactor(0,0) + M[0][1] * Cofactor(0,1) + M[0][2] * Cofactor(0,2) + M[0][3] * Cofactor(0,3); + } + + Matrix4 Adjugated() const + { + return Matrix4(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0), + Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1), + Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2), + Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3)); + } + + Matrix4 Inverted() const + { + T det = Determinant(); + OVR_MATH_ASSERT(det != 0); + return Adjugated() * (1.0f/det); + } + + void Invert() + { + *this = Inverted(); + } + + // This is more efficient than general inverse, but ONLY works + // correctly if it is a homogeneous transform matrix (rot + trans) + Matrix4 InvertedHomogeneousTransform() const + { + // Make the inverse rotation matrix + Matrix4 rinv = this->Transposed(); + rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = 0.0f; + // Make the inverse translation matrix + Vector3 tvinv(-M[0][3],-M[1][3],-M[2][3]); + Matrix4 tinv = Matrix4::Translation(tvinv); + return rinv * tinv; // "untranslate", then "unrotate" + } + + // This is more efficient than general inverse, but ONLY works + // correctly if it is a homogeneous transform matrix (rot + trans) + void InvertHomogeneousTransform() + { + *this = InvertedHomogeneousTransform(); + } + + // Matrix to Euler Angles conversion + // a,b,c, are the YawPitchRoll angles to be returned + // rotation a around axis A1 + // is followed by rotation b around axis A2 + // is followed by rotation c around axis A3 + // rotations are CCW or CW (D) in LH or RH coordinate system (S) + template + void ToEulerAngles(T *a, T *b, T *c) const + { + OVR_MATH_STATIC_ASSERT((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); + + T psign = -1; + if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation + psign = 1; + + T pm = psign*M[A1][A3]; + if (pm < -1.0f + Math::SingularityRadius) + { // South pole singularity + *a = 0; + *b = -S*D*((T)MATH_DOUBLE_PIOVER2); + *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] ); + } + else if (pm > 1.0f - Math::SingularityRadius) + { // North pole singularity + *a = 0; + *b = S*D*((T)MATH_DOUBLE_PIOVER2); + *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] ); + } + else + { // Normal case (nonsingular) + *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] ); + *b = S*D*asin(pm); + *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] ); + } + + return; + } + + // Matrix to Euler Angles conversion + // a,b,c, are the YawPitchRoll angles to be returned + // rotation a around axis A1 + // is followed by rotation b around axis A2 + // is followed by rotation c around axis A1 + // rotations are CCW or CW (D) in LH or RH coordinate system (S) + template + void ToEulerAnglesABA(T *a, T *b, T *c) const + { + OVR_MATH_STATIC_ASSERT(A1 != A2, "A1 != A2"); + + // Determine the axis that was not supplied + int m = 3 - A1 - A2; + + T psign = -1; + if ((A1 + 1) % 3 == A2) // Determine whether even permutation + psign = 1.0f; + + T c2 = M[A1][A1]; + if (c2 < -1 + Math::SingularityRadius) + { // South pole singularity + *a = 0; + *b = S*D*((T)MATH_DOUBLE_PI); + *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]); + } + else if (c2 > 1.0f - Math::SingularityRadius) + { // North pole singularity + *a = 0; + *b = 0; + *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]); + } + else + { // Normal case (nonsingular) + *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]); + *b = S*D*acos(c2); + *c = S*D*atan2( M[A1][A2],psign*M[A1][m]); + } + return; + } + + // Creates a matrix that converts the vertices from one coordinate system + // to another. + static Matrix4 AxisConversion(const WorldAxes& to, const WorldAxes& from) + { + // Holds axis values from the 'to' structure + int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis }; + + // The inverse of the toArray + int inv[4]; + inv[0] = inv[abs(to.XAxis)] = 0; + inv[abs(to.YAxis)] = 1; + inv[abs(to.ZAxis)] = 2; + + Matrix4 m(0, 0, 0, + 0, 0, 0, + 0, 0, 0); + + // Only three values in the matrix need to be changed to 1 or -1. + m.M[inv[abs(from.XAxis)]][0] = T(from.XAxis/toArray[inv[abs(from.XAxis)]]); + m.M[inv[abs(from.YAxis)]][1] = T(from.YAxis/toArray[inv[abs(from.YAxis)]]); + m.M[inv[abs(from.ZAxis)]][2] = T(from.ZAxis/toArray[inv[abs(from.ZAxis)]]); + return m; + } + + + // Creates a matrix for translation by vector + static Matrix4 Translation(const Vector3& v) + { + Matrix4 t; + t.M[0][3] = v.x; + t.M[1][3] = v.y; + t.M[2][3] = v.z; + return t; + } + + // Creates a matrix for translation by vector + static Matrix4 Translation(T x, T y, T z = 0.0f) + { + Matrix4 t; + t.M[0][3] = x; + t.M[1][3] = y; + t.M[2][3] = z; + return t; + } + + // Sets the translation part + void SetTranslation(const Vector3& v) + { + M[0][3] = v.x; + M[1][3] = v.y; + M[2][3] = v.z; + } + + Vector3 GetTranslation() const + { + return Vector3( M[0][3], M[1][3], M[2][3] ); + } + + // Creates a matrix for scaling by vector + static Matrix4 Scaling(const Vector3& v) + { + Matrix4 t; + t.M[0][0] = v.x; + t.M[1][1] = v.y; + t.M[2][2] = v.z; + return t; + } + + // Creates a matrix for scaling by vector + static Matrix4 Scaling(T x, T y, T z) + { + Matrix4 t; + t.M[0][0] = x; + t.M[1][1] = y; + t.M[2][2] = z; + return t; + } + + // Creates a matrix for scaling by constant + static Matrix4 Scaling(T s) + { + Matrix4 t; + t.M[0][0] = s; + t.M[1][1] = s; + t.M[2][2] = s; + return t; + } + + // Simple L1 distance in R^12 + T Distance(const Matrix4& m2) const + { + T d = fabs(M[0][0] - m2.M[0][0]) + fabs(M[0][1] - m2.M[0][1]); + d += fabs(M[0][2] - m2.M[0][2]) + fabs(M[0][3] - m2.M[0][3]); + d += fabs(M[1][0] - m2.M[1][0]) + fabs(M[1][1] - m2.M[1][1]); + d += fabs(M[1][2] - m2.M[1][2]) + fabs(M[1][3] - m2.M[1][3]); + d += fabs(M[2][0] - m2.M[2][0]) + fabs(M[2][1] - m2.M[2][1]); + d += fabs(M[2][2] - m2.M[2][2]) + fabs(M[2][3] - m2.M[2][3]); + d += fabs(M[3][0] - m2.M[3][0]) + fabs(M[3][1] - m2.M[3][1]); + d += fabs(M[3][2] - m2.M[3][2]) + fabs(M[3][3] - m2.M[3][3]); + return d; + } + + // Creates a rotation matrix rotating around the X axis by 'angle' radians. + // Just for quick testing. Not for final API. Need to remove case. + static Matrix4 RotationAxis(Axis A, T angle, RotateDirection d, HandedSystem s) + { + T sina = s * d *sin(angle); + T cosa = cos(angle); + + switch(A) + { + case Axis_X: + return Matrix4(1, 0, 0, + 0, cosa, -sina, + 0, sina, cosa); + case Axis_Y: + return Matrix4(cosa, 0, sina, + 0, 1, 0, + -sina, 0, cosa); + case Axis_Z: + return Matrix4(cosa, -sina, 0, + sina, cosa, 0, + 0, 0, 1); + } + } + + + // Creates a rotation matrix rotating around the X axis by 'angle' radians. + // Rotation direction is depends on the coordinate system: + // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), + // while looking in the negative axis direction. This is the + // same as looking down from positive axis values towards origin. + // LHS: Positive angle values rotate clock-wise (CW), while looking in the + // negative axis direction. + static Matrix4 RotationX(T angle) + { + T sina = sin(angle); + T cosa = cos(angle); + return Matrix4(1, 0, 0, + 0, cosa, -sina, + 0, sina, cosa); + } + + // Creates a rotation matrix rotating around the Y axis by 'angle' radians. + // Rotation direction is depends on the coordinate system: + // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), + // while looking in the negative axis direction. This is the + // same as looking down from positive axis values towards origin. + // LHS: Positive angle values rotate clock-wise (CW), while looking in the + // negative axis direction. + static Matrix4 RotationY(T angle) + { + T sina = sin(angle); + T cosa = cos(angle); + return Matrix4(cosa, 0, sina, + 0, 1, 0, + -sina, 0, cosa); + } + + // Creates a rotation matrix rotating around the Z axis by 'angle' radians. + // Rotation direction is depends on the coordinate system: + // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), + // while looking in the negative axis direction. This is the + // same as looking down from positive axis values towards origin. + // LHS: Positive angle values rotate clock-wise (CW), while looking in the + // negative axis direction. + static Matrix4 RotationZ(T angle) + { + T sina = sin(angle); + T cosa = cos(angle); + return Matrix4(cosa, -sina, 0, + sina, cosa, 0, + 0, 0, 1); + } + + // LookAtRH creates a View transformation matrix for right-handed coordinate system. + // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up' + // specifying the up vector. The resulting matrix should be used with PerspectiveRH + // projection. + static Matrix4 LookAtRH(const Vector3& eye, const Vector3& at, const Vector3& up) + { + Vector3 z = (eye - at).Normalized(); // Forward + Vector3 x = up.Cross(z).Normalized(); // Right + Vector3 y = z.Cross(x); + + Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)), + y.x, y.y, y.z, -(y.Dot(eye)), + z.x, z.y, z.z, -(z.Dot(eye)), + 0, 0, 0, 1 ); + return m; + } + + // LookAtLH creates a View transformation matrix for left-handed coordinate system. + // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up' + // specifying the up vector. + static Matrix4 LookAtLH(const Vector3& eye, const Vector3& at, const Vector3& up) + { + Vector3 z = (at - eye).Normalized(); // Forward + Vector3 x = up.Cross(z).Normalized(); // Right + Vector3 y = z.Cross(x); + + Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)), + y.x, y.y, y.z, -(y.Dot(eye)), + z.x, z.y, z.z, -(z.Dot(eye)), + 0, 0, 0, 1 ); + return m; + } + + // PerspectiveRH creates a right-handed perspective projection matrix that can be + // used with the Oculus sample renderer. + // yfov - Specifies vertical field of view in radians. + // aspect - Screen aspect ration, which is usually width/height for square pixels. + // Note that xfov = yfov * aspect. + // znear - Absolute value of near Z clipping clipping range. + // zfar - Absolute value of far Z clipping clipping range (larger then near). + // Even though RHS usually looks in the direction of negative Z, positive values + // are expected for znear and zfar. + static Matrix4 PerspectiveRH(T yfov, T aspect, T znear, T zfar) + { + Matrix4 m; + T tanHalfFov = tan(yfov * 0.5f); + + m.M[0][0] = 1. / (aspect * tanHalfFov); + m.M[1][1] = 1. / tanHalfFov; + m.M[2][2] = zfar / (znear - zfar); + m.M[3][2] = -1.; + m.M[2][3] = (zfar * znear) / (znear - zfar); + m.M[3][3] = 0.; + + // Note: Post-projection matrix result assumes Left-Handed coordinate system, + // with Y up, X right and Z forward. This supports positive z-buffer values. + // This is the case even for RHS coordinate input. + return m; + } + + // PerspectiveLH creates a left-handed perspective projection matrix that can be + // used with the Oculus sample renderer. + // yfov - Specifies vertical field of view in radians. + // aspect - Screen aspect ration, which is usually width/height for square pixels. + // Note that xfov = yfov * aspect. + // znear - Absolute value of near Z clipping clipping range. + // zfar - Absolute value of far Z clipping clipping range (larger then near). + static Matrix4 PerspectiveLH(T yfov, T aspect, T znear, T zfar) + { + Matrix4 m; + T tanHalfFov = tan(yfov * 0.5f); + + m.M[0][0] = 1. / (aspect * tanHalfFov); + m.M[1][1] = 1. / tanHalfFov; + //m.M[2][2] = zfar / (znear - zfar); + m.M[2][2] = zfar / (zfar - znear); + m.M[3][2] = -1.; + m.M[2][3] = (zfar * znear) / (znear - zfar); + m.M[3][3] = 0.; + + // Note: Post-projection matrix result assumes Left-Handed coordinate system, + // with Y up, X right and Z forward. This supports positive z-buffer values. + // This is the case even for RHS coordinate input. + return m; + } + + static Matrix4 Ortho2D(T w, T h) + { + Matrix4 m; + m.M[0][0] = 2.0/w; + m.M[1][1] = -2.0/h; + m.M[0][3] = -1.0; + m.M[1][3] = 1.0; + m.M[2][2] = 0; + return m; + } +}; + +typedef Matrix4 Matrix4f; +typedef Matrix4 Matrix4d; + +//------------------------------------------------------------------------------------- +// ***** Matrix3 +// +// Matrix3 is a 3x3 matrix used for representing a rotation matrix. +// The matrix is stored in row-major order in memory, meaning that values +// of the first row are stored before the next one. +// +// The arrangement of the matrix is chosen to be in Right-Handed +// coordinate system and counterclockwise rotations when looking down +// the axis +// +// Transformation Order: +// - Transformations are applied from right to left, so the expression +// M1 * M2 * M3 * V means that the vector V is transformed by M3 first, +// followed by M2 and M1. +// +// Coordinate system: Right Handed +// +// Rotations: Counterclockwise when looking down the axis. All angles are in radians. + +template +class Matrix3 +{ +public: + typedef T ElementType; + static const size_t Dimension = 3; + + T M[3][3]; + + enum NoInitType { NoInit }; + + // Construct with no memory initialization. + Matrix3(NoInitType) { } + + // By default, we construct identity matrix. + Matrix3() + { + M[0][0] = M[1][1] = M[2][2] = 1; + M[0][1] = M[1][0] = M[2][0] = 0; + M[0][2] = M[1][2] = M[2][1] = 0; + } + + Matrix3(T m11, T m12, T m13, + T m21, T m22, T m23, + T m31, T m32, T m33) + { + M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; + M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; + M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; + } + + // Construction from X, Y, Z basis vectors + Matrix3(const Vector3& xBasis, const Vector3& yBasis, const Vector3& zBasis) + { + M[0][0] = xBasis.x; M[0][1] = yBasis.x; M[0][2] = zBasis.x; + M[1][0] = xBasis.y; M[1][1] = yBasis.y; M[1][2] = zBasis.y; + M[2][0] = xBasis.z; M[2][1] = yBasis.z; M[2][2] = zBasis.z; + } + + explicit Matrix3(const Quat& q) + { + const T tx = q.x+q.x, ty = q.y+q.y, tz = q.z+q.z; + const T twx = q.w*tx, twy = q.w*ty, twz = q.w*tz; + const T txx = q.x*tx, txy = q.x*ty, txz = q.x*tz; + const T tyy = q.y*ty, tyz = q.y*tz, tzz = q.z*tz; + M[0][0] = T(1) - (tyy + tzz); M[0][1] = txy - twz; M[0][2] = txz + twy; + M[1][0] = txy + twz; M[1][1] = T(1) - (txx + tzz); M[1][2] = tyz - twx; + M[2][0] = txz - twy; M[2][1] = tyz + twx; M[2][2] = T(1) - (txx + tyy); + } + + inline explicit Matrix3(T s) + { + M[0][0] = M[1][1] = M[2][2] = s; + M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = 0; + } + + Matrix3(T m11, T m22, T m33) + { + M[0][0] = m11; M[0][1] = 0; M[0][2] = 0; + M[1][0] = 0; M[1][1] = m22; M[1][2] = 0; + M[2][0] = 0; M[2][1] = 0; M[2][2] = m33; + } + + explicit Matrix3(const Matrix3::OtherFloatType> &src) + { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + M[i][j] = (T)src.M[i][j]; + } + + // C-interop support. + Matrix3(const typename CompatibleTypes >::Type& s) + { + OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)"); + memcpy(M, s.M, sizeof(M)); + } + + operator const typename CompatibleTypes >::Type () const + { + typename CompatibleTypes >::Type result; + OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)"); + memcpy(result.M, M, sizeof(M)); + return result; + } + + T operator()(int i, int j) const { return M[i][j]; } + T& operator()(int i, int j) { return M[i][j]; } + + void ToString(char* dest, size_t destsize) const + { + size_t pos = 0; + for (int r=0; r<3; r++) + { + for (int c=0; c<3; c++) + pos += OVRMath_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]); + } + } + + static Matrix3 FromString(const char* src) + { + Matrix3 result; + if (src) + { + for (int r=0; r<3; r++) + { + for (int c=0; c<3; c++) + { + result.M[r][c] = (T)atof(src); + while (*src && *src != ' ') + src++; + while (*src && *src == ' ') + src++; + } + } + } + return result; + } + + static Matrix3 Identity() { return Matrix3(); } + + void SetIdentity() + { + M[0][0] = M[1][1] = M[2][2] = 1; + M[0][1] = M[1][0] = M[2][0] = 0; + M[0][2] = M[1][2] = M[2][1] = 0; + } + + static Matrix3 Diagonal(T m00, T m11, T m22) + { + return Matrix3(m00, 0, 0, + 0, m11, 0, + 0, 0, m22); + } + static Matrix3 Diagonal(const Vector3& v) { return Diagonal(v.x, v.y, v.z); } + + T Trace() const { return M[0][0] + M[1][1] + M[2][2]; } + + bool operator== (const Matrix3& b) const + { + bool isEqual = true; + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + isEqual &= (M[i][j] == b.M[i][j]); + } + + return isEqual; + } + + Matrix3 operator+ (const Matrix3& b) const + { + Matrix3 result(*this); + result += b; + return result; + } + + Matrix3& operator+= (const Matrix3& b) + { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + M[i][j] += b.M[i][j]; + return *this; + } + + void operator= (const Matrix3& b) + { + for (int i = 0; i < 3; i++) + for (int j = 0; j < 3; j++) + M[i][j] = b.M[i][j]; + } + + Matrix3 operator- (const Matrix3& b) const + { + Matrix3 result(*this); + result -= b; + return result; + } + + Matrix3& operator-= (const Matrix3& b) + { + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + M[i][j] -= b.M[i][j]; + } + + return *this; + } + + // Multiplies two matrices into destination with minimum copying. + static Matrix3& Multiply(Matrix3* d, const Matrix3& a, const Matrix3& b) + { + OVR_MATH_ASSERT((d != &a) && (d != &b)); + int i = 0; + do { + d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0]; + d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1]; + d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2]; + } while((++i) < 3); + + return *d; + } + + Matrix3 operator* (const Matrix3& b) const + { + Matrix3 result(Matrix3::NoInit); + Multiply(&result, *this, b); + return result; + } + + Matrix3& operator*= (const Matrix3& b) + { + return Multiply(this, Matrix3(*this), b); + } + + Matrix3 operator* (T s) const + { + Matrix3 result(*this); + result *= s; + return result; + } + + Matrix3& operator*= (T s) + { + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + M[i][j] *= s; + } + + return *this; + } + + Vector3 operator* (const Vector3 &b) const + { + Vector3 result; + result.x = M[0][0]*b.x + M[0][1]*b.y + M[0][2]*b.z; + result.y = M[1][0]*b.x + M[1][1]*b.y + M[1][2]*b.z; + result.z = M[2][0]*b.x + M[2][1]*b.y + M[2][2]*b.z; + + return result; + } + + Matrix3 operator/ (T s) const + { + Matrix3 result(*this); + result /= s; + return result; + } + + Matrix3& operator/= (T s) + { + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + M[i][j] /= s; + } + + return *this; + } + + Vector2 Transform(const Vector2& v) const + { + const float rcpZ = 1.0f / (M[2][0] * v.x + M[2][1] * v.y + M[2][2]); + return Vector2((M[0][0] * v.x + M[0][1] * v.y + M[0][2]) * rcpZ, + (M[1][0] * v.x + M[1][1] * v.y + M[1][2]) * rcpZ); + } + + Vector3 Transform(const Vector3& v) const + { + return Vector3(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z, + M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z, + M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z); + } + + Matrix3 Transposed() const + { + return Matrix3(M[0][0], M[1][0], M[2][0], + M[0][1], M[1][1], M[2][1], + M[0][2], M[1][2], M[2][2]); + } + + void Transpose() + { + *this = Transposed(); + } + + + T SubDet (const size_t* rows, const size_t* cols) const + { + return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]]) + - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]]) + + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]); + } + + + // M += a*b.t() + inline void Rank1Add(const Vector3 &a, const Vector3 &b) + { + M[0][0] += a.x*b.x; M[0][1] += a.x*b.y; M[0][2] += a.x*b.z; + M[1][0] += a.y*b.x; M[1][1] += a.y*b.y; M[1][2] += a.y*b.z; + M[2][0] += a.z*b.x; M[2][1] += a.z*b.y; M[2][2] += a.z*b.z; + } + + // M -= a*b.t() + inline void Rank1Sub(const Vector3 &a, const Vector3 &b) + { + M[0][0] -= a.x*b.x; M[0][1] -= a.x*b.y; M[0][2] -= a.x*b.z; + M[1][0] -= a.y*b.x; M[1][1] -= a.y*b.y; M[1][2] -= a.y*b.z; + M[2][0] -= a.z*b.x; M[2][1] -= a.z*b.y; M[2][2] -= a.z*b.z; + } + + inline Vector3 Col(int c) const + { + return Vector3(M[0][c], M[1][c], M[2][c]); + } + + inline Vector3 Row(int r) const + { + return Vector3(M[r][0], M[r][1], M[r][2]); + } + + inline Vector3 GetColumn(int c) const + { + return Vector3(M[0][c], M[1][c], M[2][c]); + } + + inline Vector3 GetRow(int r) const + { + return Vector3(M[r][0], M[r][1], M[r][2]); + } + + inline void SetColumn(int c, const Vector3& v) + { + M[0][c] = v.x; + M[1][c] = v.y; + M[2][c] = v.z; + } + + inline void SetRow(int r, const Vector3& v) + { + M[r][0] = v.x; + M[r][1] = v.y; + M[r][2] = v.z; + } + + inline T Determinant() const + { + const Matrix3& m = *this; + T d; + + d = m.M[0][0] * (m.M[1][1]*m.M[2][2] - m.M[1][2] * m.M[2][1]); + d -= m.M[0][1] * (m.M[1][0]*m.M[2][2] - m.M[1][2] * m.M[2][0]); + d += m.M[0][2] * (m.M[1][0]*m.M[2][1] - m.M[1][1] * m.M[2][0]); + + return d; + } + + inline Matrix3 Inverse() const + { + Matrix3 a; + const Matrix3& m = *this; + T d = Determinant(); + + OVR_MATH_ASSERT(d != 0); + T s = T(1)/d; + + a.M[0][0] = s * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]); + a.M[1][0] = s * (m.M[1][2] * m.M[2][0] - m.M[1][0] * m.M[2][2]); + a.M[2][0] = s * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]); + + a.M[0][1] = s * (m.M[0][2] * m.M[2][1] - m.M[0][1] * m.M[2][2]); + a.M[1][1] = s * (m.M[0][0] * m.M[2][2] - m.M[0][2] * m.M[2][0]); + a.M[2][1] = s * (m.M[0][1] * m.M[2][0] - m.M[0][0] * m.M[2][1]); + + a.M[0][2] = s * (m.M[0][1] * m.M[1][2] - m.M[0][2] * m.M[1][1]); + a.M[1][2] = s * (m.M[0][2] * m.M[1][0] - m.M[0][0] * m.M[1][2]); + a.M[2][2] = s * (m.M[0][0] * m.M[1][1] - m.M[0][1] * m.M[1][0]); + + return a; + } + + // Outer Product of two column vectors: a * b.Transpose() + static Matrix3 OuterProduct(const Vector3& a, const Vector3& b) + { + return Matrix3(a.x*b.x, a.x*b.y, a.x*b.z, + a.y*b.x, a.y*b.y, a.y*b.z, + a.z*b.x, a.z*b.y, a.z*b.z); + } + + // Angle in radians between two rotation matrices + // Uses identity trace(a*b') = 2*cos(theta) + 1 + T Angle(const Matrix3& b) const + { + const Matrix3& a = *this; + return Acos(((a * b.Transposed()).Trace() - T(1)) * T(0.5)); + } +}; + +typedef Matrix3 Matrix3f; +typedef Matrix3 Matrix3d; + +//------------------------------------------------------------------------------------- +// ***** Matrix2 + +template +class Matrix2 +{ +public: + typedef T ElementType; + static const size_t Dimension = 2; + + T M[2][2]; + + enum NoInitType { NoInit }; + + // Construct with no memory initialization. + Matrix2(NoInitType) { } + + // By default, we construct identity matrix. + Matrix2() + { + M[0][0] = M[1][1] = 1; + M[0][1] = M[1][0] = 0; + } + + Matrix2(T m11, T m12, + T m21, T m22) + { + M[0][0] = m11; M[0][1] = m12; + M[1][0] = m21; M[1][1] = m22; + } + + // Construction from X, Y basis vectors + Matrix2(const Vector2& xBasis, const Vector2& yBasis) + { + M[0][0] = xBasis.x; M[0][1] = yBasis.x; + M[1][0] = xBasis.y; M[1][1] = yBasis.y; + } + + explicit Matrix2(T s) + { + M[0][0] = M[1][1] = s; + M[0][1] = M[1][0] = 0; + } + + Matrix2(T m11, T m22) + { + M[0][0] = m11; M[0][1] = 0; + M[1][0] = 0; M[1][1] = m22; + } + + explicit Matrix2(const Matrix2::OtherFloatType> &src) + { + M[0][0] = T(src.M[0][0]); M[0][1] = T(src.M[0][1]); + M[1][0] = T(src.M[1][0]); M[1][1] = T(src.M[1][1]); + } + + // C-interop support + Matrix2(const typename CompatibleTypes >::Type& s) + { + OVR_MATH_STATIC_ASSERT(sizeof(s) == sizeof(Matrix2), "sizeof(s) == sizeof(Matrix2)"); + memcpy(M, s.M, sizeof(M)); + } + + operator const typename CompatibleTypes >::Type() const + { + typename CompatibleTypes >::Type result; + OVR_MATH_STATIC_ASSERT(sizeof(result) == sizeof(Matrix2), "sizeof(result) == sizeof(Matrix2)"); + memcpy(result.M, M, sizeof(M)); + return result; + } + + T operator()(int i, int j) const { return M[i][j]; } + T& operator()(int i, int j) { return M[i][j]; } + const T* operator[](int i) const { return M[i]; } + T* operator[](int i) { return M[i]; } + + static Matrix2 Identity() { return Matrix2(); } + + void SetIdentity() + { + M[0][0] = M[1][1] = 1; + M[0][1] = M[1][0] = 0; + } + + static Matrix2 Diagonal(T m00, T m11) + { + return Matrix2(m00, m11); + } + static Matrix2 Diagonal(const Vector2& v) { return Matrix2(v.x, v.y); } + + T Trace() const { return M[0][0] + M[1][1]; } + + bool operator== (const Matrix2& b) const + { + return M[0][0] == b.M[0][0] && M[0][1] == b.M[0][1] && + M[1][0] == b.M[1][0] && M[1][1] == b.M[1][1]; + } + + Matrix2 operator+ (const Matrix2& b) const + { + return Matrix2(M[0][0] + b.M[0][0], M[0][1] + b.M[0][1], + M[1][0] + b.M[1][0], M[1][1] + b.M[1][1]); + } + + Matrix2& operator+= (const Matrix2& b) + { + M[0][0] += b.M[0][0]; M[0][1] += b.M[0][1]; + M[1][0] += b.M[1][0]; M[1][1] += b.M[1][1]; + return *this; + } + + void operator= (const Matrix2& b) + { + M[0][0] = b.M[0][0]; M[0][1] = b.M[0][1]; + M[1][0] = b.M[1][0]; M[1][1] = b.M[1][1]; + } + + Matrix2 operator- (const Matrix2& b) const + { + return Matrix2(M[0][0] - b.M[0][0], M[0][1] - b.M[0][1], + M[1][0] - b.M[1][0], M[1][1] - b.M[1][1]); + } + + Matrix2& operator-= (const Matrix2& b) + { + M[0][0] -= b.M[0][0]; M[0][1] -= b.M[0][1]; + M[1][0] -= b.M[1][0]; M[1][1] -= b.M[1][1]; + return *this; + } + + Matrix2 operator* (const Matrix2& b) const + { + return Matrix2(M[0][0] * b.M[0][0] + M[0][1] * b.M[1][0], M[0][0] * b.M[0][1] + M[0][1] * b.M[1][1], + M[1][0] * b.M[0][0] + M[1][1] * b.M[1][0], M[1][0] * b.M[0][1] + M[1][1] * b.M[1][1]); + } + + Matrix2& operator*= (const Matrix2& b) + { + *this = *this * b; + } + + Matrix2 operator* (T s) const + { + return Matrix2(M[0][0] * s, M[0][1] * s, + M[1][0] * s, M[1][1] * s); + } + + Matrix2& operator*= (T s) + { + M[0][0] *= s; M[0][1] *= s; + M[1][0] *= s; M[1][1] *= s; + return *this; + } + + Matrix2 operator/ (T s) const + { + return *this * (T(1) / s); + } + + Matrix2& operator/= (T s) + { + return *this *= (T(1) / s); + } + + Vector2 operator* (const Vector2 &b) const + { + return Vector2(M[0][0] * b.x + M[0][1] * b.y, + M[1][0] * b.x + M[1][1] * b.y); + } + + Vector2 Transform(const Vector2& v) const + { + return Vector2(M[0][0] * v.x + M[0][1] * v.y, + M[1][0] * v.x + M[1][1] * v.y); + } + + Matrix2 Transposed() const + { + return Matrix2(M[0][0], M[1][0], + M[0][1], M[1][1]); + } + + void Transpose() + { + OVRMath_Swap(M[1][0], M[0][1]); + } + + Vector2 GetColumn(int c) const + { + return Vector2(M[0][c], M[1][c]); + } + + Vector2 GetRow(int r) const + { + return Vector2(M[r][0], M[r][1]); + } + + void SetColumn(int c, const Vector2& v) + { + M[0][c] = v.x; + M[1][c] = v.y; + } + + void SetRow(int r, const Vector2& v) + { + M[r][0] = v.x; + M[r][1] = v.y; + } + + T Determinant() const + { + return M[0][0] * M[1][1] - M[0][1] * M[1][0]; + } + + Matrix2 Inverse() const + { + T rcpDet = T(1) / Determinant(); + return Matrix2( M[1][1] * rcpDet, -M[0][1] * rcpDet, + -M[1][0] * rcpDet, M[0][0] * rcpDet); + } + + // Outer Product of two column vectors: a * b.Transpose() + static Matrix2 OuterProduct(const Vector2& a, const Vector2& b) + { + return Matrix2(a.x*b.x, a.x*b.y, + a.y*b.x, a.y*b.y); + } + + // Angle in radians between two rotation matrices + T Angle(const Matrix2& b) const + { + const Matrix2& a = *this; + return Acos(a(0, 0)*b(0, 0) + a(1, 0)*b(1, 0)); + } +}; + +typedef Matrix2 Matrix2f; +typedef Matrix2 Matrix2d; + +//------------------------------------------------------------------------------------- + +template +class SymMat3 +{ +private: + typedef SymMat3 this_type; + +public: + typedef T Value_t; + // Upper symmetric + T v[6]; // _00 _01 _02 _11 _12 _22 + + inline SymMat3() {} + + inline explicit SymMat3(T s) + { + v[0] = v[3] = v[5] = s; + v[1] = v[2] = v[4] = 0; + } + + inline explicit SymMat3(T a00, T a01, T a02, T a11, T a12, T a22) + { + v[0] = a00; v[1] = a01; v[2] = a02; + v[3] = a11; v[4] = a12; + v[5] = a22; + } + + // Cast to symmetric Matrix3 + operator Matrix3() const + { + return Matrix3(v[0], v[1], v[2], + v[1], v[3], v[4], + v[2], v[4], v[5]); + } + + static inline int Index(unsigned int i, unsigned int j) + { + return (i <= j) ? (3*i - i*(i+1)/2 + j) : (3*j - j*(j+1)/2 + i); + } + + inline T operator()(int i, int j) const { return v[Index(i,j)]; } + + inline T &operator()(int i, int j) { return v[Index(i,j)]; } + + inline this_type& operator+=(const this_type& b) + { + v[0]+=b.v[0]; + v[1]+=b.v[1]; + v[2]+=b.v[2]; + v[3]+=b.v[3]; + v[4]+=b.v[4]; + v[5]+=b.v[5]; + return *this; + } + + inline this_type& operator-=(const this_type& b) + { + v[0]-=b.v[0]; + v[1]-=b.v[1]; + v[2]-=b.v[2]; + v[3]-=b.v[3]; + v[4]-=b.v[4]; + v[5]-=b.v[5]; + + return *this; + } + + inline this_type& operator*=(T s) + { + v[0]*=s; + v[1]*=s; + v[2]*=s; + v[3]*=s; + v[4]*=s; + v[5]*=s; + + return *this; + } + + inline SymMat3 operator*(T s) const + { + SymMat3 d; + d.v[0] = v[0]*s; + d.v[1] = v[1]*s; + d.v[2] = v[2]*s; + d.v[3] = v[3]*s; + d.v[4] = v[4]*s; + d.v[5] = v[5]*s; + + return d; + } + + // Multiplies two matrices into destination with minimum copying. + static SymMat3& Multiply(SymMat3* d, const SymMat3& a, const SymMat3& b) + { + // _00 _01 _02 _11 _12 _22 + + d->v[0] = a.v[0] * b.v[0]; + d->v[1] = a.v[0] * b.v[1] + a.v[1] * b.v[3]; + d->v[2] = a.v[0] * b.v[2] + a.v[1] * b.v[4]; + + d->v[3] = a.v[3] * b.v[3]; + d->v[4] = a.v[3] * b.v[4] + a.v[4] * b.v[5]; + + d->v[5] = a.v[5] * b.v[5]; + + return *d; + } + + inline T Determinant() const + { + const this_type& m = *this; + T d; + + d = m(0,0) * (m(1,1)*m(2,2) - m(1,2) * m(2,1)); + d -= m(0,1) * (m(1,0)*m(2,2) - m(1,2) * m(2,0)); + d += m(0,2) * (m(1,0)*m(2,1) - m(1,1) * m(2,0)); + + return d; + } + + inline this_type Inverse() const + { + this_type a; + const this_type& m = *this; + T d = Determinant(); + + OVR_MATH_ASSERT(d != 0); + T s = T(1)/d; + + a(0,0) = s * (m(1,1) * m(2,2) - m(1,2) * m(2,1)); + + a(0,1) = s * (m(0,2) * m(2,1) - m(0,1) * m(2,2)); + a(1,1) = s * (m(0,0) * m(2,2) - m(0,2) * m(2,0)); + + a(0,2) = s * (m(0,1) * m(1,2) - m(0,2) * m(1,1)); + a(1,2) = s * (m(0,2) * m(1,0) - m(0,0) * m(1,2)); + a(2,2) = s * (m(0,0) * m(1,1) - m(0,1) * m(1,0)); + + return a; + } + + inline T Trace() const { return v[0] + v[3] + v[5]; } + + // M = a*a.t() + inline void Rank1(const Vector3 &a) + { + v[0] = a.x*a.x; v[1] = a.x*a.y; v[2] = a.x*a.z; + v[3] = a.y*a.y; v[4] = a.y*a.z; + v[5] = a.z*a.z; + } + + // M += a*a.t() + inline void Rank1Add(const Vector3 &a) + { + v[0] += a.x*a.x; v[1] += a.x*a.y; v[2] += a.x*a.z; + v[3] += a.y*a.y; v[4] += a.y*a.z; + v[5] += a.z*a.z; + } + + // M -= a*a.t() + inline void Rank1Sub(const Vector3 &a) + { + v[0] -= a.x*a.x; v[1] -= a.x*a.y; v[2] -= a.x*a.z; + v[3] -= a.y*a.y; v[4] -= a.y*a.z; + v[5] -= a.z*a.z; + } +}; + +typedef SymMat3 SymMat3f; +typedef SymMat3 SymMat3d; + +template +inline Matrix3 operator*(const SymMat3& a, const SymMat3& b) +{ + #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c)) + return Matrix3( + AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2), + AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2), + AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2)); + #undef AJB_ARBC +} + +template +inline Matrix3 operator*(const Matrix3& a, const SymMat3& b) +{ + #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c)) + return Matrix3( + AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2), + AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2), + AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2)); + #undef AJB_ARBC +} + +//------------------------------------------------------------------------------------- +// ***** Angle + +// Cleanly representing the algebra of 2D rotations. +// The operations maintain the angle between -Pi and Pi, the same range as atan2. + +template +class Angle +{ +public: + enum AngularUnits + { + Radians = 0, + Degrees = 1 + }; + + Angle() : a(0) {} + + // Fix the range to be between -Pi and Pi + Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*((T)MATH_DOUBLE_DEGREETORADFACTOR)) { FixRange(); } + + T Get(AngularUnits u = Radians) const { return (u == Radians) ? a : a*((T)MATH_DOUBLE_RADTODEGREEFACTOR); } + void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*((T)MATH_DOUBLE_DEGREETORADFACTOR); FixRange(); } + int Sign() const { if (a == 0) return 0; else return (a > 0) ? 1 : -1; } + T Abs() const { return (a >= 0) ? a : -a; } + + bool operator== (const Angle& b) const { return a == b.a; } + bool operator!= (const Angle& b) const { return a != b.a; } +// bool operator< (const Angle& b) const { return a < a.b; } +// bool operator> (const Angle& b) const { return a > a.b; } +// bool operator<= (const Angle& b) const { return a <= a.b; } +// bool operator>= (const Angle& b) const { return a >= a.b; } +// bool operator= (const T& x) { a = x; FixRange(); } + + // These operations assume a is already between -Pi and Pi. + Angle& operator+= (const Angle& b) { a = a + b.a; FastFixRange(); return *this; } + Angle& operator+= (const T& x) { a = a + x; FixRange(); return *this; } + Angle operator+ (const Angle& b) const { Angle res = *this; res += b; return res; } + Angle operator+ (const T& x) const { Angle res = *this; res += x; return res; } + Angle& operator-= (const Angle& b) { a = a - b.a; FastFixRange(); return *this; } + Angle& operator-= (const T& x) { a = a - x; FixRange(); return *this; } + Angle operator- (const Angle& b) const { Angle res = *this; res -= b; return res; } + Angle operator- (const T& x) const { Angle res = *this; res -= x; return res; } + + T Distance(const Angle& b) { T c = fabs(a - b.a); return (c <= ((T)MATH_DOUBLE_PI)) ? c : ((T)MATH_DOUBLE_TWOPI) - c; } + +private: + + // The stored angle, which should be maintained between -Pi and Pi + T a; + + // Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side + inline void FastFixRange() + { + if (a < -((T)MATH_DOUBLE_PI)) + a += ((T)MATH_DOUBLE_TWOPI); + else if (a > ((T)MATH_DOUBLE_PI)) + a -= ((T)MATH_DOUBLE_TWOPI); + } + + // Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method + inline void FixRange() + { + // do nothing if the value is already in the correct range, since fmod call is expensive + if (a >= -((T)MATH_DOUBLE_PI) && a <= ((T)MATH_DOUBLE_PI)) + return; + a = fmod(a,((T)MATH_DOUBLE_TWOPI)); + if (a < -((T)MATH_DOUBLE_PI)) + a += ((T)MATH_DOUBLE_TWOPI); + else if (a > ((T)MATH_DOUBLE_PI)) + a -= ((T)MATH_DOUBLE_TWOPI); + } +}; + + +typedef Angle Anglef; +typedef Angle Angled; + + +//------------------------------------------------------------------------------------- +// ***** Plane + +// Consists of a normal vector and distance from the origin where the plane is located. + +template +class Plane +{ +public: + Vector3 N; + T D; + + Plane() : D(0) {} + + // Normals must already be normalized + Plane(const Vector3& n, T d) : N(n), D(d) {} + Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {} + + // construct from a point on the plane and the normal + Plane(const Vector3& p, const Vector3& n) : N(n), D(-(p * n)) {} + + // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane). + T TestSide(const Vector3& p) const + { + return (N.Dot(p)) + D; + } + + Plane Flipped() const + { + return Plane(-N, -D); + } + + void Flip() + { + N = -N; + D = -D; + } + + bool operator==(const Plane& rhs) const + { + return (this->D == rhs.D && this->N == rhs.N); + } +}; + +typedef Plane Planef; +typedef Plane Planed; + + + + +//----------------------------------------------------------------------------------- +// ***** ScaleAndOffset2D + +struct ScaleAndOffset2D +{ + Vector2f Scale; + Vector2f Offset; + + ScaleAndOffset2D(float sx = 0.0f, float sy = 0.0f, float ox = 0.0f, float oy = 0.0f) + : Scale(sx, sy), Offset(ox, oy) + { } +}; + + +//----------------------------------------------------------------------------------- +// ***** FovPort + +// FovPort describes Field Of View (FOV) of a viewport. +// This class has values for up, down, left and right, stored in +// tangent of the angle units to simplify calculations. +// +// As an example, for a standard 90 degree vertical FOV, we would +// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }. +// +// CreateFromRadians/Degrees helper functions can be used to +// access FOV in different units. + + +// ***** FovPort + +struct FovPort +{ + float UpTan; + float DownTan; + float LeftTan; + float RightTan; + + FovPort ( float sideTan = 0.0f ) : + UpTan(sideTan), DownTan(sideTan), LeftTan(sideTan), RightTan(sideTan) { } + FovPort ( float u, float d, float l, float r ) : + UpTan(u), DownTan(d), LeftTan(l), RightTan(r) { } + + // C-interop support: FovPort <-> ovrFovPort (implementation in OVR_CAPI.cpp). + FovPort(const ovrFovPort &src) + : UpTan(src.UpTan), DownTan(src.DownTan), LeftTan(src.LeftTan), RightTan(src.RightTan) + { } + + operator ovrFovPort () const + { + ovrFovPort result; + result.LeftTan = LeftTan; + result.RightTan = RightTan; + result.UpTan = UpTan; + result.DownTan = DownTan; + return result; + } + + static FovPort CreateFromRadians(float horizontalFov, float verticalFov) + { + FovPort result; + result.UpTan = tanf ( verticalFov * 0.5f ); + result.DownTan = tanf ( verticalFov * 0.5f ); + result.LeftTan = tanf ( horizontalFov * 0.5f ); + result.RightTan = tanf ( horizontalFov * 0.5f ); + return result; + } + + static FovPort CreateFromDegrees(float horizontalFovDegrees, + float verticalFovDegrees) + { + return CreateFromRadians(DegreeToRad(horizontalFovDegrees), + DegreeToRad(verticalFovDegrees)); + } + + // Get Horizontal/Vertical components of Fov in radians. + float GetVerticalFovRadians() const { return atanf(UpTan) + atanf(DownTan); } + float GetHorizontalFovRadians() const { return atanf(LeftTan) + atanf(RightTan); } + // Get Horizontal/Vertical components of Fov in degrees. + float GetVerticalFovDegrees() const { return RadToDegree(GetVerticalFovRadians()); } + float GetHorizontalFovDegrees() const { return RadToDegree(GetHorizontalFovRadians()); } + + // Compute maximum tangent value among all four sides. + float GetMaxSideTan() const + { + return OVRMath_Max(OVRMath_Max(UpTan, DownTan), OVRMath_Max(LeftTan, RightTan)); + } + + static ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort tanHalfFov ) + { + float projXScale = 2.0f / ( tanHalfFov.LeftTan + tanHalfFov.RightTan ); + float projXOffset = ( tanHalfFov.LeftTan - tanHalfFov.RightTan ) * projXScale * 0.5f; + float projYScale = 2.0f / ( tanHalfFov.UpTan + tanHalfFov.DownTan ); + float projYOffset = ( tanHalfFov.UpTan - tanHalfFov.DownTan ) * projYScale * 0.5f; + + ScaleAndOffset2D result; + result.Scale = Vector2f(projXScale, projYScale); + result.Offset = Vector2f(projXOffset, projYOffset); + // Hey - why is that Y.Offset negated? + // It's because a projection matrix transforms from world coords with Y=up, + // whereas this is from NDC which is Y=down. + + return result; + } + + // Converts Fov Tan angle units to [-1,1] render target NDC space + Vector2f TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle) + { + ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(*this); + return tanEyeAngle * eyeToSourceNDC.Scale + eyeToSourceNDC.Offset; + } + + // Compute per-channel minimum and maximum of Fov. + static FovPort Min(const FovPort& a, const FovPort& b) + { + FovPort fov( OVRMath_Min( a.UpTan , b.UpTan ), + OVRMath_Min( a.DownTan , b.DownTan ), + OVRMath_Min( a.LeftTan , b.LeftTan ), + OVRMath_Min( a.RightTan, b.RightTan ) ); + return fov; + } + + static FovPort Max(const FovPort& a, const FovPort& b) + { + FovPort fov( OVRMath_Max( a.UpTan , b.UpTan ), + OVRMath_Max( a.DownTan , b.DownTan ), + OVRMath_Max( a.LeftTan , b.LeftTan ), + OVRMath_Max( a.RightTan, b.RightTan ) ); + return fov; + } +}; + + +} // Namespace OVR + + +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + + +#endif diff --git a/LibOVR/Include/OVR.h b/LibOVR/Include/OVR.h index b82e452..546e447 100644 --- a/LibOVR/Include/OVR.h +++ b/LibOVR/Include/OVR.h @@ -27,10 +27,14 @@ limitations under the License. #define OVR_h #include "OVR_Version.h" - -#include "../Src/Kernel/OVR_Math.h" - -#include "../Src/OVR_CAPI.h" +#include "OVR_CAPI.h" + +/* The following includes are deprecated from this location and will be removed from a future version of this library. */ +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_RefCount.h" +#include "Kernel/OVR_Std.h" +#include "Kernel/OVR_Alg.h" +#include "Extras/OVR_Math.h" #endif diff --git a/LibOVR/Include/OVR_CAPI.h b/LibOVR/Include/OVR_CAPI.h new file mode 100644 index 0000000..ab950b6 --- /dev/null +++ b/LibOVR/Include/OVR_CAPI.h @@ -0,0 +1,4 @@ + +// Temporary backward compatibility until we update all our internal code that's dependent on it. +#include "OVR_CAPI_0_5_0.h" + diff --git a/LibOVR/Include/OVR_CAPI_0_5_0.h b/LibOVR/Include/OVR_CAPI_0_5_0.h new file mode 100755 index 0000000..01f0dd8 --- /dev/null +++ b/LibOVR/Include/OVR_CAPI_0_5_0.h @@ -0,0 +1,1178 @@ +/************************************************************************************ + +Filename : OVR_CAPI_0_5_0.h +Content : C Interface to Oculus tracking and rendering. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +/// @file OVR_CAPI_0_5_0.h +/// Exposes all general Rift functionality. + +#ifndef OVR_CAPI_h // We don't use version numbers within this, as all versioned variations of +#define OVR_CAPI_h // this file are currently mutually exclusive. + + +#include "OVR_CAPI_Keys.h" +#include "OVR_Version.h" + + +#include + +#if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable: 4324) // structure was padded due to __declspec(align()) +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_OS +// +#if !defined(OVR_OS_WIN32) && defined(_WIN32) + #define OVR_OS_WIN32 +#endif + +#if !defined(OVR_OS_MAC) && defined(__APPLE__) + #define OVR_OS_MAC +#endif + +#if !defined(OVR_OS_LINUX) && defined(__linux__) + #define OVR_OS_LINUX +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP +// +#if !defined(OVR_CPP) + #if defined(__cplusplus) + #define OVR_CPP(x) x + #else + #define OVR_CPP(x) /* Not C++ */ + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_CDECL +// +// LibOVR calling convention for 32-bit Windows builds. +// +#if !defined(OVR_CDECL) + #if defined(_WIN32) + #define OVR_CDECL __cdecl + #else + #define OVR_CDECL + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_EXTERN_C +// +// Defined as extern "C" when built from C++ code. +// +#if !defined(OVR_EXTERN_C) + #ifdef __cplusplus + #define OVR_EXTERN_C extern "C" + #else + #define OVR_EXTERN_C + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_PUBLIC_FUNCTION / OVR_PRIVATE_FUNCTION +// +// OVR_PUBLIC_FUNCTION - Functions that externally visible from a shared library. Corresponds to Microsoft __dllexport. +// OVR_PUBLIC_CLASS - C++ structs and classes that are externally visible from a shared library. Corresponds to Microsoft __dllexport. +// OVR_PRIVATE_FUNCTION - Functions that are not visible outside of a shared library. They are private to the shared library. +// OVR_PRIVATE_CLASS - C++ structs and classes that are not visible outside of a shared library. They are private to the shared library. +// +// OVR_DLL_BUILD - Used to indicate that the current compilation unit is of a shared library. +// OVR_DLL_IMPORT - Used to indicate that the current compilation unit is a user of the corresponding shared library. +// OVR_DLL_BUILD - used to indicate that the current compilation unit is not a shared library but rather statically linked code. +// +#if !defined(OVR_PUBLIC_FUNCTION) + #if defined(OVR_DLL_BUILD) + #if defined(_WIN32) + #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __declspec(dllexport) rval OVR_CDECL + #define OVR_PUBLIC_CLASS __declspec(dllexport) + #define OVR_PRIVATE_FUNCTION + #define OVR_PRIVATE_CLASS + #else + #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __attribute__((visibility("default"))) rval OVR_CDECL /* Requires GCC 4.0+ */ + #define OVR_PUBLIC_CLASS __attribute__((visibility("default"))) /* Requires GCC 4.0+ */ + #define OVR_PRIVATE_FUNCTION __attribute__((visibility("hidden"))) + #define OVR_PRIVATE_CLASS __attribute__((visibility("hidden"))) + #endif + #elif defined(OVR_DLL_IMPORT) + #if defined(_WIN32) + #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C __declspec(dllimport) rval OVR_CDECL + #define OVR_PUBLIC_CLASS __declspec(dllimport) + #define OVR_PRIVATE_FUNCTION + #define OVR_PRIVATE_CLASS + #else + #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL + #define OVR_PUBLIC_CLASS + #define OVR_PRIVATE_FUNCTION + #define OVR_PRIVATE_CLASS + #endif + #else // OVR_STATIC_BUILD + #define OVR_PUBLIC_FUNCTION(rval) OVR_EXTERN_C rval OVR_CDECL + #define OVR_PUBLIC_CLASS + #define OVR_PRIVATE_FUNCTION + #define OVR_PRIVATE_CLASS + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_EXPORT +// +// Provided for backward compatibility with older usage. + +#if !defined(OVR_EXPORT) + #ifdef OVR_OS_WIN32 + #define OVR_EXPORT __declspec(dllexport) + #else + #define OVR_EXPORT + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_ALIGNAS +// + +#if !defined(OVR_ALIGNAS) + // C++11 alignas + #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)) + #define OVR_ALIGNAS(n) alignas(n) + #elif defined(__clang__) && !defined(__APPLE__) && (((__clang_major__ * 100) + __clang_minor__) >= 300) && (__cplusplus >= 201103L) + #define OVR_ALIGNAS(n) alignas(n) + #elif defined(__clang__) && defined(__APPLE__) && (((__clang_major__ * 100) + __clang_minor__) >= 401) && (__cplusplus >= 201103L) + #define OVR_ALIGNAS(n) alignas(n) + #elif defined(_MSC_VER) && (_MSC_VER >= 1900) + #define OVR_ALIGNAS(n) alignas(n) + #elif defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408) + #define OVR_ALIGNAS(n) alignas(n) + + // Pre-C++11 alignas fallbacks + #elif defined(__GNUC__) || defined(__clang__) + #define OVR_ALIGNAS(n) __attribute__((aligned(n))) + #elif defined(_MSC_VER) || defined(__INTEL_COMPILER) + #define OVR_ALIGNAS(n) __declspec(align(n)) // For Microsoft the alignment must be a literal integer. + #elif defined(__CC_ARM) + #define OVR_ALIGNAS(n) __align(n) + #else + #error Need to define OVR_ALIGNAS + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** ovrBool + +typedef char ovrBool; +#define ovrFalse 0 +#define ovrTrue 1 + + +//----------------------------------------------------------------------------------- +// ***** Simple Math Structures + +/// A 2D vector with integer components. +typedef struct ovrVector2i_ +{ + int x, y; +} ovrVector2i; + +/// A 2D size with integer components. +typedef struct ovrSizei_ +{ + int w, h; +} ovrSizei; +/// A 2D rectangle with a position and size. +/// All components are integers. +typedef struct ovrRecti_ +{ + ovrVector2i Pos; + ovrSizei Size; +} ovrRecti; + +/// A quaternion rotation. +typedef struct ovrQuatf_ +{ + float x, y, z, w; +} ovrQuatf; + +/// A 2D vector with float components. +typedef struct ovrVector2f_ +{ + float x, y; +} ovrVector2f; + +/// A 3D vector with float components. +typedef struct ovrVector3f_ +{ + float x, y, z; +} ovrVector3f; + +/// A 4x4 matrix with float elements. +typedef struct ovrMatrix4f_ +{ + float M[4][4]; +} ovrMatrix4f; + +/// Position and orientation together. +typedef struct ovrPosef_ +{ + ovrQuatf Orientation; + ovrVector3f Position; +} ovrPosef; + +/// A full pose (rigid body) configuration with first and second derivatives. +typedef struct OVR_ALIGNAS(8) ovrPoseStatef_ +{ + ovrPosef ThePose; ///< The body's position and orientation. + ovrVector3f AngularVelocity; ///< The body's angular velocity in radians per second. + ovrVector3f LinearVelocity; ///< The body's velocity in meters per second. + ovrVector3f AngularAcceleration; ///< The body's angular acceleration in radians per second per second. + ovrVector3f LinearAcceleration; ///< The body's acceleration in meters per second per second. + float Pad; ///< Unused struct padding. + double TimeInSeconds; ///< Absolute time of this state sample. +} ovrPoseStatef; + +/// Field Of View (FOV) in tangent of the angle units. +/// As an example, for a standard 90 degree vertical FOV, we would +/// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }. +typedef struct ovrFovPort_ +{ + float UpTan; ///< The tangent of the angle between the viewing vector and the top edge of the field of view. + float DownTan; ///< The tangent of the angle between the viewing vector and the bottom edge of the field of view. + float LeftTan; ///< The tangent of the angle between the viewing vector and the left edge of the field of view. + float RightTan; ///< The tangent of the angle between the viewing vector and the right edge of the field of view. +} ovrFovPort; + +//----------------------------------------------------------------------------------- +// ***** HMD Types + +/// Enumerates all HMD types that we support. +typedef enum ovrHmdType_ +{ + ovrHmd_None = 0, + ovrHmd_DK1 = 3, + ovrHmd_DKHD = 4, + ovrHmd_DK2 = 6, + ovrHmd_BlackStar = 7, + ovrHmd_CB = 8, + ovrHmd_Other = 9, + ovrHmd_EnumSize = 0x7fffffff ///< Force type int32_t. +} ovrHmdType; + +/// HMD capability bits reported by device. +typedef enum ovrHmdCaps_ +{ + // Read-only flags. + ovrHmdCap_Present = 0x0001, ///< (read only) The HMD is plugged in and detected by the system. + ovrHmdCap_Available = 0x0002, ///< (read only) The HMD and its sensor are available for ownership use. + ///< i.e. it is not already owned by another application. + ovrHmdCap_Captured = 0x0004, ///< (read only) Set to 'true' if we captured ownership of this HMD. + ovrHmdCap_ExtendDesktop = 0x0008, ///< (read only) Means the display driver works via acting as an addition display monitor. + ovrHmdCap_DebugDevice = 0x0010, ///< (read only) Means HMD device is a virtual debug device. + + // Modifiable flags (through ovrHmd_SetEnabledCaps). + ovrHmdCap_NoMirrorToWindow = 0x2000, ///< Disables mirroring of HMD output to the window. This may improve + ///< rendering performance slightly (only if 'ExtendDesktop' is off). + ovrHmdCap_DisplayOff = 0x0040, ///< Turns off HMD screen and output (only if 'ExtendDesktop' is off). + ovrHmdCap_LowPersistence = 0x0080, ///< HMD supports low persistence mode. + ovrHmdCap_DynamicPrediction = 0x0200, ///< Adjust prediction dynamically based on internally measured latency. + ovrHmdCap_NoVSync = 0x1000, ///< Support rendering without VSync for debugging. + + // These bits can be modified by ovrHmd_SetEnabledCaps. + ovrHmdCap_Writable_Mask = ovrHmdCap_NoMirrorToWindow | + ovrHmdCap_DisplayOff | + ovrHmdCap_LowPersistence | + ovrHmdCap_DynamicPrediction | + ovrHmdCap_NoVSync, + + /// These flags are currently passed into the service. May change without notice. + ovrHmdCap_Service_Mask = ovrHmdCap_NoMirrorToWindow | + ovrHmdCap_DisplayOff | + ovrHmdCap_LowPersistence | + ovrHmdCap_DynamicPrediction + , ovrHmdCap_EnumSize = 0x7fffffff ///< Force type int32_t. +} ovrHmdCaps; + + +/// Tracking capability bits reported by the device. +/// Used with ovrHmd_ConfigureTracking. +typedef enum ovrTrackingCaps_ +{ + ovrTrackingCap_Orientation = 0x0010, ///< Supports orientation tracking (IMU). + ovrTrackingCap_MagYawCorrection = 0x0020, ///< Supports yaw drift correction via a magnetometer or other means. + ovrTrackingCap_Position = 0x0040, ///< Supports positional tracking. + /// Overrides the other flags. Indicates that the application + /// doesn't care about tracking settings. This is the internal + /// default before ovrHmd_ConfigureTracking is called. + ovrTrackingCap_Idle = 0x0100, + ovrTrackingCap_EnumSize = 0x7fffffff ///< Force type int32_t. +} ovrTrackingCaps; + +/// Distortion capability bits reported by device. +/// Used with ovrHmd_ConfigureRendering and ovrHmd_CreateDistortionMesh. +typedef enum ovrDistortionCaps_ +{ + // 0x01 unused - Previously ovrDistortionCap_Chromatic now enabled permanently. + ovrDistortionCap_TimeWarp = 0x02, ///< Supports timewarp. + // 0x04 unused + + ovrDistortionCap_Vignette = 0x08, ///< Supports vignetting around the edges of the view. + ovrDistortionCap_NoRestore = 0x10, ///< Do not save and restore the graphics and compute state when rendering distortion. + ovrDistortionCap_FlipInput = 0x20, ///< Flip the vertical texture coordinate of input images. + ovrDistortionCap_SRGB = 0x40, ///< Assume input images are in sRGB gamma-corrected color space. + ovrDistortionCap_Overdrive = 0x80, ///< Overdrive brightness transitions to reduce artifacts on DK2+ displays + ovrDistortionCap_HqDistortion = 0x100, ///< High-quality sampling of distortion buffer for anti-aliasing + ovrDistortionCap_LinuxDevFullscreen = 0x200, ///< Indicates window is fullscreen on a device when set. The SDK will automatically apply distortion mesh rotation if needed. + ovrDistortionCap_ComputeShader = 0x400, ///< Using compute shader (DX11+ only) + //ovrDistortionCap_NoTimewarpJit = 0x800 RETIRED - do not reuse this bit without major versioning changes. + ovrDistortionCap_TimewarpJitDelay = 0x1000, ///< Enables a spin-wait that tries to push time-warp to be as close to V-sync as possible. WARNING - this may backfire and cause framerate loss - use with caution. + + ovrDistortionCap_ProfileNoSpinWaits = 0x10000, ///< Use when profiling with timewarp to remove false positives + ovrDistortionCap_EnumSize = 0x7fffffff ///< Force type int32_t. +} ovrDistortionCaps; + +/// Specifies which eye is being used for rendering. +/// This type explicitly does not include a third "NoStereo" option, as such is +/// not required for an HMD-centered API. +typedef enum ovrEyeType_ +{ + ovrEye_Left = 0, + ovrEye_Right = 1, + ovrEye_Count = 2, + ovrEye_EnumSize = 0x7fffffff ///< Force type int32_t. +} ovrEyeType; + +/// This is a complete descriptor of the HMD. +typedef struct ovrHmdDesc_ +{ + /// Internal handle of this HMD. + struct ovrHmdStruct* Handle; + + /// This HMD's type. + ovrHmdType Type; + + /// Name string describing the product: "Oculus Rift DK1", etc. + const char* ProductName; + /// String describing the manufacturer. Usually "Oculus". + const char* Manufacturer; + + /// HID Vendor ID of the device. + short VendorId; + /// HID Product ID of the device. + short ProductId; + /// Sensor (and display) serial number. + char SerialNumber[24]; + /// Sensor firmware major version number. + short FirmwareMajor; + /// Sensor firmware minor version number. + short FirmwareMinor; + // External tracking camera frustum dimensions (if present). + float CameraFrustumHFovInRadians; ///< Horizontal field-of-view + float CameraFrustumVFovInRadians; ///< Vertical field-of-view + float CameraFrustumNearZInMeters; ///< Near clip distance + float CameraFrustumFarZInMeters; ///< Far clip distance + + /// Capability bits described by ovrHmdCaps. + unsigned int HmdCaps; + /// Capability bits described by ovrTrackingCaps. + unsigned int TrackingCaps; + /// Capability bits described by ovrDistortionCaps. + unsigned int DistortionCaps; + + /// The recommended optical FOV for the HMD. + ovrFovPort DefaultEyeFov[ovrEye_Count]; + /// The maximum optical FOV for the HMD. + ovrFovPort MaxEyeFov[ovrEye_Count]; + + /// Preferred eye rendering order for best performance. + /// Can help reduce latency on sideways-scanned screens. + ovrEyeType EyeRenderOrder[ovrEye_Count]; + + /// Resolution of the full HMD screen (both eyes) in pixels. + ovrSizei Resolution; + /// Location of the application window on the desktop (or 0,0). + ovrVector2i WindowsPos; + + /// Display that the HMD should present on. + /// TBD: It may be good to remove this information relying on WindowPos instead. + /// Ultimately, we may need to come up with a more convenient alternative, + /// such as API-specific functions that return adapter, or something that will + /// work with our monitor driver. + /// Windows: (e.g. "\\\\.\\DISPLAY3", can be used in EnumDisplaySettings/CreateDC). + const char* DisplayDeviceName; + /// MacOS: + int DisplayId; + +} ovrHmdDesc; + +/// Simple type ovrHmd is used in ovrHmd_* calls. +typedef const ovrHmdDesc * ovrHmd; + +/// Bit flags describing the current status of sensor tracking. +// The values must be the same as in enum StatusBits +typedef enum ovrStatusBits_ +{ + ovrStatus_OrientationTracked = 0x0001, ///< Orientation is currently tracked (connected and in use). + ovrStatus_PositionTracked = 0x0002, ///< Position is currently tracked (false if out of range). + ovrStatus_CameraPoseTracked = 0x0004, ///< Camera pose is currently tracked. + ovrStatus_PositionConnected = 0x0020, ///< Position tracking hardware is connected. + ovrStatus_HmdConnected = 0x0080, ///< HMD Display is available and connected. + ovrStatus_EnumSize = 0x7fffffff ///< Force type int32_t. +} ovrStatusBits; + +/// Specifies a reading we can query from the sensor. +typedef struct ovrSensorData_ +{ + ovrVector3f Accelerometer; /// Acceleration reading in m/s^2. + ovrVector3f Gyro; /// Rotation rate in rad/s. + ovrVector3f Magnetometer; /// Magnetic field in Gauss. + float Temperature; /// Temperature of the sensor in degrees Celsius. + float TimeInSeconds; /// Time when the reported IMU reading took place, in seconds. +} ovrSensorData; + + +/// Tracking state at a given absolute time (describes predicted HMD pose etc). +/// Returned by ovrHmd_GetTrackingState. +typedef struct ovrTrackingState_ +{ + /// Predicted head pose (and derivatives) at the requested absolute time. + /// The look-ahead interval is equal to (HeadPose.TimeInSeconds - RawSensorData.TimeInSeconds). + ovrPoseStatef HeadPose; + + /// Current pose of the external camera (if present). + /// This pose includes camera tilt (roll and pitch). For a leveled coordinate + /// system use LeveledCameraPose. + ovrPosef CameraPose; + + /// Camera frame aligned with gravity. + /// This value includes position and yaw of the camera, but not roll and pitch. + /// It can be used as a reference point to render real-world objects in the correct location. + ovrPosef LeveledCameraPose; + + /// The most recent sensor data received from the HMD. + ovrSensorData RawSensorData; + + /// Tracking status described by ovrStatusBits. + unsigned int StatusFlags; + + /// Tag the vision processing results to a certain frame counter number. + uint32_t LastCameraFrameCounter; + + /// Unused struct padding. + uint32_t Pad; +} ovrTrackingState; + + + +/// Frame timing data reported by ovrHmd_BeginFrameTiming() or ovrHmd_BeginFrame(). +typedef struct OVR_ALIGNAS(8) ovrFrameTiming_ +{ + /// The amount of time that has passed since the previous frame's + /// ThisFrameSeconds value (usable for movement scaling). + /// This will be clamped to no more than 0.1 seconds to prevent + /// excessive movement after pauses due to loading or initialization. + float DeltaSeconds; + + /// Unused struct padding. + float Pad; + + /// It is generally expected that the following holds: + /// ThisFrameSeconds < TimewarpPointSeconds < NextFrameSeconds < + /// EyeScanoutSeconds[EyeOrder[0]] <= ScanoutMidpointSeconds <= EyeScanoutSeconds[EyeOrder[1]]. + + /// Absolute time value when rendering of this frame began or is expected to + /// begin. Generally equal to NextFrameSeconds of the previous frame. Can be used + /// for animation timing. + double ThisFrameSeconds; + + /// Absolute point when IMU expects to be sampled for this frame. + double TimewarpPointSeconds; + + /// Absolute time when frame Present followed by GPU Flush will finish and the next frame begins. + double NextFrameSeconds; + + /// Time when half of the screen will be scanned out. Can be passed as an absolute time + /// to ovrHmd_GetTrackingState() to get the predicted general orientation. + double ScanoutMidpointSeconds; + + /// Timing points when each eye will be scanned out to display. Used when rendering each eye. + double EyeScanoutSeconds[2]; +} ovrFrameTiming; + +/// Rendering information for each eye. Computed by either ovrHmd_ConfigureRendering() +/// or ovrHmd_GetRenderDesc() based on the specified FOV. Note that the rendering viewport +/// is not included here as it can be specified separately and modified per frame through: +/// (a) ovrHmd_GetRenderScaleAndOffset in the case of client rendered distortion, +/// or (b) passing different values via ovrTexture in the case of SDK rendered distortion. +typedef struct ovrEyeRenderDesc_ +{ + ovrEyeType Eye; ///< The eye index this instance corresponds to. + ovrFovPort Fov; ///< The field of view. + ovrRecti DistortedViewport; ///< Distortion viewport. + ovrVector2f PixelsPerTanAngleAtCenter; ///< How many display pixels will fit in tan(angle) = 1. + ovrVector3f HmdToEyeViewOffset; ///< Translation to be applied to view matrix for each eye offset. +} ovrEyeRenderDesc; + +/// Rendering information for positional TimeWarp. +/// Contains the data necessary to properly calculate position info for timewarp matrices +/// and also interpret depth info provided via the depth buffer to the timewarp shader +typedef struct ovrPositionTimewarpDesc_ +{ + /// The same offset value pair provided in ovrEyeRenderDesc. + ovrVector3f HmdToEyeViewOffset[2]; + /// The near clip distance used in the projection matrix. + float NearClip; + /// The far clip distance used in the projection matrix + /// utilized when rendering the eye depth textures provided in ovrHmd_EndFrame + float FarClip; +} ovrPositionTimewarpDesc; + +//----------------------------------------------------------------------------------- +// ***** Platform-independent Rendering Configuration + +/// These types are used to hide platform-specific details when passing +/// render device, OS, and texture data to the API. +/// +/// The benefit of having these wrappers versus platform-specific API functions is +/// that they allow game glue code to be portable. A typical example is an +/// engine that has multiple back ends, say GL and D3D. Portable code that calls +/// these back ends may also use LibOVR. To do this, back ends can be modified +/// to return portable types such as ovrTexture and ovrRenderAPIConfig. +typedef enum ovrRenderAPIType_ +{ + ovrRenderAPI_None, + ovrRenderAPI_OpenGL, + ovrRenderAPI_Android_GLES, // May include extra native window pointers, etc. + ovrRenderAPI_D3D9, // Deprecated: Not supported for SDK rendering + ovrRenderAPI_D3D10, // Deprecated: Not supported for SDK rendering + ovrRenderAPI_D3D11, + ovrRenderAPI_Count, + ovrRenderAPI_EnumSize = 0x7fffffff ///< Force type int32_t. +} ovrRenderAPIType; + +/// Platform-independent part of rendering API-configuration data. +/// It is a part of ovrRenderAPIConfig, passed to ovrHmd_Configure. +typedef struct ovrRenderAPIConfigHeader_ +{ + ovrRenderAPIType API; ///< The graphics API in use. + ovrSizei BackBufferSize; ///< Previously named RTSize. + int Multisample; ///< The number of samples per pixel. +} ovrRenderAPIConfigHeader; + +/// Contains platform-specific information for rendering. +typedef struct ovrRenderAPIConfig_ +{ + ovrRenderAPIConfigHeader Header; ///< Platform-independent rendering information. + uintptr_t PlatformData[8]; ///< Platform-specific rendering information. +} ovrRenderAPIConfig; + +/// Platform-independent part of the eye texture descriptor. +/// It is a part of ovrTexture, passed to ovrHmd_EndFrame. +/// If RenderViewport is all zeros then the full texture will be used. +typedef struct ovrTextureHeader_ +{ + ovrRenderAPIType API; ///< The graphics API in use. + ovrSizei TextureSize; ///< The size of the texture. + ovrRecti RenderViewport; ///< Pixel viewport in texture that holds eye image. +} ovrTextureHeader; + +/// Contains platform-specific information about a texture. +/// Specialized for different rendering APIs in: +/// ovrGLTexture, ovrD3D11Texture +typedef struct ovrTexture_ +{ + ovrTextureHeader Header; ///< Platform-independent data about the texture. + uintptr_t PlatformData[8]; ///< Specialized in ovrGLTextureData, ovrD3D11TextureData etc. +} ovrTexture; + + +// ----------------------------------------------------------------------------------- +// ***** API Interfaces + +// Basic steps to use the API: +// +// Setup: +// * ovrInitialize() +// * ovrHMD hmd = ovrHmd_Create(0) +// * Use hmd members and ovrHmd_GetFovTextureSize() to determine graphics configuration. +// * Call ovrHmd_ConfigureTracking() to configure and initialize tracking. +// * Call ovrHmd_ConfigureRendering() to setup graphics for SDK rendering, +// which is the preferred approach. +// Please refer to "Client Distortion Rendering" below if you prefer to do that instead. +// * If the ovrHmdCap_ExtendDesktop flag is not set, then use ovrHmd_AttachToWindow to +// associate the relevant application window with the hmd. +// * Allocate render target textures as needed. +// +// Game Loop: +// * Call ovrHmd_BeginFrame() to get the current frame timing information. +// * Render each eye using ovrHmd_GetEyePoses() to get each eye pose. +// * Call ovrHmd_EndFrame() to render the distorted textures to the back buffer +// and present them on the hmd. +// +// Shutdown: +// * ovrHmd_Destroy(hmd) +// * ovr_Shutdown() +// + +#ifdef __cplusplus +extern "C" { +#endif + + +/// ovr_InitializeRenderingShim initializes the rendering shim apart from everything +/// else in LibOVR. This may be helpful if the application prefers to avoid +/// creating any OVR resources (allocations, service connections, etc) at this point. +/// ovr_InitializeRenderingShim does not bring up anything within LibOVR except the +/// necessary hooks to enable the Direct-to-Rift functionality. +/// +/// Either ovr_InitializeRenderingShim() or ovr_Initialize() must be called before any +/// Direct3D or OpenGL initialization is done by application (creation of devices, etc). +/// ovr_Initialize() must still be called after to use the rest of LibOVR APIs. +/// +/// Same as ovr_InitializeRenderingShim except it requests to support at least the +/// given minor LibOVR library version. +OVR_PUBLIC_FUNCTION(ovrBool) ovr_InitializeRenderingShimVersion(int requestedMinorVersion); + +OVR_PUBLIC_FUNCTION(ovrBool) ovr_InitializeRenderingShim(); + + +/// Library init/shutdown, must be called around all other OVR code. +/// No other functions calls besides ovr_InitializeRenderingShim are allowed before +/// ovr_Initialize succeeds or after ovr_Shutdown. +/// Initializes all Oculus functionality. +/// A second call to ovr_Initialize after successful second call returns ovrTrue. + +/// Flags for Initialize() +typedef enum ovrInitFlags_ +{ + // When a debug library is requested, a slower debugging version of the library will + // be run which can be used to help solve problems in the library and debug game code. + ovrInit_Debug = 0x00000001, + + // When ServerOptional is set, the ovr_Initialize() call not will block waiting for + // the server to respond. If the server is not reachable it may still succeed. + ovrInit_ServerOptional = 0x00000002, + + // When a version is requested, LibOVR runtime will respect the RequestedMinorVersion + // field and will verify that the RequestedMinorVersion is supported. + ovrInit_RequestVersion = 0x00000004, + + // Forces debug features of LibOVR off explicitly, even if it is built in debug mode. + ovrInit_ForceNoDebug = 0x00000008, + +} ovrInitFlags; + +/// Logging levels +typedef enum ovrLogLevel_ +{ + ovrLogLevel_Debug = 0, + ovrLogLevel_Info = 1, + ovrLogLevel_Error = 2 +} ovrLogLevel; + +/// Signature for the logging callback. +/// Level is one of the ovrLogLevel constants. +typedef void (OVR_CDECL *ovrLogCallback)(int level, const char* message); + +/// Parameters for the ovr_Initialize() call. +typedef struct +{ + /// Flags from ovrInitFlags to override default behavior. + /// Pass 0 for the defaults. + uint32_t Flags; ///< Combination of ovrInitFlags or 0 + + /// Request a specific minimum minor version of the LibOVR runtime. + /// Flags must include ovrInit_RequestVersion or this will be ignored. + uint32_t RequestedMinorVersion; + + /// Log callback function, which may be called at any time asynchronously from + /// multiple threads until ovr_Shutdown() completes. + /// Pass 0 for no log callback. + ovrLogCallback LogCallback; ///< Function pointer or 0 + + /// Number of milliseconds to wait for a connection to the server. + /// Pass 0 for the default timeout. + uint32_t ConnectionTimeoutMS; ///< Timeout in Milliseconds or 0 +} ovrInitParams; + +/// Initialize with extra parameters. +/// Pass 0 to initialize with default parameters, suitable for released games. +/// LibOVRRT shared library search order: +/// 1) Current working directory (often the same as the application directory). +/// 2) Module directory (usually the same as the application directory, but not if the module is a separate shared library). +/// 3) Application directory +/// 4) Development directory (only if OVR_ENABLE_DEVELOPER_SEARCH is enabled, which is off by default). +/// 5) Standard OS shared library search location(s) (OS-specific). +OVR_PUBLIC_FUNCTION(ovrBool) ovr_Initialize(ovrInitParams const* params OVR_CPP(= 0)); + +/// Shuts down all Oculus functionality. +OVR_PUBLIC_FUNCTION(void) ovr_Shutdown(); + +/// Returns version string representing libOVR version. Static, so +/// string remains valid for app lifespan +OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString(); + +/// Detects or re-detects HMDs and reports the total number detected. +/// Users can get information about each HMD by calling ovrHmd_Create with an index. +/// Returns -1 when the service is unreachable. +OVR_PUBLIC_FUNCTION(int) ovrHmd_Detect(); + +/// Creates a handle to an HMD which doubles as a description structure. +/// Index can [0 .. ovrHmd_Detect()-1]. Index mappings can cange after each ovrHmd_Detect call. +/// If not null, then the returned handle must be freed with ovrHmd_Destroy. +OVR_PUBLIC_FUNCTION(ovrHmd) ovrHmd_Create(int index); +OVR_PUBLIC_FUNCTION(void) ovrHmd_Destroy(ovrHmd hmd); + +/// Creates a 'fake' HMD used for debugging only. This is not tied to specific hardware, +/// but may be used to debug some of the related rendering. +OVR_PUBLIC_FUNCTION(ovrHmd) ovrHmd_CreateDebug(ovrHmdType type); + +/// Returns last error for HMD state. Returns null for no error. +/// String is valid until next call or GetLastError or HMD is destroyed. +/// Pass null hmd to get global errors (during create etc). +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetLastError(ovrHmd hmd); + +/// Platform specific function to specify the application window whose output will be +/// displayed on the HMD. Only used if the ovrHmdCap_ExtendDesktop flag is false. +/// Windows: SwapChain associated with this window will be displayed on the HMD. +/// Specify 'destMirrorRect' in window coordinates to indicate an area +/// of the render target output that will be mirrored from 'sourceRenderTargetRect'. +/// Null pointers mean "full size". +/// @note Source and dest mirror rects are not yet implemented. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_AttachToWindow(ovrHmd hmd, void* window, + const ovrRecti* destMirrorRect, + const ovrRecti* sourceRenderTargetRect); + +/// Returns capability bits that are enabled at this time as described by ovrHmdCaps. +/// Note that this value is different font ovrHmdDesc::HmdCaps, which describes what +/// capabilities are available for that HMD. +OVR_PUBLIC_FUNCTION(unsigned int) ovrHmd_GetEnabledCaps(ovrHmd hmd); + +/// Modifies capability bits described by ovrHmdCaps that can be modified, +/// such as ovrHmdCap_LowPersistance. +OVR_PUBLIC_FUNCTION(void) ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int hmdCaps); + +//------------------------------------------------------------------------------------- +// ***** Tracking Interface + +/// All tracking interface functions are thread-safe, allowing tracking state to be sampled +/// from different threads. +/// ConfigureTracking starts sensor sampling, enabling specified capabilities, +/// described by ovrTrackingCaps. +/// - supportedTrackingCaps specifies support that is requested. The function will succeed +/// even if these caps are not available (i.e. sensor or camera is unplugged). Support +/// will automatically be enabled if such device is plugged in later. Software should +/// check ovrTrackingState.StatusFlags for real-time status. +/// - requiredTrackingCaps specify sensor capabilities required at the time of the call. +/// If they are not available, the function will fail. Pass 0 if only specifying +/// supportedTrackingCaps. +/// - Pass 0 for both supportedTrackingCaps and requiredTrackingCaps to disable tracking. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ConfigureTracking(ovrHmd hmd, unsigned int supportedTrackingCaps, + unsigned int requiredTrackingCaps); + +/// Re-centers the sensor orientation. +/// Normally this will recenter the (x,y,z) translational components and the yaw +/// component of orientation. +OVR_PUBLIC_FUNCTION(void) ovrHmd_RecenterPose(ovrHmd hmd); + +/// Returns tracking state reading based on the specified absolute system time. +/// Pass an absTime value of 0.0 to request the most recent sensor reading. In this case +/// both PredictedPose and SamplePose will have the same value. +/// ovrHmd_GetEyePoses relies on a valid ovrTrackingState. +/// This may also be used for more refined timing of FrontBuffer rendering logic, etc. +OVR_PUBLIC_FUNCTION(ovrTrackingState) ovrHmd_GetTrackingState(ovrHmd hmd, double absTime); + + + + + +//------------------------------------------------------------------------------------- +// ***** Graphics Setup + +/// Calculates the recommended viewport size for rendering a given eye within the HMD +/// with a given FOV cone. Higher FOV will generally require larger textures to +/// maintain quality. +/// - pixelsPerDisplayPixel specifies the ratio of the number of render target pixels +/// to display pixels at the center of distortion. 1.0 is the default value. Lower +/// values can improve performance, higher values give improved quality. +/// Apps packing multiple eye views together on the same textue should ensure there is +/// roughly 8 pixels of padding between them to prevent texture filtering and chromatic +/// aberration causing images to "leak" between the two eye views. +OVR_PUBLIC_FUNCTION(ovrSizei) ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov, + float pixelsPerDisplayPixel); + +//------------------------------------------------------------------------------------- +// ***** Rendering API Thread Safety + +// All of rendering functions including the configure and frame functions +// are *NOT thread safe*. It is ok to use ConfigureRendering on one thread and handle +// frames on another thread, but explicit synchronization must be done since +// functions that depend on configured state are not reentrant. +// +// As an extra requirement, any of the following calls must be done on +// the render thread, which is the same thread that calls ovrHmd_BeginFrame +// or ovrHmd_BeginFrameTiming. +// - ovrHmd_EndFrame +// - ovrHmd_GetEyeTimewarpMatrices + +//------------------------------------------------------------------------------------- +// ***** SDK Distortion Rendering Functions + +// These functions support rendering of distortion by the SDK through direct +// access to the underlying rendering API, such as D3D or GL. +// This is the recommended approach since it allows better support for future +// Oculus hardware, and enables a range of low-level optimizations. + +/// Configures rendering and fills in computed render parameters. +/// This function can be called multiple times to change rendering settings. +/// eyeRenderDescOut is a pointer to an array of two ovrEyeRenderDesc structs +/// that are used to return complete rendering information for each eye. +/// - apiConfig provides D3D/OpenGL specific parameters. Pass null +/// to shutdown rendering and release all resources. +/// - distortionCaps describe desired distortion settings. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ConfigureRendering(ovrHmd hmd, + const ovrRenderAPIConfig* apiConfig, + unsigned int distortionCaps, + const ovrFovPort eyeFovIn[2], + ovrEyeRenderDesc eyeRenderDescOut[2] ); + + +/// Begins a frame, returning timing information. +/// This should be called at the beginning of the game rendering loop (on the render thread). +/// Pass 0 for the frame index if not using ovrHmd_GetFrameTiming. +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_BeginFrame(ovrHmd hmd, unsigned int frameIndex); + +/// Ends a frame, submitting the rendered textures to the frame buffer. +/// - RenderViewport within each eyeTexture can change per frame if necessary. +/// - 'renderPose' will typically be the value returned from ovrHmd_GetEyePoses +/// but can be different if a different head pose was used for rendering. +/// - This may perform distortion and scaling internally, assuming is it not +/// delegated to another thread. +/// - Must be called on the same thread as BeginFrame. +/// - If ovrDistortionCap_DepthProjectedTimeWarp is enabled, then app must provide eyeDepthTexture +/// and posTimewarpDesc. Otherwise both can be NULL. +/// - *** This Function will call Present/SwapBuffers and potentially wait for GPU Sync ***. +OVR_PUBLIC_FUNCTION(void) ovrHmd_EndFrame(ovrHmd hmd, + const ovrPosef renderPose[2], + const ovrTexture eyeTexture[2]); + +/// Returns predicted head pose in outHmdTrackingState and offset eye poses in outEyePoses +/// as an atomic operation. Caller need not worry about applying HmdToEyeViewOffset to the +/// returned outEyePoses variables. +/// - Thread-safe function where caller should increment frameIndex with every frame +/// and pass the index where applicable to functions called on the rendering thread. +/// - hmdToEyeViewOffset[2] can be ovrEyeRenderDesc.HmdToEyeViewOffset returned from +/// ovrHmd_ConfigureRendering or ovrHmd_GetRenderDesc. For monoscopic rendering, +/// use a vector that is the average of the two vectors for both eyes. +/// - If frameIndex is not being utilized, pass in 0. +/// - Assuming outEyePoses are used for rendering, it should be passed into ovrHmd_EndFrame. +/// - If caller doesn't need outHmdTrackingState, it can be passed in as NULL +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyePoses(ovrHmd hmd, unsigned int frameIndex, + const ovrVector3f hmdToEyeViewOffset[2], + ovrPosef outEyePoses[2], + ovrTrackingState* outHmdTrackingState); + +/// Function was previously called ovrHmd_GetEyePose +/// Returns the predicted head pose to use when rendering the specified eye. +/// - Important: Caller must apply HmdToEyeViewOffset before using ovrPosef for rendering +/// - Must be called between ovrHmd_BeginFrameTiming and ovrHmd_EndFrameTiming. +/// - If returned pose is used for rendering the eye, it should be passed to ovrHmd_EndFrame. +/// - Parameter 'eye' is used internally for prediction timing only +OVR_PUBLIC_FUNCTION(ovrPosef) ovrHmd_GetHmdPosePerEye(ovrHmd hmd, ovrEyeType eye); + + +//------------------------------------------------------------------------------------- +// ***** Client Distortion Rendering Functions + +// These functions provide the distortion data and render timing support necessary to allow +// client rendering of distortion. Client-side rendering involves the following steps: +// +// 1. Setup ovrEyeDesc based on the desired texture size and FOV. +// Call ovrHmd_GetRenderDesc to get the necessary rendering parameters for each eye. +// +// 2. Use ovrHmd_CreateDistortionMesh to generate the distortion mesh. +// +// 3. Use ovrHmd_BeginFrameTiming, ovrHmd_GetEyePoses, and ovrHmd_BeginFrameTiming in +// the rendering loop to obtain timing and predicted head orientation when rendering each eye. +// - When using timewarp, use ovr_WaitTillTime after the rendering and gpu flush, followed +// by ovrHmd_GetEyeTimewarpMatrices to obtain the timewarp matrices used +// by the distortion pixel shader. This will minimize latency. +// + +/// Computes the distortion viewport, view adjust, and other rendering parameters for +/// the specified eye. This can be used instead of ovrHmd_ConfigureRendering to do +/// setup for client rendered distortion. +OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovrHmd_GetRenderDesc(ovrHmd hmd, + ovrEyeType eyeType, ovrFovPort fov); + + +/// Describes a vertex used by the distortion mesh. This is intended to be converted into +/// the engine-specific format. Some fields may be unused based on the ovrDistortionCaps +/// flags selected. TexG and TexB, for example, are not used if chromatic correction is +/// not requested. +typedef struct ovrDistortionVertex_ +{ + ovrVector2f ScreenPosNDC; ///< [-1,+1],[-1,+1] over the entire framebuffer. + float TimeWarpFactor; ///< Lerp factor between time-warp matrices. Can be encoded in Pos.z. + float VignetteFactor; ///< Vignette fade factor. Can be encoded in Pos.w. + ovrVector2f TanEyeAnglesR; ///< The tangents of the horizontal and vertical eye angles for the red channel. + ovrVector2f TanEyeAnglesG; ///< The tangents of the horizontal and vertical eye angles for the green channel. + ovrVector2f TanEyeAnglesB; ///< The tangents of the horizontal and vertical eye angles for the blue channel. +} ovrDistortionVertex; + +/// Describes a full set of distortion mesh data, filled in by ovrHmd_CreateDistortionMesh. +/// Contents of this data structure, if not null, should be freed by ovrHmd_DestroyDistortionMesh. +typedef struct ovrDistortionMesh_ +{ + ovrDistortionVertex* pVertexData; ///< The distortion vertices representing each point in the mesh. + unsigned short* pIndexData; ///< Indices for connecting the mesh vertices into polygons. + unsigned int VertexCount; ///< The number of vertices in the mesh. + unsigned int IndexCount; ///< The number of indices in the mesh. +} ovrDistortionMesh; + +/// Generate distortion mesh per eye. +/// Distortion capabilities will depend on 'distortionCaps' flags. Users should +/// render using the appropriate shaders based on their settings. +/// Distortion mesh data will be allocated and written into the ovrDistortionMesh data structure, +/// which should be explicitly freed with ovrHmd_DestroyDistortionMesh. +/// Users should call ovrHmd_GetRenderScaleAndOffset to get uvScale and Offset values for rendering. +/// The function shouldn't fail unless theres is a configuration or memory error, in which case +/// ovrDistortionMesh values will be set to null. +/// This is the only function in the SDK reliant on eye relief, currently imported from profiles, +/// or overridden here. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_CreateDistortionMesh(ovrHmd hmd, + ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, + ovrDistortionMesh *meshData); +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_CreateDistortionMeshDebug(ovrHmd hmddesc, + ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, + ovrDistortionMesh *meshData, + float debugEyeReliefOverrideInMetres); + + +/// Used to free the distortion mesh allocated by ovrHmd_GenerateDistortionMesh. meshData elements +/// are set to null and zeroes after the call. +OVR_PUBLIC_FUNCTION(void) ovrHmd_DestroyDistortionMesh(ovrDistortionMesh* meshData); + +/// Computes updated 'uvScaleOffsetOut' to be used with a distortion if render target size or +/// viewport changes after the fact. This can be used to adjust render size every frame if desired. +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetRenderScaleAndOffset(ovrFovPort fov, + ovrSizei textureSize, ovrRecti renderViewport, + ovrVector2f uvScaleOffsetOut[2] ); + +/// Thread-safe timing function for the main thread. Caller should increment frameIndex +/// with every frame and pass the index where applicable to functions called on the +/// rendering thread. +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIndex); + +/// Called at the beginning of the frame on the rendering thread. +/// Pass frameIndex == 0 if ovrHmd_GetFrameTiming isn't being used. Otherwise, +/// pass the same frame index as was used for GetFrameTiming on the main thread. +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frameIndex); + +/// Marks the end of client distortion rendered frame, tracking the necessary timing information. +/// This function must be called immediately after Present/SwapBuffers + GPU sync. GPU sync is +/// important before this call to reduce latency and ensure proper timing. +OVR_PUBLIC_FUNCTION(void) ovrHmd_EndFrameTiming(ovrHmd hmd); + +/// Initializes and resets frame time tracking. This is typically not necessary, but +/// is helpful if game changes vsync state or video mode. vsync is assumed to be on if this +/// isn't called. Resets internal frame index to the specified number. +OVR_PUBLIC_FUNCTION(void) ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex); + +/// Computes timewarp matrices used by distortion mesh shader, these are used to adjust +/// for head orientation change since the last call to ovrHmd_GetEyePoses +/// when rendering this eye. The ovrDistortionVertex::TimeWarpFactor is used to blend between the +/// matrices, usually representing two different sides of the screen. +/// Set 'calcPosition' to true when using depth based positional timewarp +/// Must be called on the same thread as ovrHmd_BeginFrameTiming. +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, + ovrMatrix4f twmOut[2]); +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyeTimewarpMatricesDebug(ovrHmd hmddesc, ovrEyeType eye, ovrPosef renderPose, + ovrQuatf playerTorsoMotion, ovrMatrix4f twmOut[2], + double debugTimingOffsetInSeconds); + + + + +//------------------------------------------------------------------------------------- +// ***** Stateless math setup functions + +/// Returns global, absolute high-resolution time in seconds. This is the same +/// value as used in sensor messages. +OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds(); + + +// ----------------------------------------------------------------------------------- +// ***** Latency Test interface + +/// Does latency test processing and returns 'TRUE' if specified rgb color should +/// be used to clear the screen. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ProcessLatencyTest(ovrHmd hmd, unsigned char rgbColorOut[3]); + +/// Returns non-null string once with latency test result, when it is available. +/// Buffer is valid until next call. +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetLatencyTestResult(ovrHmd hmd); + +/// Returns the latency testing color in rgbColorOut to render when using a DK2 +/// Returns false if this feature is disabled or not-applicable (e.g. using a DK1) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]); + +//------------------------------------------------------------------------------------- +// ***** Health and Safety Warning Display interface +// + +/// Used by ovrhmd_GetHSWDisplayState to report the current display state. +typedef struct OVR_ALIGNAS(8) ovrHSWDisplayState_ +{ + /// If true then the warning should be currently visible + /// and the following variables have meaning. Else there is no + /// warning being displayed for this application on the given HMD. + ovrBool Displayed; ///< True if the Health&Safety Warning is currently displayed. + char Pad[8-sizeof(ovrBool)]; ///< Unused struct padding. + double StartTime; ///< Absolute time when the warning was first displayed. See ovr_GetTimeInSeconds(). + double DismissibleTime; ///< Earliest absolute time when the warning can be dismissed. May be a time in the past. +} ovrHSWDisplayState; + +/// Returns the current state of the HSW display. If the application is doing the rendering of +/// the HSW display then this function serves to indicate that the warning should be +/// currently displayed. If the application is using SDK-based eye rendering then the SDK by +/// default automatically handles the drawing of the HSW display. An application that uses +/// application-based eye rendering should use this function to know when to start drawing the +/// HSW display itself and can optionally use it in conjunction with ovrhmd_DismissHSWDisplay +/// as described below. +/// +/// Example usage for application-based rendering: +/// bool HSWDisplayCurrentlyDisplayed = false; // global or class member variable +/// ovrHSWDisplayState hswDisplayState; +/// ovrhmd_GetHSWDisplayState(Hmd, &hswDisplayState); +/// +/// if (hswDisplayState.Displayed && !HSWDisplayCurrentlyDisplayed) { +/// +/// HSWDisplayCurrentlyDisplayed = true; +/// } +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetHSWDisplayState(ovrHmd hmd, ovrHSWDisplayState *hasWarningState); + +/// Requests a dismissal of the HSWDisplay at the earliest possible time, which may be seconds +/// into the future due to display longevity requirements. +/// Returns true if the display is valid, in which case the request can always be honored. +/// +/// Example usage : +/// void ProcessEvent(int key) { +/// if (key == escape) +/// ovrhmd_DismissHSWDisplay(hmd); +/// } +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_DismissHSWDisplay(ovrHmd hmd); + +/// Get boolean property. Returns first element if property is a boolean array. +/// Returns defaultValue if property doesn't exist. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetBool(ovrHmd hmd, const char* propertyName, ovrBool defaultVal); + +/// Modify bool property; false if property doesn't exist or is readonly. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetBool(ovrHmd hmd, const char* propertyName, ovrBool value); + +/// Get integer property. Returns first element if property is an integer array. +/// Returns defaultValue if property doesn't exist. +OVR_PUBLIC_FUNCTION(int) ovrHmd_GetInt(ovrHmd hmd, const char* propertyName, int defaultVal); + +/// Modify integer property; false if property doesn't exist or is readonly. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetInt(ovrHmd hmd, const char* propertyName, int value); + +/// Get float property. Returns first element if property is a float array. +/// Returns defaultValue if property doesn't exist. +OVR_PUBLIC_FUNCTION(float) ovrHmd_GetFloat(ovrHmd hmd, const char* propertyName, float defaultVal); + +/// Modify float property; false if property doesn't exist or is readonly. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetFloat(ovrHmd hmd, const char* propertyName, float value); + +/// Get float[] property. Returns the number of elements filled in, 0 if property doesn't exist. +/// Maximum of arraySize elements will be written. +OVR_PUBLIC_FUNCTION(unsigned int) ovrHmd_GetFloatArray(ovrHmd hmd, const char* propertyName, + float values[], unsigned int arraySize); + +/// Modify float[] property; false if property doesn't exist or is readonly. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetFloatArray(ovrHmd hmd, const char* propertyName, + float values[], unsigned int arraySize); + +/// Get string property. Returns first element if property is a string array. +/// Returns defaultValue if property doesn't exist. +/// String memory is guaranteed to exist until next call to GetString or GetStringArray, or HMD is destroyed. +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetString(ovrHmd hmd, const char* propertyName, + const char* defaultVal); + +/// Set string property +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetString(ovrHmd hmddesc, const char* propertyName, + const char* value); + +// ----------------------------------------------------------------------------------- +// ***** Logging + +/// Send a message string to the system tracing mechanism if enabled (currently Event Tracing for Windows) +/// Level is one of the ovrLogLevel constants. +/// returns the length of the message, or -1 if message is too large +OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message); + + +// DEPRECATED: These functions are being phased out in favor of a more comprehensive logging system. +// These functions will return false and do nothing. +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_StartPerfLog(ovrHmd hmd, const char* fileName, const char* userData1); +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_StopPerfLog(ovrHmd hmd); + + +#ifdef __cplusplus +} // extern "C" +#endif + + +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + + + +// ----------------------------------------------------------------------------------- +// ***** Backward compatibility #includes +// +// This is at the bottom of this file because the following is dependent on the +// declarations above. + +#if !defined(OVR_CAPI_NO_UTILS) + #include "OVR_CAPI_Util.h" +#endif + + +#endif // OVR_CAPI_h diff --git a/LibOVR/Include/OVR_CAPI_GL.h b/LibOVR/Include/OVR_CAPI_GL.h new file mode 100644 index 0000000..ef7cb45 --- /dev/null +++ b/LibOVR/Include/OVR_CAPI_GL.h @@ -0,0 +1,87 @@ +/************************************************************************************ + +Filename : OVR_CAPI_GL.h +Content : GL specific structures used by the CAPI interface. +Created : November 7, 2013 +Authors : Lee Cooper + +Copyright : Copyright 2013 Oculus VR, LLC. All Rights reserved. + +Use of this software is subject to the terms of the Oculus Inc license +agreement provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +************************************************************************************/ +#ifndef OVR_CAPI_GL_h +#define OVR_CAPI_GL_h + +/// @file OVR_CAPI_GL.h +/// OpenGL rendering support. + +#include "OVR_CAPI.h" + +#if defined(OVR_OS_WIN32) + #include + #include +#elif defined(__APPLE__) + #include +#else + #include +#endif + + +#if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable: 4324) // structure was padded due to __declspec(align()) +#endif + + +/// Used to configure slave GL rendering (i.e. for devices created externally). +typedef struct ovrGLConfigData_s +{ + ovrRenderAPIConfigHeader Header; ///< General device settings. + +#if defined(OVR_OS_WIN32) + HWND Window; ///< The optional window handle. If unset, rendering will use the current window. + HDC DC; ///< The optional device context. If unset, rendering will use a new context. +#elif defined (OVR_OS_LINUX) + struct _XDisplay* Disp; ///< Optional display. If unset, will issue glXGetCurrentDisplay when context is current. +#endif +} ovrGLConfigData; + +#if defined(__cplusplus) + static_assert(sizeof(ovrRenderAPIConfig) >= sizeof(ovrGLConfigData), "Insufficient size."); +#endif + +/// Contains OpenGL-specific rendering information. +union ovrGLConfig +{ + ovrRenderAPIConfig Config; ///< General device settings. + ovrGLConfigData OGL; ///< OpenGL-specific settings. +}; + +/// Used to pass GL eye texture data to ovrHmd_EndFrame. +typedef struct ovrGLTextureData_s +{ + ovrTextureHeader Header; ///< General device settings. + GLuint TexId; ///< The OpenGL name for this texture. +} ovrGLTextureData; + +#if defined(__cplusplus) + static_assert(sizeof(ovrTexture) >= sizeof(ovrGLTextureData), "Insufficient size."); +#endif + +/// Contains OpenGL-specific texture information. +typedef union ovrGLTexture_s +{ + ovrTexture Texture; ///< General device settings. + ovrGLTextureData OGL; ///< OpenGL-specific settings. +} ovrGLTexture; + + +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + + +#endif // OVR_CAPI_GL_h diff --git a/LibOVR/Include/OVR_CAPI_Keys.h b/LibOVR/Include/OVR_CAPI_Keys.h new file mode 100644 index 0000000..13451e5 --- /dev/null +++ b/LibOVR/Include/OVR_CAPI_Keys.h @@ -0,0 +1,56 @@ +/************************************************************************************ + +Filename : OVR_CAPI.h +Content : Keys for CAPI calls +Created : September 25, 2014 +Authors : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + + + +#define OVR_KEY_USER "User" // string +#define OVR_KEY_NAME "Name" // string +#define OVR_KEY_GENDER "Gender" // string +#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" // float +#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float +#define OVR_KEY_IPD "IPD" // float +#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" // float[2] +#define OVR_KEY_EYE_RELIEF_DIAL "EyeReliefDial" // int +#define OVR_KEY_EYE_TO_NOSE_DISTANCE "EyeToNoseDist" // float[2] +#define OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE "MaxEyeToPlateDist" // float[2] +#define OVR_KEY_EYE_CUP "EyeCup" // char[16] +#define OVR_KEY_CUSTOM_EYE_RENDER "CustomEyeRender" // bool +#define OVR_KEY_CAMERA_POSITION "CenteredFromWorld" // double[7] + +// Default measurements empirically determined at Oculus to make us happy +// The neck model numbers were derived as an average of the male and female averages from ANSUR-88 +// NECK_TO_EYE_HORIZONTAL = H22 - H43 = INFRAORBITALE_BACK_OF_HEAD - TRAGION_BACK_OF_HEAD +// NECK_TO_EYE_VERTICAL = H21 - H15 = GONION_TOP_OF_HEAD - ECTOORBITALE_TOP_OF_HEAD +// These were determined to be the best in a small user study, clearly beating out the previous default values +#define OVR_DEFAULT_GENDER "Unknown" +#define OVR_DEFAULT_PLAYER_HEIGHT 1.778f +#define OVR_DEFAULT_EYE_HEIGHT 1.675f +#define OVR_DEFAULT_IPD 0.064f +#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f +#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f +#define OVR_DEFAULT_EYE_RELIEF_DIAL 3 +#define OVR_DEFAULT_CAMERA_POSITION {0,0,0,1,0,0,0} + diff --git a/LibOVR/Include/OVR_CAPI_Util.h b/LibOVR/Include/OVR_CAPI_Util.h new file mode 100644 index 0000000..8d2f43d --- /dev/null +++ b/LibOVR/Include/OVR_CAPI_Util.h @@ -0,0 +1,79 @@ +/************************************************************************************ + +PublicHeader: OVR_CAPI_Util.h +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_CAPI_Util_h +#define OVR_CAPI_Util_h + + +#include "OVR_CAPI.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/// Enumerates modifications to the projection matrix based on the application's needs +typedef enum +{ + /// Use for generating a default projection matrix that is: + /// * Left-handed + /// * Near depth values stored in the depth buffer are smaller than far depth values + /// * Both near and far are explicitly defined + /// * With a clipping range that is (0 to w) + ovrProjection_None = 0x00, + + /// Enable if using right-handed transformations in your application + ovrProjection_RightHanded = 0x01, + + /// After projection transform is applied, far values stored in the depth buffer will be less than closer depth values + /// NOTE: Enable only if application is using a floating-point depth buffer for proper precision + ovrProjection_FarLessThanNear = 0x02, + + /// When this flag is used, the zfar value pushed into ovrMatrix4f_Projection() will be ignored + /// NOTE: Enable only if ovrProjection_FarLessThanNear is also enabled where the far clipping plane will be pushed to infinity + ovrProjection_FarClipAtInfinity = 0x04, + + /// Enable if application is rendering with OpenGL and expects a projection matrix with a clipping range of (-w to w) + /// Ignore this flag if your application already handles the conversion from D3D range (0 to w) to OpenGL + ovrProjection_ClipRangeOpenGL = 0x08, +} ovrProjectionModifier; + +/// Used to generate projection from ovrEyeDesc::Fov. +/// projectionFlags is a combination of the ovrProjectionModifier flags defined above +OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags); + +/// Used for 2D rendering, Y is down +/// orthoScale = 1.0f / pixelsPerTanAngleAtCenter +/// orthoDistance = distance from camera, such as 0.8m +OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale, + float orthoDistance, float hmdToEyeViewOffsetX); + +/// Waits until the specified absolute time. +OVR_PUBLIC_FUNCTION(double) ovr_WaitTillTime(double absTime); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + + +#endif // Header include guard diff --git a/LibOVR/Include/OVR_ErrorCode.h b/LibOVR/Include/OVR_ErrorCode.h new file mode 100755 index 0000000..51c9d7d --- /dev/null +++ b/LibOVR/Include/OVR_ErrorCode.h @@ -0,0 +1,66 @@ +/************************************************************************************ + +PublicHeader: OVR_ErrorCode.h +Copyright : Copyright 2015 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "OVR_Version.h" + + + + +#ifndef OVR_ErrorCode_h +#define OVR_ErrorCode_h + + +#include + + +/* API call results are represented at the highest level by a single ovrResult. */ +#ifndef OVR_RESULT_DEFINED +#define OVR_RESULT_DEFINED +typedef int32_t ovrResult; +#endif + + +/* Success is zero, while all error types are non-zero values. */ +#ifndef OVR_SUCCESS_DEFINED +#define OVR_SUCCESS_DEFINED +const ovrResult ovrSuccess = 0; +#endif + + +enum +{ + /* Initialization errors. */ + ovrError_Initialize = 1000, /* Generic initialization error. */ + ovrError_LibLoad = 1001, /* Couldn't load LibOVRRT. */ + ovrError_LibVersion = 1002, /* LibOVRRT version incompatibility. */ + ovrError_ServiceConnection = 1003, /* Couldn't connect to the OVR Service. */ + ovrError_ServiceVersion = 1004, /* OVR Service version incompatibility. */ + ovrError_IncompatibleOS = 1005, /* The operating system version is incompatible. */ + ovrError_DisplayInit = 1006, /* Unable to initialize the HMD display. */ + ovrError_ServerStart = 1007, /* Unable to start the server. Is it already running? */ + ovrError_Reinitialization = 1008 /* Attempting to re-initialize with a different version. */ +}; + + +#endif /* Header include guard */ + + diff --git a/LibOVR/Include/OVR_Kernel.h b/LibOVR/Include/OVR_Kernel.h index 1a8a903..72ab48a 100644 --- a/LibOVR/Include/OVR_Kernel.h +++ b/LibOVR/Include/OVR_Kernel.h @@ -23,20 +23,22 @@ limitations under the License. *************************************************************************************/ -#ifndef OVR_h -#define OVR_h - -#include "../Src/Kernel/OVR_Types.h" -#include "../Src/Kernel/OVR_Allocator.h" -#include "../Src/Kernel/OVR_RefCount.h" -#include "../Src/Kernel/OVR_Log.h" -#include "../Src/Kernel/OVR_Math.h" -#include "../Src/Kernel/OVR_System.h" -#include "../Src/Kernel/OVR_Nullptr.h" -#include "../Src/Kernel/OVR_String.h" -#include "../Src/Kernel/OVR_Array.h" -#include "../Src/Kernel/OVR_Timer.h" -#include "../Src/Kernel/OVR_SysFile.h" +/* This header file is deprecated and will be removed from a future version of this library */ + +#ifndef OVR_Kernel_h +#define OVR_Kernel_h + +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_RefCount.h" +#include "Kernel/OVR_Log.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Nullptr.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Timer.h" +#include "Kernel/OVR_SysFile.h" +#include "Extras/OVR_Math.h" #endif diff --git a/LibOVR/Include/OVR_Version.h b/LibOVR/Include/OVR_Version.h old mode 100644 new mode 100755 index 2ba20bc..c33fa3c --- a/LibOVR/Include/OVR_Version.h +++ b/LibOVR/Include/OVR_Version.h @@ -22,14 +22,53 @@ limitations under the License. *************************************************************************************/ -#ifndef _OVR_VERSION_H -#define _OVR_VERSION_H +#ifndef OVR_Version_h +#define OVR_Version_h -#define OVR_MAJOR_VERSION 0 -#define OVR_MINOR_VERSION 4 -#define OVR_BUILD_VERSION 4 -#define OVR_VERSION_STRING "0.4.4" -#define OVR_DK2_LATEST_FIRMWARE_MAJOR_VERSION 2 -#define OVR_DK2_LATEST_FIRMWARE_MINOR_VERSION 12 + + + +#if !defined(OVR_STRINGIZE) + #define OVR_STRINGIZEIMPL(x) #x + #define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x) #endif + +// We are on major version 5 of the beta pre-release SDK. At some point we will +// transition to product version 1 and reset the major version back to 1 (first +// product release, version 1.0). +#define OVR_PRODUCT_VERSION 0 +#define OVR_MAJOR_VERSION 5 +#define OVR_MINOR_VERSION 0 +#define OVR_PATCH_VERSION 1 +#define OVR_BUILD_NUMBER 0 + +// "Product.Major.Minor.Patch" +#if !defined(OVR_VERSION_STRING) + #define OVR_VERSION_STRING OVR_STRINGIZE(OVR_PRODUCT_VERSION.OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION) +#endif + +// "Product.Major.Minor.Patch.Build" +#if !defined(OVR_DETAILED_VERSION_STRING) + #define OVR_DETAILED_VERSION_STRING OVR_STRINGIZE(OVR_PRODUCT_VERSION.OVR_MAJOR_VERSION.OVR_MINOR_VERSION.OVR_PATCH_VERSION.OVR_BUILD_NUMBER) +#endif + +// This is the firmware version for the DK2 headset sensor board. +//#if !defined(OVR_DK2_LATEST_FIRMWARE_MAJOR_VERSION) + #define OVR_DK2_LATEST_FIRMWARE_MAJOR_VERSION 2 + #define OVR_DK2_LATEST_FIRMWARE_MINOR_VERSION 12 +//#endif + +// LibOVRRT description +// This appears in the user-visible file properties. It is intended to convey publicly available additional information +// such as feature builds. +#if !defined(OVR_FILE_DESCRIPTION_STRING) + #if defined(_DEBUG) + #define OVR_FILE_DESCRIPTION_STRING "LibOVRRT (debug)" + #else + #define OVR_FILE_DESCRIPTION_STRING "LibOVRRT" + #endif +#endif + + +#endif // OVR_Version_h diff --git a/LibOVR/Projects/Mac/LibOVRRT.plist b/LibOVR/Projects/Mac/LibOVRRT.plist new file mode 100644 index 0000000..874636a --- /dev/null +++ b/LibOVR/Projects/Mac/LibOVRRT.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + Oculus-VR.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + ${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}.${OVR_BUILD_NUMBER} + CFBundleSignature + LOVR + CFBundleVersion + ${OVR_BUILD_NUMBER} + NSHumanReadableCopyright + Copyright © 2014 Oculus VR. All rights reserved. + NSPrincipalClass + + + diff --git a/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/project.pbxproj b/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/project.pbxproj new file mode 100644 index 0000000..06218b3 --- /dev/null +++ b/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/project.pbxproj @@ -0,0 +1,793 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 160735CA1A3BE72100BC3261 /* OVR_Math.h in Headers */ = {isa = PBXBuildFile; fileRef = 160735C21A3BE72100BC3261 /* OVR_Math.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 160735CE1A3BE72100BC3261 /* OVR_CAPI_GL.h in Headers */ = {isa = PBXBuildFile; fileRef = 160735C61A3BE72100BC3261 /* OVR_CAPI_GL.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 160735CF1A3BE72100BC3261 /* OVR_CAPI_Keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 160735C71A3BE72100BC3261 /* OVR_CAPI_Keys.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 160735D11A3BE72100BC3261 /* OVR_Version.h in Headers */ = {isa = PBXBuildFile; fileRef = 160735C91A3BE72100BC3261 /* OVR_Version.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 160735D31A3D744C00BC3261 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 160735D21A3D744C00BC3261 /* IOKit.framework */; }; + 160735D51A3D745300BC3261 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 160735D41A3D745300BC3261 /* OpenGL.framework */; }; + 160735D71A3D746400BC3261 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 160735D61A3D746400BC3261 /* AudioToolbox.framework */; }; + 160735D91A3D746C00BC3261 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 160735D81A3D746C00BC3261 /* Cocoa.framework */; }; + 160738691A3D85F200BC3261 /* CAPI_DistortionRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607372B1A3D85F200BC3261 /* CAPI_DistortionRenderer.cpp */; }; + 1607386A1A3D85F200BC3261 /* CAPI_DistortionRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607372C1A3D85F200BC3261 /* CAPI_DistortionRenderer.h */; }; + 1607386D1A3D85F200BC3261 /* CAPI_HMDRenderState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607372F1A3D85F200BC3261 /* CAPI_HMDRenderState.cpp */; }; + 1607386E1A3D85F200BC3261 /* CAPI_HMDRenderState.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737301A3D85F200BC3261 /* CAPI_HMDRenderState.h */; }; + 1607386F1A3D85F200BC3261 /* CAPI_HMDState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737311A3D85F200BC3261 /* CAPI_HMDState.cpp */; }; + 160738701A3D85F200BC3261 /* CAPI_HMDState.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737321A3D85F200BC3261 /* CAPI_HMDState.h */; }; + 160738711A3D85F200BC3261 /* CAPI_HSWDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737331A3D85F200BC3261 /* CAPI_HSWDisplay.cpp */; }; + 160738721A3D85F200BC3261 /* CAPI_HSWDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737341A3D85F200BC3261 /* CAPI_HSWDisplay.h */; }; + 160738971A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607375D1A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.cpp */; }; + 160738981A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607375E1A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.h */; }; + 160738991A3D85F200BC3261 /* CAPI_GL_DistortionShaders.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607375F1A3D85F200BC3261 /* CAPI_GL_DistortionShaders.h */; }; + 1607389A1A3D85F200BC3261 /* CAPI_GL_HSWDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737601A3D85F200BC3261 /* CAPI_GL_HSWDisplay.cpp */; }; + 1607389B1A3D85F200BC3261 /* CAPI_GL_HSWDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737611A3D85F200BC3261 /* CAPI_GL_HSWDisplay.h */; }; + 1607389C1A3D85F200BC3261 /* CAPI_GL_Util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737621A3D85F200BC3261 /* CAPI_GL_Util.cpp */; }; + 1607389D1A3D85F200BC3261 /* CAPI_GL_Util.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737631A3D85F200BC3261 /* CAPI_GL_Util.h */; }; + 1607389E1A3D85F200BC3261 /* healthAndSafety.tga in Resources */ = {isa = PBXBuildFile; fileRef = 160737651A3D85F200BC3261 /* healthAndSafety.tga */; }; + 1607389F1A3D85F200BC3261 /* healthAndSafety.tga.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737661A3D85F200BC3261 /* healthAndSafety.tga.h */; }; + 160738A01A3D85F200BC3261 /* OVR_Display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737681A3D85F200BC3261 /* OVR_Display.cpp */; }; + 160738A11A3D85F200BC3261 /* OVR_Display.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737691A3D85F200BC3261 /* OVR_Display.h */; }; + 160738AC1A3D85F200BC3261 /* OVR_OSX_Display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737741A3D85F200BC3261 /* OVR_OSX_Display.cpp */; }; + 160738AD1A3D85F200BC3261 /* OVR_OSX_Display.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737751A3D85F200BC3261 /* OVR_OSX_Display.h */; }; + 160738BD1A3D85F200BC3261 /* OVR_BitStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737861A3D85F200BC3261 /* OVR_BitStream.cpp */; }; + 160738BE1A3D85F200BC3261 /* OVR_BitStream.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737871A3D85F200BC3261 /* OVR_BitStream.h */; }; + 160738BF1A3D85F200BC3261 /* OVR_MessageIDTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737881A3D85F200BC3261 /* OVR_MessageIDTypes.h */; }; + 160738C01A3D85F200BC3261 /* OVR_NetworkPlugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737891A3D85F200BC3261 /* OVR_NetworkPlugin.cpp */; }; + 160738C11A3D85F200BC3261 /* OVR_NetworkPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607378A1A3D85F200BC3261 /* OVR_NetworkPlugin.h */; }; + 160738C21A3D85F200BC3261 /* OVR_NetworkTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607378B1A3D85F200BC3261 /* OVR_NetworkTypes.h */; }; + 160738C31A3D85F200BC3261 /* OVR_PacketizedTCPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607378C1A3D85F200BC3261 /* OVR_PacketizedTCPSocket.cpp */; }; + 160738C41A3D85F200BC3261 /* OVR_PacketizedTCPSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607378D1A3D85F200BC3261 /* OVR_PacketizedTCPSocket.h */; }; + 160738C51A3D85F200BC3261 /* OVR_RPC1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607378E1A3D85F200BC3261 /* OVR_RPC1.cpp */; }; + 160738C61A3D85F200BC3261 /* OVR_RPC1.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607378F1A3D85F200BC3261 /* OVR_RPC1.h */; }; + 160738C71A3D85F200BC3261 /* OVR_Session.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737901A3D85F200BC3261 /* OVR_Session.cpp */; }; + 160738C81A3D85F200BC3261 /* OVR_Session.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737911A3D85F200BC3261 /* OVR_Session.h */; }; + 160738C91A3D85F200BC3261 /* OVR_Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737921A3D85F200BC3261 /* OVR_Socket.cpp */; }; + 160738CA1A3D85F200BC3261 /* OVR_Socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737931A3D85F200BC3261 /* OVR_Socket.h */; }; + 160738CB1A3D85F200BC3261 /* OVR_Unix_Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737941A3D85F200BC3261 /* OVR_Unix_Socket.cpp */; }; + 160738CC1A3D85F200BC3261 /* OVR_Unix_Socket.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737951A3D85F200BC3261 /* OVR_Unix_Socket.h */; }; + 160738CF1A3D85F200BC3261 /* OVR_CAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737981A3D85F200BC3261 /* OVR_CAPI.cpp */; }; + 160738D21A3D85F200BC3261 /* OVR_Profile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607379B1A3D85F200BC3261 /* OVR_Profile.cpp */; }; + 160738D31A3D85F200BC3261 /* OVR_Profile.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607379C1A3D85F200BC3261 /* OVR_Profile.h */; }; + 160738D61A3D85F200BC3261 /* OVR_SerialFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607379F1A3D85F200BC3261 /* OVR_SerialFormat.cpp */; }; + 160738D71A3D85F200BC3261 /* OVR_SerialFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737A01A3D85F200BC3261 /* OVR_SerialFormat.h */; }; + 160738D81A3D85F200BC3261 /* OVR_Stereo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737A11A3D85F200BC3261 /* OVR_Stereo.cpp */; }; + 160738D91A3D85F200BC3261 /* OVR_Stereo.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737A21A3D85F200BC3261 /* OVR_Stereo.h */; }; + 160738E51A3D85F200BC3261 /* Oculus.icns in Resources */ = {isa = PBXBuildFile; fileRef = 160737B11A3D85F200BC3261 /* Oculus.icns */; }; + 1607391C1A3D85F200BC3261 /* Service_NetClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737EB1A3D85F200BC3261 /* Service_NetClient.cpp */; }; + 1607391D1A3D85F200BC3261 /* Service_NetClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737EC1A3D85F200BC3261 /* Service_NetClient.h */; }; + 160739201A3D85F200BC3261 /* Service_NetSessionCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160737EF1A3D85F200BC3261 /* Service_NetSessionCommon.cpp */; }; + 160739211A3D85F200BC3261 /* Service_NetSessionCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = 160737F01A3D85F200BC3261 /* Service_NetSessionCommon.h */; }; + 160739381A3D85F200BC3261 /* Util_Interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607380A1A3D85F200BC3261 /* Util_Interface.cpp */; }; + 160739391A3D85F200BC3261 /* Util_Interface.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607380B1A3D85F200BC3261 /* Util_Interface.h */; }; + 1607393E1A3D85F200BC3261 /* Util_LatencyTest2Reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160738101A3D85F200BC3261 /* Util_LatencyTest2Reader.cpp */; }; + 1607393F1A3D85F200BC3261 /* Util_LatencyTest2Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = 160738111A3D85F200BC3261 /* Util_LatencyTest2Reader.h */; }; + 160739401A3D85F200BC3261 /* Util_LatencyTest2State.h in Headers */ = {isa = PBXBuildFile; fileRef = 160738121A3D85F200BC3261 /* Util_LatencyTest2State.h */; }; + 160739411A3D85F200BC3261 /* Util_Render_Stereo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160738131A3D85F200BC3261 /* Util_Render_Stereo.cpp */; }; + 160739421A3D85F200BC3261 /* Util_Render_Stereo.h in Headers */ = {isa = PBXBuildFile; fileRef = 160738141A3D85F200BC3261 /* Util_Render_Stereo.h */; }; + 164B2D101A81A21600A00FE1 /* OVR_CAPI_Util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 164B2D0D1A81A21600A00FE1 /* OVR_CAPI_Util.cpp */; }; + 164B2D111A81A21600A00FE1 /* OVR_StereoProjection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 164B2D0E1A81A21600A00FE1 /* OVR_StereoProjection.cpp */; }; + 164B2D121A81A21600A00FE1 /* OVR_StereoProjection.h in Headers */ = {isa = PBXBuildFile; fileRef = 164B2D0F1A81A21600A00FE1 /* OVR_StereoProjection.h */; }; + 164B2D171A81A2C500A00FE1 /* Vision_SensorStateReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 164B2D151A81A2C500A00FE1 /* Vision_SensorStateReader.cpp */; }; + 164B2D181A81A2C500A00FE1 /* Vision_SensorStateReader.h in Headers */ = {isa = PBXBuildFile; fileRef = 164B2D161A81A2C500A00FE1 /* Vision_SensorStateReader.h */; }; + 16535ACA1A5F0AB300E57802 /* OVR_CAPI_0_5_0.h in Headers */ = {isa = PBXBuildFile; fileRef = 16535AC91A5F0AB300E57802 /* OVR_CAPI_0_5_0.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 16535ACF1A606D1A00E57802 /* LibOVR.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 16535ACE1A606D1A00E57802 /* LibOVR.xcconfig */; }; + 16535AE71A60A54B00E57802 /* CAPI_DistortionTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16535AE11A60A54B00E57802 /* CAPI_DistortionTiming.cpp */; }; + 16535AE81A60A54B00E57802 /* CAPI_DistortionTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 16535AE21A60A54B00E57802 /* CAPI_DistortionTiming.h */; }; + 16535AE91A60A54B00E57802 /* CAPI_FrameLatencyTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16535AE31A60A54B00E57802 /* CAPI_FrameLatencyTracker.cpp */; }; + 16535AEA1A60A54B00E57802 /* CAPI_FrameLatencyTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 16535AE41A60A54B00E57802 /* CAPI_FrameLatencyTracker.h */; }; + 16535AEB1A60A54B00E57802 /* CAPI_FrameTimeManager3.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16535AE51A60A54B00E57802 /* CAPI_FrameTimeManager3.cpp */; }; + 16535AEC1A60A54B00E57802 /* CAPI_FrameTimeManager3.h in Headers */ = {isa = PBXBuildFile; fileRef = 16535AE61A60A54B00E57802 /* CAPI_FrameTimeManager3.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1607330B1A3BB73A00BC3261 /* LibOVRRT_0.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LibOVRRT_0.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 160735C21A3BE72100BC3261 /* OVR_Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Math.h; sourceTree = ""; }; + 160735C61A3BE72100BC3261 /* OVR_CAPI_GL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_CAPI_GL.h; sourceTree = ""; }; + 160735C71A3BE72100BC3261 /* OVR_CAPI_Keys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_CAPI_Keys.h; sourceTree = ""; }; + 160735C91A3BE72100BC3261 /* OVR_Version.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Version.h; sourceTree = ""; }; + 160735D21A3D744C00BC3261 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + 160735D41A3D745300BC3261 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = System/Library/Frameworks/OpenGL.framework; sourceTree = SDKROOT; }; + 160735D61A3D746400BC3261 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; + 160735D81A3D746C00BC3261 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; + 1607372B1A3D85F200BC3261 /* CAPI_DistortionRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_DistortionRenderer.cpp; sourceTree = ""; }; + 1607372C1A3D85F200BC3261 /* CAPI_DistortionRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_DistortionRenderer.h; sourceTree = ""; }; + 1607372F1A3D85F200BC3261 /* CAPI_HMDRenderState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_HMDRenderState.cpp; sourceTree = ""; }; + 160737301A3D85F200BC3261 /* CAPI_HMDRenderState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_HMDRenderState.h; sourceTree = ""; }; + 160737311A3D85F200BC3261 /* CAPI_HMDState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_HMDState.cpp; sourceTree = ""; }; + 160737321A3D85F200BC3261 /* CAPI_HMDState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_HMDState.h; sourceTree = ""; }; + 160737331A3D85F200BC3261 /* CAPI_HSWDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_HSWDisplay.cpp; sourceTree = ""; }; + 160737341A3D85F200BC3261 /* CAPI_HSWDisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_HSWDisplay.h; sourceTree = ""; }; + 1607375D1A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_GL_DistortionRenderer.cpp; sourceTree = ""; }; + 1607375E1A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_GL_DistortionRenderer.h; sourceTree = ""; }; + 1607375F1A3D85F200BC3261 /* CAPI_GL_DistortionShaders.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_GL_DistortionShaders.h; sourceTree = ""; }; + 160737601A3D85F200BC3261 /* CAPI_GL_HSWDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_GL_HSWDisplay.cpp; sourceTree = ""; }; + 160737611A3D85F200BC3261 /* CAPI_GL_HSWDisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_GL_HSWDisplay.h; sourceTree = ""; }; + 160737621A3D85F200BC3261 /* CAPI_GL_Util.cpp */ = {isa = PBXFileReference; explicitFileType = sourcecode.cpp.objcpp; fileEncoding = 4; path = CAPI_GL_Util.cpp; sourceTree = ""; }; + 160737631A3D85F200BC3261 /* CAPI_GL_Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_GL_Util.h; sourceTree = ""; }; + 160737651A3D85F200BC3261 /* healthAndSafety.tga */ = {isa = PBXFileReference; lastKnownFileType = file; path = healthAndSafety.tga; sourceTree = ""; }; + 160737661A3D85F200BC3261 /* healthAndSafety.tga.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = healthAndSafety.tga.h; sourceTree = ""; }; + 160737681A3D85F200BC3261 /* OVR_Display.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Display.cpp; sourceTree = ""; }; + 160737691A3D85F200BC3261 /* OVR_Display.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Display.h; sourceTree = ""; }; + 160737741A3D85F200BC3261 /* OVR_OSX_Display.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_OSX_Display.cpp; sourceTree = ""; }; + 160737751A3D85F200BC3261 /* OVR_OSX_Display.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_OSX_Display.h; sourceTree = ""; }; + 160737861A3D85F200BC3261 /* OVR_BitStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_BitStream.cpp; sourceTree = ""; }; + 160737871A3D85F200BC3261 /* OVR_BitStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_BitStream.h; sourceTree = ""; }; + 160737881A3D85F200BC3261 /* OVR_MessageIDTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_MessageIDTypes.h; sourceTree = ""; }; + 160737891A3D85F200BC3261 /* OVR_NetworkPlugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_NetworkPlugin.cpp; sourceTree = ""; }; + 1607378A1A3D85F200BC3261 /* OVR_NetworkPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_NetworkPlugin.h; sourceTree = ""; }; + 1607378B1A3D85F200BC3261 /* OVR_NetworkTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_NetworkTypes.h; sourceTree = ""; }; + 1607378C1A3D85F200BC3261 /* OVR_PacketizedTCPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_PacketizedTCPSocket.cpp; sourceTree = ""; }; + 1607378D1A3D85F200BC3261 /* OVR_PacketizedTCPSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_PacketizedTCPSocket.h; sourceTree = ""; }; + 1607378E1A3D85F200BC3261 /* OVR_RPC1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_RPC1.cpp; sourceTree = ""; }; + 1607378F1A3D85F200BC3261 /* OVR_RPC1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_RPC1.h; sourceTree = ""; }; + 160737901A3D85F200BC3261 /* OVR_Session.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Session.cpp; sourceTree = ""; }; + 160737911A3D85F200BC3261 /* OVR_Session.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Session.h; sourceTree = ""; }; + 160737921A3D85F200BC3261 /* OVR_Socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Socket.cpp; sourceTree = ""; }; + 160737931A3D85F200BC3261 /* OVR_Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Socket.h; sourceTree = ""; }; + 160737941A3D85F200BC3261 /* OVR_Unix_Socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Unix_Socket.cpp; sourceTree = ""; }; + 160737951A3D85F200BC3261 /* OVR_Unix_Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Unix_Socket.h; sourceTree = ""; }; + 160737981A3D85F200BC3261 /* OVR_CAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_CAPI.cpp; sourceTree = ""; }; + 1607379B1A3D85F200BC3261 /* OVR_Profile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Profile.cpp; sourceTree = ""; }; + 1607379C1A3D85F200BC3261 /* OVR_Profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Profile.h; sourceTree = ""; }; + 1607379F1A3D85F200BC3261 /* OVR_SerialFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_SerialFormat.cpp; sourceTree = ""; }; + 160737A01A3D85F200BC3261 /* OVR_SerialFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_SerialFormat.h; sourceTree = ""; }; + 160737A11A3D85F200BC3261 /* OVR_Stereo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Stereo.cpp; sourceTree = ""; }; + 160737A21A3D85F200BC3261 /* OVR_Stereo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Stereo.h; sourceTree = ""; }; + 160737B11A3D85F200BC3261 /* Oculus.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Oculus.icns; sourceTree = ""; }; + 160737EB1A3D85F200BC3261 /* Service_NetClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Service_NetClient.cpp; sourceTree = ""; }; + 160737EC1A3D85F200BC3261 /* Service_NetClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Service_NetClient.h; sourceTree = ""; }; + 160737EF1A3D85F200BC3261 /* Service_NetSessionCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Service_NetSessionCommon.cpp; sourceTree = ""; }; + 160737F01A3D85F200BC3261 /* Service_NetSessionCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Service_NetSessionCommon.h; sourceTree = ""; }; + 1607380A1A3D85F200BC3261 /* Util_Interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_Interface.cpp; sourceTree = ""; }; + 1607380B1A3D85F200BC3261 /* Util_Interface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_Interface.h; sourceTree = ""; }; + 160738101A3D85F200BC3261 /* Util_LatencyTest2Reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_LatencyTest2Reader.cpp; sourceTree = ""; }; + 160738111A3D85F200BC3261 /* Util_LatencyTest2Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_LatencyTest2Reader.h; sourceTree = ""; }; + 160738121A3D85F200BC3261 /* Util_LatencyTest2State.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_LatencyTest2State.h; sourceTree = ""; }; + 160738131A3D85F200BC3261 /* Util_Render_Stereo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_Render_Stereo.cpp; sourceTree = ""; }; + 160738141A3D85F200BC3261 /* Util_Render_Stereo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_Render_Stereo.h; sourceTree = ""; }; + 160739991A3E3FF800BC3261 /* libOVRKernel.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libOVRKernel.a; path = ../../../LibOVRKernel/Lib/Mac/x86_64/Debug/libOVRKernel.a; sourceTree = SOURCE_ROOT; }; + 164B2D0D1A81A21600A00FE1 /* OVR_CAPI_Util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_CAPI_Util.cpp; sourceTree = ""; }; + 164B2D0E1A81A21600A00FE1 /* OVR_StereoProjection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_StereoProjection.cpp; sourceTree = ""; }; + 164B2D0F1A81A21600A00FE1 /* OVR_StereoProjection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_StereoProjection.h; sourceTree = ""; }; + 164B2D151A81A2C500A00FE1 /* Vision_SensorStateReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Vision_SensorStateReader.cpp; path = Vision/SensorFusion/Vision_SensorStateReader.cpp; sourceTree = ""; }; + 164B2D161A81A2C500A00FE1 /* Vision_SensorStateReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Vision_SensorStateReader.h; path = Vision/SensorFusion/Vision_SensorStateReader.h; sourceTree = ""; }; + 16535AC91A5F0AB300E57802 /* OVR_CAPI_0_5_0.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_CAPI_0_5_0.h; sourceTree = ""; }; + 16535ACE1A606D1A00E57802 /* LibOVR.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = LibOVR.xcconfig; sourceTree = ""; }; + 16535AE11A60A54B00E57802 /* CAPI_DistortionTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_DistortionTiming.cpp; sourceTree = ""; }; + 16535AE21A60A54B00E57802 /* CAPI_DistortionTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_DistortionTiming.h; sourceTree = ""; }; + 16535AE31A60A54B00E57802 /* CAPI_FrameLatencyTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_FrameLatencyTracker.cpp; sourceTree = ""; }; + 16535AE41A60A54B00E57802 /* CAPI_FrameLatencyTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_FrameLatencyTracker.h; sourceTree = ""; }; + 16535AE51A60A54B00E57802 /* CAPI_FrameTimeManager3.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_FrameTimeManager3.cpp; sourceTree = ""; }; + 16535AE61A60A54B00E57802 /* CAPI_FrameTimeManager3.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_FrameTimeManager3.h; sourceTree = ""; }; + 16535B401A6453B500E57802 /* LibOVRRT.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = LibOVRRT.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 160733071A3BB73A00BC3261 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 160735D91A3D746C00BC3261 /* Cocoa.framework in Frameworks */, + 160735D71A3D746400BC3261 /* AudioToolbox.framework in Frameworks */, + 160735D51A3D745300BC3261 /* OpenGL.framework in Frameworks */, + 160735D31A3D744C00BC3261 /* IOKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 160733011A3BB73A00BC3261 = { + isa = PBXGroup; + children = ( + 16073A2C1A3FE73200BC3261 /* Frameworks */, + 160735C01A3BE72100BC3261 /* Include */, + 1607330C1A3BB73A00BC3261 /* Products */, + 160737291A3D85F200BC3261 /* Src */, + 16073A621A48133300BC3261 /* Supporting files */, + ); + sourceTree = ""; + }; + 1607330C1A3BB73A00BC3261 /* Products */ = { + isa = PBXGroup; + children = ( + 1607330B1A3BB73A00BC3261 /* LibOVRRT_0.framework */, + ); + name = Products; + sourceTree = ""; + }; + 160735C01A3BE72100BC3261 /* Include */ = { + isa = PBXGroup; + children = ( + 160735C11A3BE72100BC3261 /* Extras */, + 16535AC91A5F0AB300E57802 /* OVR_CAPI_0_5_0.h */, + 160735C61A3BE72100BC3261 /* OVR_CAPI_GL.h */, + 160735C71A3BE72100BC3261 /* OVR_CAPI_Keys.h */, + 160735C91A3BE72100BC3261 /* OVR_Version.h */, + ); + name = Include; + path = ../../Include; + sourceTree = ""; + }; + 160735C11A3BE72100BC3261 /* Extras */ = { + isa = PBXGroup; + children = ( + 160735C21A3BE72100BC3261 /* OVR_Math.h */, + ); + path = Extras; + sourceTree = ""; + }; + 160737291A3D85F200BC3261 /* Src */ = { + isa = PBXGroup; + children = ( + 1607372A1A3D85F200BC3261 /* CAPI */, + 160737671A3D85F200BC3261 /* Displays */, + 160737851A3D85F200BC3261 /* Net */, + 160737AF1A3D85F200BC3261 /* Resources */, + 160737E81A3D85F200BC3261 /* Service */, + 160738091A3D85F200BC3261 /* Util */, + 164B2D131A81A2A000A00FE1 /* Vision */, + 160737981A3D85F200BC3261 /* OVR_CAPI.cpp */, + 164B2D0D1A81A21600A00FE1 /* OVR_CAPI_Util.cpp */, + 1607379B1A3D85F200BC3261 /* OVR_Profile.cpp */, + 1607379C1A3D85F200BC3261 /* OVR_Profile.h */, + 1607379F1A3D85F200BC3261 /* OVR_SerialFormat.cpp */, + 160737A01A3D85F200BC3261 /* OVR_SerialFormat.h */, + 160737A11A3D85F200BC3261 /* OVR_Stereo.cpp */, + 160737A21A3D85F200BC3261 /* OVR_Stereo.h */, + 164B2D0E1A81A21600A00FE1 /* OVR_StereoProjection.cpp */, + 164B2D0F1A81A21600A00FE1 /* OVR_StereoProjection.h */, + ); + name = Src; + path = ../../Src; + sourceTree = ""; + }; + 1607372A1A3D85F200BC3261 /* CAPI */ = { + isa = PBXGroup; + children = ( + 16535AE11A60A54B00E57802 /* CAPI_DistortionTiming.cpp */, + 16535AE21A60A54B00E57802 /* CAPI_DistortionTiming.h */, + 16535AE31A60A54B00E57802 /* CAPI_FrameLatencyTracker.cpp */, + 16535AE41A60A54B00E57802 /* CAPI_FrameLatencyTracker.h */, + 16535AE51A60A54B00E57802 /* CAPI_FrameTimeManager3.cpp */, + 16535AE61A60A54B00E57802 /* CAPI_FrameTimeManager3.h */, + 1607372B1A3D85F200BC3261 /* CAPI_DistortionRenderer.cpp */, + 1607372C1A3D85F200BC3261 /* CAPI_DistortionRenderer.h */, + 1607372F1A3D85F200BC3261 /* CAPI_HMDRenderState.cpp */, + 160737301A3D85F200BC3261 /* CAPI_HMDRenderState.h */, + 160737311A3D85F200BC3261 /* CAPI_HMDState.cpp */, + 160737321A3D85F200BC3261 /* CAPI_HMDState.h */, + 160737331A3D85F200BC3261 /* CAPI_HSWDisplay.cpp */, + 160737341A3D85F200BC3261 /* CAPI_HSWDisplay.h */, + 1607375C1A3D85F200BC3261 /* GL */, + 160737641A3D85F200BC3261 /* Textures */, + ); + path = CAPI; + sourceTree = ""; + }; + 1607375C1A3D85F200BC3261 /* GL */ = { + isa = PBXGroup; + children = ( + 1607375D1A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.cpp */, + 1607375E1A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.h */, + 1607375F1A3D85F200BC3261 /* CAPI_GL_DistortionShaders.h */, + 160737601A3D85F200BC3261 /* CAPI_GL_HSWDisplay.cpp */, + 160737611A3D85F200BC3261 /* CAPI_GL_HSWDisplay.h */, + 160737621A3D85F200BC3261 /* CAPI_GL_Util.cpp */, + 160737631A3D85F200BC3261 /* CAPI_GL_Util.h */, + ); + path = GL; + sourceTree = ""; + }; + 160737641A3D85F200BC3261 /* Textures */ = { + isa = PBXGroup; + children = ( + 160737651A3D85F200BC3261 /* healthAndSafety.tga */, + 160737661A3D85F200BC3261 /* healthAndSafety.tga.h */, + ); + path = Textures; + sourceTree = ""; + }; + 160737671A3D85F200BC3261 /* Displays */ = { + isa = PBXGroup; + children = ( + 160737681A3D85F200BC3261 /* OVR_Display.cpp */, + 160737691A3D85F200BC3261 /* OVR_Display.h */, + 160737741A3D85F200BC3261 /* OVR_OSX_Display.cpp */, + 160737751A3D85F200BC3261 /* OVR_OSX_Display.h */, + ); + path = Displays; + sourceTree = ""; + }; + 160737851A3D85F200BC3261 /* Net */ = { + isa = PBXGroup; + children = ( + 160737861A3D85F200BC3261 /* OVR_BitStream.cpp */, + 160737871A3D85F200BC3261 /* OVR_BitStream.h */, + 160737881A3D85F200BC3261 /* OVR_MessageIDTypes.h */, + 160737891A3D85F200BC3261 /* OVR_NetworkPlugin.cpp */, + 1607378A1A3D85F200BC3261 /* OVR_NetworkPlugin.h */, + 1607378B1A3D85F200BC3261 /* OVR_NetworkTypes.h */, + 1607378C1A3D85F200BC3261 /* OVR_PacketizedTCPSocket.cpp */, + 1607378D1A3D85F200BC3261 /* OVR_PacketizedTCPSocket.h */, + 1607378E1A3D85F200BC3261 /* OVR_RPC1.cpp */, + 1607378F1A3D85F200BC3261 /* OVR_RPC1.h */, + 160737901A3D85F200BC3261 /* OVR_Session.cpp */, + 160737911A3D85F200BC3261 /* OVR_Session.h */, + 160737921A3D85F200BC3261 /* OVR_Socket.cpp */, + 160737931A3D85F200BC3261 /* OVR_Socket.h */, + 160737941A3D85F200BC3261 /* OVR_Unix_Socket.cpp */, + 160737951A3D85F200BC3261 /* OVR_Unix_Socket.h */, + ); + path = Net; + sourceTree = ""; + }; + 160737AF1A3D85F200BC3261 /* Resources */ = { + isa = PBXGroup; + children = ( + 160737B01A3D85F200BC3261 /* Mac */, + ); + path = Resources; + sourceTree = ""; + }; + 160737B01A3D85F200BC3261 /* Mac */ = { + isa = PBXGroup; + children = ( + 160737B11A3D85F200BC3261 /* Oculus.icns */, + ); + path = Mac; + sourceTree = ""; + }; + 160737E81A3D85F200BC3261 /* Service */ = { + isa = PBXGroup; + children = ( + 160737EB1A3D85F200BC3261 /* Service_NetClient.cpp */, + 160737EC1A3D85F200BC3261 /* Service_NetClient.h */, + 160737EF1A3D85F200BC3261 /* Service_NetSessionCommon.cpp */, + 160737F01A3D85F200BC3261 /* Service_NetSessionCommon.h */, + ); + path = Service; + sourceTree = ""; + }; + 160738091A3D85F200BC3261 /* Util */ = { + isa = PBXGroup; + children = ( + 1607380A1A3D85F200BC3261 /* Util_Interface.cpp */, + 1607380B1A3D85F200BC3261 /* Util_Interface.h */, + 160738101A3D85F200BC3261 /* Util_LatencyTest2Reader.cpp */, + 160738111A3D85F200BC3261 /* Util_LatencyTest2Reader.h */, + 160738121A3D85F200BC3261 /* Util_LatencyTest2State.h */, + 160738131A3D85F200BC3261 /* Util_Render_Stereo.cpp */, + 160738141A3D85F200BC3261 /* Util_Render_Stereo.h */, + ); + path = Util; + sourceTree = ""; + }; + 16073A2C1A3FE73200BC3261 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 160739991A3E3FF800BC3261 /* libOVRKernel.a */, + 160735D81A3D746C00BC3261 /* Cocoa.framework */, + 160735D61A3D746400BC3261 /* AudioToolbox.framework */, + 160735D41A3D745300BC3261 /* OpenGL.framework */, + 160735D21A3D744C00BC3261 /* IOKit.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 16073A621A48133300BC3261 /* Supporting files */ = { + isa = PBXGroup; + children = ( + 16535B401A6453B500E57802 /* LibOVRRT.plist */, + 16535ACE1A606D1A00E57802 /* LibOVR.xcconfig */, + ); + name = "Supporting files"; + sourceTree = ""; + }; + 164B2D131A81A2A000A00FE1 /* Vision */ = { + isa = PBXGroup; + children = ( + 164B2D141A81A2AE00A00FE1 /* SensorFusion */, + ); + name = Vision; + sourceTree = ""; + }; + 164B2D141A81A2AE00A00FE1 /* SensorFusion */ = { + isa = PBXGroup; + children = ( + 164B2D151A81A2C500A00FE1 /* Vision_SensorStateReader.cpp */, + 164B2D161A81A2C500A00FE1 /* Vision_SensorStateReader.h */, + ); + name = SensorFusion; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 160733081A3BB73A00BC3261 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 160738CC1A3D85F200BC3261 /* OVR_Unix_Socket.h in Headers */, + 160735CE1A3BE72100BC3261 /* OVR_CAPI_GL.h in Headers */, + 1607386A1A3D85F200BC3261 /* CAPI_DistortionRenderer.h in Headers */, + 160738BE1A3D85F200BC3261 /* OVR_BitStream.h in Headers */, + 16535ACA1A5F0AB300E57802 /* OVR_CAPI_0_5_0.h in Headers */, + 160738D91A3D85F200BC3261 /* OVR_Stereo.h in Headers */, + 1607389B1A3D85F200BC3261 /* CAPI_GL_HSWDisplay.h in Headers */, + 160735CF1A3BE72100BC3261 /* OVR_CAPI_Keys.h in Headers */, + 16535AE81A60A54B00E57802 /* CAPI_DistortionTiming.h in Headers */, + 164B2D121A81A21600A00FE1 /* OVR_StereoProjection.h in Headers */, + 160738AD1A3D85F200BC3261 /* OVR_OSX_Display.h in Headers */, + 16535AEC1A60A54B00E57802 /* CAPI_FrameTimeManager3.h in Headers */, + 160738C11A3D85F200BC3261 /* OVR_NetworkPlugin.h in Headers */, + 1607389D1A3D85F200BC3261 /* CAPI_GL_Util.h in Headers */, + 160738A11A3D85F200BC3261 /* OVR_Display.h in Headers */, + 160738CA1A3D85F200BC3261 /* OVR_Socket.h in Headers */, + 160738C61A3D85F200BC3261 /* OVR_RPC1.h in Headers */, + 1607391D1A3D85F200BC3261 /* Service_NetClient.h in Headers */, + 1607389F1A3D85F200BC3261 /* healthAndSafety.tga.h in Headers */, + 160735D11A3BE72100BC3261 /* OVR_Version.h in Headers */, + 160739401A3D85F200BC3261 /* Util_LatencyTest2State.h in Headers */, + 1607386E1A3D85F200BC3261 /* CAPI_HMDRenderState.h in Headers */, + 160738991A3D85F200BC3261 /* CAPI_GL_DistortionShaders.h in Headers */, + 160738C81A3D85F200BC3261 /* OVR_Session.h in Headers */, + 160738C21A3D85F200BC3261 /* OVR_NetworkTypes.h in Headers */, + 160738BF1A3D85F200BC3261 /* OVR_MessageIDTypes.h in Headers */, + 1607393F1A3D85F200BC3261 /* Util_LatencyTest2Reader.h in Headers */, + 160739421A3D85F200BC3261 /* Util_Render_Stereo.h in Headers */, + 160738981A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.h in Headers */, + 160735CA1A3BE72100BC3261 /* OVR_Math.h in Headers */, + 160738721A3D85F200BC3261 /* CAPI_HSWDisplay.h in Headers */, + 160738C41A3D85F200BC3261 /* OVR_PacketizedTCPSocket.h in Headers */, + 160739391A3D85F200BC3261 /* Util_Interface.h in Headers */, + 160739211A3D85F200BC3261 /* Service_NetSessionCommon.h in Headers */, + 16535AEA1A60A54B00E57802 /* CAPI_FrameLatencyTracker.h in Headers */, + 160738D31A3D85F200BC3261 /* OVR_Profile.h in Headers */, + 164B2D181A81A2C500A00FE1 /* Vision_SensorStateReader.h in Headers */, + 160738701A3D85F200BC3261 /* CAPI_HMDState.h in Headers */, + 160738D71A3D85F200BC3261 /* OVR_SerialFormat.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 1607330A1A3BB73A00BC3261 /* LibOVRRT */ = { + isa = PBXNativeTarget; + buildConfigurationList = 160733211A3BB73A00BC3261 /* Build configuration list for PBXNativeTarget "LibOVRRT" */; + buildPhases = ( + 160733061A3BB73A00BC3261 /* Sources */, + 160733071A3BB73A00BC3261 /* Frameworks */, + 160733081A3BB73A00BC3261 /* Headers */, + 160733091A3BB73A00BC3261 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LibOVRRT; + productName = LibOVRRT; + productReference = 1607330B1A3BB73A00BC3261 /* LibOVRRT_0.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 160733021A3BB73A00BC3261 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = "Oculus VR"; + TargetAttributes = { + 1607330A1A3BB73A00BC3261 = { + CreatedOnToolsVersion = 6.1; + }; + }; + }; + buildConfigurationList = 160733051A3BB73A00BC3261 /* Build configuration list for PBXProject "LibOVRRT" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 160733011A3BB73A00BC3261; + productRefGroup = 1607330C1A3BB73A00BC3261 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 1607330A1A3BB73A00BC3261 /* LibOVRRT */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 160733091A3BB73A00BC3261 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 16535ACF1A606D1A00E57802 /* LibOVR.xcconfig in Resources */, + 160738E51A3D85F200BC3261 /* Oculus.icns in Resources */, + 1607389E1A3D85F200BC3261 /* healthAndSafety.tga in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 160733061A3BB73A00BC3261 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 160738BD1A3D85F200BC3261 /* OVR_BitStream.cpp in Sources */, + 16535AE91A60A54B00E57802 /* CAPI_FrameLatencyTracker.cpp in Sources */, + 160738D21A3D85F200BC3261 /* OVR_Profile.cpp in Sources */, + 160738D81A3D85F200BC3261 /* OVR_Stereo.cpp in Sources */, + 160738CB1A3D85F200BC3261 /* OVR_Unix_Socket.cpp in Sources */, + 1607393E1A3D85F200BC3261 /* Util_LatencyTest2Reader.cpp in Sources */, + 160738C91A3D85F200BC3261 /* OVR_Socket.cpp in Sources */, + 1607391C1A3D85F200BC3261 /* Service_NetClient.cpp in Sources */, + 160738C71A3D85F200BC3261 /* OVR_Session.cpp in Sources */, + 1607389C1A3D85F200BC3261 /* CAPI_GL_Util.cpp in Sources */, + 160739411A3D85F200BC3261 /* Util_Render_Stereo.cpp in Sources */, + 1607389A1A3D85F200BC3261 /* CAPI_GL_HSWDisplay.cpp in Sources */, + 160738AC1A3D85F200BC3261 /* OVR_OSX_Display.cpp in Sources */, + 160738A01A3D85F200BC3261 /* OVR_Display.cpp in Sources */, + 160738D61A3D85F200BC3261 /* OVR_SerialFormat.cpp in Sources */, + 160739381A3D85F200BC3261 /* Util_Interface.cpp in Sources */, + 160738C01A3D85F200BC3261 /* OVR_NetworkPlugin.cpp in Sources */, + 16535AEB1A60A54B00E57802 /* CAPI_FrameTimeManager3.cpp in Sources */, + 164B2D171A81A2C500A00FE1 /* Vision_SensorStateReader.cpp in Sources */, + 160738C51A3D85F200BC3261 /* OVR_RPC1.cpp in Sources */, + 1607386F1A3D85F200BC3261 /* CAPI_HMDState.cpp in Sources */, + 160738691A3D85F200BC3261 /* CAPI_DistortionRenderer.cpp in Sources */, + 164B2D101A81A21600A00FE1 /* OVR_CAPI_Util.cpp in Sources */, + 164B2D111A81A21600A00FE1 /* OVR_StereoProjection.cpp in Sources */, + 160738C31A3D85F200BC3261 /* OVR_PacketizedTCPSocket.cpp in Sources */, + 16535AE71A60A54B00E57802 /* CAPI_DistortionTiming.cpp in Sources */, + 160738CF1A3D85F200BC3261 /* OVR_CAPI.cpp in Sources */, + 160738711A3D85F200BC3261 /* CAPI_HSWDisplay.cpp in Sources */, + 160738971A3D85F200BC3261 /* CAPI_GL_DistortionRenderer.cpp in Sources */, + 160739201A3D85F200BC3261 /* Service_NetSessionCommon.cpp in Sources */, + 1607386D1A3D85F200BC3261 /* CAPI_HMDRenderState.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1607331F1A3BB73A00BC3261 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 16535ACE1A606D1A00E57802 /* LibOVR.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = "${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ""; + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)_${OVR_PRODUCT_VERSION}"; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 160733201A3BB73A00BC3261 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 16535ACE1A606D1A00E57802 /* LibOVR.xcconfig */; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + CURRENT_PROJECT_VERSION = "${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = ""; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)_${OVR_PRODUCT_VERSION}"; + SDKROOT = macosx; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 160733221A3BB73A00BC3261 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + COMBINE_HIDPI_IMAGES = YES; + CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + CURRENT_PROJECT_VERSION = "${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = "${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}"; + DYLIB_CURRENT_VERSION = "${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}"; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = "${OVR_MAJOR_VERSION}"; + GCC_PREPROCESSOR_DEFINITIONS = ( + OVR_DLL_BUILD, + "DEBUG=1", + OVR_BUILD_DEBUG, + ); + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(SRCROOT)/../../Include", + "$(SRCROOT)/../../Src", + "$(SRCROOT)/../../../LibOVRKernel/Src", + "$(SRCROOT)/../../../LibOVRKernel/Src/Kernel", + "$(SRCROOT)/../../../../3rdParty/TinyXml", + ); + INFOPLIST_FILE = "$(SRCROOT)/LibOVRRT.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_DEPENDENCY_INFO_FILE = "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/$(PRODUCT_NAME)_dependency_info.dat"; + LD_MAP_FILE_PATH = "$(TARGET_TEMP_DIR)/LinkMap.txt"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../../LibOVRKernel/Lib/Mac/$CONFIGURATION", + ); + MACOSX_DEPLOYMENT_TARGET = 10.8; + OBJROOT = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + OTHER_LDFLAGS = "-lOVRKernel"; + PRODUCT_NAME = "$(TARGET_NAME)_${OVR_PRODUCT_VERSION}"; + RUN_CLANG_STATIC_ANALYZER = YES; + SKIP_INSTALL = YES; + SYMROOT = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Debug; + }; + 160733231A3BB73A00BC3261 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = YES; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + COMBINE_HIDPI_IMAGES = YES; + CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + CURRENT_PROJECT_VERSION = "${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = "${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}"; + DYLIB_CURRENT_VERSION = "${OVR_MAJOR_VERSION}.${OVR_MINOR_VERSION}.${OVR_PATCH_VERSION}"; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = "${OVR_MAJOR_VERSION}"; + GCC_PREPROCESSOR_DEFINITIONS = OVR_DLL_BUILD; + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(SRCROOT)/../../Include", + "$(SRCROOT)/../../Src", + "$(SRCROOT)/../../../LibOVRKernel/Src", + "$(SRCROOT)/../../../LibOVRKernel/Src/Kernel", + "$(SRCROOT)/../../../../3rdParty/TinyXml", + ); + INFOPLIST_FILE = "$(SRCROOT)/LibOVRRT.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_DEPENDENCY_INFO_FILE = "$(OBJECT_FILE_DIR_$(CURRENT_VARIANT))/$(CURRENT_ARCH)/$(PRODUCT_NAME)_dependency_info.dat"; + LD_MAP_FILE_PATH = "$(TARGET_TEMP_DIR)/LinkMap.txt"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(SRCROOT)/../../../LibOVRKernel/Lib/Mac/$CONFIGURATION", + ); + MACOSX_DEPLOYMENT_TARGET = 10.8; + OBJROOT = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + OTHER_LDFLAGS = "-lOVRKernel"; + PRODUCT_NAME = "$(TARGET_NAME)_${OVR_PRODUCT_VERSION}"; + RUN_CLANG_STATIC_ANALYZER = YES; + SKIP_INSTALL = YES; + SYMROOT = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + USER_HEADER_SEARCH_PATHS = ""; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 160733051A3BB73A00BC3261 /* Build configuration list for PBXProject "LibOVRRT" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1607331F1A3BB73A00BC3261 /* Debug */, + 160733201A3BB73A00BC3261 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 160733211A3BB73A00BC3261 /* Build configuration list for PBXNativeTarget "LibOVRRT" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 160733221A3BB73A00BC3261 /* Debug */, + 160733231A3BB73A00BC3261 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 160733021A3BB73A00BC3261 /* Project object */; +} diff --git a/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..c266aca --- /dev/null +++ b/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/xcshareddata/xcschemes/LibOVRRT.xcscheme b/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/xcshareddata/xcschemes/LibOVRRT.xcscheme new file mode 100644 index 0000000..5e07d8f --- /dev/null +++ b/LibOVR/Projects/Mac/LibOVRRT.xcodeproj/xcshareddata/xcschemes/LibOVRRT.xcscheme @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/LibOVR/Projects/Mac/LibOVRRT.xcworkspace/contents.xcworkspacedata b/LibOVR/Projects/Mac/LibOVRRT.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..74a4b29 --- /dev/null +++ b/LibOVR/Projects/Mac/LibOVRRT.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.pbxproj b/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.pbxproj deleted file mode 100644 index 7a406be..0000000 --- a/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.pbxproj +++ /dev/null @@ -1,839 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 46; - objects = { - -/* Begin PBXBuildFile section */ - 4683CEBE1970867300285E02 /* CAPI_GL_HSWDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4683CEBC1970867300285E02 /* CAPI_GL_HSWDisplay.cpp */; }; - 4683CEBF1970867300285E02 /* CAPI_GL_HSWDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = 4683CEBD1970867300285E02 /* CAPI_GL_HSWDisplay.h */; }; - 8864E8FD19D5289700ACEEC1 /* OVR_CAPI_Keys.h in Headers */ = {isa = PBXBuildFile; fileRef = 8864E8FC19D5289700ACEEC1 /* OVR_CAPI_Keys.h */; }; - 886FFB1E19E4898300775723 /* Util_SystemInfo_OSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 886FFB1D19E4898300775723 /* Util_SystemInfo_OSX.mm */; }; - A42F68671A11F2000027C6E1 /* Util_SystemGUI_OSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = A42F68641A11F2000027C6E1 /* Util_SystemGUI_OSX.mm */; }; - A42F68681A11F2000027C6E1 /* Util_SystemGUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A42F68651A11F2000027C6E1 /* Util_SystemGUI.cpp */; }; - A42F68691A11F2000027C6E1 /* Util_SystemGUI.h in Headers */ = {isa = PBXBuildFile; fileRef = A42F68661A11F2000027C6E1 /* Util_SystemGUI.h */; }; - A42F68751A11F2B80027C6E1 /* OVR_Compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = A42F686E1A11F2B80027C6E1 /* OVR_Compiler.h */; }; - A42F68761A11F2B80027C6E1 /* OVR_DebugHelp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A42F686F1A11F2B80027C6E1 /* OVR_DebugHelp.cpp */; }; - A42F68771A11F2B80027C6E1 /* OVR_DebugHelp.h in Headers */ = {isa = PBXBuildFile; fileRef = A42F68701A11F2B80027C6E1 /* OVR_DebugHelp.h */; }; - A42F68781A11F2B80027C6E1 /* OVR_mach_exc_OSX.c in Sources */ = {isa = PBXBuildFile; fileRef = A42F68711A11F2B80027C6E1 /* OVR_mach_exc_OSX.c */; }; - A42F68791A11F2B80027C6E1 /* OVR_mach_exc_OSX.h in Headers */ = {isa = PBXBuildFile; fileRef = A42F68721A11F2B80027C6E1 /* OVR_mach_exc_OSX.h */; }; - A42F687A1A11F2B80027C6E1 /* OVR_Nullptr.h in Headers */ = {isa = PBXBuildFile; fileRef = A42F68731A11F2B80027C6E1 /* OVR_Nullptr.h */; }; - A42F687B1A11F2B80027C6E1 /* OVR_Observer.h in Headers */ = {isa = PBXBuildFile; fileRef = A42F68741A11F2B80027C6E1 /* OVR_Observer.h */; }; - A42F687F1A11F2F10027C6E1 /* CAPI_GLE_GL.h in Headers */ = {isa = PBXBuildFile; fileRef = A42F687C1A11F2F10027C6E1 /* CAPI_GLE_GL.h */; }; - A42F68801A11F2F10027C6E1 /* CAPI_GLE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A42F687D1A11F2F10027C6E1 /* CAPI_GLE.cpp */; }; - A42F68811A11F2F10027C6E1 /* CAPI_GLE.h in Headers */ = {isa = PBXBuildFile; fileRef = A42F687E1A11F2F10027C6E1 /* CAPI_GLE.h */; }; - A4A859B619D6310100ED2071 /* CAPI_LatencyStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4A859B419D6310100ED2071 /* CAPI_LatencyStatistics.cpp */; }; - A4A859B719D6310100ED2071 /* CAPI_LatencyStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = A4A859B519D6310100ED2071 /* CAPI_LatencyStatistics.h */; }; - A4A859BA19D6311500ED2071 /* Util_SystemInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A4A859B819D6311500ED2071 /* Util_SystemInfo.cpp */; }; - A4A859BB19D6311500ED2071 /* Util_SystemInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = A4A859B919D6311500ED2071 /* Util_SystemInfo.h */; }; - E8094D0F196FAE8800937940 /* CAPI_HSWDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8094D0D196FAE8800937940 /* CAPI_HSWDisplay.cpp */; }; - E8094D10196FAE8800937940 /* CAPI_HSWDisplay.h in Headers */ = {isa = PBXBuildFile; fileRef = E8094D0E196FAE8800937940 /* CAPI_HSWDisplay.h */; }; - E85F262C1954204900AA807B /* OVR_SerialFormat.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E85F262A1954204900AA807B /* OVR_SerialFormat.cpp */; }; - E85F262D1954204900AA807B /* OVR_SerialFormat.h in Headers */ = {isa = PBXBuildFile; fileRef = E85F262B1954204900AA807B /* OVR_SerialFormat.h */; }; - E8788D1D196CF68000128BE5 /* Tracking_PoseState.h in Headers */ = {isa = PBXBuildFile; fileRef = E8788D1B196CF68000128BE5 /* Tracking_PoseState.h */; }; - E8788D1E196CF68000128BE5 /* Tracking_SensorState.h in Headers */ = {isa = PBXBuildFile; fileRef = E8788D1C196CF68000128BE5 /* Tracking_SensorState.h */; }; - E8788D22196CF98000128BE5 /* Util_LatencyTest2Reader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8788D1F196CF98000128BE5 /* Util_LatencyTest2Reader.cpp */; }; - E8788D23196CF98000128BE5 /* Util_LatencyTest2Reader.h in Headers */ = {isa = PBXBuildFile; fileRef = E8788D20196CF98000128BE5 /* Util_LatencyTest2Reader.h */; }; - E8788D24196CF98000128BE5 /* Util_LatencyTest2State.h in Headers */ = {isa = PBXBuildFile; fileRef = E8788D21196CF98000128BE5 /* Util_LatencyTest2State.h */; }; - E87DF46E196A1BEF005E383C /* OVR_CRC32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF46A196A1BEF005E383C /* OVR_CRC32.cpp */; }; - E87DF46F196A1BEF005E383C /* OVR_CRC32.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF46B196A1BEF005E383C /* OVR_CRC32.h */; }; - E87DF470196A1BEF005E383C /* OVR_SharedMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF46C196A1BEF005E383C /* OVR_SharedMemory.cpp */; }; - E87DF471196A1BEF005E383C /* OVR_SharedMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF46D196A1BEF005E383C /* OVR_SharedMemory.h */; }; - E87DF47A196A1CEF005E383C /* OVR_Display.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF474196A1CEF005E383C /* OVR_Display.h */; }; - E87DF47D196A1CEF005E383C /* OVR_OSX_Display.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF477196A1CEF005E383C /* OVR_OSX_Display.cpp */; }; - E87DF47E196A1CEF005E383C /* OVR_OSX_Display.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF478196A1CEF005E383C /* OVR_OSX_Display.h */; }; - E87DF490196A20E9005E383C /* OVR_BitStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF480196A20E9005E383C /* OVR_BitStream.cpp */; }; - E87DF491196A20E9005E383C /* OVR_BitStream.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF481196A20E9005E383C /* OVR_BitStream.h */; }; - E87DF492196A20E9005E383C /* OVR_MessageIDTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF482196A20E9005E383C /* OVR_MessageIDTypes.h */; }; - E87DF493196A20E9005E383C /* OVR_NetworkPlugin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF483196A20E9005E383C /* OVR_NetworkPlugin.cpp */; }; - E87DF494196A20E9005E383C /* OVR_NetworkPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF484196A20E9005E383C /* OVR_NetworkPlugin.h */; }; - E87DF495196A20E9005E383C /* OVR_NetworkTypes.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF485196A20E9005E383C /* OVR_NetworkTypes.h */; }; - E87DF496196A20E9005E383C /* OVR_PacketizedTCPSocket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF486196A20E9005E383C /* OVR_PacketizedTCPSocket.cpp */; }; - E87DF497196A20E9005E383C /* OVR_PacketizedTCPSocket.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF487196A20E9005E383C /* OVR_PacketizedTCPSocket.h */; }; - E87DF498196A20E9005E383C /* OVR_RPC1.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF488196A20E9005E383C /* OVR_RPC1.cpp */; }; - E87DF499196A20E9005E383C /* OVR_RPC1.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF489196A20E9005E383C /* OVR_RPC1.h */; }; - E87DF49A196A20E9005E383C /* OVR_Session.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF48A196A20E9005E383C /* OVR_Session.cpp */; }; - E87DF49B196A20E9005E383C /* OVR_Session.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF48B196A20E9005E383C /* OVR_Session.h */; }; - E87DF49C196A20E9005E383C /* OVR_Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF48C196A20E9005E383C /* OVR_Socket.cpp */; }; - E87DF49D196A20E9005E383C /* OVR_Socket.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF48D196A20E9005E383C /* OVR_Socket.h */; }; - E87DF49E196A20E9005E383C /* OVR_Unix_Socket.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF48E196A20E9005E383C /* OVR_Unix_Socket.cpp */; }; - E87DF49F196A20E9005E383C /* OVR_Unix_Socket.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF48F196A20E9005E383C /* OVR_Unix_Socket.h */; }; - E87DF4AB196A2161005E383C /* Service_NetClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF4A3196A2161005E383C /* Service_NetClient.cpp */; }; - E87DF4AC196A2161005E383C /* Service_NetClient.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF4A4196A2161005E383C /* Service_NetClient.h */; }; - E87DF4AF196A2161005E383C /* Service_NetSessionCommon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF4A7196A2161005E383C /* Service_NetSessionCommon.cpp */; }; - E87DF4B0196A2161005E383C /* Service_NetSessionCommon.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF4A8196A2161005E383C /* Service_NetSessionCommon.h */; }; - E87DF4D2196A232F005E383C /* OVR_DeviceConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF4B3196A232F005E383C /* OVR_DeviceConstants.h */; }; - E87DF4F3196A23B4005E383C /* Tracking_SensorStateReader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E87DF4F1196A23B4005E383C /* Tracking_SensorStateReader.cpp */; }; - E87DF4F4196A23B4005E383C /* Tracking_SensorStateReader.h in Headers */ = {isa = PBXBuildFile; fileRef = E87DF4F2196A23B4005E383C /* Tracking_SensorStateReader.h */; }; - E886FE9E190737FA00D5DB45 /* OVR_CAPI_GL.h in Headers */ = {isa = PBXBuildFile; fileRef = E886FE9B190737FA00D5DB45 /* OVR_CAPI_GL.h */; }; - E886FE9F190737FA00D5DB45 /* OVR_CAPI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E886FE9C190737FA00D5DB45 /* OVR_CAPI.cpp */; }; - E886FEA0190737FA00D5DB45 /* OVR_CAPI.h in Headers */ = {isa = PBXBuildFile; fileRef = E886FE9D190737FA00D5DB45 /* OVR_CAPI.h */; }; - E886FEA21907528C00D5DB45 /* CAPI_DistortionRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E886FEA11907528C00D5DB45 /* CAPI_DistortionRenderer.cpp */; }; - E8AA40D11907221900D5F144 /* OVR_Alg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40A61907221900D5F144 /* OVR_Alg.cpp */; }; - E8AA40D21907221900D5F144 /* OVR_Alg.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40A71907221900D5F144 /* OVR_Alg.h */; }; - E8AA40D31907221900D5F144 /* OVR_Allocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40A81907221900D5F144 /* OVR_Allocator.cpp */; }; - E8AA40D41907221900D5F144 /* OVR_Allocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40A91907221900D5F144 /* OVR_Allocator.h */; }; - E8AA40D51907221900D5F144 /* OVR_Array.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40AA1907221900D5F144 /* OVR_Array.h */; }; - E8AA40D61907221900D5F144 /* OVR_Atomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40AB1907221900D5F144 /* OVR_Atomic.cpp */; }; - E8AA40D71907221900D5F144 /* OVR_Atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40AC1907221900D5F144 /* OVR_Atomic.h */; }; - E8AA40D81907221900D5F144 /* OVR_Color.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40AD1907221900D5F144 /* OVR_Color.h */; }; - E8AA40D91907221900D5F144 /* OVR_ContainerAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40AE1907221900D5F144 /* OVR_ContainerAllocator.h */; }; - E8AA40DA1907221900D5F144 /* OVR_Deque.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40AF1907221900D5F144 /* OVR_Deque.h */; }; - E8AA40DB1907221900D5F144 /* OVR_File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40B01907221900D5F144 /* OVR_File.cpp */; }; - E8AA40DC1907221900D5F144 /* OVR_File.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40B11907221900D5F144 /* OVR_File.h */; }; - E8AA40DD1907221900D5F144 /* OVR_FileFILE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40B21907221900D5F144 /* OVR_FileFILE.cpp */; }; - E8AA40DE1907221900D5F144 /* OVR_Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40B31907221900D5F144 /* OVR_Hash.h */; }; - E8AA40DF1907221900D5F144 /* OVR_KeyCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40B41907221900D5F144 /* OVR_KeyCodes.h */; }; - E8AA40E01907221900D5F144 /* OVR_List.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40B51907221900D5F144 /* OVR_List.h */; }; - E8AA40E11907221900D5F144 /* OVR_Lockless.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40B61907221900D5F144 /* OVR_Lockless.cpp */; }; - E8AA40E21907221900D5F144 /* OVR_Lockless.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40B71907221900D5F144 /* OVR_Lockless.h */; }; - E8AA40E31907221900D5F144 /* OVR_Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40B81907221900D5F144 /* OVR_Log.cpp */; }; - E8AA40E41907221900D5F144 /* OVR_Log.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40B91907221900D5F144 /* OVR_Log.h */; }; - E8AA40E51907221900D5F144 /* OVR_Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40BA1907221900D5F144 /* OVR_Math.cpp */; }; - E8AA40E61907221900D5F144 /* OVR_Math.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40BB1907221900D5F144 /* OVR_Math.h */; }; - E8AA40E71907221900D5F144 /* OVR_RefCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40BC1907221900D5F144 /* OVR_RefCount.cpp */; }; - E8AA40E81907221900D5F144 /* OVR_RefCount.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40BD1907221900D5F144 /* OVR_RefCount.h */; }; - E8AA40E91907221900D5F144 /* OVR_Std.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40BE1907221900D5F144 /* OVR_Std.cpp */; }; - E8AA40EA1907221900D5F144 /* OVR_Std.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40BF1907221900D5F144 /* OVR_Std.h */; }; - E8AA40EB1907221900D5F144 /* OVR_String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40C01907221900D5F144 /* OVR_String.cpp */; }; - E8AA40EC1907221900D5F144 /* OVR_String.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40C11907221900D5F144 /* OVR_String.h */; }; - E8AA40ED1907221900D5F144 /* OVR_String_FormatUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40C21907221900D5F144 /* OVR_String_FormatUtil.cpp */; }; - E8AA40EE1907221900D5F144 /* OVR_String_PathUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40C31907221900D5F144 /* OVR_String_PathUtil.cpp */; }; - E8AA40EF1907221900D5F144 /* OVR_StringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40C41907221900D5F144 /* OVR_StringHash.h */; }; - E8AA40F01907221900D5F144 /* OVR_SysFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40C51907221900D5F144 /* OVR_SysFile.cpp */; }; - E8AA40F11907221900D5F144 /* OVR_SysFile.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40C61907221900D5F144 /* OVR_SysFile.h */; }; - E8AA40F21907221900D5F144 /* OVR_System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40C71907221900D5F144 /* OVR_System.cpp */; }; - E8AA40F31907221900D5F144 /* OVR_System.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40C81907221900D5F144 /* OVR_System.h */; }; - E8AA40F41907221900D5F144 /* OVR_Threads.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40C91907221900D5F144 /* OVR_Threads.h */; }; - E8AA40F51907221900D5F144 /* OVR_ThreadsPthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40CA1907221900D5F144 /* OVR_ThreadsPthread.cpp */; }; - E8AA40F71907221900D5F144 /* OVR_Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40CC1907221900D5F144 /* OVR_Timer.cpp */; }; - E8AA40F81907221900D5F144 /* OVR_Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40CD1907221900D5F144 /* OVR_Timer.h */; }; - E8AA40F91907221900D5F144 /* OVR_Types.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40CE1907221900D5F144 /* OVR_Types.h */; }; - E8AA40FA1907221900D5F144 /* OVR_UTF8Util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA40CF1907221900D5F144 /* OVR_UTF8Util.cpp */; }; - E8AA40FB1907221900D5F144 /* OVR_UTF8Util.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA40D01907221900D5F144 /* OVR_UTF8Util.h */; }; - E8AA410D1907224700D5F144 /* Util_Interface.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41011907224700D5F144 /* Util_Interface.cpp */; }; - E8AA410E1907224700D5F144 /* Util_Interface.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41021907224700D5F144 /* Util_Interface.h */; }; - E8AA41131907224700D5F144 /* Util_Render_Stereo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41071907224700D5F144 /* Util_Render_Stereo.cpp */; }; - E8AA41141907224700D5F144 /* Util_Render_Stereo.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41081907224700D5F144 /* Util_Render_Stereo.h */; }; - E8AA4173190722BB00D5F144 /* OVR_JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA412B190722BB00D5F144 /* OVR_JSON.cpp */; }; - E8AA4174190722BB00D5F144 /* OVR_JSON.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA412C190722BB00D5F144 /* OVR_JSON.h */; }; - E8AA4185190722BB00D5F144 /* OVR_Profile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA413D190722BB00D5F144 /* OVR_Profile.cpp */; }; - E8AA4186190722BB00D5F144 /* OVR_Profile.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA413E190722BB00D5F144 /* OVR_Profile.h */; }; - E8AA4197190722BB00D5F144 /* OVR_Stereo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA414F190722BB00D5F144 /* OVR_Stereo.cpp */; }; - E8AA4198190722BB00D5F144 /* OVR_Stereo.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA4150190722BB00D5F144 /* OVR_Stereo.h */; }; - E8AA41E2190724E600D5F144 /* CAPI_DistortionRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41BA190724E600D5F144 /* CAPI_DistortionRenderer.h */; }; - E8AA41E3190724E600D5F144 /* CAPI_FrameTimeManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41BB190724E600D5F144 /* CAPI_FrameTimeManager.cpp */; }; - E8AA41E4190724E600D5F144 /* CAPI_FrameTimeManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41BC190724E600D5F144 /* CAPI_FrameTimeManager.h */; }; - E8AA41E7190724E600D5F144 /* CAPI_HMDRenderState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41BF190724E600D5F144 /* CAPI_HMDRenderState.cpp */; }; - E8AA41E8190724E600D5F144 /* CAPI_HMDRenderState.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41C0190724E600D5F144 /* CAPI_HMDRenderState.h */; }; - E8AA41E9190724E600D5F144 /* CAPI_HMDState.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41C1190724E600D5F144 /* CAPI_HMDState.cpp */; }; - E8AA41EA190724E600D5F144 /* CAPI_HMDState.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41C2190724E600D5F144 /* CAPI_HMDState.h */; }; - E8AA41F6190724E600D5F144 /* CAPI_GL_DistortionRenderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41D0190724E600D5F144 /* CAPI_GL_DistortionRenderer.cpp */; }; - E8AA41F7190724E600D5F144 /* CAPI_GL_DistortionRenderer.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41D1190724E600D5F144 /* CAPI_GL_DistortionRenderer.h */; }; - E8AA41F8190724E600D5F144 /* CAPI_GL_Util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8AA41D2190724E600D5F144 /* CAPI_GL_Util.cpp */; }; - E8AA41F9190724E600D5F144 /* CAPI_GL_Util.h in Headers */ = {isa = PBXBuildFile; fileRef = E8AA41D3190724E600D5F144 /* CAPI_GL_Util.h */; }; - E8B18323196D376800555C29 /* OVR_ThreadCommandQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E8B18321196D376800555C29 /* OVR_ThreadCommandQueue.cpp */; }; - E8B18324196D376800555C29 /* OVR_ThreadCommandQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = E8B18322196D376800555C29 /* OVR_ThreadCommandQueue.h */; }; -/* End PBXBuildFile section */ - -/* Begin PBXFileReference section */ - 4683CEBC1970867300285E02 /* CAPI_GL_HSWDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAPI_GL_HSWDisplay.cpp; path = GL/CAPI_GL_HSWDisplay.cpp; sourceTree = ""; }; - 4683CEBD1970867300285E02 /* CAPI_GL_HSWDisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAPI_GL_HSWDisplay.h; path = GL/CAPI_GL_HSWDisplay.h; sourceTree = ""; }; - 8864E8FC19D5289700ACEEC1 /* OVR_CAPI_Keys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_CAPI_Keys.h; path = ../../../Src/OVR_CAPI_Keys.h; sourceTree = ""; }; - 886FFB1D19E4898300775723 /* Util_SystemInfo_OSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Util_SystemInfo_OSX.mm; sourceTree = ""; }; - A42F68641A11F2000027C6E1 /* Util_SystemGUI_OSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = Util_SystemGUI_OSX.mm; sourceTree = ""; }; - A42F68651A11F2000027C6E1 /* Util_SystemGUI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_SystemGUI.cpp; sourceTree = ""; }; - A42F68661A11F2000027C6E1 /* Util_SystemGUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_SystemGUI.h; sourceTree = ""; }; - A42F686E1A11F2B80027C6E1 /* OVR_Compiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Compiler.h; sourceTree = ""; }; - A42F686F1A11F2B80027C6E1 /* OVR_DebugHelp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_DebugHelp.cpp; sourceTree = ""; }; - A42F68701A11F2B80027C6E1 /* OVR_DebugHelp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_DebugHelp.h; sourceTree = ""; }; - A42F68711A11F2B80027C6E1 /* OVR_mach_exc_OSX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = OVR_mach_exc_OSX.c; sourceTree = ""; }; - A42F68721A11F2B80027C6E1 /* OVR_mach_exc_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_mach_exc_OSX.h; sourceTree = ""; }; - A42F68731A11F2B80027C6E1 /* OVR_Nullptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Nullptr.h; sourceTree = ""; }; - A42F68741A11F2B80027C6E1 /* OVR_Observer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Observer.h; sourceTree = ""; }; - A42F687C1A11F2F10027C6E1 /* CAPI_GLE_GL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAPI_GLE_GL.h; path = GL/CAPI_GLE_GL.h; sourceTree = ""; }; - A42F687D1A11F2F10027C6E1 /* CAPI_GLE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAPI_GLE.cpp; path = GL/CAPI_GLE.cpp; sourceTree = ""; }; - A42F687E1A11F2F10027C6E1 /* CAPI_GLE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAPI_GLE.h; path = GL/CAPI_GLE.h; sourceTree = ""; }; - A4A859B419D6310100ED2071 /* CAPI_LatencyStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_LatencyStatistics.cpp; sourceTree = ""; }; - A4A859B519D6310100ED2071 /* CAPI_LatencyStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_LatencyStatistics.h; sourceTree = ""; }; - A4A859B819D6311500ED2071 /* Util_SystemInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_SystemInfo.cpp; sourceTree = ""; }; - A4A859B919D6311500ED2071 /* Util_SystemInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_SystemInfo.h; sourceTree = ""; }; - E8094D0D196FAE8800937940 /* CAPI_HSWDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_HSWDisplay.cpp; sourceTree = ""; }; - E8094D0E196FAE8800937940 /* CAPI_HSWDisplay.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_HSWDisplay.h; sourceTree = ""; }; - E82D4CD31906FE640070CB3F /* libovr.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libovr.a; sourceTree = BUILT_PRODUCTS_DIR; }; - E85F262A1954204900AA807B /* OVR_SerialFormat.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SerialFormat.cpp; path = ../../../Src/OVR_SerialFormat.cpp; sourceTree = ""; }; - E85F262B1954204900AA807B /* OVR_SerialFormat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SerialFormat.h; path = ../../../Src/OVR_SerialFormat.h; sourceTree = ""; }; - E8788D1B196CF68000128BE5 /* Tracking_PoseState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Tracking_PoseState.h; path = ../../../Src/Tracking/Tracking_PoseState.h; sourceTree = ""; }; - E8788D1C196CF68000128BE5 /* Tracking_SensorState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Tracking_SensorState.h; path = ../../../Src/Tracking/Tracking_SensorState.h; sourceTree = ""; }; - E8788D1F196CF98000128BE5 /* Util_LatencyTest2Reader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_LatencyTest2Reader.cpp; sourceTree = ""; }; - E8788D20196CF98000128BE5 /* Util_LatencyTest2Reader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_LatencyTest2Reader.h; sourceTree = ""; }; - E8788D21196CF98000128BE5 /* Util_LatencyTest2State.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_LatencyTest2State.h; sourceTree = ""; }; - E87DF46A196A1BEF005E383C /* OVR_CRC32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_CRC32.cpp; sourceTree = ""; }; - E87DF46B196A1BEF005E383C /* OVR_CRC32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_CRC32.h; sourceTree = ""; }; - E87DF46C196A1BEF005E383C /* OVR_SharedMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_SharedMemory.cpp; sourceTree = ""; }; - E87DF46D196A1BEF005E383C /* OVR_SharedMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_SharedMemory.h; sourceTree = ""; }; - E87DF474196A1CEF005E383C /* OVR_Display.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Display.h; path = ../../../Src/Displays/OVR_Display.h; sourceTree = ""; }; - E87DF477196A1CEF005E383C /* OVR_OSX_Display.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_OSX_Display.cpp; path = ../../../Src/Displays/OVR_OSX_Display.cpp; sourceTree = ""; }; - E87DF478196A1CEF005E383C /* OVR_OSX_Display.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_OSX_Display.h; path = ../../../Src/Displays/OVR_OSX_Display.h; sourceTree = ""; }; - E87DF480196A20E9005E383C /* OVR_BitStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_BitStream.cpp; path = ../../../Src/Net/OVR_BitStream.cpp; sourceTree = ""; }; - E87DF481196A20E9005E383C /* OVR_BitStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_BitStream.h; path = ../../../Src/Net/OVR_BitStream.h; sourceTree = ""; }; - E87DF482196A20E9005E383C /* OVR_MessageIDTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_MessageIDTypes.h; path = ../../../Src/Net/OVR_MessageIDTypes.h; sourceTree = ""; }; - E87DF483196A20E9005E383C /* OVR_NetworkPlugin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_NetworkPlugin.cpp; path = ../../../Src/Net/OVR_NetworkPlugin.cpp; sourceTree = ""; }; - E87DF484196A20E9005E383C /* OVR_NetworkPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_NetworkPlugin.h; path = ../../../Src/Net/OVR_NetworkPlugin.h; sourceTree = ""; }; - E87DF485196A20E9005E383C /* OVR_NetworkTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_NetworkTypes.h; path = ../../../Src/Net/OVR_NetworkTypes.h; sourceTree = ""; }; - E87DF486196A20E9005E383C /* OVR_PacketizedTCPSocket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_PacketizedTCPSocket.cpp; path = ../../../Src/Net/OVR_PacketizedTCPSocket.cpp; sourceTree = ""; }; - E87DF487196A20E9005E383C /* OVR_PacketizedTCPSocket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_PacketizedTCPSocket.h; path = ../../../Src/Net/OVR_PacketizedTCPSocket.h; sourceTree = ""; }; - E87DF488196A20E9005E383C /* OVR_RPC1.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_RPC1.cpp; path = ../../../Src/Net/OVR_RPC1.cpp; sourceTree = ""; }; - E87DF489196A20E9005E383C /* OVR_RPC1.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_RPC1.h; path = ../../../Src/Net/OVR_RPC1.h; sourceTree = ""; }; - E87DF48A196A20E9005E383C /* OVR_Session.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Session.cpp; path = ../../../Src/Net/OVR_Session.cpp; sourceTree = ""; }; - E87DF48B196A20E9005E383C /* OVR_Session.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Session.h; path = ../../../Src/Net/OVR_Session.h; sourceTree = ""; }; - E87DF48C196A20E9005E383C /* OVR_Socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Socket.cpp; path = ../../../Src/Net/OVR_Socket.cpp; sourceTree = ""; }; - E87DF48D196A20E9005E383C /* OVR_Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Socket.h; path = ../../../Src/Net/OVR_Socket.h; sourceTree = ""; }; - E87DF48E196A20E9005E383C /* OVR_Unix_Socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Unix_Socket.cpp; path = ../../../Src/Net/OVR_Unix_Socket.cpp; sourceTree = ""; }; - E87DF48F196A20E9005E383C /* OVR_Unix_Socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Unix_Socket.h; path = ../../../Src/Net/OVR_Unix_Socket.h; sourceTree = ""; }; - E87DF4A3196A2161005E383C /* Service_NetClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Service_NetClient.cpp; path = ../../../Src/Service/Service_NetClient.cpp; sourceTree = ""; }; - E87DF4A4196A2161005E383C /* Service_NetClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Service_NetClient.h; path = ../../../Src/Service/Service_NetClient.h; sourceTree = ""; }; - E87DF4A7196A2161005E383C /* Service_NetSessionCommon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Service_NetSessionCommon.cpp; path = ../../../Src/Service/Service_NetSessionCommon.cpp; sourceTree = ""; }; - E87DF4A8196A2161005E383C /* Service_NetSessionCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Service_NetSessionCommon.h; path = ../../../Src/Service/Service_NetSessionCommon.h; sourceTree = ""; }; - E87DF4B3196A232F005E383C /* OVR_DeviceConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_DeviceConstants.h; path = ../../../Src/Sensors/OVR_DeviceConstants.h; sourceTree = ""; }; - E87DF4F1196A23B4005E383C /* Tracking_SensorStateReader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Tracking_SensorStateReader.cpp; path = ../../../Src/Tracking/Tracking_SensorStateReader.cpp; sourceTree = ""; }; - E87DF4F2196A23B4005E383C /* Tracking_SensorStateReader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Tracking_SensorStateReader.h; path = ../../../Src/Tracking/Tracking_SensorStateReader.h; sourceTree = ""; }; - E886FE9B190737FA00D5DB45 /* OVR_CAPI_GL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_CAPI_GL.h; path = ../../../Src/OVR_CAPI_GL.h; sourceTree = ""; }; - E886FE9C190737FA00D5DB45 /* OVR_CAPI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_CAPI.cpp; path = ../../../Src/OVR_CAPI.cpp; sourceTree = ""; }; - E886FE9D190737FA00D5DB45 /* OVR_CAPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_CAPI.h; path = ../../../Src/OVR_CAPI.h; sourceTree = ""; }; - E886FEA11907528C00D5DB45 /* CAPI_DistortionRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_DistortionRenderer.cpp; sourceTree = ""; }; - E8AA40A61907221900D5F144 /* OVR_Alg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Alg.cpp; sourceTree = ""; }; - E8AA40A71907221900D5F144 /* OVR_Alg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Alg.h; sourceTree = ""; }; - E8AA40A81907221900D5F144 /* OVR_Allocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Allocator.cpp; sourceTree = ""; }; - E8AA40A91907221900D5F144 /* OVR_Allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Allocator.h; sourceTree = ""; }; - E8AA40AA1907221900D5F144 /* OVR_Array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Array.h; sourceTree = ""; }; - E8AA40AB1907221900D5F144 /* OVR_Atomic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Atomic.cpp; sourceTree = ""; }; - E8AA40AC1907221900D5F144 /* OVR_Atomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Atomic.h; sourceTree = ""; }; - E8AA40AD1907221900D5F144 /* OVR_Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Color.h; sourceTree = ""; }; - E8AA40AE1907221900D5F144 /* OVR_ContainerAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_ContainerAllocator.h; sourceTree = ""; }; - E8AA40AF1907221900D5F144 /* OVR_Deque.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Deque.h; sourceTree = ""; }; - E8AA40B01907221900D5F144 /* OVR_File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_File.cpp; sourceTree = ""; }; - E8AA40B11907221900D5F144 /* OVR_File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_File.h; sourceTree = ""; }; - E8AA40B21907221900D5F144 /* OVR_FileFILE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_FileFILE.cpp; sourceTree = ""; }; - E8AA40B31907221900D5F144 /* OVR_Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Hash.h; sourceTree = ""; }; - E8AA40B41907221900D5F144 /* OVR_KeyCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_KeyCodes.h; sourceTree = ""; }; - E8AA40B51907221900D5F144 /* OVR_List.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_List.h; sourceTree = ""; }; - E8AA40B61907221900D5F144 /* OVR_Lockless.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Lockless.cpp; sourceTree = ""; }; - E8AA40B71907221900D5F144 /* OVR_Lockless.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Lockless.h; sourceTree = ""; }; - E8AA40B81907221900D5F144 /* OVR_Log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Log.cpp; sourceTree = ""; }; - E8AA40B91907221900D5F144 /* OVR_Log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Log.h; sourceTree = ""; }; - E8AA40BA1907221900D5F144 /* OVR_Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Math.cpp; sourceTree = ""; }; - E8AA40BB1907221900D5F144 /* OVR_Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Math.h; sourceTree = ""; }; - E8AA40BC1907221900D5F144 /* OVR_RefCount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_RefCount.cpp; sourceTree = ""; }; - E8AA40BD1907221900D5F144 /* OVR_RefCount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_RefCount.h; sourceTree = ""; }; - E8AA40BE1907221900D5F144 /* OVR_Std.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Std.cpp; sourceTree = ""; }; - E8AA40BF1907221900D5F144 /* OVR_Std.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Std.h; sourceTree = ""; }; - E8AA40C01907221900D5F144 /* OVR_String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_String.cpp; sourceTree = ""; }; - E8AA40C11907221900D5F144 /* OVR_String.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_String.h; sourceTree = ""; }; - E8AA40C21907221900D5F144 /* OVR_String_FormatUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_String_FormatUtil.cpp; sourceTree = ""; }; - E8AA40C31907221900D5F144 /* OVR_String_PathUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_String_PathUtil.cpp; sourceTree = ""; }; - E8AA40C41907221900D5F144 /* OVR_StringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_StringHash.h; sourceTree = ""; }; - E8AA40C51907221900D5F144 /* OVR_SysFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_SysFile.cpp; sourceTree = ""; }; - E8AA40C61907221900D5F144 /* OVR_SysFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_SysFile.h; sourceTree = ""; }; - E8AA40C71907221900D5F144 /* OVR_System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_System.cpp; sourceTree = ""; }; - E8AA40C81907221900D5F144 /* OVR_System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_System.h; sourceTree = ""; }; - E8AA40C91907221900D5F144 /* OVR_Threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Threads.h; sourceTree = ""; }; - E8AA40CA1907221900D5F144 /* OVR_ThreadsPthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_ThreadsPthread.cpp; sourceTree = ""; }; - E8AA40CC1907221900D5F144 /* OVR_Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_Timer.cpp; sourceTree = ""; }; - E8AA40CD1907221900D5F144 /* OVR_Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Timer.h; sourceTree = ""; }; - E8AA40CE1907221900D5F144 /* OVR_Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_Types.h; sourceTree = ""; }; - E8AA40CF1907221900D5F144 /* OVR_UTF8Util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_UTF8Util.cpp; sourceTree = ""; }; - E8AA40D01907221900D5F144 /* OVR_UTF8Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_UTF8Util.h; sourceTree = ""; }; - E8AA41011907224700D5F144 /* Util_Interface.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_Interface.cpp; sourceTree = ""; }; - E8AA41021907224700D5F144 /* Util_Interface.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_Interface.h; sourceTree = ""; }; - E8AA41071907224700D5F144 /* Util_Render_Stereo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Util_Render_Stereo.cpp; sourceTree = ""; }; - E8AA41081907224700D5F144 /* Util_Render_Stereo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Util_Render_Stereo.h; sourceTree = ""; }; - E8AA412B190722BB00D5F144 /* OVR_JSON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_JSON.cpp; path = ../../../Src/OVR_JSON.cpp; sourceTree = ""; }; - E8AA412C190722BB00D5F144 /* OVR_JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_JSON.h; path = ../../../Src/OVR_JSON.h; sourceTree = ""; }; - E8AA413D190722BB00D5F144 /* OVR_Profile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Profile.cpp; path = ../../../Src/OVR_Profile.cpp; sourceTree = ""; }; - E8AA413E190722BB00D5F144 /* OVR_Profile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Profile.h; path = ../../../Src/OVR_Profile.h; sourceTree = ""; }; - E8AA414F190722BB00D5F144 /* OVR_Stereo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Stereo.cpp; path = ../../../Src/OVR_Stereo.cpp; sourceTree = ""; }; - E8AA4150190722BB00D5F144 /* OVR_Stereo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Stereo.h; path = ../../../Src/OVR_Stereo.h; sourceTree = ""; }; - E8AA41BA190724E600D5F144 /* CAPI_DistortionRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_DistortionRenderer.h; sourceTree = ""; }; - E8AA41BB190724E600D5F144 /* CAPI_FrameTimeManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_FrameTimeManager.cpp; sourceTree = ""; }; - E8AA41BC190724E600D5F144 /* CAPI_FrameTimeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_FrameTimeManager.h; sourceTree = ""; }; - E8AA41BF190724E600D5F144 /* CAPI_HMDRenderState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_HMDRenderState.cpp; sourceTree = ""; }; - E8AA41C0190724E600D5F144 /* CAPI_HMDRenderState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_HMDRenderState.h; sourceTree = ""; }; - E8AA41C1190724E600D5F144 /* CAPI_HMDState.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_HMDState.cpp; sourceTree = ""; }; - E8AA41C2190724E600D5F144 /* CAPI_HMDState.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_HMDState.h; sourceTree = ""; }; - E8AA41D0190724E600D5F144 /* CAPI_GL_DistortionRenderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_GL_DistortionRenderer.cpp; sourceTree = ""; }; - E8AA41D1190724E600D5F144 /* CAPI_GL_DistortionRenderer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_GL_DistortionRenderer.h; sourceTree = ""; }; - E8AA41D2190724E600D5F144 /* CAPI_GL_Util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CAPI_GL_Util.cpp; sourceTree = ""; }; - E8AA41D3190724E600D5F144 /* CAPI_GL_Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CAPI_GL_Util.h; sourceTree = ""; }; - E8B18321196D376800555C29 /* OVR_ThreadCommandQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OVR_ThreadCommandQueue.cpp; sourceTree = ""; }; - E8B18322196D376800555C29 /* OVR_ThreadCommandQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OVR_ThreadCommandQueue.h; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - E82D4CD01906FE640070CB3F /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - E82D4CCA1906FE640070CB3F = { - isa = PBXGroup; - children = ( - E87DF472196A1C03005E383C /* Displays */, - E8AA41B8190724E600D5F144 /* CAPI */, - E87DF4F0196A23A2005E383C /* Tracking */, - E87DF4B1196A21DC005E383C /* Sensors */, - E87DF4A0196A2151005E383C /* Service */, - E87DF47F196A20CF005E383C /* Net */, - E8AA40A51907221900D5F144 /* Kernel */, - E8AA40FC1907224700D5F144 /* Util */, - E886FE9B190737FA00D5DB45 /* OVR_CAPI_GL.h */, - E886FE9C190737FA00D5DB45 /* OVR_CAPI.cpp */, - E886FE9D190737FA00D5DB45 /* OVR_CAPI.h */, - 8864E8FC19D5289700ACEEC1 /* OVR_CAPI_Keys.h */, - E85F262A1954204900AA807B /* OVR_SerialFormat.cpp */, - E85F262B1954204900AA807B /* OVR_SerialFormat.h */, - E8AA412B190722BB00D5F144 /* OVR_JSON.cpp */, - E8AA412C190722BB00D5F144 /* OVR_JSON.h */, - E8AA413D190722BB00D5F144 /* OVR_Profile.cpp */, - E8AA413E190722BB00D5F144 /* OVR_Profile.h */, - E8AA414F190722BB00D5F144 /* OVR_Stereo.cpp */, - E8AA4150190722BB00D5F144 /* OVR_Stereo.h */, - E82D4CD41906FE640070CB3F /* Products */, - ); - sourceTree = ""; - }; - E82D4CD41906FE640070CB3F /* Products */ = { - isa = PBXGroup; - children = ( - E82D4CD31906FE640070CB3F /* libovr.a */, - ); - name = Products; - sourceTree = ""; - }; - E87DF472196A1C03005E383C /* Displays */ = { - isa = PBXGroup; - children = ( - E87DF474196A1CEF005E383C /* OVR_Display.h */, - E87DF477196A1CEF005E383C /* OVR_OSX_Display.cpp */, - E87DF478196A1CEF005E383C /* OVR_OSX_Display.h */, - ); - name = Displays; - sourceTree = ""; - }; - E87DF47F196A20CF005E383C /* Net */ = { - isa = PBXGroup; - children = ( - E87DF480196A20E9005E383C /* OVR_BitStream.cpp */, - E87DF481196A20E9005E383C /* OVR_BitStream.h */, - E87DF482196A20E9005E383C /* OVR_MessageIDTypes.h */, - E87DF483196A20E9005E383C /* OVR_NetworkPlugin.cpp */, - E87DF484196A20E9005E383C /* OVR_NetworkPlugin.h */, - E87DF485196A20E9005E383C /* OVR_NetworkTypes.h */, - E87DF486196A20E9005E383C /* OVR_PacketizedTCPSocket.cpp */, - E87DF487196A20E9005E383C /* OVR_PacketizedTCPSocket.h */, - E87DF488196A20E9005E383C /* OVR_RPC1.cpp */, - E87DF489196A20E9005E383C /* OVR_RPC1.h */, - E87DF48A196A20E9005E383C /* OVR_Session.cpp */, - E87DF48B196A20E9005E383C /* OVR_Session.h */, - E87DF48C196A20E9005E383C /* OVR_Socket.cpp */, - E87DF48D196A20E9005E383C /* OVR_Socket.h */, - E87DF48E196A20E9005E383C /* OVR_Unix_Socket.cpp */, - E87DF48F196A20E9005E383C /* OVR_Unix_Socket.h */, - ); - name = Net; - sourceTree = ""; - }; - E87DF4A0196A2151005E383C /* Service */ = { - isa = PBXGroup; - children = ( - E87DF4A3196A2161005E383C /* Service_NetClient.cpp */, - E87DF4A4196A2161005E383C /* Service_NetClient.h */, - E87DF4A7196A2161005E383C /* Service_NetSessionCommon.cpp */, - E87DF4A8196A2161005E383C /* Service_NetSessionCommon.h */, - ); - name = Service; - sourceTree = ""; - }; - E87DF4B1196A21DC005E383C /* Sensors */ = { - isa = PBXGroup; - children = ( - E87DF4B3196A232F005E383C /* OVR_DeviceConstants.h */, - ); - name = Sensors; - sourceTree = ""; - }; - E87DF4F0196A23A2005E383C /* Tracking */ = { - isa = PBXGroup; - children = ( - E8788D1B196CF68000128BE5 /* Tracking_PoseState.h */, - E8788D1C196CF68000128BE5 /* Tracking_SensorState.h */, - E87DF4F1196A23B4005E383C /* Tracking_SensorStateReader.cpp */, - E87DF4F2196A23B4005E383C /* Tracking_SensorStateReader.h */, - ); - name = Tracking; - sourceTree = ""; - }; - E8AA40A51907221900D5F144 /* Kernel */ = { - isa = PBXGroup; - children = ( - A42F686E1A11F2B80027C6E1 /* OVR_Compiler.h */, - A42F686F1A11F2B80027C6E1 /* OVR_DebugHelp.cpp */, - A42F68701A11F2B80027C6E1 /* OVR_DebugHelp.h */, - A42F68711A11F2B80027C6E1 /* OVR_mach_exc_OSX.c */, - A42F68721A11F2B80027C6E1 /* OVR_mach_exc_OSX.h */, - A42F68731A11F2B80027C6E1 /* OVR_Nullptr.h */, - A42F68741A11F2B80027C6E1 /* OVR_Observer.h */, - E87DF46A196A1BEF005E383C /* OVR_CRC32.cpp */, - E87DF46B196A1BEF005E383C /* OVR_CRC32.h */, - E87DF46C196A1BEF005E383C /* OVR_SharedMemory.cpp */, - E87DF46D196A1BEF005E383C /* OVR_SharedMemory.h */, - E8B18321196D376800555C29 /* OVR_ThreadCommandQueue.cpp */, - E8B18322196D376800555C29 /* OVR_ThreadCommandQueue.h */, - E8AA40A61907221900D5F144 /* OVR_Alg.cpp */, - E8AA40A71907221900D5F144 /* OVR_Alg.h */, - E8AA40A81907221900D5F144 /* OVR_Allocator.cpp */, - E8AA40A91907221900D5F144 /* OVR_Allocator.h */, - E8AA40AA1907221900D5F144 /* OVR_Array.h */, - E8AA40AB1907221900D5F144 /* OVR_Atomic.cpp */, - E8AA40AC1907221900D5F144 /* OVR_Atomic.h */, - E8AA40AD1907221900D5F144 /* OVR_Color.h */, - E8AA40AE1907221900D5F144 /* OVR_ContainerAllocator.h */, - E8AA40AF1907221900D5F144 /* OVR_Deque.h */, - E8AA40B01907221900D5F144 /* OVR_File.cpp */, - E8AA40B11907221900D5F144 /* OVR_File.h */, - E8AA40B21907221900D5F144 /* OVR_FileFILE.cpp */, - E8AA40B31907221900D5F144 /* OVR_Hash.h */, - E8AA40B41907221900D5F144 /* OVR_KeyCodes.h */, - E8AA40B51907221900D5F144 /* OVR_List.h */, - E8AA40B61907221900D5F144 /* OVR_Lockless.cpp */, - E8AA40B71907221900D5F144 /* OVR_Lockless.h */, - E8AA40B81907221900D5F144 /* OVR_Log.cpp */, - E8AA40B91907221900D5F144 /* OVR_Log.h */, - E8AA40BA1907221900D5F144 /* OVR_Math.cpp */, - E8AA40BB1907221900D5F144 /* OVR_Math.h */, - E8AA40BC1907221900D5F144 /* OVR_RefCount.cpp */, - E8AA40BD1907221900D5F144 /* OVR_RefCount.h */, - E8AA40BE1907221900D5F144 /* OVR_Std.cpp */, - E8AA40BF1907221900D5F144 /* OVR_Std.h */, - E8AA40C01907221900D5F144 /* OVR_String.cpp */, - E8AA40C11907221900D5F144 /* OVR_String.h */, - E8AA40C21907221900D5F144 /* OVR_String_FormatUtil.cpp */, - E8AA40C31907221900D5F144 /* OVR_String_PathUtil.cpp */, - E8AA40C41907221900D5F144 /* OVR_StringHash.h */, - E8AA40C51907221900D5F144 /* OVR_SysFile.cpp */, - E8AA40C61907221900D5F144 /* OVR_SysFile.h */, - E8AA40C71907221900D5F144 /* OVR_System.cpp */, - E8AA40C81907221900D5F144 /* OVR_System.h */, - E8AA40C91907221900D5F144 /* OVR_Threads.h */, - E8AA40CA1907221900D5F144 /* OVR_ThreadsPthread.cpp */, - E8AA40CC1907221900D5F144 /* OVR_Timer.cpp */, - E8AA40CD1907221900D5F144 /* OVR_Timer.h */, - E8AA40CE1907221900D5F144 /* OVR_Types.h */, - E8AA40CF1907221900D5F144 /* OVR_UTF8Util.cpp */, - E8AA40D01907221900D5F144 /* OVR_UTF8Util.h */, - ); - name = Kernel; - path = ../../../Src/Kernel; - sourceTree = ""; - }; - E8AA40FC1907224700D5F144 /* Util */ = { - isa = PBXGroup; - children = ( - A42F68641A11F2000027C6E1 /* Util_SystemGUI_OSX.mm */, - A42F68651A11F2000027C6E1 /* Util_SystemGUI.cpp */, - A42F68661A11F2000027C6E1 /* Util_SystemGUI.h */, - 886FFB1D19E4898300775723 /* Util_SystemInfo_OSX.mm */, - A4A859B819D6311500ED2071 /* Util_SystemInfo.cpp */, - A4A859B919D6311500ED2071 /* Util_SystemInfo.h */, - E8788D1F196CF98000128BE5 /* Util_LatencyTest2Reader.cpp */, - E8788D20196CF98000128BE5 /* Util_LatencyTest2Reader.h */, - E8788D21196CF98000128BE5 /* Util_LatencyTest2State.h */, - E8AA41011907224700D5F144 /* Util_Interface.cpp */, - E8AA41021907224700D5F144 /* Util_Interface.h */, - E8AA41071907224700D5F144 /* Util_Render_Stereo.cpp */, - E8AA41081907224700D5F144 /* Util_Render_Stereo.h */, - ); - name = Util; - path = ../../../Src/Util; - sourceTree = ""; - }; - E8AA41B8190724E600D5F144 /* CAPI */ = { - isa = PBXGroup; - children = ( - A42F687C1A11F2F10027C6E1 /* CAPI_GLE_GL.h */, - A42F687D1A11F2F10027C6E1 /* CAPI_GLE.cpp */, - A42F687E1A11F2F10027C6E1 /* CAPI_GLE.h */, - A4A859B419D6310100ED2071 /* CAPI_LatencyStatistics.cpp */, - A4A859B519D6310100ED2071 /* CAPI_LatencyStatistics.h */, - 4683CEBC1970867300285E02 /* CAPI_GL_HSWDisplay.cpp */, - 4683CEBD1970867300285E02 /* CAPI_GL_HSWDisplay.h */, - E886FEA11907528C00D5DB45 /* CAPI_DistortionRenderer.cpp */, - E8AA41BA190724E600D5F144 /* CAPI_DistortionRenderer.h */, - E8AA41BB190724E600D5F144 /* CAPI_FrameTimeManager.cpp */, - E8AA41BC190724E600D5F144 /* CAPI_FrameTimeManager.h */, - E8094D0D196FAE8800937940 /* CAPI_HSWDisplay.cpp */, - E8094D0E196FAE8800937940 /* CAPI_HSWDisplay.h */, - E8AA41BF190724E600D5F144 /* CAPI_HMDRenderState.cpp */, - E8AA41C0190724E600D5F144 /* CAPI_HMDRenderState.h */, - E8AA41C1190724E600D5F144 /* CAPI_HMDState.cpp */, - E8AA41C2190724E600D5F144 /* CAPI_HMDState.h */, - E8AA41CF190724E600D5F144 /* GL */, - ); - name = CAPI; - path = ../../../Src/CAPI; - sourceTree = ""; - }; - E8AA41CF190724E600D5F144 /* GL */ = { - isa = PBXGroup; - children = ( - E8AA41D0190724E600D5F144 /* CAPI_GL_DistortionRenderer.cpp */, - E8AA41D1190724E600D5F144 /* CAPI_GL_DistortionRenderer.h */, - E8AA41D2190724E600D5F144 /* CAPI_GL_Util.cpp */, - E8AA41D3190724E600D5F144 /* CAPI_GL_Util.h */, - ); - path = GL; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXHeadersBuildPhase section */ - E82D4CD11906FE640070CB3F /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - E8AA4198190722BB00D5F144 /* OVR_Stereo.h in Headers */, - E8B18324196D376800555C29 /* OVR_ThreadCommandQueue.h in Headers */, - E8788D23196CF98000128BE5 /* Util_LatencyTest2Reader.h in Headers */, - E8AA41E2190724E600D5F144 /* CAPI_DistortionRenderer.h in Headers */, - E8094D10196FAE8800937940 /* CAPI_HSWDisplay.h in Headers */, - 4683CEBF1970867300285E02 /* CAPI_GL_HSWDisplay.h in Headers */, - E87DF471196A1BEF005E383C /* OVR_SharedMemory.h in Headers */, - E87DF4D2196A232F005E383C /* OVR_DeviceConstants.h in Headers */, - E8AA40DF1907221900D5F144 /* OVR_KeyCodes.h in Headers */, - E8AA40D51907221900D5F144 /* OVR_Array.h in Headers */, - E8788D24196CF98000128BE5 /* Util_LatencyTest2State.h in Headers */, - A42F68791A11F2B80027C6E1 /* OVR_mach_exc_OSX.h in Headers */, - E8AA41F7190724E600D5F144 /* CAPI_GL_DistortionRenderer.h in Headers */, - E87DF47A196A1CEF005E383C /* OVR_Display.h in Headers */, - E87DF46F196A1BEF005E383C /* OVR_CRC32.h in Headers */, - A4A859BB19D6311500ED2071 /* Util_SystemInfo.h in Headers */, - E85F262D1954204900AA807B /* OVR_SerialFormat.h in Headers */, - E8AA40DC1907221900D5F144 /* OVR_File.h in Headers */, - E8AA40D41907221900D5F144 /* OVR_Allocator.h in Headers */, - E8788D1D196CF68000128BE5 /* Tracking_PoseState.h in Headers */, - E8AA410E1907224700D5F144 /* Util_Interface.h in Headers */, - E886FEA0190737FA00D5DB45 /* OVR_CAPI.h in Headers */, - E8AA41F9190724E600D5F144 /* CAPI_GL_Util.h in Headers */, - 8864E8FD19D5289700ACEEC1 /* OVR_CAPI_Keys.h in Headers */, - E8AA40E21907221900D5F144 /* OVR_Lockless.h in Headers */, - E8AA40F31907221900D5F144 /* OVR_System.h in Headers */, - E8AA41E8190724E600D5F144 /* CAPI_HMDRenderState.h in Headers */, - E8AA41141907224700D5F144 /* Util_Render_Stereo.h in Headers */, - E8788D1E196CF68000128BE5 /* Tracking_SensorState.h in Headers */, - E8AA40E61907221900D5F144 /* OVR_Math.h in Headers */, - E87DF4B0196A2161005E383C /* Service_NetSessionCommon.h in Headers */, - E8AA40F91907221900D5F144 /* OVR_Types.h in Headers */, - A42F68691A11F2000027C6E1 /* Util_SystemGUI.h in Headers */, - E8AA40D91907221900D5F144 /* OVR_ContainerAllocator.h in Headers */, - E87DF49B196A20E9005E383C /* OVR_Session.h in Headers */, - E87DF497196A20E9005E383C /* OVR_PacketizedTCPSocket.h in Headers */, - A42F687B1A11F2B80027C6E1 /* OVR_Observer.h in Headers */, - A42F68771A11F2B80027C6E1 /* OVR_DebugHelp.h in Headers */, - E87DF492196A20E9005E383C /* OVR_MessageIDTypes.h in Headers */, - E8AA40D71907221900D5F144 /* OVR_Atomic.h in Headers */, - E8AA41E4190724E600D5F144 /* CAPI_FrameTimeManager.h in Headers */, - A42F687F1A11F2F10027C6E1 /* CAPI_GLE_GL.h in Headers */, - A42F68811A11F2F10027C6E1 /* CAPI_GLE.h in Headers */, - E8AA40D21907221900D5F144 /* OVR_Alg.h in Headers */, - A4A859B719D6310100ED2071 /* CAPI_LatencyStatistics.h in Headers */, - A42F687A1A11F2B80027C6E1 /* OVR_Nullptr.h in Headers */, - E87DF494196A20E9005E383C /* OVR_NetworkPlugin.h in Headers */, - E87DF495196A20E9005E383C /* OVR_NetworkTypes.h in Headers */, - E8AA40E01907221900D5F144 /* OVR_List.h in Headers */, - E8AA40EF1907221900D5F144 /* OVR_StringHash.h in Headers */, - E886FE9E190737FA00D5DB45 /* OVR_CAPI_GL.h in Headers */, - E87DF4F4196A23B4005E383C /* Tracking_SensorStateReader.h in Headers */, - E8AA41EA190724E600D5F144 /* CAPI_HMDState.h in Headers */, - E8AA40D81907221900D5F144 /* OVR_Color.h in Headers */, - E8AA4174190722BB00D5F144 /* OVR_JSON.h in Headers */, - E87DF49F196A20E9005E383C /* OVR_Unix_Socket.h in Headers */, - E87DF491196A20E9005E383C /* OVR_BitStream.h in Headers */, - E8AA40F11907221900D5F144 /* OVR_SysFile.h in Headers */, - E8AA40DE1907221900D5F144 /* OVR_Hash.h in Headers */, - E87DF4AC196A2161005E383C /* Service_NetClient.h in Headers */, - E87DF49D196A20E9005E383C /* OVR_Socket.h in Headers */, - E8AA40EC1907221900D5F144 /* OVR_String.h in Headers */, - E8AA4186190722BB00D5F144 /* OVR_Profile.h in Headers */, - E8AA40EA1907221900D5F144 /* OVR_Std.h in Headers */, - E87DF499196A20E9005E383C /* OVR_RPC1.h in Headers */, - E8AA40E81907221900D5F144 /* OVR_RefCount.h in Headers */, - E8AA40DA1907221900D5F144 /* OVR_Deque.h in Headers */, - E8AA40FB1907221900D5F144 /* OVR_UTF8Util.h in Headers */, - E87DF47E196A1CEF005E383C /* OVR_OSX_Display.h in Headers */, - E8AA40F41907221900D5F144 /* OVR_Threads.h in Headers */, - A42F68751A11F2B80027C6E1 /* OVR_Compiler.h in Headers */, - E8AA40F81907221900D5F144 /* OVR_Timer.h in Headers */, - E8AA40E41907221900D5F144 /* OVR_Log.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXHeadersBuildPhase section */ - -/* Begin PBXNativeTarget section */ - E82D4CD21906FE640070CB3F /* LibOVR */ = { - isa = PBXNativeTarget; - buildConfigurationList = E82D4CD71906FE640070CB3F /* Build configuration list for PBXNativeTarget "LibOVR" */; - buildPhases = ( - E82D4CCF1906FE640070CB3F /* Sources */, - E82D4CD01906FE640070CB3F /* Frameworks */, - E82D4CD11906FE640070CB3F /* Headers */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = LibOVR; - productName = LibOVR; - productReference = E82D4CD31906FE640070CB3F /* libovr.a */; - productType = "com.apple.product-type.library.static"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - E82D4CCB1906FE640070CB3F /* Project object */ = { - isa = PBXProject; - attributes = { - LastUpgradeCheck = 0510; - ORGANIZATIONNAME = "Oculus VR Inc."; - }; - buildConfigurationList = E82D4CCE1906FE640070CB3F /* Build configuration list for PBXProject "LibOVR" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; - hasScannedForEncodings = 0; - knownRegions = ( - en, - ); - mainGroup = E82D4CCA1906FE640070CB3F; - productRefGroup = E82D4CD41906FE640070CB3F /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - E82D4CD21906FE640070CB3F /* LibOVR */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXSourcesBuildPhase section */ - E82D4CCF1906FE640070CB3F /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - E8AA41E3190724E600D5F144 /* CAPI_FrameTimeManager.cpp in Sources */, - E8AA41131907224700D5F144 /* Util_Render_Stereo.cpp in Sources */, - E8AA4185190722BB00D5F144 /* OVR_Profile.cpp in Sources */, - E8094D0F196FAE8800937940 /* CAPI_HSWDisplay.cpp in Sources */, - E8AA40F01907221900D5F144 /* OVR_SysFile.cpp in Sources */, - E8AA40DB1907221900D5F144 /* OVR_File.cpp in Sources */, - E8788D22196CF98000128BE5 /* Util_LatencyTest2Reader.cpp in Sources */, - E8AA40ED1907221900D5F144 /* OVR_String_FormatUtil.cpp in Sources */, - E8AA4173190722BB00D5F144 /* OVR_JSON.cpp in Sources */, - A42F68801A11F2F10027C6E1 /* CAPI_GLE.cpp in Sources */, - E8AA40D61907221900D5F144 /* OVR_Atomic.cpp in Sources */, - E8AA40E31907221900D5F144 /* OVR_Log.cpp in Sources */, - E87DF4AF196A2161005E383C /* Service_NetSessionCommon.cpp in Sources */, - E87DF4F3196A23B4005E383C /* Tracking_SensorStateReader.cpp in Sources */, - E87DF4AB196A2161005E383C /* Service_NetClient.cpp in Sources */, - E8AA40E91907221900D5F144 /* OVR_Std.cpp in Sources */, - E8AA41F6190724E600D5F144 /* CAPI_GL_DistortionRenderer.cpp in Sources */, - E8AA40DD1907221900D5F144 /* OVR_FileFILE.cpp in Sources */, - E8AA40E51907221900D5F144 /* OVR_Math.cpp in Sources */, - E8AA40D31907221900D5F144 /* OVR_Allocator.cpp in Sources */, - E8AA41E9190724E600D5F144 /* CAPI_HMDState.cpp in Sources */, - E8AA40FA1907221900D5F144 /* OVR_UTF8Util.cpp in Sources */, - A4A859B619D6310100ED2071 /* CAPI_LatencyStatistics.cpp in Sources */, - E8AA410D1907224700D5F144 /* Util_Interface.cpp in Sources */, - E8AA40F71907221900D5F144 /* OVR_Timer.cpp in Sources */, - E87DF49A196A20E9005E383C /* OVR_Session.cpp in Sources */, - A42F68681A11F2000027C6E1 /* Util_SystemGUI.cpp in Sources */, - E8AA40D11907221900D5F144 /* OVR_Alg.cpp in Sources */, - 4683CEBE1970867300285E02 /* CAPI_GL_HSWDisplay.cpp in Sources */, - E8AA4197190722BB00D5F144 /* OVR_Stereo.cpp in Sources */, - A42F68781A11F2B80027C6E1 /* OVR_mach_exc_OSX.c in Sources */, - E87DF493196A20E9005E383C /* OVR_NetworkPlugin.cpp in Sources */, - E8AA40F21907221900D5F144 /* OVR_System.cpp in Sources */, - E8B18323196D376800555C29 /* OVR_ThreadCommandQueue.cpp in Sources */, - E8AA40EB1907221900D5F144 /* OVR_String.cpp in Sources */, - E87DF490196A20E9005E383C /* OVR_BitStream.cpp in Sources */, - E886FE9F190737FA00D5DB45 /* OVR_CAPI.cpp in Sources */, - E8AA40E71907221900D5F144 /* OVR_RefCount.cpp in Sources */, - E85F262C1954204900AA807B /* OVR_SerialFormat.cpp in Sources */, - E87DF496196A20E9005E383C /* OVR_PacketizedTCPSocket.cpp in Sources */, - A42F68761A11F2B80027C6E1 /* OVR_DebugHelp.cpp in Sources */, - A42F68671A11F2000027C6E1 /* Util_SystemGUI_OSX.mm in Sources */, - E87DF46E196A1BEF005E383C /* OVR_CRC32.cpp in Sources */, - E8AA40E11907221900D5F144 /* OVR_Lockless.cpp in Sources */, - E8AA41E7190724E600D5F144 /* CAPI_HMDRenderState.cpp in Sources */, - E8AA41F8190724E600D5F144 /* CAPI_GL_Util.cpp in Sources */, - E8AA40EE1907221900D5F144 /* OVR_String_PathUtil.cpp in Sources */, - E87DF47D196A1CEF005E383C /* OVR_OSX_Display.cpp in Sources */, - 886FFB1E19E4898300775723 /* Util_SystemInfo_OSX.mm in Sources */, - E87DF49C196A20E9005E383C /* OVR_Socket.cpp in Sources */, - E886FEA21907528C00D5DB45 /* CAPI_DistortionRenderer.cpp in Sources */, - E87DF49E196A20E9005E383C /* OVR_Unix_Socket.cpp in Sources */, - E87DF498196A20E9005E383C /* OVR_RPC1.cpp in Sources */, - E8AA40F51907221900D5F144 /* OVR_ThreadsPthread.cpp in Sources */, - A4A859BA19D6311500ED2071 /* Util_SystemInfo.cpp in Sources */, - E87DF470196A1BEF005E383C /* OVR_SharedMemory.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin XCBuildConfiguration section */ - E82D4CD51906FE640070CB3F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = NO; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - COPY_PHASE_STRIP = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.7; - OBJROOT = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = macosx; - SYMROOT = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - }; - name = Debug; - }; - E82D4CD61906FE640070CB3F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = NO; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - MACOSX_DEPLOYMENT_TARGET = 10.7; - OBJROOT = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - SDKROOT = macosx; - SYMROOT = "$(SRCROOT)/../../../Lib/Mac/Xcode/$(CONFIGURATION)"; - }; - name = Release; - }; - E82D4CD81906FE640070CB3F /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; - CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; - EXECUTABLE_PREFIX = ""; - GCC_INLINES_ARE_PRIVATE_EXTERN = YES; - GCC_PREPROCESSOR_DEFINITIONS = ( - OVR_BUILD_DEBUG, - "$(inherited)", - ); - MACOSX_DEPLOYMENT_TARGET = 10.8; - OBJROOT = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_NAME = libovr; - SYMROOT = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; - }; - name = Debug; - }; - E82D4CD91906FE640070CB3F /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; - CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; - CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; - EXECUTABLE_PREFIX = ""; - GCC_INLINES_ARE_PRIVATE_EXTERN = YES; - GCC_SYMBOLS_PRIVATE_EXTERN = NO; - MACOSX_DEPLOYMENT_TARGET = 10.8; - OBJROOT = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; - ONLY_ACTIVE_ARCH = NO; - PRODUCT_NAME = libovr; - SYMROOT = "$(SRCROOT)/../../../Lib/Mac/$(CONFIGURATION)"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - E82D4CCE1906FE640070CB3F /* Build configuration list for PBXProject "LibOVR" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E82D4CD51906FE640070CB3F /* Debug */, - E82D4CD61906FE640070CB3F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - E82D4CD71906FE640070CB3F /* Build configuration list for PBXNativeTarget "LibOVR" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - E82D4CD81906FE640070CB3F /* Debug */, - E82D4CD91906FE640070CB3F /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = E82D4CCB1906FE640070CB3F /* Project object */; -} diff --git a/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 6e21728..0000000 --- a/LibOVR/Projects/Mac/Xcode/LibOVR.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj deleted file mode 100644 index 00d8a1b..0000000 --- a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj +++ /dev/null @@ -1,489 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - - - Document - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - - - - {934B40C7-F40A-4E4C-97A7-B9659BE0A441} - Win32Proj - LibOVR - LibOVR - - - - StaticLibrary - true - Unicode - - - StaticLibrary - true - Unicode - - - StaticLibrary - false - true - Unicode - - - StaticLibrary - false - true - Unicode - - - - - - - - - - - - - - - - - - - ../../../Lib/$(Platform)/VS2010/ - - - ../../../Lib/$(Platform)/VS2010/ - - - ../../../Obj/$(Platform)/VS2010/$(Configuration)/ - - - ../../../Obj/$(Platform)/VS2010/$(Configuration)/ - - - libovrd - - - libovr64d - - - ../../../Lib/$(Platform)/VS2010/ - - - ../../../Lib/$(Platform)/VS2010/ - - - ../../../Obj/$(Platform)/VS2010/$(Configuration)/ - - - ../../../Obj/$(Platform)/VS2010/$(Configuration)/ - - - libovr - - - libovr64 - - - - - - Level4 - Disabled - OVR_BUILD_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - OldStyle - true - false - true - MultiThreadedDebug - $(DXSDK_DIR)/Include;../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - - - Windows - true - - - Setupapi.lib - - - - - - - Level4 - Disabled - OVR_BUILD_DEBUG;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) - OldStyle - true - false - true - MultiThreadedDebug - $(DXSDK_DIR)/Include;../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - - - Windows - true - - - Setupapi.lib - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreaded - true - true - OldStyle - $(DXSDK_DIR)/Include;../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - - - Windows - true - true - true - - - Setupapi.lib - - - - - Level4 - - - MaxSpeed - true - true - _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreaded - true - true - OldStyle - $(DXSDK_DIR)/Include;../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - - - Windows - true - true - true - - - Setupapi.lib - - - - - - \ No newline at end of file diff --git a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters deleted file mode 100644 index f4f3648..0000000 --- a/LibOVR/Projects/Win32/VS2010/LibOVR.vcxproj.filters +++ /dev/null @@ -1,500 +0,0 @@ - - - - - Util - - - CAPI - - - CAPI - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI - - - Util - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Tracking - - - Displays - - - Displays - - - Displays - - - Service - - - Service - - - Displays - - - Util - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\GL - - - CAPI - - - Util - - - CAPI\D3D9 - - - CAPI\D3D9 - - - CAPI\D3D9 - - - Kernel - - - Util - - - CAPI\GL - - - - - Util - - - CAPI - - - CAPI - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI - - - Util - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - - - - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Sensors - - - Tracking - - - Displays - - - Displays - - - Displays - - - Displays - - - Service - - - Service - - - Displays - - - Tracking - - - Tracking - - - Util - - - Util - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\GL - - - CAPI - - - Util - - - CAPI\D3D9 - - - CAPI\D3D9 - - - CAPI\GL - - - Kernel - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - {aa824f36-4d15-4dca-9894-fef4368ea56a} - - - {d532b65b-dee5-422f-b723-ce8639eedbe0} - - - {7ec9033e-7bc6-49de-93d0-91eecdd9a858} - - - {0ee0029b-0b10-4ad6-a10c-7bf4ccefdf54} - - - {fe5d391d-40b2-48a6-8615-6654c19b3a71} - - - {499e41fb-c8f9-4eb1-bfda-d9ec4190f884} - - - {603dfa0f-c6ed-497c-b29e-7bccbe9c442b} - - - {ca920a3e-285c-4530-a8dc-f9b09b676951} - - - {242c9ebf-ce0a-44fd-8b90-0420ffcb44c4} - - - {4db52c9f-ff4d-4aee-82b8-af6dcd6257bf} - - - {bb2d660e-9324-4735-9b3c-44209de507f8} - - - {79ee8d9c-1c2e-4f6a-a42d-edd426ae0a9b} - - - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - \ No newline at end of file diff --git a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj deleted file mode 100644 index 94bee8c..0000000 --- a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj +++ /dev/null @@ -1,497 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - - - Document - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - - - - {CCFFB3F0-DDC4-4F01-8116-A5BFC53B331C} - Win32Proj - LibOVR - LibOVR - - - - StaticLibrary - true - Unicode - v110 - - - StaticLibrary - true - Unicode - v110 - - - StaticLibrary - false - true - Unicode - v110 - - - StaticLibrary - false - true - Unicode - v110 - - - - - - - - - - - - - - - - - - - ../../../Lib/$(Platform)/VS2012/ - - - ../../../Lib/$(Platform)/VS2012/ - - - ../../../Obj/$(Platform)/VS2012/$(Configuration)/ - - - ../../../Obj/$(Platform)/VS2012/$(Configuration)/ - - - libovrd - - - libovr64d - - - ../../../Lib/$(Platform)/VS2012/ - - - ../../../Lib/$(Platform)/VS2012/ - - - ../../../Obj/$(Platform)/VS2012/$(Configuration)/ - - - ../../../Obj/$(Platform)/VS2012/$(Configuration)/ - - - libovr - - - libovr64 - - - - - - Level4 - Disabled - OVR_BUILD_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - OldStyle - true - false - true - MultiThreadedDebug - ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - - - Windows - true - - - Setupapi.lib - - - - - - - Level4 - Disabled - OVR_BUILD_DEBUG;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) - OldStyle - true - false - true - MultiThreadedDebug - ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - - - Windows - true - - - Setupapi.lib - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreaded - true - true - OldStyle - ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - /d2Zi+ %(AdditionalOptions) - - - Windows - true - true - true - - - Setupapi.lib - - - - - Level4 - - - MaxSpeed - true - true - _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreaded - true - true - OldStyle - ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - /d2Zi+ %(AdditionalOptions) - - - Windows - true - true - true - - - Setupapi.lib - - - - - - \ No newline at end of file diff --git a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters deleted file mode 100644 index 5bf7077..0000000 --- a/LibOVR/Projects/Win32/VS2012/LibOVR.vcxproj.filters +++ /dev/null @@ -1,506 +0,0 @@ - - - - - Util - - - CAPI - - - CAPI - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI - - - Util - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Displays - - - Displays - - - Displays - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Service - - - Service - - - Tracking - - - Displays - - - Util - - - Kernel - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\GL - - - CAPI - - - Util - - - CAPI\D3D9 - - - CAPI\D3D9 - - - CAPI\D3D9 - - - Util - - - Util - - - CAPI\GL - - - - - Util - - - CAPI - - - CAPI - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI - - - Util - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - - - - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Displays - - - Displays - - - Displays - - - Displays - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Sensors - - - Service - - - Service - - - Tracking - - - Displays - - - Tracking - - - Tracking - - - Util - - - Util - - - Kernel - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\GL - - - CAPI - - - Util - - - CAPI\D3D9 - - - CAPI\D3D9 - - - CAPI\GL - - - Util - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - {aa824f36-4d15-4dca-9894-fef4368ea56a} - - - {d532b65b-dee5-422f-b723-ce8639eedbe0} - - - {7ec9033e-7bc6-49de-93d0-91eecdd9a858} - - - {0ee0029b-0b10-4ad6-a10c-7bf4ccefdf54} - - - {0e2e7bad-69a3-464a-9256-12114645638c} - - - {44df3147-efdd-4001-9f31-212174da3fa2} - - - {1d053ad6-31a7-4ef9-babb-22579ba7df12} - - - {e26124bc-50b0-40a8-b678-41e4bca60564} - - - {411b56fb-26bf-4bad-bdd2-8b85dd00afbe} - - - {97998d73-b1cd-465a-9a52-8bd2d0cd4940} - - - {bf026447-0fe0-4119-82e0-5cbd34de8128} - - - {944c9556-a543-437e-a17e-10ce78ef836a} - - - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - \ No newline at end of file diff --git a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj deleted file mode 100644 index 6a271d4..0000000 --- a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj +++ /dev/null @@ -1,500 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - true - true - true - - - true - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" - - - Document - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - %(RelativeDir)%(Filename).h - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" - - - - - Document - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" - %(RelativeDir)%(Filename).h - - - - {EA50E705-5113-49E5-B105-2512EDC8DDC6} - Win32Proj - LibOVR - LibOVR - - - - StaticLibrary - true - Unicode - v120 - - - StaticLibrary - true - Unicode - v120 - - - StaticLibrary - false - true - Unicode - v120 - - - StaticLibrary - false - true - Unicode - v120 - - - - - - - - - - - - - - - - - - - ../../../Lib/$(Platform)/VS2013/ - - - ../../../Lib/$(Platform)/VS2013/ - - - ../../../Obj/$(Platform)/VS2013/$(Configuration)/ - - - ../../../Obj/$(Platform)/VS2013/$(Configuration)/ - - - libovrd - - - libovr64d - - - ../../../Lib/$(Platform)/VS2013/ - - - ../../../Lib/$(Platform)/VS2013/ - - - ../../../Obj/$(Platform)/VS2013/$(Configuration)/ - - - ../../../Obj/$(Platform)/VS2013/$(Configuration)/ - - - libovr - - - libovr64 - - - - - - Level4 - Disabled - OVR_BUILD_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) - OldStyle - true - false - true - MultiThreadedDebug - ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - - - Windows - true - - - Setupapi.lib - - - - - - - Level4 - Disabled - OVR_BUILD_DEBUG;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions) - OldStyle - true - false - true - MultiThreadedDebug - ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - false - - - Windows - true - - - Setupapi.lib - - - - - Level4 - - - MaxSpeed - true - true - WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreaded - true - true - OldStyle - ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - /d2Zi+ %(AdditionalOptions) - - - Windows - true - true - true - - - Setupapi.lib - - - - - Level4 - - - MaxSpeed - true - true - _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions) - MultiThreaded - true - true - OldStyle - ../../../../3rdParty/glext/;%(AdditionalIncludeDirectories) - false - /d2Zi+ %(AdditionalOptions) - - - Windows - true - true - true - - - Setupapi.lib - - - - - - \ No newline at end of file diff --git a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters b/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters deleted file mode 100644 index 5b873a2..0000000 --- a/LibOVR/Projects/Win32/VS2013/LibOVR.vcxproj.filters +++ /dev/null @@ -1,512 +0,0 @@ - - - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI - - - CAPI - - - CAPI - - - CAPI - - - Util - - - Util - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Displays - - - Displays - - - Service - - - Service - - - Tracking - - - Displays - - - Util - - - Displays - - - Kernel - - - CAPI - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\GL - - - CAPI - - - Util - - - CAPI\D3D9 - - - CAPI\D3D9 - - - CAPI\D3D9 - - - Kernel - - - Util - - - CAPI\GL - - - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI - - - CAPI - - - CAPI - - - CAPI - - - Util - - - Util - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - - - - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Kernel - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Net - - - Displays - - - Service - - - Service - - - Tracking - - - Displays - - - Displays - - - Util - - - Displays - - - Tracking - - - Tracking - - - Util - - - Sensors - - - Kernel - - - Displays - - - CAPI - - - CAPI\Textures - - - CAPI\D3D1X - - - CAPI\D3D1X - - - CAPI\GL - - - CAPI - - - Util - - - CAPI\D3D9 - - - CAPI\D3D9 - - - CAPI\GL - - - Kernel - - - Util - - - CAPI\GL - - - CAPI\GL - - - - - {42ff86e1-b618-4432-99ce-e6b92c7460eb} - - - {77e1d16e-00a1-4130-8ee6-f81d1e850859} - - - {b5206073-e32d-413b-804b-6c4f6984365c} - - - {470c25c2-99a2-439b-9f6b-761e8c70f84e} - - - {47ac92b1-d962-4180-90a5-846feef19a6b} - - - {908d5c2d-305b-4a8a-9b25-b551a42677d1} - - - {166e9ffc-558b-46ca-be9f-de9ac0ed89e9} - - - {5ef4cc4f-f0f2-4653-96fa-aafafd95f77e} - - - {16de1b27-4167-429c-a964-44e476ec9c95} - - - {9b464232-8a47-404b-8120-b6e8dc016c36} - - - {4133d45b-be4b-4813-afea-9ad61ce3fe11} - - - {723b8d80-1ae0-4e67-9dec-9b3397726d86} - - - {c6fb4a59-0089-41c0-b5c8-5e429addacfe} - - - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - CAPI\D3D1X\Shaders - - - \ No newline at end of file diff --git a/LibOVR/Projects/Windows/VS2013/LibOVRRT.sln b/LibOVR/Projects/Windows/VS2013/LibOVRRT.sln new file mode 100644 index 0000000..d61c4ff --- /dev/null +++ b/LibOVR/Projects/Windows/VS2013/LibOVRRT.sln @@ -0,0 +1,57 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOVRRT", "LibOVRRT.vcxproj", "{934B40C7-F40A-4E4C-97A7-B9659BE0A441}" + ProjectSection(ProjectDependencies) = postProject + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D} = {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D} + {29FA0962-DDC6-4F72-9D12-E150DF29E279} = {29FA0962-DDC6-4F72-9D12-E150DF29E279} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibOVRKernel", "..\..\..\..\LibOVRKernel\Projects\Windows\VS2013\LibOVRKernel.vcxproj", "{29FA0962-DDC6-4F72-9D12-E150DF29E279}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{2BA5450C-9D41-4AED-9744-965F24298465}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ShaderReflector", "..\..\..\..\Tools\ShaderReflector\ShaderReflector\ShaderReflector_VS2013.vcxproj", "{ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Debug|Win32.ActiveCfg = Debug|Win32 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Debug|Win32.Build.0 = Debug|Win32 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Debug|x64.ActiveCfg = Debug|x64 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Debug|x64.Build.0 = Debug|x64 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|Win32.ActiveCfg = Release|Win32 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|Win32.Build.0 = Release|Win32 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|x64.ActiveCfg = Release|x64 + {934B40C7-F40A-4E4C-97A7-B9659BE0A441}.Release|x64.Build.0 = Release|x64 + {29FA0962-DDC6-4F72-9D12-E150DF29E279}.Debug|Win32.ActiveCfg = Debug|Win32 + {29FA0962-DDC6-4F72-9D12-E150DF29E279}.Debug|Win32.Build.0 = Debug|Win32 + {29FA0962-DDC6-4F72-9D12-E150DF29E279}.Debug|x64.ActiveCfg = Debug|x64 + {29FA0962-DDC6-4F72-9D12-E150DF29E279}.Debug|x64.Build.0 = Debug|x64 + {29FA0962-DDC6-4F72-9D12-E150DF29E279}.Release|Win32.ActiveCfg = Release|Win32 + {29FA0962-DDC6-4F72-9D12-E150DF29E279}.Release|Win32.Build.0 = Release|Win32 + {29FA0962-DDC6-4F72-9D12-E150DF29E279}.Release|x64.ActiveCfg = Release|x64 + {29FA0962-DDC6-4F72-9D12-E150DF29E279}.Release|x64.Build.0 = Release|x64 + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}.Debug|Win32.ActiveCfg = Release|Win32 + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}.Debug|Win32.Build.0 = Release|Win32 + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}.Debug|x64.ActiveCfg = Release|Win32 + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}.Debug|x64.Build.0 = Release|Win32 + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}.Release|Win32.ActiveCfg = Release|Win32 + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}.Release|Win32.Build.0 = Release|Win32 + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}.Release|x64.ActiveCfg = Release|Win32 + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D}.Release|x64.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {ADCFC940-8E3E-40BB-A47A-A10CC311BC0D} = {2BA5450C-9D41-4AED-9744-965F24298465} + EndGlobalSection +EndGlobal diff --git a/LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj b/LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj new file mode 100644 index 0000000..6447a39 --- /dev/null +++ b/LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj @@ -0,0 +1,456 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Document + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + Document + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + + + Document + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + + + Document + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + + + Document + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + Document + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + + + Document + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genPixelShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + + + Document + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + %(RelativeDir)%(Filename).h + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + call %(RelativeDir)genVertexShaderHeader.bat %(Filename) "%(Fullpath)" + + + + + Document + call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + call %(RelativeDir)genComputeShaderHeader.bat %(Filename) "%(Fullpath)" + %(RelativeDir)%(Filename).h + + + + + + + + + + + {934B40C7-F40A-4E4C-97A7-B9659BE0A441} + Win32Proj + LibOVRRT + LibOVRRT + + + + DynamicLibrary + true + Unicode + v120 + + + DynamicLibrary + true + Unicode + v120 + + + DynamicLibrary + false + true + Unicode + v120 + + + DynamicLibrary + false + true + Unicode + v120 + + + + + + + + + + + + + + + + + + + + + + + + + + + ../../../Lib/Windows/$(Platform)/$(Configuration)/VS2013/ + + + ../../../Lib/Windows/$(Platform)/$(Configuration)/VS2013/ + + + ../../../Obj/Windows/$(Platform)/$(Configuration)/VS2013/ + + + ../../../Obj/Windows/$(Platform)/$(Configuration)/VS2013/ + + + LibOVRRT32_$(OVR_PRODUCT_VERSION)_$(OVR_MAJOR_VERSION) + + + LibOVRRT64_$(OVR_PRODUCT_VERSION)_$(OVR_MAJOR_VERSION) + AllRules.ruleset + false + + + ../../../Lib/Windows/$(Platform)/$(Configuration)/VS2013/ + + + ../../../Lib/Windows/$(Platform)/$(Configuration)/VS2013/ + + + ../../../Obj/Windows/$(Platform)/$(Configuration)/VS2013/ + + + ../../../Obj/Windows/$(Platform)/$(Configuration)/VS2013/ + + + LibOVRRT32_$(OVR_PRODUCT_VERSION)_$(OVR_MAJOR_VERSION) + + + LibOVRRT64_$(OVR_PRODUCT_VERSION)_$(OVR_MAJOR_VERSION) + + + + + + Level4 + Disabled + OVR_BUILD_DEBUG;WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions);OVR_DLL_BUILD + OldStyle + true + false + false + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include;../../../Src;../../../../LibOVRKernel/Src/Kernel;../../../../LibOVRKernel/Src + true + /d2Zi+ /we4263 /we4264 /we4265 /we4266 %(AdditionalOptions) + + + Windows + true + LibOVRKernel.lib;kernel32.lib;ws2_32.lib;Dbghelp.lib;user32.lib;gdi32.lib;uuid.lib;dxgi.lib;d3d11.lib;d3dcompiler.lib + ../../../../LibOVRKernel/Lib/Windows/$(Platform)/$(Configuration)/VS2013 + OpenGL32.dll;DbgHelp.dll;gdi32.dll + + + Setupapi.lib + + + _DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + + + + + Level4 + Disabled + OVR_BUILD_DEBUG;_WIN64;_DEBUG;_LIB;%(PreprocessorDefinitions);OVR_DLL_BUILD + OldStyle + true + false + false + MultiThreadedDebug + %(AdditionalIncludeDirectories);../../../Include;../../../Src;../../../../LibOVRKernel/Src/Kernel;../../../../LibOVRKernel/Src + false + false + true + /d2Zi+ /we4263 /we4264 /we4265 /we4266 %(AdditionalOptions) + + + Windows + true + LibOVRKernel.lib;kernel32.lib;ws2_32.lib;Dbghelp.lib;user32.lib;gdi32.lib;uuid.lib;dxgi.lib;d3d11.lib;d3dcompiler.lib + ../../../../LibOVRKernel/Lib/Windows/$(Platform)/$(Configuration)/VS2013 + OpenGL32.dll;DbgHelp.dll;gdi32.dll + + + Setupapi.lib + + + _DEBUG;_UNICODE;UNICODE;%(PreprocessorDefinitions) + + + + + Level4 + + + MaxSpeed + true + true + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions);OVR_DLL_BUILD + MultiThreaded + true + false + OldStyle + %(AdditionalIncludeDirectories);../../../Include;../../../Src;../../../../LibOVRKernel/Src/Kernel;../../../../LibOVRKernel/Src + true + /d2Zi+ /we4263 /we4264 /we4265 /we4266 %(AdditionalOptions) + false + false + false + StreamingSIMDExtensions2 + true + + + Windows + true + true + true + LibOVRKernel.lib;kernel32.lib;ws2_32.lib;Dbghelp.lib;user32.lib;gdi32.lib;uuid.lib;dxgi.lib;d3d11.lib;d3dcompiler.lib + ../../../../LibOVRKernel/Lib/Windows/$(Platform)/$(Configuration)/VS2013 + OpenGL32.dll;DbgHelp.dll;gdi32.dll + + + Setupapi.lib + + + + + Level4 + + + MaxSpeed + true + true + _WIN64;NDEBUG;_LIB;%(PreprocessorDefinitions);OVR_DLL_BUILD + MultiThreaded + true + false + OldStyle + %(AdditionalIncludeDirectories);../../../Include;../../../Src;../../../../LibOVRKernel/Src/Kernel;../../../../LibOVRKernel/Src + false + /d2Zi+ /we4263 /we4264 /we4265 /we4266 %(AdditionalOptions) + false + false + false + NotSet + true + + + Windows + true + true + true + LibOVRKernel.lib;kernel32.lib;ws2_32.lib;Dbghelp.lib;user32.lib;gdi32.lib;uuid.lib;dxgi.lib;d3d11.lib;d3dcompiler.lib + ../../../../LibOVRKernel/Lib/Windows/$(Platform)/$(Configuration)/VS2013 + Default + OpenGL32.dll;DbgHelp.dll;gdi32.dll + + + Setupapi.lib + + + + + + \ No newline at end of file diff --git a/LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj.filters b/LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj.filters new file mode 100644 index 0000000..462add1 --- /dev/null +++ b/LibOVR/Projects/Windows/VS2013/LibOVRRT.vcxproj.filters @@ -0,0 +1,346 @@ + + + + + CAPI\D3D11 + + + CAPI\D3D11 + + + Util + + + Util + + + Util + + + CAPI + + + CAPI + + + CAPI + + + CAPI + + + Service + + + Service + + + CAPI\D3D9 + + + CAPI\D3D9 + + + CAPI\D3D9 + + + CAPI\GL + + + CAPI\GL + + + CAPI\GL + + + + + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + CAPI\D3D11 + + + Displays + + + Displays + + + Displays + + + Displays + + + Displays + + + CAPI + + + CAPI + + + CAPI + + + Vision\SensorFusion + + + + + + + + + + CAPI\D3D11 + + + CAPI\D3D11 + + + Util + + + Util + + + Util + + + Util + + + CAPI + + + CAPI + + + CAPI + + + CAPI + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Net + + + Service + + + Service + + + CAPI\D3D9 + + + CAPI\D3D9 + + + CAPI\GL + + + CAPI\GL + + + CAPI\GL + + + CAPI\GL + + + Include\Extras + + + Include + + + Include + + + Include + + + Include + + + CAPI\D3D11 + + + Displays + + + Displays + + + Displays + + + Displays + + + Displays + + + Displays + + + Tracing + + + Tracing + + + Include + + + CAPI + + + CAPI + + + CAPI + + + Vision\SensorFusion + + + + Include + + + + + CAPI\D3D11\Shaders + + + CAPI\D3D11\Shaders + + + CAPI\D3D11\Shaders + + + CAPI\D3D11\Shaders + + + CAPI\D3D11\Shaders + + + CAPI\D3D11\Shaders + + + CAPI\D3D11\Shaders + + + CAPI\D3D11\Shaders + + + CAPI\D3D11\Shaders + + + + + {9af78ed7-067d-4eee-8bb4-b4eea5c124cc} + + + {1f52ea3c-9a0f-4915-9bd1-9f1c6c61d641} + + + {2646ae0b-bdbb-461a-bcbd-e21f0c3c9174} + + + {3a4b709b-2a67-4813-bbd8-67c26a2668b2} + + + {87e2fa1e-af58-46e4-b14e-c6303c87bd60} + + + {3673fd50-1237-4030-94e3-49769e92f1a7} + + + {77508bdc-b6b7-4de5-9aaa-33f3383096f5} + + + {6a8b4b6e-1055-46a7-910b-3483dd52957c} + + + {63dbcc31-d1ff-437f-85b3-561d90871316} + + + {075f16d4-d2b8-4c52-a275-04af68d0ae99} + + + {fb431e21-7e66-4875-9a63-479895da9622} + + + {047f6ada-3b5c-4318-978a-895e1220d0b2} + + + {aab9811a-dd13-4e2c-a39e-671c7f1a61c4} + + + {4e4e6b98-f190-4ef8-bc07-74c56bef6a02} + + + {f2322208-cafd-4b3f-b7c1-f53cf93d7f99} + + + + + Resources + + + + + Tracing + + + Tracing + + + \ No newline at end of file diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp index 78e49e7..4b61ba5 100644 --- a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.cpp @@ -29,17 +29,8 @@ limitations under the License. #if defined (OVR_OS_WIN32) // TBD: Move to separate config file that handles back-ends. -#define OVR_D3D_VERSION 11 -#include "D3D1X/CAPI_D3D1X_DistortionRenderer.h" -#undef OVR_D3D_VERSION - -#define OVR_D3D_VERSION 10 -#include "D3D1X/CAPI_D3D1X_DistortionRenderer.h" -#undef OVR_D3D_VERSION - -#define OVR_D3D_VERSION 9 +#include "D3D1X/CAPI_D3D11_DistortionRenderer.h" #include "D3D9/CAPI_D3D9_DistortionRenderer.h" -#undef OVR_D3D_VERSION #endif @@ -47,6 +38,7 @@ limitations under the License. namespace OVR { namespace CAPI { + //------------------------------------------------------------------------------------- // ***** DistortionRenderer @@ -59,7 +51,7 @@ DistortionRenderer::CreateFunc DistortionRenderer::APICreateRegistry[ovrRenderAP 0, // Android_GLES #if defined (OVR_OS_WIN32) &D3D9::DistortionRenderer::Create, - &D3D10::DistortionRenderer::Create, + 0, // D3D10 &D3D11::DistortionRenderer::Create #else 0, @@ -68,6 +60,51 @@ DistortionRenderer::CreateFunc DistortionRenderer::APICreateRegistry[ovrRenderAP #endif }; +DistortionRenderer::DistortionRenderer() : + LastUsedOverdriveTextureIndex(-1), + LatencyTestActive(false), + LatencyTest2Active(false), + RenderAPI(ovrRenderAPI_None), + Timing(nullptr), + RenderState(nullptr), + GfxState(), + RegisteredPostDistortionCallback(NULL) +{ +#ifdef OVR_OS_WIN32 + timer = CreateWaitableTimer(NULL, TRUE, NULL); + OVR_ASSERT(timer != NULL); +#endif + + // set to invalid values to catch uninit case + PositionTimewarpDesc.FarClip = -1.0f; + PositionTimewarpDesc.NearClip = -1.0f; + PositionTimewarpDesc.HmdToEyeViewOffset[0] = Vector3f(MATH_FLOAT_MAXVALUE, MATH_FLOAT_MAXVALUE, MATH_FLOAT_MAXVALUE); + PositionTimewarpDesc.HmdToEyeViewOffset[1] = Vector3f(MATH_FLOAT_MAXVALUE, MATH_FLOAT_MAXVALUE, MATH_FLOAT_MAXVALUE); +} + +DistortionRenderer::~DistortionRenderer() +{ +} + +bool DistortionRenderer::Initialize(ovrRenderAPIConfig const* apiConfig, + Vision::TrackingStateReader* stateReader, + DistortionTimer* timing, + HMDRenderState const* renderState) +{ + if (!apiConfig || !renderState || !timing || !stateReader) + { + OVR_ASSERT(false); + return false; + } + + RenderAPI = apiConfig->Header.API; + SensorReader = stateReader; + Timing = timing; + RenderState = renderState; + + return initializeRenderer(apiConfig); +} + void DistortionRenderer::SetLatencyTestColor(unsigned char* color) { if(color) @@ -153,5 +190,5 @@ double DistortionRenderer::WaitTillTime(double absTime) return newTime - initialTime; } -}} // namespace OVR::CAPI +}} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h index 0c93387..6c5b934 100644 --- a/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/CAPI_DistortionRenderer.h @@ -28,12 +28,16 @@ limitations under the License. #define OVR_CAPI_DistortionRenderer_h #include "CAPI_HMDRenderState.h" -#include "CAPI_FrameTimeManager.h" +#include "CAPI_FrameLatencyTracker.h" +#include "CAPI_FrameTimeManager3.h" +#include "CAPI_DistortionTiming.h" +#include "../Vision/SensorFusion/Vision_SensorStateReader.h" typedef void (*PostDistortionCallback)(void* pRenderContext); namespace OVR { namespace CAPI { + //------------------------------------------------------------------------------------- // ***** CAPI::DistortionRenderer @@ -41,77 +45,62 @@ namespace OVR { namespace CAPI { // in platform-independent way. // Platform-specific renderer back ends for CAPI are derived from this class. -class DistortionRenderer : public RefCountBase +class DistortionRenderer : public RefCountBase { // Quiet assignment compiler warning. void operator = (const DistortionRenderer&) { } public: - - DistortionRenderer(ovrRenderAPIType api, ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState) : - LastUsedOverdriveTextureIndex(-1), - LatencyTestActive(false), - LatencyTest2Active(false), - RenderAPI(api), - HMD(hmd), - TimeManager(timeManager), - RState(renderState), - GfxState(), - RegisteredPostDistortionCallback(NULL) - { -#ifdef OVR_OS_WIN32 - timer = CreateWaitableTimer(NULL, TRUE, NULL); - OVR_ASSERT(timer != NULL); -#endif - } - virtual ~DistortionRenderer() - { - } - + DistortionRenderer(); + virtual ~DistortionRenderer(); // Configures the Renderer based on externally passed API settings. Must be // called before use. // Under D3D, apiConfig includes D3D Device pointer, back buffer and other // needed structures. - virtual bool Initialize(const ovrRenderAPIConfig* apiConfig) = 0; + bool Initialize(ovrRenderAPIConfig const * apiConfig, + Vision::TrackingStateReader* stateReader, + DistortionTimer* distortionTiming, + HMDRenderState const * renderState); // Submits one eye texture for rendering. This is in the separate method to // allow "submit as you render" scenarios on horizontal screens where one // eye can be scanned out before the other. virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture) = 0; + virtual void SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) = 0; // Finish the frame, optionally swapping buffers. // Many implementations may actually apply the distortion here. - virtual void EndFrame(bool swapBuffers) = 0; - + virtual void EndFrame(uint32_t frameIndex, bool swapBuffers) = 0; + void RegisterPostDistortionCallback(PostDistortionCallback postDistortionCallback) { RegisteredPostDistortionCallback = postDistortionCallback; } // Stores the current graphics pipeline state so it can be restored later. - void SaveGraphicsState() { if (GfxState && !(RState.DistortionCaps & ovrDistortionCap_NoRestore)) GfxState->Save(); } + void SaveGraphicsState() { if (GfxState && !(RenderState->DistortionCaps & ovrDistortionCap_NoRestore)) GfxState->Save(); } // Restores the saved graphics pipeline state. - void RestoreGraphicsState() { if (GfxState && !(RState.DistortionCaps & ovrDistortionCap_NoRestore)) GfxState->Restore(); } + void RestoreGraphicsState() { if (GfxState && !(RenderState->DistortionCaps & ovrDistortionCap_NoRestore)) GfxState->Restore(); } // *** Creation Factory logic - + ovrRenderAPIType GetRenderAPI() const { return RenderAPI; } // Creation function for this interface, registered for API. - typedef DistortionRenderer* (*CreateFunc)(ovrHmd hmd, - FrameTimeManager &timeManager, - const HMDRenderState& renderState); + typedef DistortionRenderer* (*CreateFunc)(); static CreateFunc APICreateRegistry[ovrRenderAPI_Count]; // Color is expected to be 3 byte RGB void SetLatencyTestColor(unsigned char* color); void SetLatencyTest2Color(unsigned char* color); - + + void SetPositionTimewarpDesc(const ovrPositionTimewarpDesc& posTimewarpDesc) { PositionTimewarpDesc = posTimewarpDesc; } + protected: + virtual bool initializeRenderer(const ovrRenderAPIConfig* apiConfig) = 0; + // Used for pixel luminance overdrive on DK2 displays // A copy of back buffer images will be ping ponged // TODO: figure out 0 dynamically based on DK2 latency? @@ -127,9 +116,7 @@ protected: { // doesn't make sense to use overdrive when vsync is disabled as we cannot guarantee // when the rendered frame will be displayed - return LastUsedOverdriveTextureIndex >= 0 && - !((RState.EnabledHmdCaps & ovrHmdCap_NoVSync) > 0) && - (RState.DistortionCaps & ovrDistortionCap_Chromatic); + return LastUsedOverdriveTextureIndex >= 0 && (RenderState->EnabledHmdCaps & ovrHmdCap_NoVSync) == 0; } void GetOverdriveScales(float& outRiseScale, float& outFallScale); @@ -152,15 +139,18 @@ protected: protected: bool IsValid; }; - - const ovrRenderAPIType RenderAPI; - const ovrHmd HMD; - FrameTimeManager& TimeManager; - const HMDRenderState& RState; + + ovrRenderAPIType RenderAPI; + Vision::TrackingStateReader* SensorReader; // For reading head pose for timewarp + DistortionTimer* Timing; + HMDRenderState const * RenderState; + Ptr GfxState; + ovrPositionTimewarpDesc PositionTimewarpDesc; PostDistortionCallback RegisteredPostDistortionCallback; }; + }} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_DistortionTiming.cpp b/LibOVR/Src/CAPI/CAPI_DistortionTiming.cpp new file mode 100644 index 0000000..6780ee6 --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_DistortionTiming.cpp @@ -0,0 +1,620 @@ +/************************************************************************************ + +Filename : CAPI_DistortionTiming.cpp +Content : Implements timing for the distortion renderer +Created : Dec 16, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_DistortionRenderer.h" + +#ifdef OVR_OS_WIN32 +#include "../Displays/OVR_Win32_Dxgi_Display.h" // Display driver timing info +#endif + +namespace OVR { namespace CAPI { + + +//----------------------------------------------------------------------------- +// Timing Constants + +// Number of milliseconds to pad on top of the timewarp draw call measured time +// in order to account for random variations in execution time due to preemption. +// If this is set too low the rendering will occasionally judder. +static const double kJITPreemptBufferTime = 0.004; // 4 milliseconds + +// When validating measured frame intervals, the following constants +// bound the acceptable measurements. +static const double kMinFrameInterval = 0.001; // 1 millisecond +static const double kMaxFrameInterval = 0.020; // 20 milliseconds + +// If the last known Vsync time is older than this age limit, +// then we should not use it for extrapolating to current time. +static const double kVsyncDataAgeLimit = 10.; // 10 seconds + +// When Vsync is off and we have no idea when the last frame started, +// assume this amount of time has elapsed since the frame started. +static const double kNoVsyncInfoFrameTime = 0.002; // 2 milliseconds + +#ifdef OVR_OS_WIN32 +// The latest driver provides a post-present vsync-to-scanout delay +// that is roughly zero. The actual measured latency should be +// about the same as this. +static const double kExpectedDriverLatency = 0.0002f; // 200 microseconds +#endif + +// Number from a hat for post-present latency when Vsync is off. +static const double kExpectedNoVSyncLatency = 0.003; // 3 milliseconds + +// Number of timewarp render time samples to collect +static const int kTimewarpRenderTimeSamples = 12; // 12 samples + +// Adding a fuzz time because the last known Vsync time is sometimes fuzzy and +// we don't want to predict behind a whole frame. This is most often used in +// app rendered and D3D9 renderers and on Win/Mac/Linux with OpenGL. +static const double kFuzzyVsyncBufferTime = kJITPreemptBufferTime; +// Currently set to the same fuzz factor used for JIT preemption because the +// same amount of error is accounted for by both constants. + +// Even when the Vsync timing data source is precise we should add some kind of +// buffer in to avoid floating point rounding or unexpected sync problems. +static const double kExactVsyncBufferTime = 0.001; // 1 millisecond + + +//----------------------------------------------------------------------------- +// Helper Functions + +// Based on LastKnownVsyncTime, predict time when the previous frame Vsync occurred. +// If it has no data it will still provide a reasonable estimate of last Vsync time. +static double calculateFrameStartTime(double now, + double lastKnownVsyncTime, + double lastKnownVsyncFuzzBuffer, + double frameInterval) +{ + // Calculate time since last known vsync + // Adding a fuzz time because the last known Vsync time is sometimes fuzzy and + // we don't want to predict behind a frame. + const double delta = now - lastKnownVsyncTime + lastKnownVsyncFuzzBuffer; + + // If last known vsync time was too long ago, + if (delta < 0. || + delta > kVsyncDataAgeLimit) + { + // We have no idea when Vsync will happen! + + // Assume we are some time into the frame when this is called. + return now - kNoVsyncInfoFrameTime; + } + + // Calculate number of Vsyncs since the last known Vsync time. + int numVsyncs = (int)(delta / frameInterval); + + // Calculate the last Vsync time. + double lastFrameVsyncTime = lastKnownVsyncTime + numVsyncs * frameInterval; + + // Sanity checking... + OVR_ASSERT(lastFrameVsyncTime - now > -0.16 && lastFrameVsyncTime - now < 0.30); + + return lastFrameVsyncTime; +} + + +//----------------------------------------------------------------------------- +// DistortionTiming : Initialization + +DistortionTimer::DistortionTimer() : + LastPresentTime(0), + LastKnownVsyncTime(0), + LastKnownVsyncFuzzBuffer(0), + AppFrameIndex(0), + DistortionRenderTimes(kTimewarpRenderTimeSamples), + EstimatedTimewarpRenderTime(0), + #ifdef OVR_OS_WIN32 + DeviceHandle(nullptr), + #endif + LatencyTester(nullptr), + RenderState(nullptr), + ScreenSwitchingDelay(0), + TimeManager(true), + LastTimewarpFrameEndTime(0), + AlreadyInitialized(false), + CurrentFrameTimewarpTiming(), + LastTimewarpIMUTime(0) +{ + Reset(); +} + +void DistortionTimer::Reset() +{ + // Clear state + LastKnownVsyncTime = 0.; + LastKnownVsyncFuzzBuffer = 0.; + LastPresentTime = 0.; + LastTimewarpFrameEndTime = 0.; + AppFrameIndex = 0; + + ClearAppTimingUpdater(); + + // Does not clear the distortion render times because this data is still good + //DistortionRenderTimes.Clear(); + //EstimatedTimewarpRenderTime = 0.; + //LatencyTester = nullptr; + //RenderState = nullptr; +} + +DistortionTimer::~DistortionTimer() +{ + RenderState = nullptr; + LatencyTester = nullptr; +} + +bool DistortionTimer::Initialize(HMDRenderState const * renderState, + FrameLatencyTracker const * lagTester) +{ + if (AlreadyInitialized) + { + OVR_ASSERT(renderState == RenderState && lagTester == LatencyTester); + return true; + } + + if (!renderState || !lagTester) + { + OVR_ASSERT(false); + return false; + } + + // Store members + RenderState = renderState; + LatencyTester = lagTester; + +#ifdef OVR_OS_WIN32 + // If in direct mode, + if (!RenderState->OurHMDInfo.InCompatibilityMode) + { + // Attempt to open the driver + DeviceHandle = CreateFile(L"\\\\.\\ovr_video", + GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, 0, nullptr); + } +#endif + + HmdRenderInfo::ShutterInfo const& shutter = RenderState->RenderInfo.Shutter; + + // Calculate the screen switching delay from shutter info. + ScreenSwitchingDelay = shutter.PixelSettleTime * 0.5 + shutter.PixelPersistence * 0.5; + + // Set default frame delta for the TimeManager. + TimeMan::Timing defaultTiming; + defaultTiming.FrameDelta = shutter.VsyncToNextVsync; + TimeManager.Initialize(defaultTiming); + + AlreadyInitialized = true; + return true; +} + + +//----------------------------------------------------------------------------- +// DistortionTiming : Helper Member Functions + +double DistortionTimer::getFrameInterval() const +{ + // Get the latest frame interval from the time manager. + double frameInterval = TimeManager.GetFrameDelta(); + + // If bad data is coming from the frame delta calculator, + if (frameInterval < kMinFrameInterval || + frameInterval > kMaxFrameInterval) + { + // Use the shutter value by default. + HmdRenderInfo::ShutterInfo const& shutter = RenderState->RenderInfo.Shutter; + frameInterval = shutter.VsyncToNextVsync; + } + + return frameInterval; +} + +double DistortionTimer::getScanoutDelay() +{ + // If Vsync is off, + if ((RenderState->EnabledHmdCaps & ovrHmdCap_NoVSync) != 0) + return kExpectedNoVSyncLatency; + + double vsyncToScanoutDelay = 0.; + + // If latency tester results are not available, + if (!LatencyTester || !LatencyTester->GetVsyncToScanout(vsyncToScanoutDelay)) + { + // Use a reasonable default post-present latency estimate. +#ifdef OVR_OS_WIN32 + vsyncToScanoutDelay = RenderState->OurHMDInfo.InCompatibilityMode ? + RenderState->RenderInfo.Shutter.VsyncToNextVsync : kExpectedDriverLatency; +#else + // FIXME: This is a heuristic value that may need to be better tuned later + // as the Mac/Linux render architecture solidifies. + vsyncToScanoutDelay = 0.0007; // Observed as 0.7 ms on Linux +#endif + } + + // Clamp the result be zero or positive. + if (vsyncToScanoutDelay < 0.) + vsyncToScanoutDelay = 0; + + return vsyncToScanoutDelay; +} + +#ifdef OVR_OS_WIN32 + +bool DistortionTimer::getDriverVsyncTime(double* previousKnownVsyncTime) +{ + // If using the driver, + if (!RenderState->OurHMDInfo.InCompatibilityMode) + { + ULONG riftId = (ULONG)RenderState->OurHMDInfo.ShimInfo.DeviceNumber; + UINT64 results[2]; + ULONG bytesReturned = 0; + + BOOL success = DeviceIoControl(DeviceHandle.Get(), IOCTL_RIFTMGR_GETCURRENTFRAMEINFO, &riftId, + sizeof(riftId), results, sizeof(results), &bytesReturned, nullptr); + + if (success) + { + // Calculate Vsync time in seconds based on QPC from display driver. + *previousKnownVsyncTime = results[1] * Timer::GetPerfFrequencyInverse(); + return true; + } + } + + return false; +} + +#endif // OVR_OS_WIN32 + + +//----------------------------------------------------------------------------- +// DistortionTiming : Timewarp Timing + +void DistortionTimer::AddDistortionTimeMeasurement(double distortionTimeSeconds) +{ + // Accumulate the new measurement. + DistortionRenderTimes.Add(distortionTimeSeconds); + + // If enough measurements are collected now, + if (!NeedDistortionTimeMeasurement()) + { + EstimatedTimewarpRenderTime = DistortionRenderTimes.GetMedian(); + } +} + +void DistortionTimer::submitDisplayFrame(double frameEndTime, double frameInterval) +{ + // Get the last display frame index + uint32_t frameIndex = TimeManager.GetLastDisplayFrameIndex(); + double lastTime = TimeManager.GetLastDisplayFrameTime(); + + // If a previous submit time was recorded, + if (lastTime > 0.) + { + // Calculate number of elapsed frames since last submit + int elapsed = (int)((frameEndTime - lastTime + frameInterval * 0.5) / frameInterval); + + frameIndex += elapsed; + } + + // Submit this display frame to the TimeManager + TimeManager.SubmitDisplayFrame(frameIndex, AppFrameIndex, frameEndTime); +} + +void DistortionTimer::updateLastKnownVsyncTime(double previousKnownVsyncTime) +{ + // Assume the data is exact. + LastKnownVsyncFuzzBuffer = kExactVsyncBufferTime; + + // If previous vsync time was not provided, + if (previousKnownVsyncTime <= 0.) + { +#ifdef OVR_OS_WIN32 + // If the display driver was not helpful, + if (!getDriverVsyncTime(&previousKnownVsyncTime)) +#endif + { + // Use the last fuzzy vsync time and frame index + // Add in a fuzz factor to prevent from predicting behind a whole frame! + previousKnownVsyncTime = LastPresentTime; + + // The data is pretty fuzzy so increase the buffer time. + LastKnownVsyncFuzzBuffer = kFuzzyVsyncBufferTime; + } + } + + // Update last known vsync time + LastKnownVsyncTime = previousKnownVsyncTime; +} + +double DistortionTimer::getJITTimewarpTime(double frameEndTime) +{ + // If there is no timing information available for the timewarp draw call, + if (EstimatedTimewarpRenderTime <= 0.) + { + // Disable JIT until we have some idea how long timewarp draw call takes. + return 0.; + } + + // Calculate Just-in-Time timewarp time + return frameEndTime - EstimatedTimewarpRenderTime - kJITPreemptBufferTime; +} + +// Rolls the previous known vsync time forward and then checks queue-ahead conditions +void DistortionTimer::CalculateTimewarpTiming(uint32_t frameIndex, double previousKnownVsyncTime) +{ + // Update LastKnownVsyncTime from previous known vsync time. + updateLastKnownVsyncTime(previousKnownVsyncTime); + + // Calculate the frame start time from available information. + const double frameInterval = getFrameInterval(); + const double frameStartTime = calculateFrameStartTime( + Timer::GetSeconds(), + LastKnownVsyncTime, + LastKnownVsyncFuzzBuffer, + frameInterval); + const double scanoutDelay = getScanoutDelay(); + + // If Vsync is off, + if ((RenderState->EnabledHmdCaps & ovrHmdCap_NoVSync) != 0) + { + // Always render for current frame start-end times. + CurrentFrameTimewarpTiming.ScanoutTime = frameStartTime + scanoutDelay; + CurrentFrameTimewarpTiming.JIT_TimewarpTime = 0.; // JIT disabled when Vsync is off + + // Reset the last timewarp frame end time when Vsync is turned off. + LastTimewarpFrameEndTime = 0.; + + // Set the reference point for the scanout delay to the frame start time when Vsync + // is off. + LatencyTesterPresentTime = frameStartTime; + } + else // Vsync is on: + { + // Calculate frame end time with Vsync on. + double frameEndTime = frameStartTime + frameInterval; + + // If JIT is turned off, + if (!(RenderState->DistortionCaps & ovrDistortionCap_TimewarpJitDelay)) + { +#ifdef OVR_SUPPORT_QUEUE_AHEAD + // Without JIT it can render ahead a frame. + // If Vsync is on and it targets the same end of frame time twice + // then the second timewarp render is queued ahead a frame, as two + // consecutive distortion renders cannot target the same frame twice. + + // If the last frame end time is about the same as this one, + if (fabs(LastTimewarpFrameEndTime - frameEndTime) < frameInterval * 0.25) + { + // Skip ahead to the next frame time. + frameEndTime += frameInterval; + } +#endif + + // Set JIT time to zero so that if JIT is turned off after this, + // that the JIT wait code will be skipped and timing will be right + // for this frame. + CurrentFrameTimewarpTiming.JIT_TimewarpTime = 0.; + } + else + { + // JIT timewarp is enabled, so provide a time estimate. + CurrentFrameTimewarpTiming.JIT_TimewarpTime = getJITTimewarpTime(frameEndTime); + } + + // Record the new frame end time. + LastTimewarpFrameEndTime = frameEndTime; + + // Scanout is based on frame end time when Vsync is on due to potential queue-ahead. + CurrentFrameTimewarpTiming.ScanoutTime = frameEndTime + scanoutDelay; + + // Update the TimeManager. + submitDisplayFrame(frameEndTime, frameInterval); + + // Set the reference point for the scanout delay to the frame end time when Vsync + // is on. This way our calculations will work out where we add scanout delay to + // get the actual scanout time from this reference point in the future. + LatencyTesterPresentTime = frameEndTime; + } + + // Update lockless app timing base values + LocklessAppTimingBase appTimingBase; + appTimingBase.FrameInterval = frameInterval; + appTimingBase.LastEndFrameIndex = frameIndex; + appTimingBase.LastStartFrameTime = frameStartTime; + appTimingBase.LastKnownVsyncTime = LastKnownVsyncTime; + appTimingBase.ScanoutDelay = scanoutDelay; + appTimingBase.ScreenSwitchingDelay = ScreenSwitchingDelay; + appTimingBase.VsyncFuzzFactor = LastKnownVsyncFuzzBuffer; + appTimingBase.IsValid = 1; + LocklessAppTimingBaseUpdater.SetState(appTimingBase); + + // Get eye timewarp times + // NOTE: Approximating scanline start-end interval with Vsync-Vsync interval here. + CalculateEyeTimewarpTimes( + CurrentFrameTimewarpTiming.ScanoutTime + ScreenSwitchingDelay, + frameInterval, + RenderState->RenderInfo.Shutter.Type, + CurrentFrameTimewarpTiming.EyeStartEndTimes[0], + CurrentFrameTimewarpTiming.EyeStartEndTimes[1]); +} + + +//----------------------------------------------------------------------------- +// AppDistortionTimer + +AppRenderTimer::AppRenderTimer() : + AppTimingBaseUpdater(nullptr) +{ +} + +AppRenderTimer::~AppRenderTimer() +{ +} + +void AppRenderTimer::GetAppTimingForIndex(AppTiming& result, bool vsyncOn, uint32_t frameIndex) +{ + /* + This code has to handle two big cases: + + Queue-Ahead: + + In this case the application is requesting poses for an upcoming frame, which is + very common. We need to predict ahead potentially beyond the next frame scanout + time to a following scanout time. + + Missed Frames: + + In this case the rendering + (1) game physics/other code ate too much CPU time and delayed the frame, or + (2) the render command queuing took too long, or + (3) took too long to complete on the GPU. + + Regarding (1): + Game code is pretty much out of the way in the case of Unity which has + two threads: A game code thread and a render thread. So in a real game + engine it's mainly due to too much render complexity not CPU game logic. + + Regarding (2): + Distortion is done after the game queues render commands, and so + the timewarp timing calculation can get pushed off into the next frame + and actually get timed correctly. + + So as a result judder is mainly due to GPU performance, as other other sources + of frame drops are mitigated. + */ + + if (!IsValid()) + { + OVR_ASSERT(false); + result.Clear(); + return; + } + + LocklessAppTimingBase base = AppTimingBaseUpdater->GetState(); + + // If no timing data is available, + if (!base.IsValid) + { + result.Clear(); + return; + } + + int32_t deltaIndex = (int32_t)(frameIndex - base.LastEndFrameIndex); + + // Calculate the end frame time. + // Vsync on: This is the targeted Vsync for the provided frame index. + // Vsync off: This is the middle of the frame requested by index. + double endFrameTime; + if (vsyncOn) + { + endFrameTime = base.LastStartFrameTime + base.FrameInterval * (deltaIndex + 1); + } + else + { + endFrameTime = base.LastStartFrameTime + base.FrameInterval * 0.5; + endFrameTime += base.FrameInterval * deltaIndex; + } + + // If targeted Vsync is now in the past, + const double now = Timer::GetSeconds(); + if (now + base.VsyncFuzzFactor > endFrameTime) + { + // Assume there is no queue-ahead, so we should target the very + // next upcoming Vsync + double frameStartTime = calculateFrameStartTime(now, base.LastKnownVsyncTime, + base.VsyncFuzzFactor, + base.FrameInterval); + if (vsyncOn) + { + // End frame time is just one frame ahead of the frame start + endFrameTime = frameStartTime + base.FrameInterval; + } + else + { + // End frame time is half way through the current frame + endFrameTime = frameStartTime + base.FrameInterval * 0.5; + } + } + + // Add Vsync-Scanout delay to get scanout time + double scanoutTime = endFrameTime + base.ScanoutDelay; + + // Construct app frame information object + result.FrameInterval = base.FrameInterval; + result.ScanoutStartTime = scanoutTime; + // NOTE: Approximating scanline start-end interval with Vsync-Vsync interval here. + result.VisibleMidpointTime = scanoutTime + base.ScreenSwitchingDelay + base.FrameInterval * 0.5; +} + + +//----------------------------------------------------------------------------- +// AppTimingHistory + +AppTimingHistory::AppTimingHistory() +{ + Clear(); +} + +AppTimingHistory::~AppTimingHistory() +{ +} + +void AppTimingHistory::Clear() +{ + LastWriteIndex = 0; + memset(History, 0, sizeof(History)); +} + +void AppTimingHistory::SetScanoutTimeForFrame(uint32_t frameIndex, double scanoutTime) +{ + if (++LastWriteIndex >= kFramesMax) + { + LastWriteIndex = 0; + } + + History[LastWriteIndex].FrameIndex = frameIndex; + History[LastWriteIndex].ScanoutTime = scanoutTime; +} + +double AppTimingHistory::LookupScanoutTime(uint32_t frameIndex) +{ + // Check last written entry first + if (History[LastWriteIndex].FrameIndex == frameIndex) + { + return History[LastWriteIndex].ScanoutTime; + } + + for (int i = 0; i < kFramesMax; ++i) + { + if (History[i].FrameIndex == frameIndex) + { + return History[i].ScanoutTime; + } + } + + return 0.; +} + + +}} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_DistortionTiming.h b/LibOVR/Src/CAPI/CAPI_DistortionTiming.h new file mode 100644 index 0000000..422daf3 --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_DistortionTiming.h @@ -0,0 +1,395 @@ +/************************************************************************************ + +Filename : CAPI_DistortionTiming.h +Content : Implements timing for the distortion renderer +Created : Dec 16, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_DistortionTiming_h +#define OVR_CAPI_DistortionTiming_h + +#include "CAPI_HMDRenderState.h" +#include "CAPI_FrameLatencyTracker.h" +#include "CAPI_FrameTimeManager3.h" +#include "CAPI_HMDRenderState.h" +#include +#include // ovrFrameTiming + +/* + ----------------------------- + Distortion Timing Terminology + ----------------------------- + + To fix on one set of terminology, a frame life-cycle is defined the following: + + (1) Get prediction time for app left/right eye rendering. + (2) App renders left/right eyes. + (3) Get prediction time for timewarp. + (4) SDK renders distortion/timewarp/chroma, perhaps measuring the time it takes. + (5) SDK presents frame and waits for end of frame to occur. + (6) End of frame occurs at Vsync. + (7) App goes back to step 1 and starts rendering the next frame. + (8) Scanout starts some time later for frame from step 6. + (9) Display panel emits photons some time later for scanout from step 8. + + "Frame interval" is the time interval between Vsyncs, whether or not Vsync is on. + "Frame end" time means the time at which the scanout starts at scanline 0. + "Visible midpoint" is when the middle scanline is half-visible to the user's eye. + + "Start of scanout" is when the hardware begins scanout. The pixels may not be fully + illuminated at this point. A hardware-specific rise time on the order of a millisecond + or two must be added to get photons time. + + All timing is done in units of seconds. + + We approximate the scanline start-end interval with the frame interval. +*/ + +namespace OVR { namespace CAPI { + + +//----------------------------------------------------------------------------- +// AppTiming +// +// This structure provides the measurements for the current app frame. +struct AppTiming +{ + // When half of the frame image data has been visible to the eye. + double VisibleMidpointTime; + + // When the Rift starts scanning out, not including ScreenSwitchingDelay. + double ScanoutStartTime; + + // Time between frames. + double FrameInterval; + + void Clear() + { + FrameInterval = 0.013; // A value that should not break anything. + ScanoutStartTime = 0.; // Predict to current time. + VisibleMidpointTime = 0.; // Predict to current time. + } +}; + + +//----------------------------------------------------------------------------- +// TimewarpTiming +// +// This structure provides the measurements for the current frame timewarp. +struct TimewarpTiming +{ + // Time at which scanout is predicted to start. + double ScanoutTime; + + // The time when Just-In-Time timewarp should be started. + // The app should busy/idle-wait until this time before doing timewarp. + double JIT_TimewarpTime; + + // Left and right eye start and end render times, respectively. + double EyeStartEndTimes[2][2]; +}; + + +//----------------------------------------------------------------------------- +// LocklessAppTimingBase +// +// Base timing info shared via lockless data structure. +// The AppDistortionTimer can use a copy of this data to derive an AppTiming +// object for a given frame index. +struct LocklessAppTimingBase +{ + // Is the data valid? + // 0 = Not valid. + uint32_t IsValid; + + // Frame index of the last EndFrame() call to update timing. + uint32_t LastEndFrameIndex; + + // Frame start time targetted by the last EndFrame() call to update timing. + double LastStartFrameTime; + + // Last known Vsync time from distortion timer. + double LastKnownVsyncTime; + + // Vsync fuzz factor used to measure uncertainty in timing. + double VsyncFuzzFactor; + + // Most updated measurement of the frame interval. + double FrameInterval; + + // Scanout delay measured by the builtin latency tester. + double ScanoutDelay; + + // Screen switching delay calculated in distortion timer. + double ScreenSwitchingDelay; +}; + + +//----------------------------------------------------------------------------- +// DistortionTimer +// +// This is a calculator for the app and timewarp/distortion timing. +class DistortionTimer +{ + typedef OVR::CAPI::FTM3::FrameTimeManagerCore TimeMan; + +public: + DistortionTimer(); + ~DistortionTimer(); + + // Returns false if distortion timing could not be initialized. + bool Initialize(HMDRenderState const* renderState, + FrameLatencyTracker const* lagTester); + void Reset(); + + //------------------------------------------------------------------------- + // Timewarp Timing + + // Calculate timing for current frame timewarp. + // Result can be retrieved via GetTimewarpTiming(). + void CalculateTimewarpTiming(uint32_t frameIndex, double previousKnownVsyncTime = 0.); + + // Called after CalculateTimewarpTiming() will retrieve the timewarp + // timing for this frame. + TimewarpTiming const* GetTimewarpTiming() + { + return &CurrentFrameTimewarpTiming; + } + + // Add a distortion draw call timing measurement. + void AddDistortionTimeMeasurement(double distortionTimeSeconds); + + // Returns true if more distortion timing measurements are needed. + bool NeedDistortionTimeMeasurement() const + { + // NOTE: Even when Vsync is off this measurement is still valid and useful. + return !DistortionRenderTimes.AtCapacity(); + } + + // Insert right after spin-wait for Present query to finish for the renderer. + void SetLastPresentTime() + { + // Update vsync time. This is the post-present time, which is expected to be + // after the Vsync has completed and our query event put in after the Present + // has indicated that it is signaled. However this is not reliable. + LastPresentTime = Timer::GetSeconds(); + } + + // Returns the time to use for the current frame for latency tester present time, + // which is not the same as the LastPresentTime. + double GetLatencyTesterPresentTime() const + { + return LatencyTesterPresentTime; + } + + // Set/get the Timewarp IMU time, which is the time at which the IMU was sampled. + void SetTimewarpIMUTime(double t) + { + LastTimewarpIMUTime = t; + } + + double GetTimewarpIMUTime() const + { + return LastTimewarpIMUTime; + } + +protected: + // Vsync/no-vsync versions split out for readability. + AppTiming getAppTimingWithVsync(); + AppTiming getAppTimingNoVsync(); + +protected: + // Last time that Present() was called for post-present latency measurement. + // Provided by SetLastPresentTime() cooperatively with the distortion renderer. + double LastPresentTime; + + // The time to use for the latency tester for present time, which is the reference + // time used for calculating present-scanout delay. + double LatencyTesterPresentTime; + + // Last known Vsync time, provided cooperatively by the distortion renderer + // via the GetTimewarpTiming() call or internal estimation. + double LastKnownVsyncTime; + + // Time in seconds that the Vsync measurement may be in error. + // It is assumed to be pretty tight for D3D11 and Display Driver data but for + // end frame -based timing we need to add some buffer to avoid misprediction. + double LastKnownVsyncFuzzBuffer; + + // The current app frame index, initially zero. + uint32_t AppFrameIndex; + // Updated in getAppTiming() + // Read in CalculateTimewarpTiming() + +protected: + // Calculator for the time it takes to render distortion. + mutable OVR::CAPI::FTM3::MedianCalculator DistortionRenderTimes; + + // Current estimate for timewarp render time. + double EstimatedTimewarpRenderTime; + +protected: +#ifdef OVR_OS_WIN32 + ScopedFileHANDLE DeviceHandle; + + // Attempt to use the display driver for getting a previous vsync + bool getDriverVsyncTime(double* previousKnownVsyncTime); +#endif + + // Get Vsync to next Vsync interval. + // NOTE: Technically the Vsync-Vsync frame interval is not the same as the scanout + // start to end interval because there is a back porch that implies some blanking time + double getFrameInterval() const; + + // Get Frame End to Scanout delay. Measured by DK2 Latency Tester if available. + // This works for Vsync on or off. + double getScanoutDelay(); + +protected: + // Update the TimeManager during timewarp calculation + void submitDisplayFrame(double frameEndTime, double frameInterval); + + // Update LastKnownVsyncTime. + // Pass zero if no Vsync timing information is available. + void updateLastKnownVsyncTime(double previousKnownVsyncTime = 0.); + + double getJITTimewarpTime(double frameEndTime); + +protected: + // DK2 Latency Tester object + FrameLatencyTracker const* LatencyTester; + + // Render state parameters from HMD + HMDRenderState const* RenderState; + + // Constant screen switching delay calculated from the shutter info. + // This is the time it takes between pixels starting to scan out and + // for the visible light to rise to half the expected brightness value. + // For OLEDs on the DK2 this is about 1 millisecond. + double ScreenSwitchingDelay; + + // Time Manager + TimeMan TimeManager; + + // The last predicted vsync time from the previous frame. + double LastTimewarpFrameEndTime; + + // Has the timing object already been initialized? + bool AlreadyInitialized; + +protected: + // Updated by CalculateTimewarpTiming(). + TimewarpTiming CurrentFrameTimewarpTiming; + + // Time when sensor was sampled for timewarp pose. + double LastTimewarpIMUTime; + +protected: + // Lockless data used by application for eye pose timing via the + // provided AppDistortionTimer class. + LocklessUpdater LocklessAppTimingBaseUpdater; + + void ClearAppTimingUpdater() + { + LocklessAppTimingBase cleared = LocklessAppTimingBase(); + LocklessAppTimingBaseUpdater.SetState(cleared); + } + +public: + LocklessUpdater* GetUpdater() + { + return &LocklessAppTimingBaseUpdater; + } +}; + + +// TODO: This header needs to be split up. + + +//----------------------------------------------------------------------------- +// AppRenderTimer +// +// This is an app-side calculator for predicted render times based on frame +// indices provided by the app. +class AppRenderTimer +{ +public: + AppRenderTimer(); + ~AppRenderTimer(); + + void SetUpdater(LocklessUpdater* updater) + { + AppTimingBaseUpdater = updater; + } + + bool IsValid() const + { + return AppTimingBaseUpdater != nullptr; + } + + // Returns true on success. + // Pass in 0 for frameIndex to use the next scanout time, + // or a non-zero incrementing number for each frame to support queue ahead. + void GetAppTimingForIndex(AppTiming& result, bool vsyncOn, uint32_t frameIndex = 0); + +protected: + LocklessUpdater* AppTimingBaseUpdater; +}; + + +//----------------------------------------------------------------------------- +// AppTimingHistory +// +// Keep a history of recent application render timing data, to keep a record of +// when frame indices are expected to scanout. This is used later to compare +// with when those frames scan out to self-test the timing code. +// +// This class is not thread-safe. +class AppTimingHistory +{ +public: + AppTimingHistory(); + ~AppTimingHistory(); + + void Clear(); + void SetScanoutTimeForFrame(uint32_t frameIndex, double scanoutTime); + + // Returns 0.0 if not found. + double LookupScanoutTime(uint32_t frameIndex); + +protected: + static const int kFramesMax = 8; + + struct Record + { + uint32_t FrameIndex; + double ScanoutTime; + }; + + int LastWriteIndex; + Record History[kFramesMax]; +}; + + +}} // namespace OVR::CAPI + +#endif // OVR_CAPI_DistortionTiming_h diff --git a/LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.cpp b/LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.cpp new file mode 100644 index 0000000..d0d3bcf --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.cpp @@ -0,0 +1,253 @@ +/************************************************************************************ + +Filename : CAPI_FrameLatencyTracker.cpp +Content : DK2 Latency Tester implementation +Created : Dec 12, 2013 +Authors : Volga Aksoy, Michael Antonov + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_FrameLatencyTracker.h" +#include "Kernel/OVR_Log.h" + +namespace OVR { namespace CAPI { + + +// Number of frame delta samples to include in the median calculation. +static const int kFrameDeltaSamples = 12; + + +//------------------------------------------------------------------------------------- +// ***** FrameLatencyTracker + +FrameLatencyTracker::FrameLatencyTracker() : + FrameDeltas(kFrameDeltaSamples) +{ + Reset(); +} + +void FrameLatencyTracker::Reset() +{ + TrackerEnabled = true; + WaitMode = SampleWait_Zeroes; + MatchCount = 0; + memset(History, 0, sizeof(History)); + FrameIndex = 0; + LatencyRecordTime = 0.0; + + OutputTimings.Clear(); + + FrameDeltas.Clear(); +} + +unsigned char FrameLatencyTracker::GetNextDrawColor() +{ + if (!TrackerEnabled || (WaitMode == SampleWait_Zeroes) || + (FrameIndex >= FramesTracked)) + { + return (unsigned char)Util::FrameTimeRecord::ReadbackIndexToColor(0); + } + + OVR_ASSERT(FrameIndex < FramesTracked); + return (unsigned char)Util::FrameTimeRecord::ReadbackIndexToColor(FrameIndex+1); +} + +void FrameLatencyTracker::SaveDrawColor(FrameLatencyData const & data) +{ + if (!TrackerEnabled || (WaitMode == SampleWait_Zeroes)) + return; + + if (FrameIndex < FramesTracked) + { + OVR_ASSERT(Util::FrameTimeRecord::ReadbackIndexToColor(FrameIndex + 1) == data.DrawColor); + + // FrameTimeRecord data + History[FrameIndex].ReadbackIndex = FrameIndex + 1; + History[FrameIndex].TimeSeconds = data.PresentTime; + + // FrameTimeRecordEx data + History[FrameIndex].MatchedRecord = false; + History[FrameIndex].FrameData = data; + + FrameIndex++; + } + else + { + // If the request was outstanding for too long, switch to zero mode to restart. + if (data.PresentTime > (History[FrameIndex-1].TimeSeconds + 0.15)) + { + if (MatchCount == 0) + { + OutputTimings.Clear(); + } + + WaitMode = SampleWait_Zeroes; + MatchCount = 0; + FrameIndex = 0; + } + } +} + +void FrameLatencyTracker::onRecordMatch(FrameTimeRecordEx& renderFrame, + Util::FrameTimeRecord const& scanoutFrame) +{ + MatchCount++; + + double deltaSeconds = scanoutFrame.TimeSeconds - renderFrame.TimeSeconds; + + // Reject latencies longer than 100 ms + // This can happen in transient situations like dragging the render window around, + // and since some critical systems depend on this latency data to provide steady-state + // statistics for prediction purposes these outliers should not dirty the data. + if (deltaSeconds < 0.1) + { + if (deltaSeconds < 0.) + { + deltaSeconds = 0.; + } + + FrameDeltas.Add(deltaSeconds); + } + + LatencyRecordTime = scanoutFrame.TimeSeconds; + OutputTimings.LatencyRender = scanoutFrame.TimeSeconds - renderFrame.FrameData.RenderIMUTime; + OutputTimings.LatencyTimewarp = (renderFrame.FrameData.TimewarpIMUTime == 0.0) ? 0.0 : + (scanoutFrame.TimeSeconds - renderFrame.FrameData.TimewarpIMUTime); + OutputTimings.ErrorRender = scanoutFrame.TimeSeconds - renderFrame.FrameData.RenderPredictedScanoutTime; + OutputTimings.ErrorTimewarp = scanoutFrame.TimeSeconds - renderFrame.FrameData.TimewarpPredictedScanoutTime; +} + +void FrameLatencyTracker::MatchRecord(Util::FrameTimeRecordSet const & r) +{ + if (!TrackerEnabled) + return; + + if (WaitMode == SampleWait_Zeroes) + { + // Do we have all zeros? + if (r.IsAllZeroes()) + { + OVR_ASSERT(FrameIndex == 0); + WaitMode = SampleWait_Match; + MatchCount = 0; + } + return; + } + + // We are in Match Mode. Wait until all colors are matched or timeout, + // at which point we go back to zeros. + + for (int i = 0; i < FrameIndex; i++) + { + int recordIndex = 0; + int consecutiveMatch = 0; + + OVR_ASSERT(History[i].ReadbackIndex != 0); + + if (r.FindReadbackIndex(&recordIndex, History[i].ReadbackIndex)) + { + // Advance forward to see that we have several more matches. + int ri = recordIndex + 1; + int j = i + 1; + + consecutiveMatch++; + + for (; (j < FrameIndex) && (ri < Util::FrameTimeRecordSet::RecordCount); j++, ri++) + { + if (r[ri].ReadbackIndex != History[j].ReadbackIndex) + break; + consecutiveMatch++; + } + + // Match at least 2 items in the row, to avoid accidentally matching color. + if (consecutiveMatch > 1) + { + // Record latency values for all but last samples. Keep last 2 samples + // for the future to simplify matching. + for (int q = 0; q < consecutiveMatch; q++) + { + const Util::FrameTimeRecord &scanoutFrame = r[recordIndex+q]; + FrameTimeRecordEx &renderFrame = History[i+q]; + + if (!renderFrame.MatchedRecord) + { + renderFrame.MatchedRecord = true; + + onRecordMatch(renderFrame, scanoutFrame); + } + } + + // Exit for. + break; + } + } + } // for ( i => FrameIndex ) + + // If we matched all frames, start over. + if (MatchCount == FramesTracked) + { + WaitMode = SampleWait_Zeroes; + MatchCount = 0; + FrameIndex = 0; + } +} + +bool FrameLatencyTracker::IsLatencyTimingAvailable() +{ + return ovr_GetTimeInSeconds() < (LatencyRecordTime + 2.0); +} + +void FrameLatencyTracker::GetLatencyTimings(OutputLatencyTimings& timings) +{ + if (!IsLatencyTimingAvailable()) + { + timings.Clear(); + return; + } + + timings = OutputTimings; + timings.LatencyPostPresent = FrameDeltas.GetMedian(); +} + +bool FrameLatencyTracker::GetVsyncToScanout(double& vsyncToScanoutTime) const +{ + if (FrameDeltas.GetCount() <= 3) + { + return false; + } + + double medianDelta = FrameDeltas.GetMedian(); + + // Sanity check the result + static const double SmallestAcceptedDelta = -0.0020; // -20 ms + static const double LargestAcceptedDelta = 0.060; // 60 ms + + if ((medianDelta < SmallestAcceptedDelta) || + (medianDelta > LargestAcceptedDelta)) + { + return false; + } + + vsyncToScanoutTime = medianDelta; + return true; +} + + +}} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.h b/LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.h new file mode 100644 index 0000000..842d7fb --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_FrameLatencyTracker.h @@ -0,0 +1,151 @@ +/************************************************************************************ + +Filename : CAPI_FrameLatencyTracker.h +Content : DK2 Latency Tester implementation +Created : Dec 12, 2013 +Authors : Volga Aksoy, Michael Antonov + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_FrameLatencyTracker_h +#define OVR_CAPI_FrameLatencyTracker_h + +#include +#include +#include +#include +#include "CAPI_FrameTimeManager3.h" + +namespace OVR { namespace CAPI { + + +//------------------------------------------------------------------------------------- +// ***** FrameLatencyData + +// This structure contains the timing data for each frame that is tracked by the +// latency tester. + +struct FrameLatencyData +{ + uint8_t DrawColor; // Red channel color value drawn for the latency tester quad for this frame + double PresentTime; // (seconds) Time at which Vsync/Present occurred + double RenderIMUTime; // (seconds) Time when hardware sensors were sampled for render pose + double TimewarpIMUTime; // (seconds) Time when hardware sensors were sampled for timewarp pose + + double TimewarpPredictedScanoutTime; // (seconds) Time at which we expected scanout to start at timewarp time + double RenderPredictedScanoutTime; // (seconds) Time at which we expected scanout to start at render time +}; + + +//------------------------------------------------------------------------------------- +// ***** OutputLatencyTimings + +// Latency timings returned to the application. + +struct OutputLatencyTimings +{ + double LatencyRender; // (seconds) Last time between render IMU sample and scanout + double LatencyTimewarp; // (seconds) Last time between timewarp IMU sample and scanout + double LatencyPostPresent; // (seconds) Average time between Vsync and scanout + double ErrorRender; // (seconds) Last error in render predicted scanout time + double ErrorTimewarp; // (seconds) Last error in timewarp predicted scanout time + + void Clear() + { + LatencyRender = 0.; + LatencyTimewarp = 0.; + LatencyPostPresent = 0.; + ErrorRender = 0.; + ErrorTimewarp = 0.; + } +}; + + +//------------------------------------------------------------------------------------- +// ***** FrameLatencyTracker + +// FrameLatencyTracker tracks frame Present to display Scan-out timing, as reported by +// the DK2 internal latency tester pixel read-back. The computed value is used in +// FrameTimeManager for prediction. View Render and TimeWarp to scan-out latencies are +// also reported for debugging. +// +// The class operates by generating color values from GetNextDrawColor() that must +// be rendered on the back end and then looking for matching values in FrameTimeRecordSet +// structure as reported by HW. + +class FrameLatencyTracker +{ +public: + enum { FramesTracked = Util::LT2_IncrementCount-1 }; + + FrameLatencyTracker(); + + // DrawColor == 0 is special in that it doesn't need saving of timestamp + unsigned char GetNextDrawColor(); + + void SaveDrawColor(FrameLatencyData const & data); + + void MatchRecord(Util::FrameTimeRecordSet const & r); + + bool IsLatencyTimingAvailable(); + void GetLatencyTimings(OutputLatencyTimings& timings); + + // Returns time between vsync and scanout in seconds as measured by DK2 latency tester. + // Returns false if measurements are unavailable. + bool GetVsyncToScanout(double& vsyncToScanoutTime) const; + + void Reset(); + +protected: + struct FrameTimeRecordEx : public Util::FrameTimeRecord + { + bool MatchedRecord; + FrameLatencyData FrameData; + }; + + void onRecordMatch(FrameTimeRecordEx& renderFrame, + Util::FrameTimeRecord const& scanoutFrame); + + // True if rendering read-back is enabled. + bool TrackerEnabled; + + enum SampleWaitType + { + SampleWait_Zeroes, // We are waiting for a record with all zeros. + SampleWait_Match // We are issuing & matching colors. + }; + + SampleWaitType WaitMode; + int MatchCount; + // Records of frame timings that we are trying to measure. + FrameTimeRecordEx History[FramesTracked]; + int FrameIndex; + // Median filter for (ScanoutTimeSeconds - PostPresent frame time) + mutable OVR::CAPI::FTM3::MedianCalculator FrameDeltas; + double LatencyRecordTime; + + // Latency reporting results + OutputLatencyTimings OutputTimings; +}; + + +}} // namespace OVR::CAPI + +#endif // OVR_CAPI_FrameLatencyTracker_h diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp b/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp deleted file mode 100644 index 8f44063..0000000 --- a/LibOVR/Src/CAPI/CAPI_FrameTimeManager.cpp +++ /dev/null @@ -1,946 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_FrameTimeManager.cpp -Content : Manage frame timing and pose prediction for rendering -Created : November 30, 2013 -Authors : Volga Aksoy, Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "CAPI_FrameTimeManager.h" - -#include "../Kernel/OVR_Log.h" - -namespace OVR { namespace CAPI { - - -//------------------------------------------------------------------------------------- -// ***** FrameLatencyTracker - - -FrameLatencyTracker::FrameLatencyTracker() -{ - Reset(); -} - - -void FrameLatencyTracker::Reset() -{ - TrackerEnabled = true; - WaitMode = SampleWait_Zeroes; - MatchCount = 0; - memset(FrameEndTimes, 0, sizeof(FrameEndTimes)); - FrameIndex = 0; - //FrameDeltas - RenderLatencySeconds = 0.0; - TimewarpLatencySeconds = 0.0; - LatencyRecordTime = 0.0; - - FrameDeltas.Clear(); -} - - -unsigned char FrameLatencyTracker::GetNextDrawColor() -{ - if (!TrackerEnabled || (WaitMode == SampleWait_Zeroes) || - (FrameIndex >= FramesTracked)) - { - return (unsigned char)Util::FrameTimeRecord::ReadbackIndexToColor(0); - } - - OVR_ASSERT(FrameIndex < FramesTracked); - return (unsigned char)Util::FrameTimeRecord::ReadbackIndexToColor(FrameIndex+1); -} - - -void FrameLatencyTracker::SaveDrawColor(unsigned char drawColor, double endFrameTime, - double renderIMUTime, double timewarpIMUTime ) -{ - if (!TrackerEnabled || (WaitMode == SampleWait_Zeroes)) - return; - - if (FrameIndex < FramesTracked) - { - OVR_ASSERT(Util::FrameTimeRecord::ReadbackIndexToColor(FrameIndex+1) == drawColor); - OVR_UNUSED(drawColor); - - // saves {color, endFrame time} - FrameEndTimes[FrameIndex].ReadbackIndex = FrameIndex + 1; - FrameEndTimes[FrameIndex].TimeSeconds = endFrameTime; - FrameEndTimes[FrameIndex].RenderIMUTimeSeconds = renderIMUTime; - FrameEndTimes[FrameIndex].TimewarpIMUTimeSeconds= timewarpIMUTime; - FrameEndTimes[FrameIndex].MatchedRecord = false; - FrameIndex++; - } - else - { - // If the request was outstanding for too long, switch to zero mode to restart. - if (endFrameTime > (FrameEndTimes[FrameIndex-1].TimeSeconds + 0.15)) - { - if (MatchCount == 0) - { - // If nothing was matched, we have no latency reading. - RenderLatencySeconds = 0.0; - TimewarpLatencySeconds = 0.0; - } - - WaitMode = SampleWait_Zeroes; - MatchCount = 0; - FrameIndex = 0; - } - } -} - - -void FrameLatencyTracker::MatchRecord(const Util::FrameTimeRecordSet &r) -{ - if (!TrackerEnabled) - return; - - if (WaitMode == SampleWait_Zeroes) - { - // Do we have all zeros? - if (r.IsAllZeroes()) - { - OVR_ASSERT(FrameIndex == 0); - WaitMode = SampleWait_Match; - MatchCount = 0; - } - return; - } - - // We are in Match Mode. Wait until all colors are matched or timeout, - // at which point we go back to zeros. - - for (int i = 0; i < FrameIndex; i++) - { - int recordIndex = 0; - int consecutiveMatch = 0; - - OVR_ASSERT(FrameEndTimes[i].ReadbackIndex != 0); - - if (r.FindReadbackIndex(&recordIndex, FrameEndTimes[i].ReadbackIndex)) - { - // Advance forward to see that we have several more matches. - int ri = recordIndex + 1; - int j = i + 1; - - consecutiveMatch++; - - for (; (j < FrameIndex) && (ri < Util::FrameTimeRecordSet::RecordCount); j++, ri++) - { - if (r[ri].ReadbackIndex != FrameEndTimes[j].ReadbackIndex) - break; - consecutiveMatch++; - } - - // Match at least 2 items in the row, to avoid accidentally matching color. - if (consecutiveMatch > 1) - { - // Record latency values for all but last samples. Keep last 2 samples - // for the future to simplify matching. - for (int q = 0; q < consecutiveMatch; q++) - { - const Util::FrameTimeRecord &scanoutFrame = r[recordIndex+q]; - FrameTimeRecordEx &renderFrame = FrameEndTimes[i+q]; - - if (!renderFrame.MatchedRecord) - { - double deltaSeconds = scanoutFrame.TimeSeconds - renderFrame.TimeSeconds; - if (deltaSeconds > 0.0) - { - FrameDeltas.AddTimeDelta(deltaSeconds); - - // FIRMWARE HACK: don't take new readings if they're 10ms higher than previous reading - // but only do that for 1 second, after that accept it regardless of the timing difference - double newRenderLatency = scanoutFrame.TimeSeconds - renderFrame.RenderIMUTimeSeconds; - if( newRenderLatency < RenderLatencySeconds + 0.01 || - scanoutFrame.TimeSeconds > LatencyRecordTime + 1.0) - { - LatencyRecordTime = scanoutFrame.TimeSeconds; - RenderLatencySeconds = scanoutFrame.TimeSeconds - renderFrame.RenderIMUTimeSeconds; - TimewarpLatencySeconds = (renderFrame.TimewarpIMUTimeSeconds == 0.0) ? 0.0 : - (scanoutFrame.TimeSeconds - renderFrame.TimewarpIMUTimeSeconds); - } - } - - renderFrame.MatchedRecord = true; - MatchCount++; - } - } - - // Exit for. - break; - } - } - } // for ( i => FrameIndex ) - - - // If we matched all frames, start over. - if (MatchCount == FramesTracked) - { - WaitMode = SampleWait_Zeroes; - MatchCount = 0; - FrameIndex = 0; - } -} - -bool FrameLatencyTracker::IsLatencyTimingAvailable() -{ - return ovr_GetTimeInSeconds() < (LatencyRecordTime + 2.0); -} - -void FrameLatencyTracker::GetLatencyTimings(float& latencyRender, float& latencyTimewarp, float& latencyPostPresent) -{ - if (!IsLatencyTimingAvailable()) - { - latencyRender = 0.0f; - latencyTimewarp = 0.0f; - latencyPostPresent = 0.0f; - } - else - { - latencyRender = (float)RenderLatencySeconds; - latencyTimewarp = (float)TimewarpLatencySeconds; - latencyPostPresent = (float)FrameDeltas.GetMedianTimeDelta(); - } -} - - -//------------------------------------------------------------------------------------- -// ***** FrameTimeManager - -FrameTimeManager::FrameTimeManager(bool vsyncEnabled) : - RenderInfo(), - FrameTimeDeltas(), - DistortionRenderTimes(), - ScreenLatencyTracker(), - VsyncEnabled(vsyncEnabled), - DynamicPrediction(true), - SdkRender(false), - //DirectToRift(false), Initialized below. - //VSyncToScanoutDelay(0.0), Initialized below. - //NoVSyncToScanoutDelay(0.0), Initialized below. - ScreenSwitchingDelay(0.0), - FrameTiming(), - LocklessTiming(), - RenderIMUTimeSeconds(0.0), - TimewarpIMUTimeSeconds(0.0) -{ - // If driver is in use, - DirectToRift = !Display::InCompatibilityMode(false); - if (DirectToRift) - { - // The latest driver provides a post-present vsync-to-scan-out delay - // that is roughly zero. The latency tester will provide real numbers - // but when it is unavailable for some reason, we should default to - // an expected value. - VSyncToScanoutDelay = 0.0001f; - } - else - { - // HACK: SyncToScanoutDelay observed close to 1 frame in video cards. - // Overwritten by dynamic latency measurement on DK2. - VSyncToScanoutDelay = 0.013f; - } - NoVSyncToScanoutDelay = 0.004f; -} - -void FrameTimeManager::Init(HmdRenderInfo& renderInfo) -{ - // Set up prediction distances. - // With-Vsync timings. - RenderInfo = renderInfo; - - ScreenSwitchingDelay = RenderInfo.Shutter.PixelSettleTime * 0.5f + - RenderInfo.Shutter.PixelPersistence * 0.5f; -} - -void FrameTimeManager::ResetFrameTiming(unsigned frameIndex, - bool dynamicPrediction, - bool sdkRender) -{ - DynamicPrediction = dynamicPrediction; - SdkRender = sdkRender; - - FrameTimeDeltas.Clear(); - DistortionRenderTimes.Clear(); - ScreenLatencyTracker.Reset(); - //Revisit dynamic pre-Timewarp delay adjustment logic - //TimewarpAdjuster.Reset(); - - FrameTiming.FrameIndex = frameIndex; - FrameTiming.NextFrameTime = 0.0; - FrameTiming.ThisFrameTime = 0.0; - FrameTiming.Inputs.FrameDelta = calcFrameDelta(); - // This one is particularly critical, and has been missed in the past because - // this init function wasn't called for app-rendered. - FrameTiming.Inputs.ScreenDelay = calcScreenDelay(); - FrameTiming.Inputs.TimewarpWaitDelta = 0.0f; - - LocklessTiming.SetState(FrameTiming); -} - - -double FrameTimeManager::calcFrameDelta() const -{ - // Timing difference between frame is tracked by FrameTimeDeltas, or - // is a hard-coded value of 1/FrameRate. - double frameDelta; - - if (!VsyncEnabled) - { - frameDelta = 0.0; - } - else if (FrameTimeDeltas.GetCount() > 3) - { - frameDelta = FrameTimeDeltas.GetMedianTimeDelta(); - if (frameDelta > (RenderInfo.Shutter.VsyncToNextVsync + 0.001)) - frameDelta = RenderInfo.Shutter.VsyncToNextVsync; - } - else - { - frameDelta = RenderInfo.Shutter.VsyncToNextVsync; - } - - return frameDelta; -} - - -double FrameTimeManager::calcScreenDelay() const -{ - double screenDelay = ScreenSwitchingDelay; - double measuredVSyncToScanout; - - // Use real-time DK2 latency tester HW for prediction if its is working. - // Do sanity check under 60 ms - if (!VsyncEnabled) - { - screenDelay += NoVSyncToScanoutDelay; - } - else if ( DynamicPrediction && - (ScreenLatencyTracker.FrameDeltas.GetCount() > 3) && - (measuredVSyncToScanout = ScreenLatencyTracker.FrameDeltas.GetMedianTimeDelta(), - (measuredVSyncToScanout > -0.0001) && (measuredVSyncToScanout < 0.06)) ) - { - screenDelay += measuredVSyncToScanout; - } - else - { - screenDelay += VSyncToScanoutDelay; - } - - return screenDelay; -} - -double FrameTimeManager::calcTimewarpWaitDelta() const -{ - // If timewarp timing hasn't been calculated, we should wait. - if (!VsyncEnabled) - return 0.0; - - if (SdkRender) - { - if (NeedDistortionTimeMeasurement()) - return 0.0; - return -(DistortionRenderTimes.GetMedianTimeDelta() + 0.0035); - - //Revisit dynamic pre-Timewarp delay adjustment logic - /*return -(DistortionRenderTimes.GetMedianTimeDelta() + 0.002 + - TimewarpAdjuster.GetDelayReduction());*/ - } - - // Just a hard-coded "high" value for game-drawn code. - // TBD: Just return 0 and let users calculate this themselves? - return -0.004; - - //Revisit dynamic pre-Timewarp delay adjustment logic - //return -(0.003 + TimewarpAdjuster.GetDelayReduction()); -} - -//Revisit dynamic pre-Timewarp delay adjustment logic -/* -void FrameTimeManager::updateTimewarpTiming() -{ - // If timewarp timing changes based on this sample, update it. - double newTimewarpWaitDelta = calcTimewarpWaitDelta(); - if (newTimewarpWaitDelta != FrameTiming.Inputs.TimewarpWaitDelta) - { - FrameTiming.Inputs.TimewarpWaitDelta = newTimewarpWaitDelta; - LocklessTiming.SetState(FrameTiming); - } -} -*/ - -void FrameTimeManager::Timing::InitTimingFromInputs(const FrameTimeManager::TimingInputs& inputs, - HmdShutterTypeEnum shutterType, - double thisFrameTime, unsigned int frameIndex) -{ - // ThisFrameTime comes from the end of last frame, unless it it changed. - double nextFrameBase; - double frameDelta = inputs.FrameDelta; - - FrameIndex = frameIndex; - - ThisFrameTime = thisFrameTime; - NextFrameTime = ThisFrameTime + frameDelta; - nextFrameBase = NextFrameTime + inputs.ScreenDelay; - MidpointTime = nextFrameBase + frameDelta * 0.5; - TimewarpPointTime = (inputs.TimewarpWaitDelta == 0.0) ? - 0.0 : (NextFrameTime + inputs.TimewarpWaitDelta); - - // Calculate absolute points in time when eye rendering or corresponding time-warp - // screen edges will become visible. - // This only matters with VSync. - switch(shutterType) - { - case HmdShutter_RollingTopToBottom: - EyeRenderTimes[0] = MidpointTime; - EyeRenderTimes[1] = MidpointTime; - TimeWarpStartEndTimes[0][0] = nextFrameBase; - TimeWarpStartEndTimes[0][1] = nextFrameBase + frameDelta; - TimeWarpStartEndTimes[1][0] = nextFrameBase; - TimeWarpStartEndTimes[1][1] = nextFrameBase + frameDelta; - break; - case HmdShutter_RollingLeftToRight: - EyeRenderTimes[0] = nextFrameBase + frameDelta * 0.25; - EyeRenderTimes[1] = nextFrameBase + frameDelta * 0.75; - - /* - // TBD: MA: It is probably better if mesh sets it up per-eye. - // Would apply if screen is 0 -> 1 for each eye mesh - TimeWarpStartEndTimes[0][0] = nextFrameBase; - TimeWarpStartEndTimes[0][1] = MidpointTime; - TimeWarpStartEndTimes[1][0] = MidpointTime; - TimeWarpStartEndTimes[1][1] = nextFrameBase + frameDelta; - */ - - // Mesh is set up to vary from Edge of scree 0 -> 1 across both eyes - TimeWarpStartEndTimes[0][0] = nextFrameBase; - TimeWarpStartEndTimes[0][1] = nextFrameBase + frameDelta; - TimeWarpStartEndTimes[1][0] = nextFrameBase; - TimeWarpStartEndTimes[1][1] = nextFrameBase + frameDelta; - - break; - case HmdShutter_RollingRightToLeft: - - EyeRenderTimes[0] = nextFrameBase + frameDelta * 0.75; - EyeRenderTimes[1] = nextFrameBase + frameDelta * 0.25; - - // This is *Correct* with Tom's distortion mesh organization. - TimeWarpStartEndTimes[0][0] = nextFrameBase ; - TimeWarpStartEndTimes[0][1] = nextFrameBase + frameDelta; - TimeWarpStartEndTimes[1][0] = nextFrameBase ; - TimeWarpStartEndTimes[1][1] = nextFrameBase + frameDelta; - break; - case HmdShutter_Global: - // TBD - EyeRenderTimes[0] = MidpointTime; - EyeRenderTimes[1] = MidpointTime; - TimeWarpStartEndTimes[0][0] = MidpointTime; - TimeWarpStartEndTimes[0][1] = MidpointTime; - TimeWarpStartEndTimes[1][0] = MidpointTime; - TimeWarpStartEndTimes[1][1] = MidpointTime; - break; - default: - break; - } -} - - -double FrameTimeManager::BeginFrame(unsigned frameIndex) -{ - RenderIMUTimeSeconds = 0.0; - TimewarpIMUTimeSeconds = 0.0; - - // TPH - putting an assert so this doesn't remain a hidden problem. - OVR_ASSERT(FrameTiming.Inputs.ScreenDelay != 0); - - // ThisFrameTime comes from the end of last frame, unless it it changed. - double thisFrameTime = (FrameTiming.NextFrameTime != 0.0) ? - FrameTiming.NextFrameTime : ovr_GetTimeInSeconds(); - - // We are starting to process a new frame... - FrameTiming.InitTimingFromInputs(FrameTiming.Inputs, RenderInfo.Shutter.Type, - thisFrameTime, frameIndex); - - return FrameTiming.ThisFrameTime; -} - - -void FrameTimeManager::EndFrame() -{ - // Record timing since last frame; must be called after Present & sync. - FrameTiming.NextFrameTime = ovr_GetTimeInSeconds(); - if (FrameTiming.ThisFrameTime > 0.0) - { - //Revisit dynamic pre-Timewarp delay adjustment logic - /* - double actualFrameDelta = FrameTiming.NextFrameTime - FrameTiming.ThisFrameTime; - - if (VsyncEnabled) - TimewarpAdjuster.UpdateTimewarpWaitIfSkippedFrames(this, actualFrameDelta, - FrameTiming.NextFrameTime); - - FrameTimeDeltas.AddTimeDelta(actualFrameDelta); - */ - FrameTimeDeltas.AddTimeDelta(FrameTiming.NextFrameTime - FrameTiming.ThisFrameTime); - FrameTiming.Inputs.FrameDelta = calcFrameDelta(); - } - - // Write to Lock-less - LocklessTiming.SetState(FrameTiming); -} - -// Thread-safe function to query timing for a future frame - -FrameTimeManager::Timing FrameTimeManager::GetFrameTiming(unsigned frameIndex) -{ - Timing frameTiming = LocklessTiming.GetState(); - - if (frameTiming.ThisFrameTime == 0.0) - { - // If timing hasn't been initialized, starting based on "now" is the best guess. - frameTiming.InitTimingFromInputs(frameTiming.Inputs, RenderInfo.Shutter.Type, - ovr_GetTimeInSeconds(), frameIndex); - } - - else if (frameIndex > frameTiming.FrameIndex) - { - unsigned frameDelta = frameIndex - frameTiming.FrameIndex; - double thisFrameTime = frameTiming.NextFrameTime + - double(frameDelta-1) * frameTiming.Inputs.FrameDelta; - // Don't run away too far into the future beyond rendering. - OVR_DEBUG_LOG_COND(frameDelta >= 6, ("GetFrameTiming is 6 or more frames in future beyond rendering!")); - - frameTiming.InitTimingFromInputs(frameTiming.Inputs, RenderInfo.Shutter.Type, - thisFrameTime, frameIndex); - } - - return frameTiming; -} - - -double FrameTimeManager::GetEyePredictionTime(ovrEyeType eye, unsigned int frameIndex) -{ - if (VsyncEnabled) - { - FrameTimeManager::Timing frameTiming = GetFrameTiming(frameIndex); - - // Special case: ovrEye_Count predicts to midpoint - return (eye == ovrEye_Count) ? frameTiming.MidpointTime : frameTiming.EyeRenderTimes[eye]; - } - - // No VSync: Best guess for the near future - return ovr_GetTimeInSeconds() + ScreenSwitchingDelay + NoVSyncToScanoutDelay; -} - -ovrTrackingState FrameTimeManager::GetEyePredictionTracking(ovrHmd hmd, ovrEyeType eye, unsigned int frameIndex) -{ - double eyeRenderTime = GetEyePredictionTime(eye, frameIndex); - ovrTrackingState eyeState = ovrHmd_GetTrackingState(hmd, eyeRenderTime); - - // Record view pose sampling time for Latency reporting. - if (RenderIMUTimeSeconds == 0.0) - { - // TODO: Figure out why this are not as accurate as ovr_GetTimeInSeconds() - //RenderIMUTimeSeconds = eyeState.RawSensorData.TimeInSeconds; - RenderIMUTimeSeconds = ovr_GetTimeInSeconds(); - } - - return eyeState; -} - -Posef FrameTimeManager::GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye) -{ - double eyeRenderTime = GetEyePredictionTime(eye, 0); - ovrTrackingState eyeState = ovrHmd_GetTrackingState(hmd, eyeRenderTime); - - // Record view pose sampling time for Latency reporting. - if (RenderIMUTimeSeconds == 0.0) - { - // TODO: Figure out why this are not as accurate as ovr_GetTimeInSeconds() - //RenderIMUTimeSeconds = eyeState.RawSensorData.TimeInSeconds; - RenderIMUTimeSeconds = ovr_GetTimeInSeconds(); - } - - return eyeState.HeadPose.ThePose; -} - -void FrameTimeManager::GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2]) -{ - if (VsyncEnabled) - { - timewarpStartEnd[0] = FrameTiming.TimeWarpStartEndTimes[eye][0]; - timewarpStartEnd[1] = FrameTiming.TimeWarpStartEndTimes[eye][1]; - return; - } - - // Free-running, so this will be displayed immediately. - // Unfortunately we have no idea which bit of the screen is actually going to be displayed. - // TODO: guess which bit of the screen is being displayed! - // (e.g. use DONOTWAIT on present and see when the return isn't WASSTILLWAITING?) - - // We have no idea where scan-out is currently, so we can't usefully warp the screen spatially. - timewarpStartEnd[0] = ovr_GetTimeInSeconds() + ScreenSwitchingDelay + NoVSyncToScanoutDelay; - timewarpStartEnd[1] = timewarpStartEnd[0]; -} - - -void FrameTimeManager::GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eyeId, - ovrPosef renderPose, ovrMatrix4f twmOut[2], - double debugTimingOffsetInSeconds) -{ - if (!hmd) - { - return; - } - - double timewarpStartEnd[2] = { 0.0, 0.0 }; - GetTimewarpPredictions(eyeId, timewarpStartEnd); - - //TPH, to vary timing, to allow developers to debug, to shunt the predicted time forward - //and back, and see if the SDK is truly delivering the correct time. Also to allow - //illustration of the detrimental effects when this is not done right. - timewarpStartEnd[0] += debugTimingOffsetInSeconds; - timewarpStartEnd[1] += debugTimingOffsetInSeconds; - - - //HMDState* p = (HMDState*)hmd; - ovrTrackingState startState = ovrHmd_GetTrackingState(hmd, timewarpStartEnd[0]); - ovrTrackingState endState = ovrHmd_GetTrackingState(hmd, timewarpStartEnd[1]); - - if (TimewarpIMUTimeSeconds == 0.0) - { - // TODO: Figure out why this are not as accurate as ovr_GetTimeInSeconds() - //TimewarpIMUTimeSeconds = startState.RawSensorData.TimeInSeconds; - TimewarpIMUTimeSeconds = ovr_GetTimeInSeconds(); - } - - Quatf quatFromStart = startState.HeadPose.ThePose.Orientation; - Quatf quatFromEnd = endState.HeadPose.ThePose.Orientation; - Quatf quatFromEye = renderPose.Orientation; //EyeRenderPoses[eyeId].Orientation; - quatFromEye.Invert(); // because we need the view matrix, not the camera matrix - - Quatf timewarpStartQuat = quatFromEye * quatFromStart; - Quatf timewarpEndQuat = quatFromEye * quatFromEnd; - - Matrix4f timewarpStart(timewarpStartQuat); - Matrix4f timewarpEnd(timewarpEndQuat); - - - // The real-world orientations have: X=right, Y=up, Z=backwards. - // The vectors inside the mesh are in NDC to keep the shader simple: X=right, Y=down, Z=forwards. - // So we need to perform a similarity transform on this delta matrix. - // The verbose code would look like this: - /* - Matrix4f matBasisChange; - matBasisChange.SetIdentity(); - matBasisChange.M[0][0] = 1.0f; - matBasisChange.M[1][1] = -1.0f; - matBasisChange.M[2][2] = -1.0f; - Matrix4f matBasisChangeInv = matBasisChange.Inverted(); - matRenderFromNow = matBasisChangeInv * matRenderFromNow * matBasisChange; - */ - // ...but of course all the above is a constant transform and much more easily done. - // We flip the signs of the Y&Z row, then flip the signs of the Y&Z column, - // and of course most of the flips cancel: - // +++ +-- +-- - // +++ -> flip Y&Z columns -> +-- -> flip Y&Z rows -> -++ - // +++ +-- -++ - timewarpStart.M[0][1] = -timewarpStart.M[0][1]; - timewarpStart.M[0][2] = -timewarpStart.M[0][2]; - timewarpStart.M[1][0] = -timewarpStart.M[1][0]; - timewarpStart.M[2][0] = -timewarpStart.M[2][0]; - - timewarpEnd .M[0][1] = -timewarpEnd .M[0][1]; - timewarpEnd .M[0][2] = -timewarpEnd .M[0][2]; - timewarpEnd .M[1][0] = -timewarpEnd .M[1][0]; - timewarpEnd .M[2][0] = -timewarpEnd .M[2][0]; - - twmOut[0] = timewarpStart; - twmOut[1] = timewarpEnd; -} - - -// Used by renderer to determine if it should time distortion rendering. -bool FrameTimeManager::NeedDistortionTimeMeasurement() const -{ - if (!VsyncEnabled) - return false; - return DistortionRenderTimes.GetCount() < DistortionRenderTimes.Capacity; -} - - -void FrameTimeManager::AddDistortionTimeMeasurement(double distortionTimeSeconds) -{ - DistortionRenderTimes.AddTimeDelta(distortionTimeSeconds); - - //Revisit dynamic pre-Timewarp delay adjustment logic - //updateTimewarpTiming(); - - // If timewarp timing changes based on this sample, update it. - double newTimewarpWaitDelta = calcTimewarpWaitDelta(); - if (newTimewarpWaitDelta != FrameTiming.Inputs.TimewarpWaitDelta) - { - FrameTiming.Inputs.TimewarpWaitDelta = newTimewarpWaitDelta; - LocklessTiming.SetState(FrameTiming); - } -} - - -void FrameTimeManager::UpdateFrameLatencyTrackingAfterEndFrame( - unsigned char frameLatencyTestColor[3], - const Util::FrameTimeRecordSet& rs) -{ - // FrameTiming.NextFrameTime in this context (after EndFrame) is the end frame time. - ScreenLatencyTracker.SaveDrawColor(frameLatencyTestColor[0], - FrameTiming.NextFrameTime, - RenderIMUTimeSeconds, - TimewarpIMUTimeSeconds); - - ScreenLatencyTracker.MatchRecord(rs); - - // If screen delay changed, update timing. - double newScreenDelay = calcScreenDelay(); - if (newScreenDelay != FrameTiming.Inputs.ScreenDelay) - { - FrameTiming.Inputs.ScreenDelay = newScreenDelay; - LocklessTiming.SetState(FrameTiming); - } -} - - -//----------------------------------------------------------------------------------- -//Revisit dynamic pre-Timewarp delay adjustment logic -/* -void FrameTimeManager::TimewarpDelayAdjuster::Reset() -{ - State = State_WaitingToReduceLevel; - DelayLevel = 0; - InitialFrameCounter = 0; - TimewarpDelayReductionSeconds = 0.0; - DelayLevelFinishTime = 0.0; - - memset(WaitTimeIndexForLevel, 0, sizeof(WaitTimeIndexForLevel)); - // If we are at level 0, waits are infinite. - WaitTimeIndexForLevel[0] = MaxTimeIndex; -} - - -void FrameTimeManager::TimewarpDelayAdjuster:: - UpdateTimewarpWaitIfSkippedFrames(FrameTimeManager* manager, - double measuredFrameDelta, double nextFrameTime) -{ - // Times in seconds - const static double delayTimingTiers[7] = { 1.0, 5.0, 15.0, 30.0, 60.0, 120.0, 1000000.0 }; - - const double currentFrameDelta = manager->FrameTiming.Inputs.FrameDelta; - - - // Once we detected frame spike, we skip several frames before testing again. - if (InitialFrameCounter > 0) - { - InitialFrameCounter --; - return; - } - - // Skipped frame would usually take 2x longer then regular frame - if (measuredFrameDelta > currentFrameDelta * 1.8) - { - if (State == State_WaitingToReduceLevel) - { - // If we got here, escalate the level again. - if (DelayLevel < MaxDelayLevel) - { - DelayLevel++; - InitialFrameCounter = 3; - } - } - - else if (State == State_VerifyingAfterReduce) - { - // So we went down to this level and tried to wait to see if there was - // as skipped frame and there is -> go back up a level and incrment its timing tier - if (DelayLevel < MaxDelayLevel) - { - DelayLevel++; - State = State_WaitingToReduceLevel; - - // For higher level delays reductions, i.e. more then half a frame, - // we don't go into the infinite wait tier. - int maxTimingTier = MaxTimeIndex; - if (DelayLevel > MaxInfiniteTimingLevel) - maxTimingTier--; - - if (WaitTimeIndexForLevel[DelayLevel] < maxTimingTier ) - WaitTimeIndexForLevel[DelayLevel]++; - } - } - - DelayLevelFinishTime = nextFrameTime + - delayTimingTiers[WaitTimeIndexForLevel[DelayLevel]]; - TimewarpDelayReductionSeconds = currentFrameDelta * 0.125 * DelayLevel; - manager->updateTimewarpTiming(); - - } - - else if (nextFrameTime > DelayLevelFinishTime) - { - if (State == State_WaitingToReduceLevel) - { - if (DelayLevel > 0) - { - DelayLevel--; - State = State_VerifyingAfterReduce; - // Always use 1 sec to see if "down sampling mode" caused problems - DelayLevelFinishTime = nextFrameTime + 1.0f; - } - } - else if (State == State_VerifyingAfterReduce) - { - // Prior display level successfully reduced, - // try to see we we could go down further after wait. - WaitTimeIndexForLevel[DelayLevel+1] = 0; - State = State_WaitingToReduceLevel; - DelayLevelFinishTime = nextFrameTime + - delayTimingTiers[WaitTimeIndexForLevel[DelayLevel]]; - } - - // TBD: Update TimeWarpTiming - TimewarpDelayReductionSeconds = currentFrameDelta * 0.125 * DelayLevel; - manager->updateTimewarpTiming(); - } - - - //static int oldDelayLevel = 0; - - //if (oldDelayLevel != DelayLevel) - //{ - //OVR_DEBUG_LOG(("DelayLevel:%d tReduction = %0.5f ", DelayLevel, TimewarpDelayReductionSeconds)); - //oldDelayLevel = DelayLevel; - //} - } - */ - -//----------------------------------------------------------------------------------- -// ***** TimeDeltaCollector - -void TimeDeltaCollector::AddTimeDelta(double timeSeconds) -{ - // avoid adding invalid timing values - if(timeSeconds < 0.0f) - return; - - if (Count == Capacity) - { - for(int i=0; i< Count-1; i++) - TimeBufferSeconds[i] = TimeBufferSeconds[i+1]; - Count--; - } - TimeBufferSeconds[Count++] = timeSeconds; - - ReCalcMedian = true; -} - -// KevinJ: Better median function -double CalculateListMedianRecursive(const double inputList[TimeDeltaCollector::Capacity], int inputListLength, int lessThanSum, int greaterThanSum) -{ - double lessThanMedian[TimeDeltaCollector::Capacity], greaterThanMedian[TimeDeltaCollector::Capacity]; - int lessThanMedianListLength = 0, greaterThanMedianListLength = 0; - double median = inputList[0]; - int i; - for (i = 1; i < inputListLength; i++) - { - // If same value, spread among lists evenly - if (inputList[i] < median || ((i & 1) == 0 && inputList[i] == median)) - lessThanMedian[lessThanMedianListLength++] = inputList[i]; - else - greaterThanMedian[greaterThanMedianListLength++] = inputList[i]; - } - if (lessThanMedianListLength + lessThanSum == greaterThanMedianListLength + greaterThanSum + 1 || - lessThanMedianListLength + lessThanSum == greaterThanMedianListLength + greaterThanSum - 1) - return median; - - if (lessThanMedianListLength + lessThanSum < greaterThanMedianListLength + greaterThanSum) - { - lessThanMedian[lessThanMedianListLength++] = median; - return CalculateListMedianRecursive(greaterThanMedian, greaterThanMedianListLength, lessThanMedianListLength + lessThanSum, greaterThanSum); - } - else - { - greaterThanMedian[greaterThanMedianListLength++] = median; - return CalculateListMedianRecursive(lessThanMedian, lessThanMedianListLength, lessThanSum, greaterThanMedianListLength + greaterThanSum); - } -} -// KevinJ: Excludes Firmware hack -double TimeDeltaCollector::GetMedianTimeDeltaNoFirmwareHack() const -{ - if (ReCalcMedian) - { - ReCalcMedian = false; - Median = CalculateListMedianRecursive(TimeBufferSeconds, Count, 0, 0); - } - return Median; -} -double TimeDeltaCollector::GetMedianTimeDelta() const -{ - if(ReCalcMedian) - { - double SortedList[Capacity]; - bool used[Capacity]; - - memset(used, 0, sizeof(used)); - SortedList[0] = 0.0; // In case Count was 0... - - // Probably the slowest way to find median... - for (int i=0; i= NextFrameTime, since that's the time we expect next - // vsync to succeed. - double ThisFrameTime; - double TimewarpPointTime; - double NextFrameTime; - double MidpointTime; - double EyeRenderTimes[2]; - double TimeWarpStartEndTimes[2][2]; - - Timing() - { - memset(this, 0, sizeof(Timing)); - } - - void InitTimingFromInputs(const TimingInputs& inputs, HmdShutterTypeEnum shutterType, - double thisFrameTime, unsigned int frameIndex); - }; - - - // Called on startup to provided data on HMD timing. - void Init(HmdRenderInfo& renderInfo); - - // Called with each new ConfigureRendering. - void ResetFrameTiming(unsigned frameIndex, - bool dynamicPrediction, bool sdkRender); - - void SetVsync(bool enabled) { VsyncEnabled = enabled; } - - // BeginFrame returns time of the call - // TBD: Should this be a predicted time value instead ? - double BeginFrame(unsigned frameIndex); - void EndFrame(); - - // Thread-safe function to query timing for a future frame - Timing GetFrameTiming(unsigned frameIndex); - - // if eye == ovrEye_Count, timing is for MidpointTime as opposed to any specific eye - double GetEyePredictionTime(ovrEyeType eye, unsigned int frameIndex); - ovrTrackingState GetEyePredictionTracking(ovrHmd hmd, ovrEyeType eye, unsigned int frameIndex); - Posef GetEyePredictionPose(ovrHmd hmd, ovrEyeType eye); - - void GetTimewarpPredictions(ovrEyeType eye, double timewarpStartEnd[2]); - void GetTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2],double debugTimingOffsetInSeconds = 0.0); - - // Used by renderer to determine if it should time distortion rendering. - bool NeedDistortionTimeMeasurement() const; - void AddDistortionTimeMeasurement(double distortionTimeSeconds); - - - // DK2 Latency test interface - - // Get next draw color for DK2 latency tester (3-byte RGB) - void GetFrameLatencyTestDrawColor(unsigned char outColor[3]) - { - outColor[0] = ScreenLatencyTracker.GetNextDrawColor(); - outColor[1] = ScreenLatencyTracker.IsLatencyTimingAvailable() ? 255 : 0; - outColor[2] = ScreenLatencyTracker.IsLatencyTimingAvailable() ? 0 : 255; - } - - // Must be called after EndFrame() to update latency tester timings. - // Must pass color reported by NextFrameColor for this frame. - void UpdateFrameLatencyTrackingAfterEndFrame(unsigned char frameLatencyTestColor[3], - const Util::FrameTimeRecordSet& rs); - - void GetLatencyTimings(float& latencyRender, float& latencyTimewarp, float& latencyPostPresent) - { - return ScreenLatencyTracker.GetLatencyTimings(latencyRender, latencyTimewarp, latencyPostPresent); - } - - const Timing& GetFrameTiming() const { return FrameTiming; } - -private: - double calcFrameDelta() const; - double calcScreenDelay() const; - double calcTimewarpWaitDelta() const; - - //Revisit dynamic pre-Timewarp delay adjustment logic - /* - void updateTimewarpTiming(); - - - - // TimewarpDelayAdjuster implements a simple state machine that reduces the amount - // of time-warp waiting based on skipped frames. - struct TimewarpDelayAdjuster - { - enum StateInLevel - { - // We are ok at this level, and will be waiting for some time before trying to reduce. - State_WaitingToReduceLevel, - // After decrementing a level, we are verifying that this won't cause skipped frames. - State_VerifyingAfterReduce - }; - - enum { - MaxDelayLevel = 5, - MaxInfiniteTimingLevel = 3, - MaxTimeIndex = 6 - }; - - StateInLevel State; - // Current level. Higher levels means larger delay reduction (smaller overall time-warp delay). - int DelayLevel; - // Index for the amount of time we'd wait in this level. If attempt to decrease level fails, - // with is incrementing causing the level to become "sticky". - int WaitTimeIndexForLevel[MaxTimeIndex + 1]; - // We skip few frames after each escalation to avoid too rapid of a reduction. - int InitialFrameCounter; - // What th currect "reduction" currently is. - double TimewarpDelayReductionSeconds; - // When we should try changing the level again. - double DelayLevelFinishTime; - - public: - TimewarpDelayAdjuster() { Reset(); } - - void Reset(); - - void UpdateTimewarpWaitIfSkippedFrames(FrameTimeManager* manager, - double measuredFrameDelta, - double nextFrameTime); - - double GetDelayReduction() const { return TimewarpDelayReductionSeconds; } - }; - */ - - - HmdRenderInfo RenderInfo; - // Timings are collected through a median filter, to avoid outliers. - TimeDeltaCollector FrameTimeDeltas; - TimeDeltaCollector DistortionRenderTimes; - FrameLatencyTracker ScreenLatencyTracker; - - // Timing changes if we have no Vsync (all prediction is reduced to fixed interval). - bool VsyncEnabled; - // Set if we are rendering via the SDK, so DistortionRenderTimes is valid. - bool DynamicPrediction; - // Set if SDk is doing the rendering. - bool SdkRender; - // Direct to rift. - bool DirectToRift; - - // Total frame delay due to VsyncToFirstScanline, persistence and settle time. - // Computed from RenderInfor.Shutter. - double VSyncToScanoutDelay; - double NoVSyncToScanoutDelay; - double ScreenSwitchingDelay; - - //Revisit dynamic pre-Timewarp delay adjustment logic - //TimewarpDelayAdjuster TimewarpAdjuster; - - // Current (or last) frame timing info. Used as a source for LocklessTiming. - Timing FrameTiming; - // TBD: Don't we need NextFrame here as well? - LocklessUpdater LocklessTiming; - - // IMU Read timings - double RenderIMUTimeSeconds; - double TimewarpIMUTimeSeconds; -}; - - -}} // namespace OVR::CAPI - -#endif // OVR_CAPI_FrameTimeManager_h diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager3.cpp b/LibOVR/Src/CAPI/CAPI_FrameTimeManager3.cpp new file mode 100644 index 0000000..d42ba41 --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager3.cpp @@ -0,0 +1,517 @@ +/************************************************************************************ + +Filename : CAPI_FrameTimeManager3.cpp +Content : Manage frame timing and pose prediction for rendering +Created : November 30, 2013 +Authors : Volga Aksoy, Michael Antonov + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_FrameTimeManager3.h" + +#include "Kernel/OVR_Log.h" + +//#include + +namespace OVR { namespace CAPI { namespace FTM3 { + + +// Number of frame delta samples to include in the median calculation. +static const int kFrameDeltaSamples = 12; + + +void LogTime(const char* msg) +{ + static double lastTime = 0.0; + double now = ovr_GetTimeInSeconds(); + + LogText("t=%.3f, dt=%.3f: %s\n", now, now-lastTime, msg); + lastTime = now; +} + + +//------------------------------------------------------------------------------------- + +FrameTimeManagerCore::FrameTimeManagerCore(bool vsyncEnabled) : + VsyncEnabled(vsyncEnabled), + LastTiming(), + FrameTimeDeltas(kFrameDeltaSamples) +{ +} + +void FrameTimeManagerCore::Initialize(const Timing& defaultTiming) +{ + // Contains default frame delta and indices. + // - TBD determine how those are initialized + // + FrameTimeDeltas.Clear(); + FrameIndices.Reset(); + + LastTiming = defaultTiming; + DefaultFrameDelta = defaultTiming.FrameDelta; + + LocklessTiming.SetState(LastTiming); +} + + +FrameTimeManagerCore::Timing FrameTimeManagerCore::GetAppFrameTiming(unsigned appFrameIndex) +{ + // Right now this is required for timing. + + Timing timing = LocklessTiming.GetState(); + + // TBD: We need AppFrameIndex and DisplayIndex initialized before this is called. + + OVR_ASSERT(appFrameIndex == 0 || appFrameIndex == timing.AppFrameIndex + 1); + + if (appFrameIndex > timing.AppFrameIndex) + { + int appFrameDelta = appFrameIndex - timing.AppFrameIndex; + + // Don't run away too far into the future beyond rendering. + // OVR_ASSERT(appFrameDelta < 6); + + // Convert to display frames. If we have one-to-one frame sync, appFrameDelta + // will be 1.0, so this will give us a correct frame value. + int displayFrame = timing.DisplayFrameIndex + + (int) (appFrameDelta * ( 1.0 / timing.AppToDisplayFrameRatio)); + + double prevFrameSubmitSeconds = (timing.FrameSubmitSeconds == 0.0) ? + ovr_GetTimeInSeconds() : timing.FrameSubmitSeconds; + + double displayFrameSubmitTime = prevFrameSubmitSeconds + + double(displayFrame-timing.DisplayFrameIndex) * + timing.FrameDelta; + + // Initialize to new values. + timing.AppFrameIndex = appFrameIndex; + timing.DisplayFrameIndex = displayFrame; + timing.FrameSubmitSeconds = displayFrameSubmitTime; + } + + return timing; +} + + +// Next: GetDisplayFrameTiming - used for timewarp and late-latching +// +FrameTimeManagerCore::Timing FrameTimeManagerCore::GetDisplayFrameTiming(unsigned displayFrameIndex) +{ + // Thus assumes caller has checked the 'displayFrameIndex' agains the current + // clock/vsync and this is the actual desired value. + + // TBD: Should we use Lockless here? It depends if we plan to access this form different threads. + Timing timing = LastTiming; + + if (displayFrameIndex > timing.DisplayFrameIndex) + { + double prevFrameSubmitSeconds = (timing.FrameSubmitSeconds == 0.0) ? + ovr_GetTimeInSeconds() : timing.FrameSubmitSeconds; + + // Initialize to new values. + timing.FrameSubmitSeconds = prevFrameSubmitSeconds + + double(displayFrameIndex - timing.DisplayFrameIndex) * + timing.FrameDelta; + timing.DisplayFrameIndex = displayFrameIndex; + + // Last submitted AppFrameIndex is ok. + } + + return timing; +} + + +void FrameTimeManagerCore::SubmitDisplayFrame( unsigned displayFrameIndex, + unsigned appFrameIndex, + double scanoutStartSeconds ) +{ + int displayFrameDelta = (displayFrameIndex - LastTiming.DisplayFrameIndex); + + // FIXME: Add queue ahead support here by detecting two frames targeting the same scanout. + + // Update frameDelta tracking. + if ((LastTiming.FrameSubmitSeconds > 0.0) && (displayFrameDelta < 2)) + { + if (displayFrameDelta > 0) + { + double thisFrameDelta = (scanoutStartSeconds - LastTiming.FrameSubmitSeconds) / displayFrameDelta; + FrameTimeDeltas.Add(thisFrameDelta); + } + LastTiming.FrameDelta = calcFrameDelta(); + } + + // Update indices mapping + FrameIndices.Add(displayFrameIndex, appFrameIndex); + + LastTiming.AppFrameIndex = appFrameIndex; + LastTiming.DisplayFrameIndex = displayFrameIndex; + LastTiming.FrameSubmitSeconds = scanoutStartSeconds; + LastTiming.AppToDisplayFrameRatio = FrameIndices.GetAppToDisplayFrameRatio(); + + // Update Lockless + LocklessTiming.SetState(LastTiming); +} + + + +double FrameTimeManagerCore::calcFrameDelta() const +{ + // Timing difference between frame is tracked by FrameTimeDeltas, or + // is a hard-coded value of 1/FrameRate. + double frameDelta; + + if (!VsyncEnabled) + { + frameDelta = 0.0; + } + else if (FrameTimeDeltas.GetCount() > 3) + { + frameDelta = FrameTimeDeltas.GetMedian(); + if (frameDelta > (DefaultFrameDelta + 0.001)) + frameDelta = DefaultFrameDelta; + } + else + { + frameDelta = DefaultFrameDelta; + } + + return frameDelta; +} + + + +/* + +// ***** Support code + +struct FrameStatisticsSampler +{ + + FrameStatisticsSampler(IDXGISwapChain* swapChain, double frameDelta); + + DXGI_FRAME_STATISTICS FStats; + double LastReportedFrameSeconds; + unsigned CurrentDisplayFrameIndex; + unsigned CurrentFrameScanoutSeconds; +}; + +FrameStatisticsSampler::FrameStatisticsSampler(IDXGISwapChain* swapChain, double frameDelta) +{ + swapChain->GetFrameStatistics(&FStats); + + UINT lastReportedFrameIndex = FStats.SyncRefreshCount; + LastReportedFrameSeconds = Timer::GetSecondsFromOSTicks(FStats.SyncQPCTime.QuadPart); + + double currentSeconds = ovr_GetTimeInSeconds(); + + // Determine what frame we are currently scanning out and when it started. + // This will be a part of input for FrameTimeManager... + CurrentDisplayFrameIndex = lastReportedFrameIndex + + (unsigned)((currentSeconds - LastReportedFrameSeconds) / frameDelta); + CurrentFrameScanoutSeconds = LastReportedFrameSeconds + + (CurrentDisplayFrameIndex - lastReportedFrameIndex) * frameDelta; +} + + +// Default, initial frame timing +FrameTimeManagerCore::Timing GetDefaultTiming(unsigned appFrameIndex, + IDXGISwapChain* swapChain, const HmdRenderInfo& hri) +{ + FrameStatisticsSampler fstats(swapChain, hri.Shutter.VsyncToNextVsync); + FrameTimeManagerCore::Timing t; + + t.FrameDelta = hri.Shutter.VsyncToNextVsync; + t.AppFrameIndex = appFrameIndex; + t.DisplayFrameIndex = fstats.CurrentDisplayFrameIndex; + t.FrameSubmitSeconds = fstats.CurrentFrameScanoutSeconds; + t.AppToDisplayFrameRatio = 1.0; + + return t; +} + + +void InitializeFrame() +{ + FrameStatisticsSampler fstats(pswapChain, ftm->GetFrameDelta()); + + unsigned DisplayFrameIndex; + //= FI(clock) + 1; +} + + + +void UpdateFrame() +{ + IDXGISwapChain* pswapChain = 0; // TBD: Pass argument + FrameTimeManagerCore* ftm = 0; + + FrameStatisticsSampler fstats(pswapChain, ftm->GetFrameDelta()); + + // Note that for rendering, there is actually a separate DisplayFrameIndex to think about. + + // Target 'Display FrameIndex' for next frame. Fix-up if the clock avanced too much. + DisplayFrameIndex++; + if (fstats.CurrentDisplayFrameIndex >= DisplayFrameIndex) + DisplayFrameIndex = fstats.CurrentDisplayFrameIndex + 1; + + GetDisplayFrameTiming(DisplayFrameIndex); + +} + +FrameTimeManagerCore::ScanoutTimes::ScanoutTimes( + const TimingInputs& inputs, + double frameSubmitSeconds, HmdShutterTypeEnum shutterType) +{ + double frameDelta = inputs.FrameDelta; + + ScanoutStartSeconds = frameSubmitSeconds + inputs.ScreenDelay; + ScanoutMidpointSeconds = ScanoutStartSeconds + frameDelta * 0.5; + + //... +} +*/ + + +//----------------------------------------------------------------------------------- +// MedianCalculator + +MedianCalculator::MedianCalculator(int capacity) : + Capacity(capacity) +{ + Data.Resize(Capacity); + SortBuffer.Resize(Capacity); + + Clear(); +} + +void MedianCalculator::Clear() +{ + MinValue = 0.; + MaxValue = 0.; + MeanValue = 0.; + MedianValue = 0.; + Index = 0; + DataCount = 0; + Recalculate = false; +} + +void MedianCalculator::Add(double datum) +{ + // Write next datum + Data[Index] = datum; + + // Loop circular buffer index around + if (++Index >= Capacity) + { + Index = 0; + } + + // Update data count + if (!AtCapacity()) + { + // Limited to capacity + ++DataCount; + } + + // Mark as dirty + Recalculate = true; +} + +double MedianCalculator::GetMedian() +{ + if (Recalculate) + { + doRecalculate(); + } + + return MedianValue; +} + +bool MedianCalculator::GetStats(double& minValue, double& maxValue, + double& meanValue, double& medianValue) +{ + if (GetCount() <= 0) + { + // Cannot get statistics without one data point. + return false; + } + + if (Recalculate) + { + doRecalculate(); + } + + minValue = MinValue; + maxValue = MaxValue; + meanValue = MeanValue; + medianValue = MedianValue; + return true; +} + +/* + quick_select() + + Calculates the median. + + This Quickselect routine is based on the algorithm described in + "Numerical recipes in C", Second Edition, + Cambridge University Press, 1992, Section 8.5, ISBN 0-521-43108-5 + This code by Nicolas Devillard - 1998. Public domain. +*/ + +#define ELEM_SWAP(a,b) {double t=(a);(a)=(b);(b)=t; } + +static double quick_select(double arr[], int n) +{ + int low, high ; + int median; + int middle, ll, hh; + low = 0 ; high = n-1 ; median = (low + high) / 2; + for (;;) { + if (high <= low) /* One element only */ + return arr[median] ; + if (high == low + 1) { /* Two elements only */ + if (arr[low] > arr[high]) + ELEM_SWAP(arr[low], arr[high]) ; + return arr[median] ; + } + /* Find median of low, middle and high items; swap into position low */ + middle = (low + high) / 2; + if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; + if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; + if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; + /* Swap low item (now in position middle) into position (low+1) */ + ELEM_SWAP(arr[middle], arr[low+1]) ; + /* Nibble from each end towards middle, swapping items when stuck */ + ll = low + 1; + hh = high; + for (;;) { + do ll++; while (arr[low] > arr[ll]) ; + do hh--; while (arr[hh] > arr[low]) ; + if (hh < ll) + break; + ELEM_SWAP(arr[ll], arr[hh]) ; + } + /* Swap middle item (in position low) back into correct position */ + ELEM_SWAP(arr[low], arr[hh]) ; + /* Re-set active partition */ + if (hh <= median) + low = ll; + if (hh >= median) + high = hh - 1; + } +} +#undef ELEM_SWAP + +void MedianCalculator::doRecalculate() +{ + Recalculate = false; + + // Set default result + MinValue = 0.; + MaxValue = 0.; + MeanValue = 0.; + MedianValue = 0.; + + // Calculate median + const int count = GetCount(); + for (int i = 0; i < count; ++i) + SortBuffer[i] = Data[i]; + MedianValue = quick_select(&SortBuffer[0], count); + + double minValue = Data[0], maxValue = Data[0], sumValue = Data[0]; + + for (int i = 1; i < count; ++i) + { + double value = Data[i]; + + if (value < minValue) + { + minValue = value; + } + + if (value > maxValue) + { + maxValue = value; + } + + sumValue += value; + } + + MinValue = minValue; + MaxValue = maxValue; + MeanValue = sumValue / count; + + OVR_ASSERT(MinValue <= MeanValue && MeanValue <= MaxValue); + OVR_ASSERT(MinValue <= MedianValue && MedianValue <= MaxValue); +} + + +//----------------------------------------------------------------------------------- +// ***** FrameIndexMapper + +void FrameIndexMapper::Add(unsigned displayFrameIndex, unsigned appFrameIndex) +{ + // Circular buffer; fill up then overwrite tail + if (Count == Capacity) + { + DisplayFrameIndices[StartIndex] = displayFrameIndex; + AppFrameIndices[StartIndex] = appFrameIndex; + StartIndex++; + if (StartIndex == Count) + StartIndex = 0; + } + else + { + OVR_ASSERT(StartIndex == 0); + DisplayFrameIndices[Count] = displayFrameIndex; + AppFrameIndices[Count] = appFrameIndex; + Count++; + } +} + +double FrameIndexMapper::GetAppToDisplayFrameRatio() const +{ + // Default ratio is one-to-one. Do aggressive clamping since we + // don't want ratio to go too low since we can't predict that far anyway. + if (Count < 3) + return 1.0; + + unsigned newestIndex = StartIndex + Count - 1; + if (newestIndex >= Capacity) + newestIndex -= Capacity; + + unsigned displayDelta = DisplayFrameIndices[newestIndex] - DisplayFrameIndices[StartIndex]; + unsigned appDelta = AppFrameIndices[newestIndex] - AppFrameIndices[StartIndex]; + + if (displayDelta < 2) + return 1.0f; + + double frameRatio = double(appDelta) / double(displayDelta); + if (frameRatio < 0.33f) + return 0.33f; + + return frameRatio; +} + + + +}}} // namespace OVR::CAPI::FTM2 + diff --git a/LibOVR/Src/CAPI/CAPI_FrameTimeManager3.h b/LibOVR/Src/CAPI/CAPI_FrameTimeManager3.h new file mode 100644 index 0000000..1baf5b4 --- /dev/null +++ b/LibOVR/Src/CAPI/CAPI_FrameTimeManager3.h @@ -0,0 +1,228 @@ +/************************************************************************************ + +Filename : CAPI_FrameTimeManager3.h +Content : Manage frame timing and pose prediction for rendering +Created : November 30, 2013 +Authors : Volga Aksoy, Michael Antonov + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_FrameTimeManager3_h +#define OVR_CAPI_FrameTimeManager3_h + +#include +#include +#include +#include + +namespace OVR { namespace CAPI { namespace FTM3 { + +void LogTime(const char* msg); + + +//------------------------------------------------------------------------------------- +// MedianCalculator +// +// Helper class to calculate statistics +class MedianCalculator +{ +public: + MedianCalculator(int capacity); + + void Clear(); + + // This function throws away data larger than 100 milliseconds, + // and it sanitizes negative time deltas replacing them with zero milliseconds. + void Add(double timeDelta); + + int GetCount() const + { + return DataCount; + } + int GetCapacity() const + { + return Capacity; + } + bool AtCapacity() const + { + return DataCount >= Capacity; + } + + double GetMedian(); + bool GetStats(double& minValue, double& maxValue, + double& meanValue, double& medianValue); + +private: + Array Data; + Array SortBuffer; // Buffer for quick select algorithm + + double MinValue, MaxValue, MeanValue, MedianValue; + + int Index; + int DataCount, Capacity; + bool Recalculate; + + // Precondition: Count > 0 + void doRecalculate(); +}; + + +// Helper used to compute AddFrameIndex to DisplayFrameIndex ratio, by tracking +// how much each has advanced over the recent frames. +struct FrameIndexMapper +{ + enum { Capacity = 12 }; + + // Circular buffer starting with StartIndex + unsigned DisplayFrameIndices[Capacity]; + unsigned AppFrameIndices[Capacity]; + unsigned StartIndex; + unsigned Count; + + FrameIndexMapper() : StartIndex(0), Count(0) { } + + void Reset() + { StartIndex = Count = 0; } + + void Add(unsigned displayFrameIndex, unsigned appFrameIndex); + + double GetAppToDisplayFrameRatio() const; +}; + + +//------------------------------------------------------------------------------------- +// ***** FrameTimeManagerCore + +// FrameTimeManager keeps track of rendered frame timing needed for predictions for +// orientations and time-warp. +// +// The following items are not in Core for now +// +// - TimewarpWaitDelta (how many seconds before EndFrame we start timewarp) +// this should be handled externally. +// +// - ScreenDelay (Screen delay from present to scan-out, as potentially reported by ScreenLatencyTracker.) +// this si rendering setup and HW specific +// +// - TimeWarpStartEndTimes (move matrices logic outside for now) +// +// - For now, always assume VSync on + + +class FrameTimeManagerCore +{ +public: + + // Describes last presented frame data. + struct Timing + { + // Hard-coded value or dynamic as reported by FrameTimeDeltas.GetMedianTimeDelta(). + double FrameDelta; + + // Application frame index for which we requested timing. + unsigned AppFrameIndex; + // HW frame index that we expect this will hit, the specified + // frame will start scan-out at ScanoutStartSeconds. Monotonically increasing. + unsigned DisplayFrameIndex; + + // PostPresent & Flush (old approach) or reported scan-out time (new HW-reported approach). + double FrameSubmitSeconds; + + // Ratio of (AppFrames/DisplayFrames) in + double AppToDisplayFrameRatio; + + Timing() + { + memset(this, 0, sizeof(Timing)); + } + + }; + +public: + + FrameTimeManagerCore(bool vsyncEnabled); + + // Called on startup to provided data on HMD timing. DefayltTiming should include FrameDelta + // and other default values. This can also be called to reset timing. + void Initialize(const Timing& defaultTiming); + + // Returns frame timing data for any thread to access, including + // - Simulating thread that may be running ahead + // - Rendering thread, which would treat as BeginFrame data + Timing GetAppFrameTiming(unsigned appFrameIndex); + + // Returns frame timing values for a particular DisplayFrameIndex. + // Maintaining DisplayFrameIndex is the job of the caller, as it may be fied to OS + // VSync frame reporting functionality ad/or system clock. + Timing GetDisplayFrameTiming(unsigned displayFrameIndex); + + // To be called from TW Thread when displayFrame has been submitted for present. + // This call is used to update lock-less timing frame basis. The provided + // values do the following: + // - Establish relationship between App and Display frame index. + // - Track the real frameDelta (difference between VSyncs) + void SubmitDisplayFrame(unsigned displayFrameIndex, + unsigned appFrameIndex, + double scanoutStartSeconds); + + unsigned GetLastDisplayFrameIndex() const + { + return LastTiming.DisplayFrameIndex; + } + double GetLastDisplayFrameTime() const + { + return LastTiming.FrameSubmitSeconds; + } + + double GetFrameDelta() const + { + return calcFrameDelta(); + } + + void SetVsync(bool enabled) { VsyncEnabled = enabled; } + + // ovrFrameTiming ovrFrameTimingFromTiming(const Timing& timing) const; + +private: + + double calcFrameDelta() const; + + + // Timing changes if we have no Vsync (all prediction is reduced to fixed interval). + bool VsyncEnabled; + // Default VsyncToVSync value, received in Initialize. + double DefaultFrameDelta; + // Last timing + Timing LastTiming; + + // Current (or last) frame timing info. Used as a source for LocklessTiming. + LocklessUpdater LocklessTiming; + + // Timings are collected through a median filter, to avoid outliers. + mutable MedianCalculator FrameTimeDeltas; + // Associates AppFrameIndex <-> + FrameIndexMapper FrameIndices; + +}; + + +}}} // namespace OVR::CAPI::FTM3 + +#endif // OVR_CAPI_FrameTimeManager_h diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp old mode 100644 new mode 100755 index 6630607..a22079d --- a/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp +++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.cpp @@ -26,6 +26,7 @@ limitations under the License. #include "CAPI_HMDRenderState.h" + namespace OVR { namespace CAPI { @@ -38,9 +39,10 @@ ovrHmdDesc HMDRenderState::GetDesc() const memset(&d, 0, sizeof(d)); d.Type = ovrHmd_Other; - + d.ProductName = OurHMDInfo.ProductName; d.Manufacturer = OurHMDInfo.Manufacturer; + d.Resolution.w = OurHMDInfo.ResolutionInPixels.w; d.Resolution.h = OurHMDInfo.ResolutionInPixels.h; d.WindowsPos.x = OurHMDInfo.DesktopX; @@ -60,9 +62,9 @@ ovrHmdDesc HMDRenderState::GetDesc() const d.HmdCaps = ovrHmdCap_Present | ovrHmdCap_NoVSync; d.TrackingCaps = ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Orientation; - d.DistortionCaps = ovrDistortionCap_Chromatic | ovrDistortionCap_TimeWarp | - ovrDistortionCap_Vignette | ovrDistortionCap_SRGB | - ovrDistortionCap_FlipInput | ovrDistortionCap_ProfileNoTimewarpSpinWaits | + d.DistortionCaps = ovrDistortionCap_TimeWarp | //ovrDistortionCap_DepthProjectedTimeWarp | + ovrDistortionCap_Vignette | ovrDistortionCap_SRGB | ovrDistortionCap_FlipInput | + ovrDistortionCap_TimewarpJitDelay | ovrDistortionCap_ProfileNoSpinWaits | ovrDistortionCap_HqDistortion | ovrDistortionCap_LinuxDevFullscreen; #if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) @@ -71,20 +73,22 @@ ovrHmdDesc HMDRenderState::GetDesc() const #endif if( OurHMDInfo.InCompatibilityMode ) + { d.HmdCaps |= ovrHmdCap_ExtendDesktop; + } - if (strstr(OurHMDInfo.ProductName, "DK1")) + if (OurHMDInfo.HmdType == HmdType_DK1) { d.Type = ovrHmd_DK1; } - else if (strstr(OurHMDInfo.ProductName, "DK2")) + else if (OurHMDInfo.HmdType == HmdType_DK2) { - d.Type = ovrHmd_DK2; - d.HmdCaps |= ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction; + d.Type = ovrHmd_DK2; + d.HmdCaps |= ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction; d.TrackingCaps |= ovrTrackingCap_Position; - d.DistortionCaps |= ovrDistortionCap_Overdrive; + d.DistortionCaps |= ovrDistortionCap_Overdrive; } - + const DistortionRenderDesc& leftDistortion = Distortion[0]; const DistortionRenderDesc& rightDistortion = Distortion[1]; @@ -108,15 +112,19 @@ ovrHmdDesc HMDRenderState::GetDesc() const } // MA: Taking this out on purpose. - // Important information for those that are required to do their own timing, + // Important information for those that are required to do their own timing, // because of shortfalls in timing code. - //d.VsyncToNextVsync = OurHMDInfo.Shutter.VsyncToNextVsync; - //d.PixelPersistence = OurHMDInfo.Shutter.PixelPersistence; + //d.VsyncToNextVsync = OurHMDInfo.Shutter.VsyncToNextVsync; + //d.PixelPersistence = OurHMDInfo.Shutter.PixelPersistence; + + if (OurHMDInfo.DebugDevice) + { + d.HmdCaps |= ovrHmdCap_DebugDevice; + } return d; } - ovrSizei HMDRenderState::GetFOVTextureSize(int eye, ovrFovPort fov, float pixelsPerDisplayPixel) const { OVR_ASSERT((unsigned)eye < 2); diff --git a/LibOVR/Src/CAPI/CAPI_HMDRenderState.h b/LibOVR/Src/CAPI/CAPI_HMDRenderState.h index 05c4e1b..30f8635 100644 --- a/LibOVR/Src/CAPI/CAPI_HMDRenderState.h +++ b/LibOVR/Src/CAPI/CAPI_HMDRenderState.h @@ -27,10 +27,10 @@ limitations under the License. #ifndef OVR_CAPI_HMDRenderState_h #define OVR_CAPI_HMDRenderState_h -#include "../OVR_CAPI.h" -#include "../Kernel/OVR_Math.h" -#include "../Util/Util_Render_Stereo.h" -#include "../Service/Service_NetSessionCommon.h" +#include "OVR_CAPI.h" +#include "Extras/OVR_Math.h" +#include "Util/Util_Render_Stereo.h" +#include "Service/Service_NetSessionCommon.h" namespace OVR { namespace CAPI { @@ -52,7 +52,7 @@ struct HMDRenderState ovrEyeRenderDesc CalcRenderDesc(ovrEyeType eyeType, const ovrFovPort& fov) const; HMDInfo OurHMDInfo; - + ProfileRenderInfo OurProfileRenderInfo; HmdRenderInfo RenderInfo; DistortionRenderDesc Distortion[2]; ovrEyeRenderDesc EyeRenderDesc[2]; @@ -64,7 +64,7 @@ struct HMDRenderState ovrPosef EyeRenderPoses[2]; // Capabilities passed to Configure. - unsigned EnabledHmdCaps; + unsigned EnabledHmdCaps; // enum ovrHmdCaps unsigned DistortionCaps; // enum ovrDistortionCaps }; diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.cpp b/LibOVR/Src/CAPI/CAPI_HMDState.cpp old mode 100644 new mode 100755 index 6ea9958..4aae646 --- a/LibOVR/Src/CAPI/CAPI_HMDState.cpp +++ b/LibOVR/Src/CAPI/CAPI_HMDState.cpp @@ -27,116 +27,80 @@ limitations under the License. #include "CAPI_HMDState.h" #include "../OVR_Profile.h" #include "../Service/Service_NetClient.h" + #ifdef OVR_OS_WIN32 -#include "../Displays/OVR_Win32_ShimFunctions.h" + #include "../Displays/OVR_Win32_ShimFunctions.h" + + // For auto-detection of window handle for direct mode: + #include + #include + #include + +#elif defined(OVR_OS_LINUX) + + #include "../Displays/OVR_Linux_SDKWindow.h" // For screen rotation + #endif +#include "Tracing/Tracing.h" + namespace OVR { namespace CAPI { -// Accessed via HMDState::GetHMDStateList() +// Accessed via HMDState::EnumerateHMDStateList() +static OVR::Lock hmdStateListLock; static OVR::List hmdStateList; // List of all created HMDStates. //------------------------------------------------------------------------------------- // ***** HMDState -HMDState::HMDState(const OVR::Service::HMDNetworkInfo& netInfo, - const OVR::HMDInfo& hmdInfo, - Profile* profile, - Service::NetClient* client) : +HMDState::HMDState(HMDInfo const & hmdInfo, + Profile* profile, + Service::HMDNetworkInfo const * netInfo, + Service::NetClient* client) : + TimewarpTimer(), + RenderTimer(), + RenderIMUTimeSeconds(0.), pProfile(profile), pHmdDesc(0), pWindow(0), pClient(client), - NetId(netInfo.NetId), - NetInfo(netInfo), - OurHMDInfo(hmdInfo), - pLastError(NULL), - EnabledHmdCaps(0), - EnabledServiceHmdCaps(0), - SharedStateReader(), - TheSensorStateReader(), - TheLatencyTestStateReader(), - LatencyTestActive(false), - //LatencyTestDrawColor(), - LatencyTest2Active(false), - //LatencyTest2DrawColor(), - TimeManager(true), - RenderState(), - pRenderer(), - pHSWDisplay(), - LastFrameTimeSeconds(0.), - LastGetFrameTimeSeconds(0.), - //LastGetStringValue(), - RenderingConfigured(false), - BeginFrameCalled(false), - BeginFrameThreadId(), - RenderAPIThreadChecker(), - BeginFrameTimingCalled(false) -{ - sharedInit(profile); - hmdStateList.PushBack(this); -} - - -HMDState::HMDState(const OVR::HMDInfo& hmdInfo, Profile* profile) : - pProfile(profile), - pHmdDesc(0), - pWindow(0), - pClient(0), NetId(InvalidVirtualHmdId), NetInfo(), OurHMDInfo(hmdInfo), - pLastError(NULL), + pLastError(nullptr), EnabledHmdCaps(0), EnabledServiceHmdCaps(0), - SharedStateReader(), - TheSensorStateReader(), + CombinedHmdReader(), + TheTrackingStateReader(), TheLatencyTestStateReader(), LatencyTestActive(false), //LatencyTestDrawColor(), LatencyTest2Active(false), //LatencyTest2DrawColor(), - TimeManager(true), + ScreenLatencyTracker(), RenderState(), pRenderer(), pHSWDisplay(), - LastFrameTimeSeconds(0.), - LastGetFrameTimeSeconds(0.), //LastGetStringValue(), RenderingConfigured(false), BeginFrameCalled(false), BeginFrameThreadId(), + BeginFrameIndex(0), RenderAPIThreadChecker(), BeginFrameTimingCalled(false) { - sharedInit(profile); - hmdStateList.PushBack(this); -} - -HMDState::~HMDState() -{ - hmdStateList.Remove(this); - - if (pClient) + if (netInfo) { - pClient->Hmd_Release(NetId); - pClient = 0; + NetId = netInfo->NetId; + NetInfo = *netInfo; } - ConfigureRendering(0,0,0,0); - - if (pHmdDesc) - { - OVR_FREE(pHmdDesc); - pHmdDesc = NULL; - } -} + // Hook up the app timing lockless updater + RenderTimer.SetUpdater(TimewarpTimer.GetUpdater()); -void HMDState::sharedInit(Profile* profile) -{ // TBD: We should probably be looking up the default profile for the given // device type + user if profile == 0. pLastError = 0; @@ -154,10 +118,12 @@ void HMDState::sharedInit(Profile* profile) RenderState.ClearColor[1] = 0.0f; RenderState.ClearColor[2] = 0.0f; RenderState.ClearColor[3] = 0.0f; - RenderState.EnabledHmdCaps = 0; - TimeManager.Init(RenderState.RenderInfo); + if (!TimewarpTimer.Initialize(&RenderState, &ScreenLatencyTracker)) + { + OVR_ASSERT(false); + } /* LatencyTestDrawColor[0] = 0; @@ -165,19 +131,60 @@ void HMDState::sharedInit(Profile* profile) LatencyTestDrawColor[2] = 0; */ - RenderingConfigured = false; - BeginFrameCalled = false; - BeginFrameThreadId = 0; + RenderingConfigured = false; + BeginFrameCalled = false; + BeginFrameThreadId = 0; BeginFrameTimingCalled = false; // Construct the HSWDisplay. We will later reconstruct it with a specific ovrRenderAPI type if the application starts using SDK-based rendering. if(!pHSWDisplay) { pHSWDisplay = *OVR::CAPI::HSWDisplay::Factory(ovrRenderAPI_None, pHmdDesc, RenderState); - pHSWDisplay->Enable(pProfile->GetBoolValue("HSW", true)); + } + + RenderIMUTimeSeconds = 0.; + + hmdStateListLock.DoLock(); + hmdStateList.PushBack(this); + hmdStateListLock.Unlock(); +} + +HMDState::~HMDState() +{ + hmdStateListLock.DoLock(); + hmdStateList.Remove(this); + hmdStateListLock.Unlock(); + + if (pClient) + { + pClient->Hmd_Release(NetId); + pClient = 0; + } + + ConfigureRendering(0,0,0,0); + + if (pHmdDesc) + { + OVR_FREE(pHmdDesc); + pHmdDesc = nullptr; } } +bool HMDState::InitializeSharedState() +{ + if (!CombinedHmdReader.Open(NetInfo.SharedMemoryName.Hmd.ToCStr()) || + !CameraReader.Open(NetInfo.SharedMemoryName.Camera.ToCStr())) + { + return false; + } + + TheTrackingStateReader.SetUpdaters(CombinedHmdReader.Get(), CameraReader.Get()); + TheLatencyTestStateReader.SetUpdater(CombinedHmdReader.Get()); + + + return true; +} + static Vector3f GetNeckModelFromProfile(Profile* profile) { OVR_ASSERT(profile); @@ -220,7 +227,9 @@ static float GetCenterPupilDepthFromRenderInfo(HmdRenderInfo* hmdRenderInfo) void HMDState::UpdateRenderProfile(Profile* profile) { // Apply the given profile to generate a render context - RenderState.RenderInfo = GenerateHmdRenderInfoFromHmdInfo(RenderState.OurHMDInfo, profile); + RenderState.OurProfileRenderInfo = GenerateProfileRenderInfoFromProfile(RenderState.OurHMDInfo, profile); + RenderState.RenderInfo = GenerateHmdRenderInfoFromHmdInfo(RenderState.OurHMDInfo, RenderState.OurProfileRenderInfo); + RenderState.Distortion[0] = CalculateDistortionRenderDesc(StereoEye_Left, RenderState.RenderInfo, 0); RenderState.Distortion[1] = CalculateDistortionRenderDesc(StereoEye_Right, RenderState.RenderInfo, 0); @@ -239,19 +248,25 @@ void HMDState::UpdateRenderProfile(Profile* profile) }; pClient->SetNumberValues(GetNetId(), "NeckModelVector3f", neckModelArray, 3); - double camerastate[7]; - if (profile->GetDoubleValues(OVR_KEY_CAMERA_POSITION, camerastate, 7) == 0) + // Camera position + + // OVR_KEY_CAMERA_POSITION is actually the *inverse* of a camera position. + Posed centeredFromWorld; + + double values[7]; + if (profile->GetDoubleValues(OVR_KEY_CAMERA_POSITION, values, 7) == 7) { - //there is no value, so we load the default - for (int i = 0; i < 7; i++) camerastate[i] = 0; - camerastate[3] = 1;//no offset. by default, give the quaternion w component value 1 + centeredFromWorld = Posed::FromArray(values); } else + { + centeredFromWorld = TheTrackingStateReader.GetDefaultCenteredFromWorld(); + } - TheSensorStateReader.setCenteredFromWorld(OVR::Posed::FromArray(camerastate)); + // ComputeCenteredFromWorld wants a worldFromCpf pose, so invert it. + // FIXME: The stored centeredFromWorld doesn't have a neck model offset applied, but probably should. + TheTrackingStateReader.ComputeCenteredFromWorld(centeredFromWorld.Inverted(), Vector3d(0, 0, 0)); } - - } HMDState* HMDState::CreateHMDState(NetClient* client, const HMDNetworkInfo& netInfo) @@ -261,11 +276,11 @@ HMDState* HMDState::CreateHMDState(NetClient* client, const HMDNetworkInfo& netI if (!client->Hmd_GetHmdInfo(netInfo.NetId, &hinfo)) { OVR_DEBUG_LOG(("[HMDState] Unable to get HMD info")); - return NULL; + return nullptr; } #ifdef OVR_OS_WIN32 - OVR_DEBUG_LOG(("Setting up display shim")); + OVR_DEBUG_LOG(("[HMDState] Setting up display shim")); // Initialize the display shim before reporting the display to the user code // so that this will happen before the D3D display object is created. @@ -273,23 +288,20 @@ HMDState* HMDState::CreateHMDState(NetClient* client, const HMDNetworkInfo& netI #endif Ptr pDefaultProfile = *ProfileManager::GetInstance()->GetDefaultUserProfile(&hinfo); - OVR_DEBUG_LOG(("Using profile %s", pDefaultProfile->GetValue(OVR_KEY_USER))); + OVR_DEBUG_LOG(("[HMDState] Using profile %s", pDefaultProfile->GetValue(OVR_KEY_USER))); - HMDState* hmds = new HMDState(netInfo, hinfo, pDefaultProfile, client); + HMDState* hmds = new HMDState(hinfo, pDefaultProfile, &netInfo, client); - if (!hmds->SharedStateReader.Open(netInfo.SharedMemoryName.ToCStr())) + if (!hmds->InitializeSharedState()) { delete hmds; - return NULL; + return nullptr; } - hmds->TheSensorStateReader.SetUpdater(hmds->SharedStateReader.Get()); - hmds->TheLatencyTestStateReader.SetUpdater(hmds->SharedStateReader.Get()); - return hmds; } -HMDState* HMDState::CreateHMDState(ovrHmdType hmdType) +HMDState* HMDState::CreateDebugHMDState(ovrHmdType hmdType) { HmdTypeEnum t = HmdType_None; if (hmdType == ovrHmd_DK1) @@ -299,41 +311,51 @@ HMDState* HMDState::CreateHMDState(ovrHmdType hmdType) // FIXME: This does not actually grab the right user.. Ptr pDefaultProfile = *ProfileManager::GetInstance()->GetDefaultProfile(t); - + return new HMDState(CreateDebugHMDInfo(t), pDefaultProfile); } - -const OVR::List& HMDState::GetHMDStateList() +// Enumerate each open HMD +unsigned HMDState::EnumerateHMDStateList(bool (*callback)(const HMDState *state)) { - return hmdStateList; + unsigned count = 0; + hmdStateListLock.DoLock(); + for (const HMDState *hmds = hmdStateList.GetFirst(); !hmdStateList.IsNull(hmds); hmds = hmdStateList.GetNext(hmds)) + { + if (callback && !callback(hmds)) + break; + ++count; + } + hmdStateListLock.Unlock(); + return count; } - //------------------------------------------------------------------------------------- // *** Sensor bool HMDState::ConfigureTracking(unsigned supportedCaps, unsigned requiredCaps) { - return pClient ? pClient->Hmd_ConfigureTracking(NetId, supportedCaps, requiredCaps) : true; + return pClient ? pClient->Hmd_ConfigureTracking(NetId, supportedCaps, requiredCaps) : true; } -void HMDState::ResetTracking() +void HMDState::ResetTracking(bool visionReset) { - if (pClient) pClient->Hmd_ResetTracking(NetId); + if (pClient) pClient->Hmd_ResetTracking(NetId, visionReset); } // Re-center the orientation. void HMDState::RecenterPose() { - TheSensorStateReader.RecenterPose(); + float hnm[3]; + getFloatArray("NeckModelVector3f", hnm, 3); + TheTrackingStateReader.RecenterPose(Vector3d(hnm[0], hnm[1], hnm[2])); } // Returns prediction for time. -ovrTrackingState HMDState::PredictedTrackingState(double absTime) -{ - Tracking::TrackingState ss; - TheSensorStateReader.GetSensorStateAtTime(absTime, ss); +ovrTrackingState HMDState::PredictedTrackingState(double absTime, void*) +{ + Vision::TrackingState ss; + TheTrackingStateReader.GetTrackingStateAtTime(absTime, ss); // Zero out the status flags if (!pClient || !pClient->IsConnected(false, false)) @@ -341,6 +363,12 @@ ovrTrackingState HMDState::PredictedTrackingState(double absTime) ss.StatusFlags = 0; } +#ifdef OVR_OS_WIN32 + // Set up display code for Windows + Win32::DisplayShim::GetInstance().Active = (ss.StatusFlags & ovrStatus_HmdConnected) != 0; +#endif + + return ss; } @@ -350,31 +378,11 @@ void HMDState::SetEnabledHmdCaps(unsigned hmdCaps) { // disable low persistence and pentile. hmdCaps &= ~ovrHmdCap_LowPersistence; - hmdCaps &= ~ovrHmdCap_DirectPentile; // disable dynamic prediction using the internal latency tester hmdCaps &= ~ovrHmdCap_DynamicPrediction; } - if (OurHMDInfo.HmdType >= HmdType_DK2) - { - if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_DynamicPrediction) - { - // DynamicPrediction change - TimeManager.ResetFrameTiming(TimeManager.GetFrameTiming().FrameIndex, - (hmdCaps & ovrHmdCap_DynamicPrediction) ? true : false, - RenderingConfigured); - } - } - - // Pentile unsupported on everything right now. - hmdCaps &= ~ovrHmdCap_DirectPentile; - - if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_NoVSync) - { - TimeManager.SetVsync((hmdCaps & ovrHmdCap_NoVSync) ? false : true); - } - if ((EnabledHmdCaps ^ hmdCaps) & ovrHmdCap_NoMirrorToWindow) { #ifdef OVR_OS_WIN32 @@ -398,7 +406,7 @@ void HMDState::SetEnabledHmdCaps(unsigned hmdCaps) unsigned newServiceCaps = hmdCaps & ovrHmdCap_Writable_Mask & ovrHmdCap_Service_Mask; if (prevServiceCaps ^ newServiceCaps) - { + { EnabledServiceHmdCaps = pClient ? pClient->Hmd_SetEnabledCaps(NetId, newServiceCaps) : newServiceCaps; } @@ -407,7 +415,7 @@ void HMDState::SetEnabledHmdCaps(unsigned hmdCaps) unsigned HMDState::SetEnabledHmdCaps() { - unsigned serviceCaps = pClient ? pClient->Hmd_GetEnabledCaps(NetId) : + unsigned serviceCaps = pClient ? pClient->Hmd_GetEnabledCaps(NetId) : EnabledServiceHmdCaps; return serviceCaps & ((~ovrHmdCap_Service_Mask) | EnabledHmdCaps); @@ -436,12 +444,12 @@ bool HMDState::getBoolValue(const char* propertyName, bool defaultVal) bool HMDState::setBoolValue(const char* propertyName, bool value) { - if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetBoolValue, propertyName)) - { - return NetClient::GetInstance()->SetBoolValue(GetNetId(), propertyName, value); - } + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetBoolValue, propertyName)) + { + return NetClient::GetInstance()->SetBoolValue(GetNetId(), propertyName, value); + } - return false; + return false; } int HMDState::getIntValue(const char* propertyName, int defaultVal) @@ -459,12 +467,12 @@ int HMDState::getIntValue(const char* propertyName, int defaultVal) bool HMDState::setIntValue(const char* propertyName, int value) { - if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetIntValue, propertyName)) - { - return NetClient::GetInstance()->SetIntValue(GetNetId(), propertyName, value); - } + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetIntValue, propertyName)) + { + return NetClient::GetInstance()->SetIntValue(GetNetId(), propertyName, value); + } - return false; + return false; } float HMDState::getFloatValue(const char* propertyName, float defaultVal) @@ -495,12 +503,12 @@ float HMDState::getFloatValue(const char* propertyName, float defaultVal) bool HMDState::setFloatValue(const char* propertyName, float value) { - if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetNumberValue, propertyName)) - { - return NetClient::GetInstance()->SetNumberValue(GetNetId(), propertyName, value); - } + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetNumberValue, propertyName)) + { + return NetClient::GetInstance()->SetNumberValue(GetNetId(), propertyName, value); + } - return false; + return false; } static unsigned CopyFloatArrayWithLimit(float dest[], unsigned destSize, @@ -514,37 +522,70 @@ static unsigned CopyFloatArrayWithLimit(float dest[], unsigned destSize, unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsigned arraySize) { - if (arraySize) - { - if (OVR_strcmp(propertyName, "ScreenSize") == 0) - { - float data[2] = { OurHMDInfo.ScreenSizeInMeters.w, OurHMDInfo.ScreenSizeInMeters.h }; + if (arraySize) + { + if (OVR_strcmp(propertyName, "ScreenSize") == 0) + { + float data[2] = { OurHMDInfo.ScreenSizeInMeters.w, OurHMDInfo.ScreenSizeInMeters.h }; return CopyFloatArrayWithLimit(values, arraySize, data, 2); - } + } else if (OVR_strcmp(propertyName, "DistortionClearColor") == 0) { return CopyFloatArrayWithLimit(values, arraySize, RenderState.ClearColor, 4); } else if (OVR_strcmp(propertyName, "DK2Latency") == 0) { - if (OurHMDInfo.HmdType != HmdType_DK2) + if (OurHMDInfo.HmdType < HmdType_DK2) { return 0; } - union { - struct X { - float latencyRender, latencyTimewarp, latencyPostPresent; - } x; - float data[3]; - } m; + OutputLatencyTimings timings; + ScreenLatencyTracker.GetLatencyTimings(timings); + + if (arraySize > 0) + { + switch (arraySize) + { + default: values[4] = (float)timings.ErrorTimewarp; // Fall-thru + case 4: values[3] = (float)timings.ErrorRender; // Fall-thru + case 3: values[2] = (float)timings.LatencyPostPresent; // Fall-thru + case 2: values[1] = (float)timings.LatencyTimewarp; // Fall-thru + case 1: values[0] = (float)timings.LatencyRender; + } + } + + return arraySize > 5 ? 5 : arraySize; + } + else if (OVR_strcmp(propertyName, "NeckModelVector3f") == 0) + { + // Query the service to grab the HNM. + double hnm[3] = {}; + int count = NetClient::GetInstance()->GetNumberValues(GetNetId(), propertyName, hnm, (int)arraySize); - static_assert(sizeof(m.x)==sizeof(m.data), "sizeof(struct X) failure"); + // If the service is unavailable or returns zero data, + if (count < 3 || + (hnm[0] == 0.0 && hnm[1] == 0.0 && hnm[2] == 0.0)) + { + // These are the default values used if the server does not return any data, due to not + // being reachable or other errors. + OVR_ASSERT(pProfile.GetPtr()); + if (pProfile.GetPtr()) + { + Vector3f neckModel = GetNeckModelFromProfile(pProfile); + hnm[0] = neckModel.x; + hnm[1] = neckModel.y; + hnm[2] = neckModel.z; + } + } - TimeManager.GetLatencyTimings(m.x.latencyRender, m.x.latencyTimewarp, m.x.latencyPostPresent); + for (unsigned i = 0; i < 3 && i < arraySize; ++i) + { + values[i] = (float)hnm[i]; + } - return CopyFloatArrayWithLimit(values, arraySize, m.data, 3); + return arraySize > 3 ? 3 : arraySize; } else if (NetSessionCommon::IsServiceProperty(NetSessionCommon::EGetNumberValues, propertyName)) { @@ -566,16 +607,16 @@ unsigned HMDState::getFloatArray(const char* propertyName, float values[], unsig return count; } - else if (pProfile) - { - // TBD: Not quite right. Should update profile interface, so that - // we can return 0 in all conditions if property doesn't exist. - + else if (pProfile) + { + // TBD: Not quite right. Should update profile interface, so that + // we can return 0 in all conditions if property doesn't exist. + return pProfile->GetFloatValues(propertyName, values, arraySize); - } - } + } + } - return 0; + return 0; } bool HMDState::setFloatArray(const char* propertyName, float values[], unsigned arraySize) @@ -591,22 +632,22 @@ bool HMDState::setFloatArray(const char* propertyName, float values[], unsigned return true; } - if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetNumberValues, propertyName)) - { - double* da = new double[arraySize]; - for (int i = 0; i < (int)arraySize; ++i) - { - da[i] = values[i]; - } + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetNumberValues, propertyName)) + { + double* da = new double[arraySize]; + for (int i = 0; i < (int)arraySize; ++i) + { + da[i] = values[i]; + } - bool result = NetClient::GetInstance()->SetNumberValues(GetNetId(), propertyName, da, arraySize); + bool result = NetClient::GetInstance()->SetNumberValues(GetNetId(), propertyName, da, arraySize); - delete[] da; + delete[] da; - return result; - } + return result; + } - return false; + return false; } const char* HMDState::getString(const char* propertyName, const char* defaultVal) @@ -616,26 +657,26 @@ const char* HMDState::getString(const char* propertyName, const char* defaultVal return NetClient::GetInstance()->GetStringValue(GetNetId(), propertyName, defaultVal); } - if (pProfile) - { - LastGetStringValue[0] = 0; - if (pProfile->GetValue(propertyName, LastGetStringValue, sizeof(LastGetStringValue))) - { - return LastGetStringValue; - } - } + if (pProfile) + { + LastGetStringValue[0] = 0; + if (pProfile->GetValue(propertyName, LastGetStringValue, sizeof(LastGetStringValue))) + { + return LastGetStringValue; + } + } - return defaultVal; + return defaultVal; } bool HMDState::setString(const char* propertyName, const char* value) { - if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetStringValue, propertyName)) - { - return NetClient::GetInstance()->SetStringValue(GetNetId(), propertyName, value); - } + if (NetSessionCommon::IsServiceProperty(NetSessionCommon::ESetStringValue, propertyName)) + { + return NetClient::GetInstance()->SetStringValue(GetNetId(), propertyName, value); + } - return false; + return false; } @@ -647,6 +688,200 @@ bool HMDState::ProcessLatencyTest(unsigned char rgbColorOut[3]) return NetClient::GetInstance()->LatencyUtil_ProcessInputs(Timer::GetSeconds(), rgbColorOut); } + +//------------------------------------------------------------------------------------- +// *** Timewarp + +AppTiming HMDState::GetAppTiming(uint32_t frameIndex) +{ + // Get prediction time for the requested frame index + AppTiming timing; + const bool VsyncOn = ((RenderState.EnabledHmdCaps & ovrHmdCap_NoVSync) == 0); + RenderTimer.GetAppTimingForIndex(timing, VsyncOn, frameIndex); + + // Update the predicted scanout time for this frame index + TimingHistory.SetScanoutTimeForFrame(frameIndex, timing.ScanoutStartTime); + + return timing; +} + +ovrFrameTiming HMDState::GetFrameTiming(uint32_t frameIndex) +{ + AppTiming timing = GetAppTiming(frameIndex); + + // Calculate eye render times based on shutter type + double eyePhotonsTimes[2]; + CalculateEyeRenderTimes(timing.VisibleMidpointTime, timing.FrameInterval, + RenderState.RenderInfo.Shutter.Type, + eyePhotonsTimes[0], eyePhotonsTimes[1]); + + RenderIMUTimeSeconds = Timer::GetSeconds(); // RenderPrediction.RawSensorData.TimeInSeconds; + + // Construct a ovrFrameTiming object from the base app timing information + ovrFrameTiming result; + result.DeltaSeconds = (float)timing.FrameInterval; + result.EyeScanoutSeconds[0] = eyePhotonsTimes[0]; + result.EyeScanoutSeconds[1] = eyePhotonsTimes[1]; + result.ScanoutMidpointSeconds = timing.VisibleMidpointTime; + result.ThisFrameSeconds = timing.ScanoutStartTime - timing.FrameInterval; + result.NextFrameSeconds = timing.ScanoutStartTime; + // Deprecated: This should be queried after render work completes. Please delete me from CAPI. + result.TimewarpPointSeconds = 0.; + return result; +} + +ovrTrackingState HMDState::GetMidpointPredictionTracking(uint32_t frameIndex) +{ + AppTiming timing = GetAppTiming(frameIndex); + RenderIMUTimeSeconds = Timer::GetSeconds(); // RenderPrediction.RawSensorData.TimeInSeconds; + return PredictedTrackingState(timing.VisibleMidpointTime); +} + +Posef HMDState::GetEyePredictionPose(ovrEyeType eye) +{ + // Note that this function does not get the frame index parameter and depends + // on whichever value is passed into the BeginFrame() function. + ovrTrackingState ts = GetMidpointPredictionTracking(BeginFrameIndex); + TraceTrackingState(ts); + Posef const & hmdPose = ts.HeadPose.ThePose; + + // Currently HmdToEyeViewOffset is only a 3D vector + // (Negate HmdToEyeViewOffset because offset is a view matrix offset and not a camera offset) + if (eye == ovrEye_Left) + { + return Posef(hmdPose.Rotation, ((Posef)hmdPose).Apply(-((Vector3f)RenderState.EyeRenderDesc[0].HmdToEyeViewOffset))); + } + else + { + return Posef(hmdPose.Rotation, ((Posef)hmdPose).Apply(-((Vector3f)RenderState.EyeRenderDesc[1].HmdToEyeViewOffset))); + } +} + +void HMDState::endFrameRenderTiming() +{ + TimewarpTimer.SetLastPresentTime(); // Record approximate vsync time + + bool dk2LatencyTest = (EnabledHmdCaps & ovrHmdCap_DynamicPrediction) != 0; + if (dk2LatencyTest) + { + Util::FrameTimeRecordSet recordSet; + TheLatencyTestStateReader.GetRecordSet(recordSet); + + FrameLatencyData data; + data.DrawColor = LatencyTest2DrawColor[0]; + data.RenderIMUTime = RenderIMUTimeSeconds; + data.RenderPredictedScanoutTime = TimingHistory.LookupScanoutTime(BeginFrameIndex); + data.PresentTime = TimewarpTimer.GetLatencyTesterPresentTime(); + data.TimewarpPredictedScanoutTime = TimewarpTimer.GetTimewarpTiming()->ScanoutTime; + data.TimewarpIMUTime = TimewarpTimer.GetTimewarpIMUTime(); + + //OVR_ASSERT(data.TimewarpIMUTime == 0. || data.TimewarpIMUTime >= data.RenderIMUTime); + + ScreenLatencyTracker.SaveDrawColor(data); + ScreenLatencyTracker.MatchRecord(recordSet); + } +} + +void HMDState::getTimewarpStartEnd(ovrEyeType eyeId, double timewarpStartEnd[2]) +{ + // Get eye start/end scanout times + TimewarpTiming const* timewarpTiming = TimewarpTimer.GetTimewarpTiming(); + + for (int i = 0; i < 2; ++i) + { + timewarpStartEnd[i] = timewarpTiming->EyeStartEndTimes[eyeId][i]; + } +} + +void HMDState::GetTimewarpMatricesEx(ovrEyeType eyeId, + ovrPosef renderPose, + bool calcPosition, const ovrVector3f hmdToEyeViewOffset[2], + ovrMatrix4f twmOut[2], double debugTimingOffsetInSeconds) +{ + // Get timewarp start/end timing + double timewarpStartEnd[2]; + getTimewarpStartEnd(eyeId, timewarpStartEnd); + + //TPH, to vary timing, to allow developers to debug, to shunt the predicted time forward + //and back, and see if the SDK is truly delivering the correct time. Also to allow + //illustration of the detrimental effects when this is not done right. + timewarpStartEnd[0] += debugTimingOffsetInSeconds; + timewarpStartEnd[1] += debugTimingOffsetInSeconds; + + ovrTrackingState startState = PredictedTrackingState(timewarpStartEnd[0]); + ovrTrackingState endState = PredictedTrackingState(timewarpStartEnd[1]); + + ovrPosef startHmdPose = startState.HeadPose.ThePose; + ovrPosef endHmdPose = endState.HeadPose.ThePose; + Vector3f eyeOffset = Vector3f(0.0f, 0.0f, 0.0f); + Matrix4f timewarpStart, timewarpEnd; + if (calcPosition) + { + if (!hmdToEyeViewOffset) + { + OVR_ASSERT(false); + LogError("{ERR-102} [FrameTime] No hmdToEyeViewOffset provided even though calcPosition is true."); + + // disable position to avoid positional issues + renderPose.Position = Vector3f::Zero(); + startHmdPose.Position = Vector3f::Zero(); + endHmdPose.Position = Vector3f::Zero(); + } + else if (hmdToEyeViewOffset[eyeId].x >= MATH_FLOAT_MAXVALUE) + { + OVR_ASSERT(false); + LogError("{ERR-103} [FrameTime] Invalid hmdToEyeViewOffset provided by client."); + + // disable position to avoid positional issues + renderPose.Position = Vector3f::Zero(); + startHmdPose.Position = Vector3f::Zero(); + endHmdPose.Position = Vector3f::Zero(); + } + else + { + // Currently HmdToEyeViewOffset is only a 3D vector + // (Negate HmdToEyeViewOffset because offset is a view matrix offset and not a camera offset) + eyeOffset = ((Posef)startHmdPose).Apply(-((Vector3f)hmdToEyeViewOffset[eyeId])); + } + + Posef fromEye = Posef(renderPose).Inverted(); // because we need the view matrix, not the camera matrix + CalculatePositionalTimewarpMatrix(fromEye, startHmdPose, eyeOffset, timewarpStart); + CalculatePositionalTimewarpMatrix(fromEye, endHmdPose, eyeOffset, timewarpEnd); + } + else + { + Quatf fromEye = Quatf(renderPose.Orientation).Inverted(); // because we need the view matrix, not the camera matrix + CalculateOrientationTimewarpMatrix(fromEye, startHmdPose.Orientation, timewarpStart); + CalculateOrientationTimewarpMatrix(fromEye, endHmdPose.Orientation, timewarpEnd); + } + twmOut[0] = timewarpStart; + twmOut[1] = timewarpEnd; +} + +void HMDState::GetTimewarpMatrices(ovrEyeType eyeId, ovrPosef renderPose, + ovrMatrix4f twmOut[2]) +{ + // Get timewarp start/end timing + double timewarpStartEnd[2]; + getTimewarpStartEnd(eyeId, timewarpStartEnd); + + ovrTrackingState startState = PredictedTrackingState(timewarpStartEnd[0]); + ovrTrackingState endState = PredictedTrackingState(timewarpStartEnd[1]); + + Quatf quatFromEye = Quatf(renderPose.Orientation); + quatFromEye.Invert(); // because we need the view matrix, not the camera matrix + + Matrix4f timewarpStart, timewarpEnd; + CalculateOrientationTimewarpMatrix( + quatFromEye, startState.HeadPose.ThePose.Orientation, timewarpStart); + CalculateOrientationTimewarpMatrix( + quatFromEye, endState.HeadPose.ThePose.Orientation, timewarpEnd); + + twmOut[0] = timewarpStart; + twmOut[1] = timewarpEnd; +} + + //------------------------------------------------------------------------------------- // *** Rendering @@ -686,7 +921,7 @@ bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], pRenderer.Clear(); } - distortionCaps = distortionCaps & pHmdDesc->DistortionCaps; + distortionCaps = distortionCaps & pHmdDesc->DistortionCaps; // Step 1: do basic setup configuration RenderState.EnabledHmdCaps = EnabledHmdCaps; // This is a copy... Any cleaner way? @@ -696,27 +931,22 @@ bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], eyeRenderDescOut[0] = RenderState.EyeRenderDesc[0]; eyeRenderDescOut[1] = RenderState.EyeRenderDesc[1]; - TimeManager.ResetFrameTiming(0, - (EnabledHmdCaps & ovrHmdCap_DynamicPrediction) ? true : false, - true); - - LastFrameTimeSeconds = 0.0f; - // Set RenderingConfigured early to avoid ASSERTs in renderer initialization. RenderingConfigured = true; if (!pRenderer) { pRenderer = *DistortionRenderer::APICreateRegistry - [apiConfig->Header.API](pHmdDesc, TimeManager, RenderState); + [apiConfig->Header.API](); } if (!pRenderer || - !pRenderer->Initialize(apiConfig)) + !pRenderer->Initialize(apiConfig, &TheTrackingStateReader, + &TimewarpTimer, &RenderState)) { RenderingConfigured = false; return false; - } + } // Setup the Health and Safety Warning display system. if(pHSWDisplay && (pHSWDisplay->GetRenderAPIType() != apiConfig->Header.API)) // If we need to reconstruct the HSWDisplay for a different graphics API type, delete the existing display. @@ -728,83 +958,120 @@ bool HMDState::ConfigureRendering(ovrEyeRenderDesc eyeRenderDescOut[2], if(!pHSWDisplay) // Use * below because that for of operator= causes it to inherit the refcount the factory gave the object. { pHSWDisplay = *OVR::CAPI::HSWDisplay::Factory(apiConfig->Header.API, pHmdDesc, RenderState); - pHSWDisplay->Enable(pProfile->GetBoolValue("HSW", true)); } if (pHSWDisplay) + { pHSWDisplay->Initialize(apiConfig); // This is potentially re-initializing it with a new config. + } + +#ifdef OVR_OS_WIN32 + if (!pWindow) + { + // We can automatically populate the window to attach to by + // pulling that information off the swap chain that the + // application provides. If the application later calls the + // ovrHmd_AttachToWindow() function these will get harmlessly + // overwritten. The check above verifies that the window is + // not set yet, and it insures that this default doesn't + // overwrite the application setting. + + if (apiConfig->Header.API == ovrRenderAPI_D3D11) + { + ovrD3D11Config* d3d11Config = (ovrD3D11Config*)apiConfig; + if (d3d11Config->D3D11.pSwapChain) + { + DXGI_SWAP_CHAIN_DESC desc = {}; + HRESULT hr = d3d11Config->D3D11.pSwapChain->GetDesc(&desc); + if (SUCCEEDED(hr)) + { + pWindow = (void*)desc.OutputWindow; + } + } + } + else if (apiConfig->Header.API == ovrRenderAPI_OpenGL) + { + ovrGLConfig* glConfig = (ovrGLConfig*)apiConfig; + pWindow = (void*)glConfig->OGL.Window; + } +OVR_DISABLE_MSVC_WARNING(4996) // Disable deprecation warning + else if (apiConfig->Header.API == ovrRenderAPI_D3D9) + { + ovrD3D9Config* dx9Config = (ovrD3D9Config*)apiConfig; + if (dx9Config->D3D9.pDevice) + { + D3DDEVICE_CREATION_PARAMETERS params = {}; + HRESULT hr = dx9Config->D3D9.pDevice->GetCreationParameters(¶ms); + if (SUCCEEDED(hr)) + { + pWindow = (void*)params.hFocusWindow; + } + } + } +OVR_RESTORE_MSVC_WARNING() + + // If a window handle was implied by render configuration, + if (pWindow) + { + // This is the same logic as ovrHmd_AttachToWindow() on Windows: + if (pClient) + pClient->Hmd_AttachToWindow(GetNetId(), pWindow); + Win32::DisplayShim::GetInstance().hWindow = (HWND)pWindow; + // On the server side it is updating the association of connection + // to window handle. This is perfectly safe to update later to + // a new window handle (verified). Also verified that if this + // handle is garbage that it doesn't crash anything. + } + } +#endif return true; } void HMDState::SubmitEyeTextures(const ovrPosef renderPose[2], - const ovrTexture eyeTexture[2]) + const ovrTexture eyeTexture[2], + const ovrTexture eyeDepthTexture[2]) { RenderState.EyeRenderPoses[0] = renderPose[0]; RenderState.EyeRenderPoses[1] = renderPose[1]; if (pRenderer) { + if(eyeDepthTexture) + { + pRenderer->SubmitEyeWithDepth(0, &eyeTexture[0], &eyeDepthTexture[0]); + pRenderer->SubmitEyeWithDepth(1, &eyeTexture[1], &eyeDepthTexture[1]); + } + else + { + //OVR_ASSERT(!(RenderState.DistortionCaps & ovrDistortionCap_DepthProjectedTimeWarp)); + //LogError("{ERR-104} [HMDState] Even though ovrDistortionCap_DepthProjectedTimeWarp is enabled, no depth buffer was provided."); + pRenderer->SubmitEye(0, &eyeTexture[0]); pRenderer->SubmitEye(1, &eyeTexture[1]); } } +} - -// I appreciate this is not an idea place for this function, but it didn't seem to be -// being linked properly when in OVR_CAPI.cpp. -// Please relocate if you know of a better place -ovrBool ovrHmd_CreateDistortionMeshInternal( ovrHmdStruct * hmd, - ovrEyeType eyeType, ovrFovPort fov, - unsigned int distortionCaps, - ovrDistortionMesh *meshData, - float overrideEyeReliefIfNonZero ) +bool HMDState::CreateDistortionMesh(ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, + ovrDistortionMesh *meshData, + float overrideEyeReliefIfNonZero) { - if (!meshData) - return 0; - HMDState* hmds = (HMDState*)hmd; - - // Not used now, but Chromatic flag or others could possibly be checked for in the future. - OVR_UNUSED1(distortionCaps); - -#if defined (OVR_CC_MSVC) - static_assert(sizeof(DistortionMeshVertexData) == sizeof(ovrDistortionVertex), "DistortionMeshVertexData size mismatch"); -#endif - - // *** Calculate a part of "StereoParams" needed for mesh generation - - // Note that mesh distortion generation is invariant of RenderTarget UVs, allowing - // render target size and location to be changed after the fact dynamically. - // eyeToSourceUV is computed here for convenience, so that users don't need - // to call ovrHmd_GetRenderScaleAndOffset unless changing RT dynamically. + const HmdRenderInfo& hmdri = RenderState.RenderInfo; - const HmdRenderInfo& hmdri = hmds->RenderState.RenderInfo; - StereoEye stereoEye = (eyeType == ovrEye_Left) ? StereoEye_Left : StereoEye_Right; - - DistortionRenderDesc& distortion = hmds->RenderState.Distortion[eyeType]; - if (overrideEyeReliefIfNonZero) - { - distortion.Lens = GenerateLensConfigFromEyeRelief(overrideEyeReliefIfNonZero,hmdri); - } - - // Find the mapping from TanAngle space to target NDC space. - ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(fov); - - int triangleCount = 0; - int vertexCount = 0; - - DistortionMeshCreate((DistortionMeshVertexData**)&meshData->pVertexData, - (uint16_t**)&meshData->pIndexData, - &vertexCount, &triangleCount, - (stereoEye == StereoEye_Right), - hmdri, distortion, eyeToSourceNDC); + DistortionRenderDesc& distortion = RenderState.Distortion[eyeType]; + if (overrideEyeReliefIfNonZero) + { + distortion.Lens = GenerateLensConfigFromEyeRelief(overrideEyeReliefIfNonZero, hmdri); + } - if (meshData->pVertexData) + if (CalculateDistortionMeshFromFOV( + hmdri, distortion, + (eyeType == ovrEye_Left ? StereoEye_Left : StereoEye_Right), + fov, distortionCaps, meshData)) { - // Convert to index - meshData->IndexCount = triangleCount * 3; - meshData->VertexCount = vertexCount; return 1; } @@ -812,5 +1079,4 @@ ovrBool ovrHmd_CreateDistortionMeshInternal( ovrHmdStruct * hmd, } - }} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_HMDState.h b/LibOVR/Src/CAPI/CAPI_HMDState.h old mode 100644 new mode 100755 index 81ca64f..18342bb --- a/LibOVR/Src/CAPI/CAPI_HMDState.h +++ b/LibOVR/Src/CAPI/CAPI_HMDState.h @@ -27,20 +27,22 @@ limitations under the License. #ifndef OVR_CAPI_HMDState_h #define OVR_CAPI_HMDState_h -#include "../Kernel/OVR_Math.h" -#include "../Kernel/OVR_List.h" -#include "../Kernel/OVR_Log.h" -#include "../OVR_CAPI.h" +#include "Extras/OVR_Math.h" +#include "Kernel/OVR_List.h" +#include "Kernel/OVR_Log.h" +#include "OVR_CAPI.h" + +#include "CAPI_FrameTimeManager3.h" +#include "CAPI_FrameLatencyTracker.h" -#include "CAPI_FrameTimeManager.h" -#include "CAPI_LatencyStatistics.h" #include "CAPI_HMDRenderState.h" #include "CAPI_DistortionRenderer.h" #include "CAPI_HSWDisplay.h" -#include "../Service/Service_NetClient.h" -#include "../Net/OVR_NetworkTypes.h" -#include "../Util/Util_LatencyTest2Reader.h" +#include "Service/Service_NetClient.h" +#include "Net/OVR_NetworkTypes.h" +#include "Util/Util_LatencyTest2Reader.h" + struct ovrHmdStruct { }; @@ -131,25 +133,30 @@ class HMDState : public ListNode, void operator=(const HMDState&) { } // Quiet warning. protected: - HMDState(const OVR::Service::HMDNetworkInfo& netInfo, - const OVR::HMDInfo& hmdInfo, - Profile* profile, - Service::NetClient* client); - HMDState(const HMDInfo& src, Profile* profile); + HMDState(HMDInfo const & hmdInfo, + Profile* profile, + Service::HMDNetworkInfo const * netInfo = nullptr, + Service::NetClient* client = nullptr); public: virtual ~HMDState(); static HMDState* CreateHMDState(Service::NetClient* client, const HMDNetworkInfo& netInfo); - static HMDState* CreateHMDState(ovrHmdType hmdType); // Used for debug mode - static const OVR::List& GetHMDStateList(); + static HMDState* CreateDebugHMDState(ovrHmdType hmdType); // Used for debug mode + + // Call the optional provided callback for each open HMD, stopping when the callback returns false. + // Return a count of the enumerated HMDStates. Note that this may deadlock if ovrHmd_Create/Destroy + // are called from the callback. + static unsigned EnumerateHMDStateList(bool (*callback)(const HMDState *state)); + + bool InitializeSharedState(); // *** Sensor Setup bool ConfigureTracking(unsigned supportedCaps, unsigned requiredCaps); - void ResetTracking(); - void RecenterPose(); - ovrTrackingState PredictedTrackingState(double absTime); + void ResetTracking(bool visionReset); + void RecenterPose(); + ovrTrackingState PredictedTrackingState(double absTime, void* unused = nullptr); // Changes HMD Caps. // Capability bits that are not directly or logically tied to one system (such as sensor) @@ -169,10 +176,8 @@ public: void SubmitEyeTextures(const ovrPosef renderPose[2], - const ovrTexture eyeTexture[2]); - - - void sharedInit ( Profile *profile ); + const ovrTexture eyeTexture[2], + const ovrTexture eyeDepthTexture[2]); void applyProfileToSensorFusion(); @@ -184,7 +189,7 @@ public: OVR_UNUSED1(functionName); // for Release build. OVR_ASSERT_LOG(BeginFrameCalled == true, ("%s called outside ovrHmd_BeginFrame.", functionName)); - OVR_DEBUG_LOG_COND(BeginFrameThreadId != OVR::GetCurrentThreadId(), + OVR_DEBUG_LOG_COND(BeginFrameThreadId != OVR::GetCurrentThreadId(), ("%s called on a different thread then ovrHmd_BeginFrame.", functionName)); } @@ -202,31 +207,58 @@ public: ("%s called outside ovrHmd_BeginFrameTiming.", functionName)); } - // Get properties by name. + // Get properties by name. bool getBoolValue(const char* propertyName, bool defaultVal); bool setBoolValue(const char* propertyName, bool value); int getIntValue(const char* propertyName, int defaultVal); bool setIntValue(const char* propertyName, int value); float getFloatValue(const char* propertyName, float defaultVal); bool setFloatValue(const char* propertyName, float value); - unsigned getFloatArray(const char* propertyName, float values[], unsigned arraySize); + unsigned getFloatArray(const char* propertyName, float values[], unsigned arraySize); bool setFloatArray(const char* propertyName, float values[], unsigned arraySize); const char* getString(const char* propertyName, const char* defaultVal); bool setString(const char* propertyName, const char* value); - VirtualHmdId GetNetId() { return NetId; } + VirtualHmdId GetNetId() { return NetId; } + +public: + // Distortion mesh creation + bool CreateDistortionMesh(ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, + ovrDistortionMesh *meshData, + float overrideEyeReliefIfNonZero); + + AppTiming GetAppTiming(uint32_t frameIndex); + ovrFrameTiming GetFrameTiming(uint32_t frameIndex); + ovrTrackingState GetMidpointPredictionTracking(uint32_t frameIndex); + Posef GetEyePredictionPose(ovrEyeType eye); + + void GetTimewarpMatricesEx(ovrEyeType eye, ovrPosef renderPose, + bool usePosition, const ovrVector3f hmdToEyeViewOffset[2], ovrMatrix4f twmOut[2], + double debugTimingOffsetInSeconds = 0.0); + void GetTimewarpMatrices(ovrEyeType eyeId, ovrPosef renderPose, + ovrMatrix4f twmOut[2]); + + // Render timing + void getTimewarpStartEnd(ovrEyeType eyeId, double timewarpStartEnd[2]); + void endFrameRenderTiming(); + + DistortionTimer TimewarpTimer; // Timing for timewarp rendering + AppRenderTimer RenderTimer; // Timing for eye rendering + AppTimingHistory TimingHistory; // History of predicted scanout times + double RenderIMUTimeSeconds; // IMU Read timings public: - Ptr pProfile; + Ptr pProfile; // Descriptor that gets allocated and returned to the user as ovrHmd. ovrHmdDesc* pHmdDesc; // Window handle passed in AttachWindow. void* pWindow; - // Network - Service::NetClient* pClient; - VirtualHmdId NetId; - HMDNetworkInfo NetInfo; + // Network + Service::NetClient* pClient; + VirtualHmdId NetId; + HMDNetworkInfo NetInfo; // HMDInfo shouldn't change, as its string pointers are passed out. HMDInfo OurHMDInfo; @@ -244,9 +276,12 @@ public: //unsigned HmdCapsAppliedToSensor; // *** Sensor - Tracking::CombinedSharedStateReader SharedStateReader; - Tracking::SensorStateReader TheSensorStateReader; - Util::RecordStateReader TheLatencyTestStateReader; + SharedObjectReader CombinedHmdReader; + SharedObjectReader CameraReader; + + + Vision::TrackingStateReader TheTrackingStateReader; + Util::RecordStateReader TheLatencyTestStateReader; bool LatencyTestActive; unsigned char LatencyTestDrawColor[3]; @@ -255,21 +290,13 @@ public: unsigned char LatencyTest2DrawColor[3]; // Rendering part - FrameTimeManager TimeManager; - LagStatsCalculator LagStats; - LatencyStatisticsCSV LagStatsCSV; + FrameLatencyTracker ScreenLatencyTracker; HMDRenderState RenderState; Ptr pRenderer; // Health and Safety Warning display. Ptr pHSWDisplay; - // Last timing value reported by BeginFrame. - double LastFrameTimeSeconds; - // Last timing value reported by GetFrameTime. These are separate since the intended - // use is from different threads. TBD: Move to FrameTimeManager? Make atomic? - double LastGetFrameTimeSeconds; - // Last cached value returned by ovrHmd_GetString/ovrHmd_GetStringArray. char LastGetStringValue[256]; @@ -277,28 +304,15 @@ public: bool RenderingConfigured; // Set after BeginFrame succeeds, and its corresponding thread id for debug checks. bool BeginFrameCalled; - ThreadId BeginFrameThreadId; + ThreadId BeginFrameThreadId; + uint32_t BeginFrameIndex; // Graphics functions are not re-entrant from other threads. ThreadChecker RenderAPIThreadChecker; - // + // Has BeginFrameTiming() or BeginFrame() been called? bool BeginFrameTimingCalled; }; - - -//I appreciate this isn't an idea place for this function prototype, but needed -//to be seen by OVR_CAPI.cpp and the various SDK renderers of CAPI, -//and have everything defined. Please move to a better place if you know of one. -ovrBool ovrHmd_CreateDistortionMeshInternal( ovrHmdStruct * hmd, - ovrEyeType eyeType, ovrFovPort fov, - unsigned int distortionCaps, - ovrDistortionMesh *meshData, - float overrideEyeReliefIfNonZero=0 ); - - - - }} // namespace OVR::CAPI #endif // OVR_CAPI_HMDState_h diff --git a/LibOVR/Src/CAPI/CAPI_HSWDisplay.cpp b/LibOVR/Src/CAPI/CAPI_HSWDisplay.cpp index ae11f5e..4883d56 100644 --- a/LibOVR/Src/CAPI/CAPI_HSWDisplay.cpp +++ b/LibOVR/Src/CAPI/CAPI_HSWDisplay.cpp @@ -26,10 +26,9 @@ limitations under the License. #include "CAPI_HSWDisplay.h" #include "CAPI_HMDState.h" -#include "../Kernel/OVR_Log.h" -#include "../Kernel/OVR_String.h" +#include "Kernel/OVR_Log.h" +#include "Kernel/OVR_String.h" #include "Textures/healthAndSafety.tga.h" // TGA file as a C array declaration. -#include //------------------------------------------------------------------------------------- // ***** HSWDISPLAY_DEBUGGING @@ -46,8 +45,7 @@ limitations under the License. #if HSWDISPLAY_DEBUGGING OVR_DISABLE_ALL_MSVC_WARNINGS() - #include - #include + #include "Kernel/OVR_Win32_IncludeWindows.h" OVR_RESTORE_ALL_MSVC_WARNINGS() #endif @@ -66,28 +64,6 @@ OVR_DISABLE_MSVC_WARNING(4996) // "This function or variable may be unsafe..." -//------------------------------------------------------------------------------------- -// ***** Experimental C API functions -// - -extern "C" -{ - OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enabled) - { - OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; - - if (pHMDState) - { - OVR::CAPI::HSWDisplay* pHSWDisplay = pHMDState->pHSWDisplay; - - if(pHSWDisplay) - pHSWDisplay->EnableRender((enabled == 0) ? false : true); - } - } -} - - - //------------------------------------------------------------------------------------- // ***** HSWDisplay implementation @@ -129,6 +105,15 @@ HSWDisplay::HSWDisplay(ovrRenderAPIType renderAPIType, ovrHmd hmd, const HMDRend LastProfileName(), LastHSWTime(0) { + HMDState* pHMDState = (HMDState*)HMD->Handle; + + if(pHMDState) + { + if(pHMDState->pHmdDesc->HmdCaps & ovrHmdCap_DebugDevice) + Enabled = false; + else if(pHMDState->pProfile) + Enable(pHMDState->pProfile->GetBoolValue("HSW", true)); + } } @@ -385,18 +370,19 @@ void HSWDisplay::SetCurrentProfileLastHSWTime(time_t t) // Generates an appropriate stereo ortho projection matrix. -void HSWDisplay::GetOrthoProjection(const HMDRenderState& RenderState, Matrix4f OrthoProjection[2]) +void HSWDisplay::GetOrthoProjection(const HMDRenderState& renderState, Matrix4f orthoProjection[2]) { Matrix4f perspectiveProjection[2]; - perspectiveProjection[0] = ovrMatrix4f_Projection(RenderState.EyeRenderDesc[0].Fov, 0.01f, 10000.f, true); - perspectiveProjection[1] = ovrMatrix4f_Projection(RenderState.EyeRenderDesc[1].Fov, 0.01f, 10000.f, true); + unsigned int projectionModifier = ovrProjection_RightHanded | ((RenderAPIType == ovrRenderAPI_OpenGL) ? ovrProjection_ClipRangeOpenGL : 0); + perspectiveProjection[0] = ovrMatrix4f_Projection(renderState.EyeRenderDesc[0].Fov, 0.01f, 10000.f, projectionModifier); + perspectiveProjection[1] = ovrMatrix4f_Projection(renderState.EyeRenderDesc[1].Fov, 0.01f, 10000.f, projectionModifier); const float orthoDistance = HSWDISPLAY_DISTANCE; // This is meters from the camera (viewer) that we place the ortho plane. - const Vector2f orthoScale0 = Vector2f(1.f) / Vector2f(RenderState.EyeRenderDesc[0].PixelsPerTanAngleAtCenter); - const Vector2f orthoScale1 = Vector2f(1.f) / Vector2f(RenderState.EyeRenderDesc[1].PixelsPerTanAngleAtCenter); + const Vector2f orthoScale0 = Vector2f(1.f) / Vector2f(renderState.EyeRenderDesc[0].PixelsPerTanAngleAtCenter); + const Vector2f orthoScale1 = Vector2f(1.f) / Vector2f(renderState.EyeRenderDesc[1].PixelsPerTanAngleAtCenter); - OrthoProjection[0] = ovrMatrix4f_OrthoSubProjection(perspectiveProjection[0], orthoScale0, orthoDistance, RenderState.EyeRenderDesc[0].HmdToEyeViewOffset.x); - OrthoProjection[1] = ovrMatrix4f_OrthoSubProjection(perspectiveProjection[1], orthoScale1, orthoDistance, RenderState.EyeRenderDesc[1].HmdToEyeViewOffset.x); + orthoProjection[0] = ovrMatrix4f_OrthoSubProjection(perspectiveProjection[0], orthoScale0, orthoDistance, renderState.EyeRenderDesc[0].HmdToEyeViewOffset.x); + orthoProjection[1] = ovrMatrix4f_OrthoSubProjection(perspectiveProjection[1], orthoScale1, orthoDistance, renderState.EyeRenderDesc[1].HmdToEyeViewOffset.x); } @@ -418,17 +404,8 @@ const uint8_t* HSWDisplay::GetDefaultTexture(size_t& TextureSize) // #if defined (OVR_OS_WIN32) - #define OVR_D3D_VERSION 9 #include "D3D9/CAPI_D3D9_HSWDisplay.h" - #undef OVR_D3D_VERSION - - #define OVR_D3D_VERSION 10 - #include "D3D1X/CAPI_D3D10_HSWDisplay.h" - #undef OVR_D3D_VERSION - - #define OVR_D3D_VERSION 11 #include "D3D1X/CAPI_D3D11_HSWDisplay.h" - #undef OVR_D3D_VERSION #endif #include "GL/CAPI_GL_HSWDisplay.h" @@ -453,10 +430,6 @@ OVR::CAPI::HSWDisplay* OVR::CAPI::HSWDisplay::Factory(ovrRenderAPIType apiType, pHSWDisplay = new OVR::CAPI::D3D9::HSWDisplay(apiType, hmd, renderState); break; - case ovrRenderAPI_D3D10: - pHSWDisplay = new OVR::CAPI::D3D10::HSWDisplay(apiType, hmd, renderState); - break; - case ovrRenderAPI_D3D11: pHSWDisplay = new OVR::CAPI::D3D11::HSWDisplay(apiType, hmd, renderState); break; diff --git a/LibOVR/Src/CAPI/CAPI_HSWDisplay.h b/LibOVR/Src/CAPI/CAPI_HSWDisplay.h index ee984d8..d98f351 100644 --- a/LibOVR/Src/CAPI/CAPI_HSWDisplay.h +++ b/LibOVR/Src/CAPI/CAPI_HSWDisplay.h @@ -27,7 +27,7 @@ limitations under the License. #ifndef OVR_CAPI_HSWDisplay_h #define OVR_CAPI_HSWDisplay_h -#include "../OVR_CAPI.h" +#include "OVR_CAPI.h" #include "CAPI_HMDRenderState.h" #include @@ -78,23 +78,6 @@ limitations under the License. -//------------------------------------------------------------------------------------- -// ***** Experimental C API functions -// -// These are currently not formally supported and may be promoted to the formal C API -// or may be removed in the future. - -extern "C" -{ - // Normally if an application uses SDK-based distortion rendering - // (ovrHmd_BeginFrame / ovrHmd_EndFrame) then the SDK also takes care of - // drawing the health and safety warning. If an application is using - // SDK-based rendering but wants to draw the warning display itself, - // it call this function with enabled set to false. - OVR_EXPORT void ovrhmd_EnableHSWDisplaySDKRender(ovrHmd hmd, ovrBool enabled); -} - - namespace OVR { namespace CAPI { @@ -214,7 +197,7 @@ protected: void SetCurrentProfileLastHSWTime(time_t t); // Generates an appropriate stereo ortho projection matrix. - static void GetOrthoProjection(const HMDRenderState& RenderState, Matrix4f OrthoProjection[2]); + void GetOrthoProjection(const HMDRenderState& RenderState, Matrix4f OrthoProjection[2]); // Returns the default HSW display texture data. static const uint8_t* GetDefaultTexture(size_t& TextureSize); diff --git a/LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp b/LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp deleted file mode 100644 index c43418a..0000000 --- a/LibOVR/Src/CAPI/CAPI_LatencyStatistics.cpp +++ /dev/null @@ -1,316 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_LatencyStatistics.cpp -Content : Record latency statistics during rendering -Created : Sept 23, 2014 -Authors : Chris Taylor, Kevin Jenkins - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "CAPI_LatencyStatistics.h" - -#include "../Kernel/OVR_Log.h" -#include "../Kernel/OVR_Threads.h" -#include "../Util/Util_SystemInfo.h" - -namespace OVR { namespace CAPI { - -//----------------------------------------------------------------------------- -// ***** LatencyStatisticsObserver - -LatencyStatisticsCSV::LatencyStatisticsCSV() -{ -} - -LatencyStatisticsCSV::~LatencyStatisticsCSV() -{ - Stop(); -} - -bool LatencyStatisticsCSV::Start(String fileName, String userData1) -{ - if (_File.IsValid()) - { - if (fileName == FileName) - { - UserData1 = userData1; - return true; - } - else - { - Stop(); - } - } - - OVR::String basePath = OVR::GetBaseOVRPath(true); - OVR::String path = basePath; - path.AppendString("\\"); - path.AppendString(fileName); - OS = OVR::Util::OSAsString(); - OSVersion = OVR::Util::OSVersionAsString(); -#if defined (OVR_OS_WIN64) || defined (OVR_OS_WIN32) - ProcessInfo = OVR::Util::GetProcessInfo(); - DisplayDriverVersion = OVR::Util::GetDisplayDriverVersion(); - CameraDriverVersion = OVR::Util::GetCameraDriverVersion(); - OVR::Array< OVR::String > gpus; - OVR::Util::GetGraphicsCardList(gpus); - StringBuffer sb; - size_t gpuIdx; - for (gpuIdx = 0; gpuIdx < gpus.GetSize(); gpuIdx++) - { - sb.AppendString(gpus[gpuIdx]); - if (gpuIdx + 1 < gpus.GetSize()) - sb.AppendString("; "); - } - GPUVersion = sb; -#endif - Guid = OVR::Util::GetGuidString(); - - if (!_File.Open(path, OVR::File::Open_Write, OVR::File::Mode_Write)) - { - _File.Create(path, OVR::File::Mode_Write); - WriteHeaderV1(); - } - else - { - _File.Seek(0, FileConstants::Seek_End); - } - - if (_File.IsValid()) - { - UserData1 = userData1; - FileName = fileName; - _Observer.SetHandler(LatencyStatisticsSlot::FromMember(this)); - - return true; - } - - return false; -} -bool LatencyStatisticsCSV::Stop() -{ - if (_File.IsValid()) - { - _File.Flush(); - _File.Close(); - _Observer.ReleaseAll(); - - Guid.Clear(); - FileName.Clear(); - return true; - } - return false; -} -void LatencyStatisticsCSV::WriteHeaderV1() -{ - if (_File.IsValid()) - { - // Write header if creating the file - const char *str = "GUID,OS,OSVersion,Process,DisplayDriver,CameraDriver,GPU,Time,Interval,FPS,EndFrameExecutionTime,LatencyRender,LatencyTimewarp,LatencyPostPresent,LatencyVisionProc,LatencyVisionFrame,UserData1\n"; - _File.Write((const uint8_t *) str, (int)OVR_strlen(str)); - } -} - -void LatencyStatisticsCSV::WriteResultsV1(LatencyStatisticsResults *results) -{ - if (_File.IsValid()) - { - char str[512]; - OVR_sprintf(str, sizeof(str), - "%s,%s,%s,%s,%s,%s,%s,%f,%f,%f,%f,%f,%f,%f,%f,%f,%s\n", - Guid.ToCStr(), - OS.ToCStr(), - OSVersion.ToCStr(), - ProcessInfo.ToCStr(), - DisplayDriverVersion.ToCStr(), - CameraDriverVersion.ToCStr(), - GPUVersion.ToCStr(), - ovr_GetTimeInSeconds(), - results->IntervalSeconds, - results->FPS, - results->EndFrameExecutionTime, - results->LatencyRender, - results->LatencyTimewarp, - results->LatencyPostPresent, - results->LatencyVisionProc, - results->LatencyVisionFrame, - UserData1.ToCStr()); - str[sizeof(str)-1] = 0; - _File.Write((const uint8_t *)str, (int)OVR_strlen(str)); - } -} -void LatencyStatisticsCSV::OnResults(LatencyStatisticsResults *results) -{ - WriteResultsV1(results); -} -//------------------------------------------------------------------------------------- -// ***** LatencyStatisticsCalculator - -LagStatsCalculator::LagStatsCalculator() -{ - resetPerfStats(); -} - -void LagStatsCalculator::resetPerfStats(double resetTime) -{ - EndFrameStartTime = 0.; - EndFrameEndTime = 0.; - - LastCameraFrameCounter = ~(uint32_t)0; - - EpochBegin = resetTime; // Set epoch start to now - - FrameCount = 0; - //EndFrameSum = 0.; - - //VisionProcSum = 0.; - //VisionLagSum = 0.; - VisionFrames = 0; - - //for (int i = 0; i < 3; ++i) - //{ - // LatencyData[i] = 0.f; - // LatencySum[i] = 0.; - //} - - latencyStatisticsData.EndFrameExecutionTime = 0; - latencyStatisticsData.LatencyRender = 0; - latencyStatisticsData.LatencyTimewarp = 0; - latencyStatisticsData.LatencyPostPresent = 0; - latencyStatisticsData.LatencyVisionProc = 0; - latencyStatisticsData.LatencyVisionFrame = 0; -} - -void LagStatsCalculator::GetLatestResults(LatencyStatisticsResults* results) -{ - *results = Results.GetState(); -} -void LagStatsCalculator::AddResultsObserver(ObserverScope *calculateResultsObserver) -{ - Lock::Locker locker(&calculateResultsLock); - calculateResultsObserver->GetPtr()->Observe(calculateResultsSubject); -} -void LagStatsCalculator::InstrumentEndFrameStart(double timestamp) -{ - EndFrameStartTime = timestamp; -} - -void LagStatsCalculator::InstrumentLatencyTimings(FrameTimeManager& ftm) -{ - //latencies[0] = (float)RenderLatencySeconds; - //latencies[1] = (float)TimewarpLatencySeconds; - //latencies[2] = (float)FrameDeltas.GetMedianTimeDelta(); - - // Note: This assumes that it is called right before InstrumentEndFrameEnd() - float latencyRender, latencyTimewarp, latencyPostPresent; - ftm.GetLatencyTimings(latencyRender, latencyTimewarp, latencyPostPresent); - latencyStatisticsData.LatencyRender += latencyRender; - latencyStatisticsData.LatencyTimewarp += latencyTimewarp; - latencyStatisticsData.LatencyPostPresent += latencyPostPresent; -} - -void LagStatsCalculator::InstrumentEndFrameEnd(double timestamp) -{ - EndFrameEndTime = timestamp; - - calculateResults(); -} - -void LagStatsCalculator::InstrumentEyePose(const ovrTrackingState& state) -{ - // If the camera frame counter has rolled, - if (LastCameraFrameCounter != state.LastCameraFrameCounter) - { - // Accumulate eye pose data - if (state.StatusFlags != 0) - { - latencyStatisticsData.LatencyVisionProc += state.LastVisionProcessingTime; - latencyStatisticsData.LatencyVisionFrame += state.LastVisionFrameLatency; - } - ++VisionFrames; - - LastCameraFrameCounter = state.LastCameraFrameCounter; - } -} - -// Note: Currently assumes this is being called from OnEndFrameEnd() above. -void LagStatsCalculator::calculateResults() -{ - // Calculate time in the current epoch so far - double intervalDuration = EndFrameEndTime - EpochBegin; - - // If stats should be reset due to inactivity, - if (intervalDuration >= OVR_LAG_STATS_RESET_LIMIT) - { - resetPerfStats(EndFrameEndTime); - return; - } - - // Calculate EndFrame() duration - double endFrameDuration = EndFrameEndTime - EndFrameStartTime; - - // Incorporate EndFrame() duration into the running sum - latencyStatisticsData.EndFrameExecutionTime += endFrameDuration; - - //for (int i = 0; i < 3; ++i) - //{ - // LatencySum[i] += LatencyData[i]; - //} - - // Increment frame counter - ++FrameCount; - - // If enough time has passed, - if (intervalDuration >= OVR_LAG_STATS_EPOCH) - { - LatencyStatisticsResults results; - - float invFrameCount = 1.0f / (float) FrameCount; - - // EndFrame() instrumentation - results.IntervalSeconds = intervalDuration; - results.FPS = FrameCount / intervalDuration; - results.EndFrameExecutionTime = latencyStatisticsData.EndFrameExecutionTime * invFrameCount; - - // Latency data - results.LatencyRender = latencyStatisticsData.LatencyRender * invFrameCount; - results.LatencyTimewarp = latencyStatisticsData.LatencyTimewarp * invFrameCount; - results.LatencyPostPresent = latencyStatisticsData.LatencyPostPresent * invFrameCount; - - double invVisionFrameCount = 1. / VisionFrames; - - // Eye pose instrumentation - results.LatencyVisionProc = latencyStatisticsData.LatencyVisionProc * invVisionFrameCount; - results.LatencyVisionFrame = latencyStatisticsData.LatencyVisionFrame * invVisionFrameCount; - - Results.SetState(results); - - { - Lock::Locker locker(&calculateResultsLock); - calculateResultsSubject.GetPtr()->Call(&results); - } - - // Reset for next frame - resetPerfStats(); - } -} - - -}} // namespace OVR::CAPI diff --git a/LibOVR/Src/CAPI/CAPI_LatencyStatistics.h b/LibOVR/Src/CAPI/CAPI_LatencyStatistics.h deleted file mode 100644 index 0c2f3bd..0000000 --- a/LibOVR/Src/CAPI/CAPI_LatencyStatistics.h +++ /dev/null @@ -1,178 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_LatencyStatistics.h -Content : Record latency statistics during rendering -Created : Sept 23, 2014 -Authors : Chris Taylor, Kevin Jenkins - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_CAPI_LatencyStatistics_h -#define OVR_CAPI_LatencyStatistics_h - -#include "../OVR_CAPI.h" -#include "../Kernel/OVR_Timer.h" -#include "../Kernel/OVR_Lockless.h" -#include "../Kernel/OVR_SysFile.h" -#include "CAPI_FrameTimeManager.h" - -namespace OVR { namespace CAPI { - - -// Define epoch period for lag statistics -#define OVR_LAG_STATS_EPOCH 1.0 /* seconds */ -// Define seconds without frames before resetting stats -#define OVR_LAG_STATS_RESET_LIMIT 2.0 /* seconds */ - - -//------------------------------------------------------------------------------------- -// ***** LatencyStatisticsResults - -// Results from statistics collection -struct LatencyStatisticsResults -{ - // Number of seconds of data represented by these statistics. - double IntervalSeconds; - - // Frames per second during the epoch. - double FPS; - - // Measures average time for EndFrame() call over each of the frames. - double EndFrameExecutionTime; - - // Measures the time between first scanline and first pose request before app starts rendering eyes. - float LatencyRender; - - // Measures the time between first scanline and distortion/timewarp rendering. - float LatencyTimewarp; - - // Time between Present() call and photon emission from first scanline of screen - float LatencyPostPresent; - - // Measures the time from receiving the camera frame until vision CPU processing completes. - double LatencyVisionProc; - - // Measures the time from exposure until the pose is available for the frame, including processing time. - double LatencyVisionFrame; -}; - -//----------------------------------------------------------------------------- -typedef Delegate1 LatencyStatisticsSlot; - -// ***** LatencyStatisticsObserver -class LatencyStatisticsCSV -{ -public: - LatencyStatisticsCSV(); - ~LatencyStatisticsCSV(); - bool Start(String fileName, String userData1); - bool Stop(); - void OnResults(LatencyStatisticsResults *results); - - // Internal - void WriteHeaderV1(); - void WriteResultsV1(LatencyStatisticsResults *results); - ObserverScope* GetObserver() { return &_Observer; } - -protected: - ObserverScope _Observer; - String Guid, UserData1; - String FileName; - OVR::SysFile _File; - String OS, OSVersion, ProcessInfo, DisplayDriverVersion, CameraDriverVersion, GPUVersion; -}; - -//----------------------------------------------------------------------------- -// ***** LatencyStatisticsCalculator - -// Calculator for latency statistics -class LagStatsCalculator -{ - // Statistics instrumentation inputs: - - // Timestamp when the EndFrame() call started executing - double EndFrameStartTime; - // Timestamp when the EndFrame() call finished executing - double EndFrameEndTime; - - // Latency statistics for the epoch - LatencyStatisticsResults latencyStatisticsData; - - // Last latency data - // float LatencyData[3]; // render, timewarp, median post-present - - // Last vision processing frame counter number - uint32_t LastCameraFrameCounter; - - // Running statistics: - - void resetPerfStats(double resetTime = 0.); - - // Start of the current statistics epoch - double EpochBegin; - // Count of frames in this stats epoch, measured at EndFrame() - int FrameCount; - // Sum of end frame durations for this stats epoch - //double EndFrameSum; - - // Sum of latencies - // double LatencySum[3]; - - // Sum of vision processing times - //double VisionProcSum; - // Sum of vision latency times - //double VisionLagSum; - // Count of vision frames - int VisionFrames; - - // Statistics results: - - LocklessUpdater Results; - - void calculateResults(); - - OVR::ObserverScope calculateResultsSubject; - OVR::Lock calculateResultsLock; - -public: - LagStatsCalculator(); - - void GetLatestResults(LatencyStatisticsResults* results); - void AddResultsObserver(ObserverScope *calculateResultsObserver); - -public: - // Internal instrumentation interface: - - // EndFrame() instrumentation - void InstrumentEndFrameStart(double timestamp); - void InstrumentEndFrameEnd(double timestamp); - - // DK2 latency tester instrumentation - // Note: This assumes that it is called right before InstrumentEndFrameEnd() - void InstrumentLatencyTimings(FrameTimeManager& ftm); - - // Eye pose instrumentation - void InstrumentEyePose(const ovrTrackingState& state); -}; - - -}} // namespace OVR::CAPI - -#endif // OVR_CAPI_LatencyStatistics_h diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp deleted file mode 100644 index 6439b57..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.cpp +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D10_DistortionRenderer.cpp -Content : Distortion renderer instantiation for D3D10 -Created : November 11, 2013 -Authors : Volga Aksoy, Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#define OVR_D3D_VERSION 10 -#include "CAPI_D3D1X_Util.cpp" -#include "CAPI_D3D1X_DistortionRenderer.cpp" diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h deleted file mode 100644 index a6750f5..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_DistortionRenderer.h +++ /dev/null @@ -1,34 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D10_DistortionRenderer.h -Content : Distortion renderer header for D3D10 -Created : November 11, 2013 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef INC_CAPI_D3D10_DistortionRenderer_h -#define INC_CAPI_D3D10_DistortionRenderer_h - -#define OVR_D3D_VERSION 10 -#include "CAPI_D3D1X_DistortionRenderer.h" -#undef OVR_D3D_VERSION - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp deleted file mode 100644 index 33deffa..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D10_HSWDisplay.cpp -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#define OVR_D3D_VERSION 10 -#include "CAPI_D3D1X_HSWDisplay.cpp" -#undef OVR_D3D_VERSION - - - - - - diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h deleted file mode 100644 index c681c73..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D10_HSWDisplay.h +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D10_HSWDisplay.h -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_CAPI_D3D10_HSWDisplay_h -#define OVR_CAPI_D3D10_HSWDisplay_h - -#if !defined(OVR_D3D_VERSION) || ((OVR_D3D_VERSION != 10) && (OVR_D3D_VERSION != 11)) - #error This header expects OVR_D3D_VERSION to be defined, to 10 or 11. -#endif - -// Due to the similarities between DX10 and DX11, there is a shared implementation of the headers and source -// which is differentiated only by the OVR_D3D_VERSION define. This define causes D3D_NS (D3D namespace) to -// be defined to either D3D10 or D3D11, as well as other similar effects. -#include "CAPI_D3D1X_HSWDisplay.h" - - -#endif // OVR_CAPI_D3D10_HSWDisplay_h - diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp index 2ba9ccc..334869c 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.cpp @@ -1,30 +1,1677 @@ -/************************************************************************************ - -Filename : CAPI_D3D11_DistortionRenderer.cpp -Content : Distortion renderer instantiation for D3D11 -Created : November 11, 2013 -Authors : Volga Aksoy, Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#define OVR_D3D_VERSION 11 -#include "CAPI_D3D1X_Util.cpp" -#include "CAPI_D3D1X_DistortionRenderer.cpp" - +/************************************************************************************ + +Filename : CAPI_D3D11_DistortionRenderer.cpp +Content : Experimental distortion renderer +Created : November 11, 2013 +Authors : Volga Aksoy, Michael Antonov, Shariq Hashme + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_D3D11_DistortionRenderer.h" + +#include "OVR_CAPI_D3D.h" +#include "../CAPI_HMDState.h" +#include "Kernel/OVR_Color.h" +#include "../Textures/overdriveLut_dk2.h" + +#include "../../Displays/OVR_Win32_Dxgi_Display.h" // Display driver timing info + + +namespace OVR { namespace CAPI { namespace D3D11 { + +#include "Shaders/Distortion_ps.h" +#include "Shaders/DistortionChroma_vs.h" +#include "Shaders/DistortionChroma_ps.h" +#include "Shaders/DistortionTimewarpChroma_vs.h" +#include "Shaders/DistortionCS2x2.h" + +#include "Shaders/SimpleQuad_vs.h" +#include "Shaders/SimpleQuad_ps.h" + +#include "Tracing/Tracing.h" + +#include +DEFINE_GUID(IID_OVRDXGISwapchain, 0x868f9b4f, 0xe427, 0x46ed, 0xb0, 0x94, 0x66, 0xd1, 0x3b, 0xb, 0x48, 0xf7); + +[uuid(E741B60E-3AC8-418A-AB3C-26C1D4EDD33B)] +interface IOVRDXGISwapChain : IUnknown +{ + virtual HRESULT GetDirectBuffer(REFIID riid, void** ppv) = 0; +}; + +#include + +// Distortion pixel shader lookup. +// Bit 0: Chroma Correction +// Bit 1: Timewarp + +enum { + DistortionVertexShaderBitMask = 3, + DistortionVertexShaderCount = DistortionVertexShaderBitMask + 1, + DistortionPixelShaderBitMask = 0, + DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1, +}; + +struct PrecompiledShader +{ + const unsigned char* ShaderData; + size_t ShaderSize; + const ShaderBase::Uniform* ReflectionData; + size_t ReflectionSize; +}; + +// To add a new distortion shader use these macros (with or w/o reflection) +#define PCS_NOREFL(shader) { shader, sizeof(shader), NULL, 0 } +#define PCS_REFL__(shader) { shader, sizeof(shader), shader ## _refl, sizeof( shader ## _refl )/sizeof(*(shader ## _refl)) } + + +static PrecompiledShader DistortionVertexShaderLookup[DistortionVertexShaderCount] = +{ + PCS_REFL__(DistortionChroma_vs), + PCS_REFL__(DistortionTimewarpChroma_vs), + PCS_REFL__(DistortionTimewarpChroma_vs), + { NULL, 0, NULL, 0 }, +}; + +static PrecompiledShader DistortionPixelShaderLookup[DistortionPixelShaderCount] = +{ + PCS_REFL__(DistortionChroma_ps) +}; + +enum +{ + DistortionComputeShader2x2 = 0, + DistortionComputeShaderCount +}; +static PrecompiledShader DistortionComputeShaderLookup[DistortionComputeShaderCount] = +{ + PCS_REFL__(DistortionCS2x2) +}; + + + +void DistortionShaderBitIndexCheck() +{ + OVR_COMPILER_ASSERT(ovrDistortionCap_TimeWarp == 2); +} + + + +struct DistortionVertex // Must match the VB description DistortionMeshVertexDesc +{ + Vector2f ScreenPosNDC; + Vector2f TanEyeAnglesR; + Vector2f TanEyeAnglesG; + Vector2f TanEyeAnglesB; + Color Col; +}; + +struct DistortionComputePin // Must match the ones declared in DistortionCS*.csh +{ + Vector2f TanEyeAnglesR; + Vector2f TanEyeAnglesG; + Vector2f TanEyeAnglesB; + Color Col; + int padding[1]; // Aligns to power-of-two boundary, increases performance significantly. +}; + + +// Vertex type; same format is used for all shapes for simplicity. +// Shapes are built by adding vertices to Model. +struct Vertex +{ + Vector3f Pos; + Color C; + float U, V; + Vector3f Norm; + + Vertex(const Vector3f& p, const Color& c = Color(64, 0, 0, 255), + float u = 0, float v = 0, Vector3f n = Vector3f(1, 0, 0)) + : Pos(p), C(c), U(u), V(v), Norm(n) + {} + Vertex(float x, float y, float z, const Color& c = Color(64, 0, 0, 255), + float u = 0, float v = 0) : Pos(x, y, z), C(c), U(u), V(v) + { } + + bool operator==(const Vertex& b) const + { + return Pos == b.Pos && C == b.C && U == b.U && V == b.V; + } +}; + + +//---------------------------------------------------------------------------- +// ***** D3D11::DistortionRenderer + +DistortionRenderer::DistortionRenderer() +{ + SrgbBackBuffer = false; + + EyeTextureSize[0] = Sizei(0); + EyeRenderViewport[0] = Recti(); + EyeTextureSize[1] = Sizei(0); + EyeRenderViewport[1] = Recti(); +} + +DistortionRenderer::~DistortionRenderer() +{ + destroy(); +} + +// static +CAPI::DistortionRenderer* DistortionRenderer::Create() +{ + return new DistortionRenderer; +} + + +bool DistortionRenderer::initializeRenderer(const ovrRenderAPIConfig* apiConfig) +{ + const ovrD3D11Config* config = (const ovrD3D11Config*)apiConfig; + + // Reset the frame index read failure count, as this function is called when + // switching between windowed and fullscreen mode. + FrameIndexFailureCount = 0; + + if (!config) + { + // Cleanup + pEyeTextures[0].Clear(); + pEyeTextures[1].Clear(); + pEyeDepthTextures[0].Clear(); + pEyeDepthTextures[1].Clear(); + memset(&RParams, 0, sizeof(RParams)); + return true; + } + + if (!config->D3D11.pDevice || !config->D3D11.pBackBufferRT) + return false; + + if (Display::GetDirectDisplayInitialized()) + { + Ptr ovrSwapChain; + if (config->D3D11.pSwapChain->QueryInterface(IID_OVRDXGISwapchain, (void**)&ovrSwapChain.GetRawRef()) == E_NOINTERFACE) + { + OVR_DEBUG_LOG_TEXT(("ovr_Initialize() or ovr_InitializeRenderingShim() wasn't called before DXGISwapChain was created.")); + } + } + + RParams.pDevice = config->D3D11.pDevice; + RParams.pContext = config->D3D11.pDeviceContext; + RParams.pBackBufferRT = config->D3D11.pBackBufferRT; + RParams.pBackBufferUAV = config->D3D11.pBackBufferUAV; + RParams.pSwapChain = config->D3D11.pSwapChain; + RParams.BackBufferSize = config->D3D11.Header.BackBufferSize; + RParams.Multisample = config->D3D11.Header.Multisample; + RParams.VidPnTargetId = 0; + + // set RParams.VidPnTargetId to the display target id for ETW tracing in order + // to match Microsoft-Windows-DxgKrnl's VSync event + IDXGIOutput *pOutput = NULL; + RParams.pSwapChain->GetContainingOutput(&pOutput); + if (pOutput) + { + // get the swapchain's DeviceName + DXGI_OUTPUT_DESC desc; + pOutput->GetDesc(&desc); + + // allocate the required buffers for QueryDisplayConfig (we don't need pModeInfoArray but it can't be NULL or less than needed) + UINT32 NumPathArrayElements = 0, NumModeInfoArrayElements = 0; + DISPLAYCONFIG_PATH_INFO *pPathInfoArray = NULL; + DISPLAYCONFIG_MODE_INFO *pModeInfoArray = NULL; + LONG st = ERROR_INSUFFICIENT_BUFFER; + while (ERROR_INSUFFICIENT_BUFFER == st) + { + st = GetDisplayConfigBufferSizes(QDC_ONLY_ACTIVE_PATHS, &NumPathArrayElements, &NumModeInfoArrayElements); + if (ERROR_SUCCESS != st) + { + OVR_DEBUG_LOG_TEXT(("Error: GetDisplayConfigBufferSizes failed with %ld\n", st)); + break; + } + + pPathInfoArray = new DISPLAYCONFIG_PATH_INFO[NumPathArrayElements]; + pModeInfoArray = new DISPLAYCONFIG_MODE_INFO[NumModeInfoArrayElements]; + + st = QueryDisplayConfig(QDC_ONLY_ACTIVE_PATHS, &NumPathArrayElements, pPathInfoArray, &NumModeInfoArrayElements, pModeInfoArray, NULL); + if (ERROR_SUCCESS != st) OVR_DEBUG_LOG_TEXT(("Error: QueryDisplayConfig failed with %ld\n", st)); + } + + // search for matching display targets for the SwapChain's display source + if (ERROR_SUCCESS == st) + { + for (UINT32 i = 0; i < NumPathArrayElements; ++i) + { + DISPLAYCONFIG_PATH_INFO *p = &pPathInfoArray[i]; + + DISPLAYCONFIG_SOURCE_DEVICE_NAME sdn; + sdn.header.size = sizeof(sdn); + sdn.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_SOURCE_NAME; + sdn.header.adapterId = p->sourceInfo.adapterId; + sdn.header.id = p->sourceInfo.id; + st = DisplayConfigGetDeviceInfo(&sdn.header); + + DISPLAYCONFIG_TARGET_DEVICE_NAME tdn; + tdn.header.size = sizeof(tdn); + tdn.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME; + tdn.header.adapterId = p->targetInfo.adapterId; + tdn.header.id = p->targetInfo.id; + st = DisplayConfigGetDeviceInfo(&tdn.header); + + if (wcsncmp(sdn.viewGdiDeviceName, desc.DeviceName, sizeof(desc.DeviceName)) == 0) + { + // pick anything if nothing was found yet, else give precedence to "Rift" monitors on this display device + static const wchar_t Rift[] = { L'R', L'i', L'f', L't' }; + if (!RParams.VidPnTargetId || (wcsncmp(tdn.monitorFriendlyDeviceName, Rift, sizeof(Rift)) == 0)) + { + RParams.VidPnTargetId = p->targetInfo.id; + OVR_DEBUG_LOG_TEXT(("Debug: Found VidPnTargetId=%d for display %d name=\"%ls\"\n", RParams.VidPnTargetId, p->sourceInfo.id, tdn.monitorFriendlyDeviceName)); + } + } + } + } + + delete [] pPathInfoArray; + delete [] pModeInfoArray; + + pOutput->Release(); + } + + GfxState = *new GraphicsState(RParams.pContext); + + D3D11_RENDER_TARGET_VIEW_DESC backBufferDesc; + RParams.pBackBufferRT->GetDesc(&backBufferDesc); + SrgbBackBuffer = (backBufferDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) || + (backBufferDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB) || + (backBufferDesc.Format == DXGI_FORMAT_B8G8R8X8_UNORM_SRGB); + + +#if 0 // enable related section in DistortionChroma.psh shader + // aniso requires proper sRGB sampling + SampleMode hqFilter = (RenderState->DistortionCaps & ovrDistortionCap_HqDistortion) ? Sample_Anisotropic : Sample_Linear; +#else + SampleMode hqFilter = Sample_Linear; +#endif + + pEyeTextures[0] = *new Texture(&RParams, Texture_RGBA, Sizei(0), + getSamplerState(hqFilter | Sample_ClampBorder)); + pEyeTextures[1] = *new Texture(&RParams, Texture_RGBA, Sizei(0), + getSamplerState(hqFilter | Sample_ClampBorder)); + + pEyeDepthTextures[0] = *new Texture(&RParams, Texture_Depth, Sizei(0), + getSamplerState(hqFilter | Sample_ClampBorder)); + pEyeDepthTextures[1] = *new Texture(&RParams, Texture_Depth, Sizei(0), + getSamplerState(hqFilter | Sample_ClampBorder)); + + if (!initBuffersAndShaders()) + { + return false; + } + + // Rasterizer state + D3D11_RASTERIZER_DESC rs; + memset(&rs, 0, sizeof(rs)); + rs.AntialiasedLineEnable = true; + rs.CullMode = D3D11_CULL_BACK; + rs.DepthClipEnable = true; + rs.FillMode = D3D11_FILL_SOLID; + Rasterizer = NULL; + RParams.pDevice->CreateRasterizerState(&rs, &Rasterizer.GetRawRef()); + + initOverdrive(); + + // TBD: Blend state.. not used? + // We'll want to turn off blending + + GpuProfiler.Init(RParams.pDevice, RParams.pContext); + + return true; +} + +void DistortionRenderer::initOverdrive() +{ + if (RenderState->DistortionCaps & ovrDistortionCap_Overdrive) + { + LastUsedOverdriveTextureIndex = 0; + + D3D11_RENDER_TARGET_VIEW_DESC backBufferDesc; + RParams.pBackBufferRT->GetDesc(&backBufferDesc); + + for (int i = 0; i < NumOverdriveTextures; i++) + { + pOverdriveTextures[i] = *new Texture(&RParams, Texture_RGBA, RParams.BackBufferSize, + getSamplerState(Sample_Linear | Sample_ClampBorder)); + + D3D11_TEXTURE2D_DESC dsDesc; + dsDesc.Width = RParams.BackBufferSize.w; + dsDesc.Height = RParams.BackBufferSize.h; + dsDesc.MipLevels = 1; + dsDesc.ArraySize = 1; + dsDesc.Format = backBufferDesc.Format; + dsDesc.SampleDesc.Count = 1; + dsDesc.SampleDesc.Quality = 0; + dsDesc.Usage = D3D11_USAGE_DEFAULT; + dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET; + dsDesc.CPUAccessFlags = 0; + dsDesc.MiscFlags = 0; + + HRESULT hr = RParams.pDevice->CreateTexture2D(&dsDesc, NULL, &pOverdriveTextures[i]->Tex.GetRawRef()); + if (FAILED(hr)) + { + OVR_DEBUG_LOG_TEXT(("Failed to create overdrive texture.")); + // Remove overdrive flag since we failed to create the texture + LastUsedOverdriveTextureIndex = -1; // disables feature + break; + } + + RParams.pDevice->CreateShaderResourceView(pOverdriveTextures[i]->Tex, NULL, &pOverdriveTextures[i]->TexSv.GetRawRef()); + RParams.pDevice->CreateRenderTargetView(pOverdriveTextures[i]->Tex, NULL, &pOverdriveTextures[i]->TexRtv.GetRawRef()); + } + + const int dimSize = 256; + OVR_COMPILER_ASSERT(dimSize * dimSize * 4 == sizeof(overdriveLut_dk2)); + OverdriveLutTexture = *new Texture(&RParams, Texture_RGBA, Sizei(dimSize, dimSize), + getSamplerState(Sample_Linear | Sample_Clamp), overdriveLut_dk2, 1); + } + else + { + LastUsedOverdriveTextureIndex = -1; + } +} + +void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) +{ + if (eyeTexture) + { + const ovrD3D11Texture* tex = (const ovrD3D11Texture*)eyeTexture; + + // Use tex->D3D11.Header.RenderViewport to update UVs for rendering in case they changed. + // TBD: This may be optimized through some caching. + EyeTextureSize[eyeId] = tex->D3D11.Header.TextureSize; + EyeRenderViewport[eyeId] = tex->D3D11.Header.RenderViewport; + + const ovrEyeRenderDesc& erd = RenderState->EyeRenderDesc[eyeId]; + + ovrHmd_GetRenderScaleAndOffset(erd.Fov, + EyeTextureSize[eyeId], EyeRenderViewport[eyeId], + UVScaleOffset[eyeId]); + + if (RenderState->DistortionCaps & ovrDistortionCap_FlipInput) + { + UVScaleOffset[eyeId][0].y = -UVScaleOffset[eyeId][0].y; + UVScaleOffset[eyeId][1].y = 1.0f - UVScaleOffset[eyeId][1].y; + } + + // Get multisample count from texture + D3D11_TEXTURE2D_DESC desc; + tex->D3D11.pTexture->GetDesc(&desc); + + pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->D3D11.pTexture, tex->D3D11.pSRView, + tex->D3D11.Header.TextureSize, desc.SampleDesc.Count); + } +} + +void DistortionRenderer::SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) +{ + SubmitEye(eyeId, eyeColorTexture); + + if (eyeDepthTexture) + { + const ovrD3D11Texture* depthTex = (const ovrD3D11Texture*)eyeDepthTexture; + + // Use tex->D3D11.Header.RenderViewport to update UVs for rendering in case they changed. + // TBD: This may be optimized through some caching. + EyeTextureSize[eyeId] = depthTex->D3D11.Header.TextureSize; + EyeRenderViewport[eyeId] = depthTex->D3D11.Header.RenderViewport; + + const ovrEyeRenderDesc& erd = RenderState->EyeRenderDesc[eyeId]; + + ovrHmd_GetRenderScaleAndOffset(erd.Fov, + EyeTextureSize[eyeId], EyeRenderViewport[eyeId], + UVScaleOffset[eyeId]); + + if (RenderState->DistortionCaps & ovrDistortionCap_FlipInput) + { + UVScaleOffset[eyeId][0].y = -UVScaleOffset[eyeId][0].y; + UVScaleOffset[eyeId][1].y = 1.0f - UVScaleOffset[eyeId][1].y; + } + + // Get multisample count from texture + D3D11_TEXTURE2D_DESC desc; + depthTex->D3D11.pTexture->GetDesc(&desc); + + pEyeDepthTextures[eyeId]->UpdatePlaceholderTexture(depthTex->D3D11.pTexture, depthTex->D3D11.pSRView, + depthTex->D3D11.Header.TextureSize, desc.SampleDesc.Count); + } +} + +void DistortionRenderer::renderEndFrame() +{ + renderDistortion(); + + if (RegisteredPostDistortionCallback) + RegisteredPostDistortionCallback(RParams.pContext); + + if (LatencyTest2Active) + { + renderLatencyPixel(LatencyTest2DrawColor); + } +} + +/******************************************************************/ +// Attempt to use DXGI for getting a previous vsync +double DistortionRenderer::getDXGILastVsyncTime() +{ + OVR_ASSERT(RParams.pSwapChain != nullptr); + + // If in driver mode, + if (!RenderState->OurHMDInfo.InCompatibilityMode) + { + // Prefer the driver mode + return 0.; + } + + // If failure count is exceeded, + if (FrameIndexFailureCount >= FrameIndexFailureLimit) + { + if (FrameIndexFailureCount == FrameIndexFailureLimit) + { + LogError("[D3D11DistortionRenderer] Performance Warning: DXGI GetFrameStatistics could not get Vsync timing. The game should be running in fullscreen mode on the Rift to get adequate timing information."); + ++FrameIndexFailureCount; + } + + return 0.; + } + + // Get frame statistics from the D3D11 renderer + DXGI_FRAME_STATISTICS stats; + HRESULT hr = RParams.pSwapChain->GetFrameStatistics(&stats); + if (SUCCEEDED(hr)) + { + FrameIndexFailureCount = 0; // Reset failure count + + // Return Vsync time in seconds + return stats.SyncQPCTime.QuadPart * Timer::GetPerfFrequencyInverse(); + } + + FrameIndexFailureCount++; // Increment failure count + return 0.; +} + +void DistortionRenderer::EndFrame(uint32_t frameIndex, bool swapBuffers) +{ + // Calculate the display frame index from the last known vsync time and + // corresponding display frame index + Timing->CalculateTimewarpTiming(frameIndex, getDXGILastVsyncTime()); + + // Don't spin if we are explicitly asked not to + if ( (RenderState->DistortionCaps & ovrDistortionCap_TimeWarp) && + (RenderState->DistortionCaps & ovrDistortionCap_TimewarpJitDelay) && + !(RenderState->DistortionCaps & ovrDistortionCap_ProfileNoSpinWaits)) + { + if (!Timing->NeedDistortionTimeMeasurement()) + { + // Wait for timewarp distortion if it is time and Gpu idle + FlushGpuAndWaitTillTime(Timing->GetTimewarpTiming()->JIT_TimewarpTime); + + renderEndFrame(); + } + else + { + // If needed, measure distortion time so that TimeManager can better estimate + // latency-reducing time-warp wait timing. + WaitUntilGpuIdle(); + double distortionStartTime = ovr_GetTimeInSeconds(); + + renderEndFrame(); + + WaitUntilGpuIdle(); + Timing->AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + } + } + else + { + renderEndFrame(); + } + + if (LatencyTestActive) + { + renderLatencyQuad(LatencyTestDrawColor); + } + + if (swapBuffers) + { + if (RParams.pSwapChain) + { + TraceDistortionPresent(RParams.VidPnTargetId, 0); + + UINT swapInterval = (RenderState->EnabledHmdCaps & ovrHmdCap_NoVSync) ? 0 : 1; + RParams.pSwapChain->Present(swapInterval, 0); + + // Force GPU to flush the scene, resulting in the lowest possible latency. + // It's critical that this flush is *after* present. + // With the display driver this flush is obsolete and theoretically should + // be a no-op. + // Doesn't need to be done if running through the Oculus driver. + if (RenderState->OurHMDInfo.InCompatibilityMode && + !(RenderState->DistortionCaps & ovrDistortionCap_ProfileNoSpinWaits)) + { + WaitUntilGpuIdle(); + } + } + else + { + // TBD: Generate error - swapbuffer option used with null swapchain. + } + } + + TraceDistortionEnd(RParams.VidPnTargetId, 0); +} + + +void DistortionRenderer::WaitUntilGpuIdle() +{ + HRESULT hr; + + TraceDistortionWaitGPU(RParams.VidPnTargetId, 0); + + // Flush and Stall CPU while waiting for GPU to complete rendering all of the queued draw calls + D3D11_QUERY_DESC queryDesc = { D3D11_QUERY_EVENT, 0 }; + Ptr query; + hr = RParams.pDevice->CreateQuery(&queryDesc, &query.GetRawRef()); + + if (SUCCEEDED(hr)) + { + RParams.pContext->End(query); + + // This flush is very important to measure Present() time in practice and prevent the + // GPU from allowing us to queue ahead unintentionally in extended mode. + RParams.pContext->Flush(); + + for (;;) + { + BOOL done = FALSE; + hr = RParams.pContext->GetData(query, &done, sizeof(done), 0); + + // Exit on failure to avoid infinite loop. + if (FAILED(hr)) + { + break; + } + + // If event succeeded and it's done, + if (SUCCEEDED(hr) && done) + { + break; + } + } + } +} + +double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) +{ + RParams.pContext->Flush(); + return WaitTillTime(absTime); +} + +bool DistortionRenderer::initBuffersAndShaders() +{ + if (RenderState->DistortionCaps & ovrDistortionCap_ComputeShader) + { + // Compute shader distortion grid. + // TODO - only do this if the CS is actually enabled? + for (int eyeNum = 0; eyeNum < 2; eyeNum++) + { + // Compute shader setup of regular grid. + DistortionMeshVBs[eyeNum] = NULL; + DistortionMeshIBs[eyeNum] = NULL; + + // These constants need to match those declared in the shader in DistortionCS*.csh + const int gridSizeInPixels = 16; + const int pinsPerEdge = 128; + + + // TODO: clean up this mess! + ovrEyeType eyeType = RenderState->EyeRenderDesc[eyeNum].Eye; + ovrFovPort fov = RenderState->EyeRenderDesc[eyeNum].Fov; + + HmdRenderInfo const & hmdri = RenderState->RenderInfo; + DistortionRenderDesc const & distortion = RenderState->Distortion[eyeType]; + + + // Find the mapping from TanAngle space to target NDC space. + ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(fov); + + //const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; + OVR_ASSERT(gridSizeInPixels * (pinsPerEdge - 1) > hmdri.ResolutionInPixels.w / 2); + OVR_ASSERT(gridSizeInPixels * (pinsPerEdge - 1) > hmdri.ResolutionInPixels.h); + DistortionComputePin Verts[pinsPerEdge*pinsPerEdge]; + // Vertices are laid out in a vertical scanline pattern, + // scanning right to left, then within each scan going top to bottom, like DK2. + // If we move to a different panel orientation, we may need to flip this around. + int vertexNum = 0; + for (int x = 0; x < pinsPerEdge; x++) + { + for (int y = 0; y < pinsPerEdge; y++) + { + int pixX = x * gridSizeInPixels; + int pixY = y * gridSizeInPixels; +#if 0 + // Simple version, ignoring pentile offsets + Vector2f screenPosNdc; + screenPosNdc.x = 2.0f * (0.5f - ((float)pixX / (hmdri.ResolutionInPixels.w / 2))); // Note signs! + screenPosNdc.y = 2.0f * (-0.5f + ((float)pixY / hmdri.ResolutionInPixels.h)); // Note signs! + + DistortionMeshVertexData vertex = DistortionMeshMakeVertex(screenPosNdc, + (eyeNum == 1), + hmdri, + distortion, + eyeToSourceNDC); + DistortionComputePin *pCurVert = &(Verts[vertexNum]); + pCurVert->TanEyeAnglesR = vertex.TanEyeAnglesR; + pCurVert->TanEyeAnglesG = vertex.TanEyeAnglesG; + pCurVert->TanEyeAnglesB = vertex.TanEyeAnglesB; +#else + // Pentile offsets are messy. + Vector2f screenPos[3]; // R=0, G=1, B=2 + DistortionMeshVertexData vertexRGB[3]; + screenPos[1] = Vector2f((float)pixX, (float)pixY); + screenPos[0] = screenPos[1]; + screenPos[2] = screenPos[1]; + + + for (int i = 0; i < 3; i++) + { + Vector2f screenPosNdc; + screenPosNdc.x = 2.0f * (0.5f - (screenPos[i].x / (hmdri.ResolutionInPixels.w / 2))); // Note signs! + screenPosNdc.y = 2.0f * (-0.5f + (screenPos[i].y / hmdri.ResolutionInPixels.h)); // Note signs! + vertexRGB[i] = DistortionMeshMakeVertex(screenPosNdc, + (eyeNum == 1), + hmdri, + distortion, + eyeToSourceNDC); + } + // Most data (fade, TW interpolate, etc) comes from the green channel. + DistortionMeshVertexData vertex = vertexRGB[1]; + DistortionComputePin *pCurVert = &(Verts[vertexNum]); + pCurVert->TanEyeAnglesR = vertexRGB[0].TanEyeAnglesR; + pCurVert->TanEyeAnglesG = vertexRGB[1].TanEyeAnglesG; + pCurVert->TanEyeAnglesB = vertexRGB[2].TanEyeAnglesB; +#endif + + // vertex.Shade will go negative beyond the edges to produce correct intercept with the 0.0 plane. + // We want to preserve this, so bias and offset to fit [-1,+1] in a byte. + // The reverse wll be done in the shader. + float shade = Alg::Clamp(vertex.Shade * 0.5f + 0.5f, 0.0f, 1.0f); + pCurVert->Col.R = (OVR::UByte)(floorf(shade * 255.999f)); + pCurVert->Col.G = pCurVert->Col.R; + pCurVert->Col.B = pCurVert->Col.R; + pCurVert->Col.A = (OVR::UByte)(floorf(vertex.TimewarpLerp * 255.999f)); + + vertexNum++; + } + } + DistortionPinBuffer[eyeNum] = *new Buffer(&RParams); + DistortionPinBuffer[eyeNum]->Data(Buffer_Compute, Verts, vertexNum * sizeof(Verts[0]), sizeof(Verts[0])); + } + + } + else + { + for (int eyeNum = 0; eyeNum < 2; eyeNum++) + { + // Allocate & generate distortion mesh vertices. + DistortionPinBuffer[eyeNum] = NULL; + + ovrDistortionMesh meshData; + + // double startT = ovr_GetTimeInSeconds(); + + if (!CalculateDistortionMeshFromFOV(RenderState->RenderInfo, + RenderState->Distortion[eyeNum], + (RenderState->EyeRenderDesc[eyeNum].Eye == ovrEye_Left ? StereoEye_Left : StereoEye_Right), + RenderState->EyeRenderDesc[eyeNum].Fov, + RenderState->DistortionCaps, + &meshData)) + { + OVR_ASSERT(false); + return false; + } + + // double deltaT = ovr_GetTimeInSeconds() - startT; + // LogText("GenerateDistortion time = %f\n", deltaT); + + // Now parse the vertex data and create a render ready vertex buffer from it + DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC(sizeof(DistortionVertex) * meshData.VertexCount); + DistortionVertex * pCurVBVert = pVBVerts; + ovrDistortionVertex* pCurOvrVert = meshData.pVertexData; + + for (unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++) + { + pCurVBVert->ScreenPosNDC.x = pCurOvrVert->ScreenPosNDC.x; + pCurVBVert->ScreenPosNDC.y = pCurOvrVert->ScreenPosNDC.y; + pCurVBVert->TanEyeAnglesR = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesR); + pCurVBVert->TanEyeAnglesG = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesG); + pCurVBVert->TanEyeAnglesB = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesB); + + // Convert [0.0f,1.0f] to [0,255] + if (RenderState->DistortionCaps & ovrDistortionCap_Vignette) + pCurVBVert->Col.R = (uint8_t)(Alg::Max(pCurOvrVert->VignetteFactor, 0.0f) * 255.99f); + else + pCurVBVert->Col.R = 255; + + pCurVBVert->Col.G = pCurVBVert->Col.R; + pCurVBVert->Col.B = pCurVBVert->Col.R; + pCurVBVert->Col.A = (uint8_t)(pCurOvrVert->TimeWarpFactor * 255.99f); + pCurOvrVert++; + pCurVBVert++; + } + + DistortionMeshVBs[eyeNum] = *new Buffer(&RParams); + DistortionMeshVBs[eyeNum]->Data(Buffer_Vertex | Buffer_ReadOnly, pVBVerts, sizeof(DistortionVertex)* meshData.VertexCount); + DistortionMeshIBs[eyeNum] = *new Buffer(&RParams); + DistortionMeshIBs[eyeNum]->Data(Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, (sizeof(INT16)* meshData.IndexCount)); + + OVR_FREE(pVBVerts); + ovrHmd_DestroyDistortionMesh(&meshData); + } + } + + + // Uniform buffers + for (int i = 0; i < Shader_Count; i++) + { + UniformBuffers[i] = *new Buffer(&RParams); + //MaxTextureSet[i] = 0; + } + + initShaders(); + + return true; +} + + + +void DistortionRenderer::renderDistortion() +{ + // XXX takes a frameIndex second parameter, how do we get that here? + TraceDistortionBegin(RParams.VidPnTargetId, 0); + + Ptr ovrSwap; + HRESULT hr = RParams.pSwapChain->QueryInterface(IID_PPV_ARGS(&ovrSwap.GetRawRef())); + if (SUCCEEDED(hr)) + { + Ptr texture; + hr = ovrSwap->GetDirectBuffer(IID_PPV_ARGS(&texture.GetRawRef())); + if (SUCCEEDED(hr)) + { + Ptr rtv; + auto it = RenderTargetMap.Find(texture.GetPtr()); + if (it == RenderTargetMap.End()) + { + hr = RParams.pDevice->CreateRenderTargetView(texture, nullptr, &rtv.GetRawRef()); + if (SUCCEEDED(hr)) + { + RenderTargetMap.Add(texture.GetPtr(), rtv); + } + } + else + { + rtv = it->Second; + } + + if (rtv) + { + // The RenderTargets map holds the ref count on this for us + RParams.pBackBufferRT = rtv; + } + } + } + + RParams.pContext->HSSetShader(NULL, NULL, 0); + RParams.pContext->DSSetShader(NULL, NULL, 0); + RParams.pContext->GSSetShader(NULL, NULL, 0); + + RParams.pContext->RSSetState(Rasterizer); + + bool overdriveActive = IsOverdriveActive(); + int currOverdriveTextureIndex = -1; + + if (overdriveActive) + { + currOverdriveTextureIndex = (LastUsedOverdriveTextureIndex + 1) % NumOverdriveTextures; + ID3D11RenderTargetView* distortionRtv = pOverdriveTextures[currOverdriveTextureIndex]->TexRtv.GetRawRef(); + ID3D11RenderTargetView* mrtRtv[2] = { distortionRtv, RParams.pBackBufferRT }; + RParams.pContext->OMSetRenderTargets(2, mrtRtv, 0); + + RParams.pContext->ClearRenderTargetView(distortionRtv, RenderState->ClearColor); + } + else + { + RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0); + } + + // Not affected by viewport. + RParams.pContext->ClearRenderTargetView(RParams.pBackBufferRT, RenderState->ClearColor); + + setViewport(Recti(0, 0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); + + + for (int eyeNum = 0; eyeNum < 2; eyeNum++) + { + ShaderFill distortionShaderFill(DistortionShader); + distortionShaderFill.SetTexture(0, pEyeTextures[eyeNum], Shader_Pixel); + + if (pEyeDepthTextures[eyeNum]->Tex != NULL) + { + OVR_ASSERT(pEyeDepthTextures[eyeNum]->GetSamples() <= 4); + DistortionShader->SetUniform1f("depthMsaaSamples", (float)pEyeDepthTextures[eyeNum]->GetSamples()); + + // the shader will select the right version + distortionShaderFill.SetTexture(2, pEyeDepthTextures[eyeNum], Shader_Vertex); // DepthTexture4x + switch (pEyeDepthTextures[eyeNum]->GetSamples()) + { + case 1: distortionShaderFill.SetTexture(0, pEyeDepthTextures[eyeNum], Shader_Vertex); break; // Set DepthTexture1x + case 2: distortionShaderFill.SetTexture(1, pEyeDepthTextures[eyeNum], Shader_Vertex); break; // Set DepthTexture2x + case 4: distortionShaderFill.SetTexture(2, pEyeDepthTextures[eyeNum], Shader_Vertex); break; // Set DepthTexture4x + + default: + OVR_ASSERT(false); // unsupported MSAA sample count (requires shader update) + LogError("{ERR-105} [D3D1x] Unsupported MSAA sample count (requires D3D shader update)"); + } + + if (PositionTimewarpDesc.NearClip >= 0.0f && PositionTimewarpDesc.FarClip >= 0.0f) + { + float NearClip = PositionTimewarpDesc.NearClip; + float FarClip = PositionTimewarpDesc.FarClip; + + float DepthProjectorX = FarClip / (FarClip - NearClip); + float DepthProjectorY = (-FarClip * NearClip) / (FarClip - NearClip); + DistortionShader->SetUniform2f("DepthProjector", DepthProjectorX, DepthProjectorY); + } + else + { + OVR_ASSERT(false); + LogError("{ERR-101} [D3D1x] Invalid ovrPositionTimewarpDesc data provided by client."); + + DistortionShader->SetUniform2f("DepthProjector", 1.0f, 1.0f); + } + + // DepthProjector values can also be calculated as: + //float DepthProjectorX = FarClip / (FarClip - NearClip); + //float DepthProjectorY = (-FarClip * NearClip) / (FarClip - NearClip); + //DistortionShader->SetUniform2f("DepthProjector", -eyeProj[eyeNum].M[2][2], eyeProj[eyeNum].M[2][3]); + DistortionShader->SetUniform2f("DepthDimSize", (float)pEyeDepthTextures[eyeNum]->TextureSize.w, + (float)pEyeDepthTextures[eyeNum]->TextureSize.h); + } + else + { + // -1.0 disables the use of the depth buffer + DistortionShader->SetUniform1f("depthMsaaSamples", -1.0f); + } + + if (RenderState->DistortionCaps & ovrDistortionCap_HqDistortion) + { + static float aaDerivMult = 1.0f; + DistortionShader->SetUniform1f("AaDerivativeMult", aaDerivMult); + } + else + { + // 0.0 disables high quality anti-aliasing + DistortionShader->SetUniform1f("AaDerivativeMult", -1.0f); + } + + if (overdriveActive) + { + distortionShaderFill.SetTexture(1, pOverdriveTextures[LastUsedOverdriveTextureIndex], Shader_Pixel); + distortionShaderFill.SetTexture(2, OverdriveLutTexture, Shader_Pixel); + + // Toggle this to compare LUTs vs analytical values for overdrive + static bool enableLut = false; + + float overdriveScaleRegularRise; + float overdriveScaleRegularFall; + GetOverdriveScales(overdriveScaleRegularRise, overdriveScaleRegularFall); + DistortionShader->SetUniform3f("OverdriveScales", enableLut ? 2.0f : 1.0f, + overdriveScaleRegularRise, overdriveScaleRegularFall); + } + else + { + // -1.0f disables PLO + DistortionShader->SetUniform3f("OverdriveScales", -1.0f, -1.0f, -1.0f); + } + + distortionShaderFill.SetInputLayout(DistortionVertexIL); + + DistortionShader->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y); + DistortionShader->SetUniform2f("EyeToSourceUVOffset", UVScaleOffset[eyeNum][1].x, UVScaleOffset[eyeNum][1].y); + + + if (RenderState->DistortionCaps & ovrDistortionCap_TimeWarp) + { + Matrix4f startEndMatrices[2]; + double timewarpIMUTime = 0.; + // TODO: if (pEyeDepthTextures[eyeNum]->Tex != NULL), need to use CalculateTimewarpFromSensors instead. + CalculateOrientationTimewarpFromSensors( + RenderState->EyeRenderPoses[eyeNum].Orientation, + SensorReader, Timing->GetTimewarpTiming()->EyeStartEndTimes[eyeNum], + startEndMatrices, timewarpIMUTime); + Timing->SetTimewarpIMUTime(timewarpIMUTime); + + if (RenderState->DistortionCaps & ovrDistortionCap_ComputeShader) + { + DistortionShader->SetUniform3x3f("EyeRotationStart", startEndMatrices[0]); + DistortionShader->SetUniform3x3f("EyeRotationEnd", startEndMatrices[1]); + } + else + { + // Can feed identity like matrices incase of concern over timewarp calculations + DistortionShader->SetUniform4x4f("EyeRotationStart", startEndMatrices[0]); + DistortionShader->SetUniform4x4f("EyeRotationEnd", startEndMatrices[1]); + } + } + + + if (RenderState->DistortionCaps & ovrDistortionCap_ComputeShader) + { + //RParams.pContext->CSCSSetShaderResources + //RParams.pContext->CSSetUnorderedAccessViews + //RParams.pContext->CSSetShader + //RParams.pContext->CSSetSamplers + //RParams.pContext->CSSetConstantBuffers + + + // These need to match the values used in the compiled shader + //const int gridSizeInPixels = 16; // GRID_SIZE_IN_PIXELS + //const int pinsPerEdge = 128; // PINS_PER_EDGE + const int nxnBlockSizeInPixels = 2; // NXN_BLOCK_SIZE_PIXELS + const int simdSquareSize = 16; // SIMD_SQUARE_SIZE + + const int invocationSizeInPixels = nxnBlockSizeInPixels * simdSquareSize; + + distortionShaderFill.SetTexture(0, pEyeTextures[eyeNum], Shader_Compute); + + DistortionShader->SetUniform1f("RightEye", (float)eyeNum); + DistortionShader->SetUniform1f("UseOverlay", 0.0f); // No overlay supported here. + DistortionShader->SetUniform1f("FbSizePixelsX", (float)RParams.BackBufferSize.w); + + + ShaderSet* shaders = distortionShaderFill.GetShaders(); + ShaderBase* cshader = ((ShaderBase*)shaders->GetShader(Shader_Compute)); + + ID3D11UnorderedAccessView *uavRendertarget = RParams.pBackBufferUAV; + int SizeX = RParams.BackBufferSize.w / 2; + int SizeY = RParams.BackBufferSize.h; + + int TileNumX = (SizeX + (invocationSizeInPixels - 1)) / invocationSizeInPixels; + int TileNumY = (SizeY + (invocationSizeInPixels - 1)) / invocationSizeInPixels; + + RParams.pContext->CSSetUnorderedAccessViews(0, 1, &uavRendertarget, NULL); + + + // Incoming eye-buffer textures start at t0 onwards, so set this in slot #4 + // Subtlety - can't put this in slot 0 because fill->Set stops at the first NULL texture. + ID3D11ShaderResourceView *d3dSrv = DistortionPinBuffer[eyeNum]->GetSrv(); + RParams.pContext->CSSetShaderResources(4, 1, &d3dSrv); + + // TODO: uniform/constant buffers + cshader->UpdateBuffer(UniformBuffers[Shader_Compute]); + cshader->SetUniformBuffer(UniformBuffers[Shader_Compute]); + + // Primitive type is ignored for CS. + // This call actually sets the textures and does pContext->CSSetShader(). Primitive type is ignored. + distortionShaderFill.Set(Prim_Unknown); + + RParams.pContext->Dispatch(TileNumX, TileNumY, 1); + } + else + { + renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], + NULL, 0, (int)DistortionMeshIBs[eyeNum]->GetSize() / 2, Prim_Triangles); + } + } + + LastUsedOverdriveTextureIndex = currOverdriveTextureIndex; + + // Re-activate to only draw on back buffer + if (overdriveActive) + { + RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0); + } +} + +void DistortionRenderer::createDrawQuad() +{ + const int numQuadVerts = 4; + LatencyTesterQuadVB = *new Buffer(&RParams); + if (!LatencyTesterQuadVB) + { + return; + } + + LatencyTesterQuadVB->Data(Buffer_Vertex, NULL, numQuadVerts * sizeof(Vertex)); + Vertex* vertices = (Vertex*)LatencyTesterQuadVB->Map(0, numQuadVerts * sizeof(Vertex), Map_Discard); + if (!vertices) + { + OVR_ASSERT(false); // failed to lock vertex buffer + return; + } + + const float left = -1.0f; + const float top = -1.0f; + const float right = 1.0f; + const float bottom = 1.0f; + + vertices[0] = Vertex(Vector3f(left, top, 0.0f), Color(255, 255, 255, 255)); + vertices[1] = Vertex(Vector3f(left, bottom, 0.0f), Color(255, 255, 255, 255)); + vertices[2] = Vertex(Vector3f(right, top, 0.0f), Color(255, 255, 255, 255)); + vertices[3] = Vertex(Vector3f(right, bottom, 0.0f), Color(255, 255, 255, 255)); + + LatencyTesterQuadVB->Unmap(vertices); +} + +void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor) +{ + const int numQuadVerts = 4; + + if (!LatencyTesterQuadVB) + { + createDrawQuad(); + } + + ShaderFill quadFill(SimpleQuadShader); + quadFill.SetInputLayout(SimpleQuadVertexIL); + + setViewport(Recti(0, 0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); + + float testerLuminance = (float)latencyTesterDrawColor[0] / 255.99f; + if (SrgbBackBuffer) + { + testerLuminance = pow(testerLuminance, 2.2f); + } + + SimpleQuadShader->SetUniform2f("Scale", 0.3f, 0.3f); + SimpleQuadShader->SetUniform4f("Color", testerLuminance, testerLuminance, testerLuminance, 1.0f); + + for (int eyeNum = 0; eyeNum < 2; eyeNum++) + { + SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.5f : 0.5f, 0.0f); + renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip); + } +} + +void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelColor) +{ + const int numQuadVerts = 4; + + if (!LatencyTesterQuadVB) + { + createDrawQuad(); + } + + ShaderFill quadFill(SimpleQuadShader); + quadFill.SetInputLayout(SimpleQuadVertexIL); + + setViewport(Recti(0, 0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); + + Vector3f testerColor = Vector3f((float)latencyTesterPixelColor[0] / 255.99f, + (float)latencyTesterPixelColor[1] / 255.99f, + (float)latencyTesterPixelColor[2] / 255.99f); + if (SrgbBackBuffer) + { + // 2.2 gamma is close enough for our purposes of matching sRGB + testerColor.x = pow(testerColor.x, 2.2f); + testerColor.y = pow(testerColor.y, 2.2f); + testerColor.z = pow(testerColor.z, 2.2f); + } + +#ifdef OVR_BUILD_DEBUG + SimpleQuadShader->SetUniform4f("Color", testerColor.x, testerColor.y, testerColor.z, 1.0f); + + Vector2f scale(20.0f / RParams.BackBufferSize.w, 20.0f / RParams.BackBufferSize.h); +#else + // sending in as gray scale + SimpleQuadShader->SetUniform4f("Color", testerColor.x, testerColor.x, testerColor.x, 1.0f); + + Vector2f scale(1.0f / RParams.BackBufferSize.w, 1.0f / RParams.BackBufferSize.h); +#endif + SimpleQuadShader->SetUniform2f("Scale", scale.x, scale.y); + + float xOffset = RenderState->RenderInfo.OffsetLatencyTester ? -0.5f * scale.x : 1.0f - scale.x; + float yOffset = 1.0f - scale.y; + + // Render the latency tester quad in the correct location. + if (RenderState->RenderInfo.Rotation == 270) + { + xOffset = -xOffset; + } + else if (RenderState->RenderInfo.Rotation == 180) + { + xOffset = -xOffset; + yOffset = -yOffset; + } + else if (RenderState->RenderInfo.Rotation == 90) + { + yOffset = -yOffset; + } + + SimpleQuadShader->SetUniform2f("PositionOffset", xOffset, yOffset); + + renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip); +} + +void DistortionRenderer::renderPrimitives( + const ShaderFill* fill, + Buffer* vertices, Buffer* indices, + Matrix4f* viewMatrix, int offset, int count, + PrimitiveType rprim) +{ + OVR_ASSERT(fill->GetInputLayout() != 0); + RParams.pContext->IASetInputLayout((ID3D11InputLayout*)fill->GetInputLayout()); + + if (indices) + { + RParams.pContext->IASetIndexBuffer(indices->GetBuffer(), DXGI_FORMAT_R16_UINT, 0); + } + + ID3D11Buffer* vertexBuffer = vertices->GetBuffer(); + UINT vertexStride = sizeof(Vertex); + UINT vertexOffset = offset; + RParams.pContext->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); + + ShaderSet* shaders = ((ShaderFill*)fill)->GetShaders(); + + ShaderBase* vshader = ((ShaderBase*)shaders->GetShader(Shader_Vertex)); + unsigned char* vertexData = vshader->UniformData; + if (vertexData) + { + // TODO: some VSes don't start with StandardUniformData! + if (viewMatrix) + { + StandardUniformData* stdUniforms = (StandardUniformData*)vertexData; + stdUniforms->View = viewMatrix->Transposed(); + stdUniforms->Proj = StdUniforms.Proj; + } + UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize); + vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]); + } + + for (int i = Shader_Vertex + 1; i < Shader_Count; i++) + { + if (shaders->GetShader(i)) + { + ((ShaderBase*)shaders->GetShader(i))->UpdateBuffer(UniformBuffers[i]); + ((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]); + } + } + + D3D11_PRIMITIVE_TOPOLOGY prim; + switch (rprim) + { + case Prim_Triangles: + prim = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST; + break; + case Prim_Lines: + prim = D3D11_PRIMITIVE_TOPOLOGY_LINELIST; + break; + case Prim_TriangleStrip: + prim = D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; + break; + default: + OVR_ASSERT(0); + return; + } + RParams.pContext->IASetPrimitiveTopology(prim); + + fill->Set(rprim); + + if (indices) + { + RParams.pContext->DrawIndexed(count, 0, 0); + } + else + { + RParams.pContext->Draw(count, 0); + } +} + +void DistortionRenderer::setViewport(const Recti& vp) +{ + D3D11_VIEWPORT d3dvp; + + d3dvp.Width = (float)vp.w; + d3dvp.Height = (float)vp.h; + d3dvp.TopLeftX = (float)vp.x; + d3dvp.TopLeftY = (float)vp.y; + d3dvp.MinDepth = 0; + d3dvp.MaxDepth = 1; + RParams.pContext->RSSetViewports(1, &d3dvp); +} + + + +// Must match struct DistortionVertex +static D3D11_INPUT_ELEMENT_DESC DistortionMeshVertexDesc[] = +{ + { "Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TexCoord", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TexCoord", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 32, D3D11_INPUT_PER_VERTEX_DATA, 0 }, +}; + +static D3D11_INPUT_ELEMENT_DESC SimpleQuadMeshVertexDesc[] = +{ + { "Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, +}; + + +void DistortionRenderer::initShaders() +{ + if ((RenderState->DistortionCaps & ovrDistortionCap_ComputeShader) != 0) + { + // Compute shader + DistortionShader = *new ShaderSet; + + int shaderNum = DistortionComputeShader2x2; + + PrecompiledShader psShaderByteCode = DistortionComputeShaderLookup[shaderNum]; + Ptr cs = *new D3D11::ComputeShader( + &RParams, + (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize, + psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize); + + DistortionShader->SetShader(cs); + } + else + { + // Vertex + pixel distortion shader. + PrecompiledShader& vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & RenderState->DistortionCaps]; + if (vsShaderByteCode.ShaderData != NULL) + { + Ptr vtxShader = *new D3D11::VertexShader( + &RParams, + (void*)vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize, + vsShaderByteCode.ReflectionData, vsShaderByteCode.ReflectionSize); + + DistortionVertexIL = NULL; + ID3D11InputLayout** objRef = &DistortionVertexIL.GetRawRef(); + + HRESULT validate = RParams.pDevice->CreateInputLayout( + DistortionMeshVertexDesc, sizeof(DistortionMeshVertexDesc) / sizeof(DistortionMeshVertexDesc[0]), + vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize, objRef); + OVR_UNUSED(validate); + + DistortionShader = *new ShaderSet; + DistortionShader->SetShader(vtxShader); + } + else + { + OVR_ASSERT_M(false, "Unsupported distortion feature used\n"); + } + + PrecompiledShader& psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & RenderState->DistortionCaps]; + if (psShaderByteCode.ShaderData) + { + Ptr ps = *new D3D11::PixelShader( + &RParams, + (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize, + psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize); + + DistortionShader->SetShader(ps); + } + else + { + OVR_ASSERT_M(false, "Unsupported distortion feature used\n"); + } + } + + { + Ptr vtxShader = *new D3D11::VertexShader( + &RParams, + (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs), + SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0])); + //NULL, 0); + + SimpleQuadVertexIL = NULL; + ID3D11InputLayout** objRef = &SimpleQuadVertexIL.GetRawRef(); + + HRESULT validate = RParams.pDevice->CreateInputLayout( + SimpleQuadMeshVertexDesc, sizeof(SimpleQuadMeshVertexDesc) / sizeof(SimpleQuadMeshVertexDesc[0]), + (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs), objRef); + OVR_UNUSED(validate); + + SimpleQuadShader = *new ShaderSet; + SimpleQuadShader->SetShader(vtxShader); + + Ptr ps = *new D3D11::PixelShader( + &RParams, + (void*)SimpleQuad_ps, sizeof(SimpleQuad_ps), + SimpleQuad_ps_refl, sizeof(SimpleQuad_ps_refl) / sizeof(SimpleQuad_ps_refl[0])); + + SimpleQuadShader->SetShader(ps); + } +} + + + +ID3D11SamplerState* DistortionRenderer::getSamplerState(int sm) +{ + if (SamplerStates[sm]) + return SamplerStates[sm]; + + D3D11_SAMPLER_DESC ss; + memset(&ss, 0, sizeof(ss)); + switch(sm & Sample_AddressMask) + { + case Sample_Clamp: ss.AddressU = ss.AddressV = ss.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; break; + case Sample_ClampBorder: ss.AddressU = ss.AddressV = ss.AddressW = D3D11_TEXTURE_ADDRESS_BORDER; break; + case Sample_Repeat: ss.AddressU = ss.AddressV = ss.AddressW = D3D11_TEXTURE_ADDRESS_WRAP; break; + case Sample_Mirror: ss.AddressU = ss.AddressV = ss.AddressW = D3D11_TEXTURE_ADDRESS_MIRROR; break; + default: OVR_ASSERT(false); + } + + switch(sm & Sample_FilterMask) + { + case Sample_Linear: + ss.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + break; + + case Sample_Nearest: + ss.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + break; + + case Sample_Anisotropic: + ss.Filter = D3D11_FILTER_ANISOTROPIC; + ss.MaxAnisotropy = 4; + break; + + default: OVR_ASSERT(false); + } + + ss.MaxLOD = 15; + RParams.pDevice->CreateSamplerState(&ss, &SamplerStates[sm].GetRawRef()); + return SamplerStates[sm]; +} + + +void DistortionRenderer::destroy() +{ + for (int eyeNum = 0; eyeNum < 2; eyeNum++) + { + DistortionMeshVBs[eyeNum].Clear(); + DistortionMeshIBs[eyeNum].Clear(); + DistortionPinBuffer[eyeNum].Clear(); + } + + DistortionVertexIL.Clear(); + + if (DistortionShader) + { + DistortionShader->UnsetShader(Shader_Vertex); + DistortionShader->UnsetShader(Shader_Pixel); + DistortionShader->UnsetShader(Shader_Compute); + DistortionShader.Clear(); + } + + LatencyTesterQuadVB.Clear(); +} + + +DistortionRenderer::GraphicsState::GraphicsState(ID3D11DeviceContext* c) + : context(c) + , memoryCleared(TRUE) + , rasterizerState(NULL) + //samplerStates[] + , inputLayoutState(NULL) + //psShaderResourceState[] + //vsShaderResourceState[] + //psConstantBuffersState[] + //vsConstantBuffersState[] + //renderTargetViewState[] + , depthStencilViewState(NULL) + , omBlendState(NULL) + //omBlendFactorState[] + , omSampleMaskState(0xffffffff) + , primitiveTopologyState(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED) + , iaIndexBufferPointerState(NULL) + , iaIndexBufferFormatState(DXGI_FORMAT_UNKNOWN) + , iaIndexBufferOffsetState(0) + //iaVertexBufferPointersState[] + //iaVertexBufferStridesState[] + //iaVertexBufferOffsetsState[] + , currentPixelShader(NULL) + , currentVertexShader(NULL) + , currentGeometryShader(NULL) + , currentHullShader(NULL) + , currentDomainShader(NULL) + , currentComputeShader(NULL) +{ + for (int i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + psSamplerStates[i] = NULL; + vsSamplerStates[i] = NULL; + csSamplerStates[i] = NULL; + } + + for (int i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + { + psShaderResourceState[i] = NULL; + vsShaderResourceState[i] = NULL; + csShaderResourceState[i] = NULL; + } + + for (int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + { + psConstantBuffersState[i] = NULL; + vsConstantBuffersState[i] = NULL; + csConstantBuffersState[i] = NULL; + } + + for (int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + renderTargetViewState[i] = NULL; + csUnorderedAccessViewState[i] = NULL; + } + + for (int i = 0; i < 4; i++) + omBlendFactorState[i] = NULL; + + for (int i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + { + iaVertexBufferPointersState[i] = NULL; + iaVertexBufferStridesState[i] = NULL; + iaVertexBufferOffsetsState[i] = NULL; + } +} + +#define SAFE_RELEASE(x) if ( (x) != NULL ) { (x)->Release(); (x)=NULL; } + +void DistortionRenderer::GraphicsState::clearMemory() +{ + SAFE_RELEASE(rasterizerState); + + for (int i = 0; i < D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) + { + SAFE_RELEASE(psSamplerStates[i]); + SAFE_RELEASE(vsSamplerStates[i]); + SAFE_RELEASE(csSamplerStates[i]); + } + + SAFE_RELEASE(inputLayoutState); + + for (int i = 0; i < D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) + { + SAFE_RELEASE(psShaderResourceState[i]); + SAFE_RELEASE(vsShaderResourceState[i]); + SAFE_RELEASE(csShaderResourceState[i]); + } + + for (int i = 0; i < D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) + { + SAFE_RELEASE(psConstantBuffersState[i]); + SAFE_RELEASE(vsConstantBuffersState[i]); + SAFE_RELEASE(csConstantBuffersState[i]); + } + + for (int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + SAFE_RELEASE(renderTargetViewState[i]); + SAFE_RELEASE(csUnorderedAccessViewState[i]); + } + + SAFE_RELEASE(depthStencilViewState); + SAFE_RELEASE(omBlendState); + SAFE_RELEASE(iaIndexBufferPointerState); + + for (int i = 0; i < D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) + { + SAFE_RELEASE(iaVertexBufferPointersState[i]); + } + + SAFE_RELEASE(currentPixelShader); + SAFE_RELEASE(currentVertexShader); + SAFE_RELEASE(currentGeometryShader); + + SAFE_RELEASE(currentHullShader); + SAFE_RELEASE(currentDomainShader); + SAFE_RELEASE(currentComputeShader); + + memoryCleared = TRUE; +} + +#undef SAFE_RELEASE + +DistortionRenderer::GraphicsState::~GraphicsState() +{ + clearMemory(); +} + + +void DistortionRenderer::GraphicsState::Save() +{ + if (!memoryCleared) + clearMemory(); + + memoryCleared = FALSE; + + context->RSGetState(&rasterizerState); + context->IAGetInputLayout(&inputLayoutState); + + context->PSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, psShaderResourceState); + context->PSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, psSamplerStates); + context->PSGetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, psConstantBuffersState); + + context->VSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, vsShaderResourceState); + context->VSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, vsSamplerStates); + context->VSGetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, vsConstantBuffersState); + + context->CSGetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, csShaderResourceState); + context->CSGetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, csSamplerStates); + context->CSGetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, csConstantBuffersState); + context->CSGetUnorderedAccessViews(0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, csUnorderedAccessViewState); + + context->OMGetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, renderTargetViewState, &depthStencilViewState); + + context->OMGetBlendState(&omBlendState, omBlendFactorState, &omSampleMaskState); + + context->IAGetPrimitiveTopology(&primitiveTopologyState); + + context->IAGetIndexBuffer(&iaIndexBufferPointerState, &iaIndexBufferFormatState, &iaIndexBufferOffsetState); + + context->IAGetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, iaVertexBufferPointersState, iaVertexBufferStridesState, iaVertexBufferOffsetsState); + + context->PSGetShader(¤tPixelShader, NULL, NULL); + context->VSGetShader(¤tVertexShader, NULL, NULL); + context->GSGetShader(¤tGeometryShader, NULL, NULL); + context->HSGetShader(¤tHullShader, NULL, NULL); + context->DSGetShader(¤tDomainShader, NULL, NULL); + context->CSGetShader(¤tComputeShader, NULL, NULL); + /* maybe above doesn't work; then do something with this (must test on dx11) + ID3D11ClassInstance* blank_array[0]; + UINT blank_uint = 0; + context->PSGetShader(¤tPixelShader, blank_array, blank_uint); + context->VSGetShader(¤tVertexShader, blank_array, blank_uint); + context->GSGetShader(¤tGeometryShader, blank_array, blank_uint); + context->HSGetShader(¤tHullShader, blank_array, blank_uint); + context->DSGetShader(¤tDomainShader, blank_array, blank_uint); + context->CSGetShader(¤tComputeShader, blank_array, blank_uint); + */ +} + + +void DistortionRenderer::GraphicsState::Restore() +{ + if (rasterizerState != NULL) + context->RSSetState(rasterizerState); + + if (inputLayoutState != NULL) + context->IASetInputLayout(inputLayoutState); + + context->PSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, psSamplerStates); + if (psShaderResourceState != NULL) + context->PSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, psShaderResourceState); + if (psConstantBuffersState != NULL) + context->PSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, psConstantBuffersState); + + context->VSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, vsSamplerStates); + if (vsShaderResourceState != NULL) + context->VSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, vsShaderResourceState); + if (vsConstantBuffersState != NULL) + context->VSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, vsConstantBuffersState); + + context->CSSetSamplers(0, D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT, csSamplerStates); + if (csShaderResourceState != NULL) + context->CSSetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, csShaderResourceState); + if (csConstantBuffersState != NULL) + context->CSSetConstantBuffers(0, D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, csConstantBuffersState); + if (csUnorderedAccessViewState != NULL) + context->CSSetUnorderedAccessViews(0, D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, csUnorderedAccessViewState, NULL); + + if (depthStencilViewState != NULL || renderTargetViewState != NULL) + context->OMSetRenderTargets(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, renderTargetViewState, depthStencilViewState); + + if (omBlendState != NULL) + context->OMSetBlendState(omBlendState, omBlendFactorState, omSampleMaskState); + + context->IASetPrimitiveTopology(primitiveTopologyState); + + if (iaIndexBufferPointerState != NULL) + context->IASetIndexBuffer(iaIndexBufferPointerState, iaIndexBufferFormatState, iaIndexBufferOffsetState); + + if (iaVertexBufferPointersState != NULL) + context->IASetVertexBuffers(0, D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, iaVertexBufferPointersState, iaVertexBufferStridesState, iaVertexBufferOffsetsState); + + if (currentPixelShader != NULL) + context->PSSetShader(currentPixelShader, NULL, 0); + if (currentVertexShader != NULL) + context->VSSetShader(currentVertexShader, NULL, 0); + if (currentGeometryShader != NULL) + context->GSSetShader(currentGeometryShader, NULL, 0); + if (currentHullShader != NULL) + context->HSSetShader(currentHullShader, NULL, 0); + if (currentDomainShader != NULL) + context->DSSetShader(currentDomainShader, NULL, 0); + if (currentComputeShader != NULL) + context->CSSetShader(currentComputeShader, NULL, 0); + + clearMemory(); +} + +}}} // OVR::CAPI::D3D11 diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h index 0216232..4282074 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_DistortionRenderer.h @@ -1,34 +1,206 @@ -/************************************************************************************ - -Filename : CAPI_D3D11_DistortionRenderer.h -Content : Distortion renderer header for D3D11 -Created : November 11, 2013 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef INC_CAPI_D3D11_DistortionRenderer_h -#define INC_CAPI_D3D11_DistortionRenderer_h - -#define OVR_D3D_VERSION 11 -#include "CAPI_D3D1X_DistortionRenderer.h" -#undef OVR_D3D_VERSION - -#endif +/************************************************************************************ + +Filename : CAPI_D3D11_DistortionRenderer.h +Content : Experimental distortion renderer +Created : November 11, 2013 +Authors : Volga Aksoy + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_D3D11_DistortionRenderer_h +#define OVR_CAPI_D3D11_DistortionRenderer_h + +#include "CAPI_D3D11_Util.h" +#include "../CAPI_DistortionRenderer.h" + +#include "Kernel/OVR_Log.h" + +namespace OVR { namespace CAPI { namespace D3D11 { + + +// ***** D3D11::DistortionRenderer + +// Implementation of DistortionRenderer for D3D11. + +class DistortionRenderer : public CAPI::DistortionRenderer +{ +public: + DistortionRenderer(); + ~DistortionRenderer(); + + + // Creation function for the device. + static CAPI::DistortionRenderer* Create(); + + + // ***** Public DistortionRenderer interface + + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture) OVR_OVERRIDE; + virtual void SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) OVR_OVERRIDE; + + virtual void EndFrame(uint32_t frameIndex, bool swapBuffers); + + // TBD: Make public? + void WaitUntilGpuIdle(); + + // Similar to ovr_WaitTillTime but it also flushes GPU. + // Note, it exits when time expires, even if GPU is not in idle state yet. + double FlushGpuAndWaitTillTime(double absTime); + +protected: + virtual bool initializeRenderer(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; + + class GraphicsState : public CAPI::DistortionRenderer::GraphicsState + { + public: + GraphicsState(ID3D11DeviceContext* context); + virtual ~GraphicsState(); + virtual void clearMemory(); + virtual void Save(); + virtual void Restore(); + + protected: + ID3D11DeviceContext* context; + BOOL memoryCleared; + + ID3D11RasterizerState* rasterizerState; + ID3D11InputLayout* inputLayoutState; + + ID3D11ShaderResourceView* psShaderResourceState[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11SamplerState* psSamplerStates[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D11Buffer* psConstantBuffersState[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + + ID3D11ShaderResourceView* vsShaderResourceState[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11SamplerState* vsSamplerStates[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D11Buffer* vsConstantBuffersState[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + + ID3D11ShaderResourceView* csShaderResourceState[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; + ID3D11SamplerState* csSamplerStates[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT]; + ID3D11Buffer* csConstantBuffersState[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; + ID3D11UnorderedAccessView* csUnorderedAccessViewState[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; + + ID3D11RenderTargetView* renderTargetViewState[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT]; + ID3D11DepthStencilView* depthStencilViewState; + + ID3D11BlendState* omBlendState; + FLOAT omBlendFactorState[4]; + UINT omSampleMaskState; + + D3D11_PRIMITIVE_TOPOLOGY primitiveTopologyState; + + ID3D11Buffer* iaIndexBufferPointerState; + DXGI_FORMAT iaIndexBufferFormatState; + UINT iaIndexBufferOffsetState; + + ID3D11Buffer* iaVertexBufferPointersState[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + UINT iaVertexBufferStridesState[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + UINT iaVertexBufferOffsetsState[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; + + ID3D11PixelShader* currentPixelShader; + ID3D11VertexShader* currentVertexShader; + ID3D11GeometryShader* currentGeometryShader; + ID3D11HullShader* currentHullShader; + ID3D11DomainShader* currentDomainShader; + ID3D11ComputeShader* currentComputeShader; + }; + +private: + // Helpers + bool initBuffersAndShaders(); + void initShaders(); + void initFullscreenQuad(); + void initOverdrive(); + void destroy(); + + void setViewport(const Recti& vp); + + void renderDistortion(); + + void renderPrimitives(const ShaderFill* fill, Buffer* vertices, Buffer* indices, + Matrix4f* viewMatrix, int offset, int count, + PrimitiveType rprim); + + void renderEndFrame(); + + void createDrawQuad(); + void renderLatencyQuad(unsigned char* latencyTesterDrawColor); + void renderLatencyPixel(unsigned char* latencyTesterPixelColor); + + // Attempt to use DXGI GetFrameStatistics for getting a previous vsync + // Returns 0 if no Vsync timing information is available. + double getDXGILastVsyncTime(); + + // Create or get cached D3D sampler based on flags. + ID3D11SamplerState* getSamplerState(int sm); + + + //// TBD: Should we be using oe from RState instead? + //unsigned DistortionCaps; + + // Back buffer is properly set as an SRGB format? + bool SrgbBackBuffer; + + // Failures retrieving the frame index from renderer + int FrameIndexFailureCount; + static const int FrameIndexFailureLimit = 5; // After a few failures stop trying. + + // D3DX device and utility variables. + RenderParams RParams; + Ptr pEyeTextures[2]; + Ptr pEyeDepthTextures[2]; + + // U,V scale and offset needed for timewarp. + ovrVector2f UVScaleOffset[2][2]; + ovrSizei EyeTextureSize[2]; + ovrRecti EyeRenderViewport[2]; + + Ptr pOverdriveTextures[NumOverdriveTextures]; + Ptr OverdriveLutTexture; + + //Ptr mpFullScreenVertexBuffer; + + Ptr DistortionMeshVBs[2]; // one per-eye + Ptr DistortionMeshIBs[2]; // one per-eye + Ptr DistortionPinBuffer[2]; // one per-eye + + Ptr DistortionShader; + Ptr DistortionVertexIL; + + struct StandardUniformData + { + Matrix4f Proj; + Matrix4f View; + } StdUniforms; + Ptr UniformBuffers[Shader_Count]; + + Ptr SamplerStates[Sample_Count]; + Ptr Rasterizer; + + Ptr LatencyTesterQuadVB; + Ptr SimpleQuadShader; + Ptr SimpleQuadVertexIL; + + GpuTimer GpuProfiler; + Hash> RenderTargetMap; +}; + +}}} // OVR::CAPI::D3D11 + +#endif // OVR_CAPI_D3D11_DistortionRenderer_h diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp index 2177815..44479cb 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.cpp @@ -1,35 +1,532 @@ -/************************************************************************************ - -Filename : CAPI_D3D11_HSWDisplay.cpp -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#define OVR_D3D_VERSION 11 -#include "CAPI_D3D1X_HSWDisplay.cpp" -#undef OVR_D3D_VERSION - - - - - - +/************************************************************************************ + +Filename : CAPI_D3D11_HSWDisplay.cpp +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Util/Util_Direct3D.h" +#include "OVR_CAPI_D3D.h" +#include "CAPI_D3D11_HSWDisplay.h" +#include "Kernel/OVR_File.h" +#include "Kernel/OVR_SysFile.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Color.h" +#include "Extras/OVR_Math.h" + +// We currently borrow the SimpleQuad shaders +#include "Shaders/SimpleTexturedQuad_vs.h" +#include "Shaders/SimpleTexturedQuad_ps.h" + +// For a given DXGI format: if the format is a typeless one then this function returns a +// suitable typed one. If the format is a typed one then this function returns it as-is. +static DXGI_FORMAT GetFullyTypedDXGIFormat(DXGI_FORMAT textureFormat) +{ + // http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx + + DXGI_FORMAT fullyTypedFormat = textureFormat; + + switch (textureFormat) + { + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + return DXGI_FORMAT_R32G32B32A32_FLOAT; // or DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_SINT + + case DXGI_FORMAT_R32G32B32_TYPELESS: + return DXGI_FORMAT_R32G32B32_FLOAT; // or DXGI_FORMAT_R32G32B32_UINT, DXGI_FORMAT_R32G32B32_SINT + + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + return DXGI_FORMAT_R16G16B16A16_UNORM; // or DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_SINT + + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + return DXGI_FORMAT_R8G8B8A8_UNORM; // or DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SINT + + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; + + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; + + // Others which we don't currently support: + //case DXGI_FORMAT_R32G32_TYPELESS: + //case DXGI_FORMAT_R32G8X24_TYPELESS: + //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + //case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + //case DXGI_FORMAT_R10G10B10A2_TYPELESS: + //case DXGI_FORMAT_R16G16_TYPELESS: + //case DXGI_FORMAT_R32_TYPELESS: + //case DXGI_FORMAT_R24G8_TYPELESS: + //case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + //case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + //case DXGI_FORMAT_R8G8_TYPELESS: + //case DXGI_FORMAT_R16_TYPELESS: + //case DXGI_FORMAT_R8_TYPELESS: + //case DXGI_FORMAT_BC1_TYPELESS: + //case DXGI_FORMAT_BC2_TYPELESS: + //case DXGI_FORMAT_BC3_TYPELESS: + //case DXGI_FORMAT_BC4_TYPELESS: + //case DXGI_FORMAT_BC5_TYPELESS: + //case DXGI_FORMAT_BC6H_TYPELESS: + //case DXGI_FORMAT_BC7_TYPELESS: + } + + return fullyTypedFormat; +} + + + +namespace OVR { namespace CAPI { + +// To do Need to move LoadTextureTgaData to a shared location. +uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height); + +namespace D3D11 { + +// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. +Texture* LoadTextureTga(RenderParams& rParams, ID3D11SamplerState* pSamplerState, OVR::File* f, uint8_t alpha) +{ + Texture* pTexture = NULL; + + int width, height; + const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); + + if (pRGBA) + { + pTexture = new Texture(&rParams, Texture_RGBA, OVR::Sizei(0, 0), pSamplerState, 1); + + // Create the D3D texture + D3D11_TEXTURE2D_DESC dsDesc; + dsDesc.Width = width; + dsDesc.Height = height; + dsDesc.MipLevels = 1; + dsDesc.ArraySize = 1; + dsDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + dsDesc.SampleDesc.Count = 1; + dsDesc.SampleDesc.Quality = 0; + dsDesc.Usage = D3D11_USAGE_DEFAULT; + dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + dsDesc.CPUAccessFlags = 0; + dsDesc.MiscFlags = 0; + + HRESULT hr = rParams.pDevice->CreateTexture2D(&dsDesc, NULL, &pTexture->Tex.GetRawRef()); + + if (SUCCEEDED(hr)) + { + if (dsDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + rParams.pDevice->CreateShaderResourceView(pTexture->Tex, NULL, &pTexture->TexSv.GetRawRef()); + + rParams.pContext->UpdateSubresource(pTexture->Tex, 0, NULL, pRGBA, width * 4, width * height * 4); + } + else + { + OVR_DEBUG_LOG_TEXT(("[LoadTextureTga] CreateTexture2D failed")); + pTexture->Release(); + } + + OVR_FREE(const_cast(pRGBA)); + } + + return pTexture; +} + + +// Loads a texture from a memory image of a TGA file. +Texture* LoadTextureTga(RenderParams& rParams, ID3D11SamplerState* pSamplerState, const uint8_t* pData, int dataSize, uint8_t alpha) +{ + MemoryFile memoryFile("", pData, dataSize); + + return LoadTextureTga(rParams, pSamplerState, &memoryFile, alpha); +} + + +// Loads a texture from a disk TGA file. +Texture* LoadTextureTga(RenderParams& rParams, ID3D11SamplerState* pSamplerState, const char* pFilePath, uint8_t alpha) +{ + SysFile sysFile; + + if (sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) + return LoadTextureTga(rParams, pSamplerState, &sysFile, alpha); + + return NULL; +} + + + +// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h +struct HASWVertex +{ + Vector3f Pos; + Color C; + float U, V; + + HASWVertex(const Vector3f& p, const Color& c = Color(64, 0, 0, 255), float u = 0, float v = 0) + : Pos(p), C(c), U(u), V(v) + {} + + HASWVertex(float x, float y, float z, const Color& c = Color(64, 0, 0, 255), float u = 0, float v = 0) + : Pos(x, y, z), C(c), U(u), V(v) + {} + + bool operator==(const HASWVertex& b) const + { + return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V); + } +}; + + + +// The texture below may conceivably be shared between HSWDisplay instances. However, +// beware that sharing may not be possible if two HMDs are using different locales +// simultaneously. As of this writing it's not clear if that can occur in practice. + +HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) + : OVR::CAPI::HSWDisplay(api, hmd, renderState), + RenderParams() +{ +} + +bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) +{ + const ovrD3D11Config* config = reinterpret_cast(apiConfig); + + if (config) + { + RenderParams.pDevice = config->D3D11.pDevice; + RenderParams.pContext = config->D3D11.pDeviceContext; + RenderParams.pBackBufferUAV = config->D3D11.pBackBufferUAV; + RenderParams.pBackBufferRT = config->D3D11.pBackBufferRT; + RenderParams.pSwapChain = config->D3D11.pSwapChain; + RenderParams.BackBufferSize = config->D3D11.Header.BackBufferSize; + RenderParams.Multisample = config->D3D11.Header.Multisample; + RenderParams.VidPnTargetId = 0; + + // We may want to create RasterizerState, or alternatively let the DistortionRenderer handle it. + } + // else do any necessary cleanup + + return true; +} + +void HSWDisplay::Shutdown() +{ + UnloadGraphics(); +} + + +void HSWDisplay::DisplayInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D11] DisplayInternal()")); + // We may want to call LoadGraphics here instead of within Render. +} + + +void HSWDisplay::DismissInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D11] DismissInternal()")); + UnloadGraphics(); +} + + +void HSWDisplay::UnloadGraphics() +{ + //RenderParams: nothing to do. + pSamplerState.Clear(); + pTexture.Clear(); + pVB.Clear(); + for (size_t i = 0; i < OVR_ARRAY_COUNT(UniformBufferArray); i++) + UniformBufferArray[i].Clear(); + pShaderSet.Clear(); + pVertexInputLayout.Clear(); + pBlendState.Clear(); + pRasterizerState.Clear(); + // OrthoProjection: No need to clear. +} + +void HSWDisplay::LoadGraphics() +{ + // Load the graphics if not loaded already. + if (!pSamplerState) + { + D3D11_SAMPLER_DESC sDesc; + + memset(&sDesc, 0, sizeof(sDesc)); + sDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + sDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + sDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + sDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + + RenderParams.pDevice->CreateSamplerState(&sDesc, &pSamplerState.GetRawRef()); + } + +#if defined(OVR_BUILD_DEBUG) + if (!pTexture) + pTexture = *LoadTextureTga(RenderParams, pSamplerState, "C:\\TestPath\\TestFile.tga", 255); +#endif + + if (!pTexture) // To do: Add support for .dds files, which would be significantly smaller than the size of the tga. + { + size_t textureSize; + const uint8_t* TextureData = GetDefaultTexture(textureSize); + pTexture = *LoadTextureTga(RenderParams, pSamplerState, TextureData, (int)textureSize, 255); + } + + if (!UniformBufferArray[0]) + { + for (size_t i = 0; i < OVR_ARRAY_COUNT(UniformBufferArray); i++) + UniformBufferArray[i] = *new Buffer(&RenderParams); + } + + if (!pShaderSet) + { + pShaderSet = *new ShaderSet; + + // Setup the vertex shader + const D3D11_INPUT_ELEMENT_DESC VertexDescription[] = { + { "Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(HASWVertex, Pos), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(HASWVertex, C), D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(HASWVertex, U), D3D11_INPUT_PER_VERTEX_DATA, 0 } + }; + + Ptr vs = *new VertexShader(&RenderParams, (void*)SimpleTexturedQuad_vs, sizeof(SimpleTexturedQuad_vs), SimpleTexturedQuad_vs_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_vs_refl)); + pVertexInputLayout = NULL; // Make sure it's cleared in case it wasn't. + ID3D11InputLayout** ppD3DInputLayout = &pVertexInputLayout.GetRawRef(); + HRESULT hResult = RenderParams.pDevice->CreateInputLayout(VertexDescription, OVR_ARRAY_COUNT(VertexDescription), SimpleTexturedQuad_vs, sizeof(SimpleTexturedQuad_vs), ppD3DInputLayout); + OVR_ASSERT(SUCCEEDED(hResult)); + if (SUCCEEDED(hResult)) + pShaderSet->SetShader(vs); + + // Setup the pixel shader + Ptr ps = *new PixelShader(&RenderParams, (void*)SimpleTexturedQuad_ps, sizeof(SimpleTexturedQuad_ps), SimpleTexturedQuad_ps_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_ps_refl)); + pShaderSet->SetShader(ps); + + if (!pBlendState) + { + D3D11_BLEND_DESC bm; + memset(&bm, 0, sizeof(bm)); + bm.RenderTarget[0].BlendEnable = TRUE; + bm.RenderTarget[0].BlendOp = bm.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; + bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; + bm.RenderTarget[0].DestBlend = bm.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; + bm.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + RenderParams.pDevice->CreateBlendState(&bm, &pBlendState.GetRawRef()); + } + + if (!pRasterizerState) + { + D3D11_RASTERIZER_DESC rs; + memset(&rs, 0, sizeof(rs)); + rs.AntialiasedLineEnable = true; + rs.CullMode = D3D11_CULL_BACK; + rs.DepthClipEnable = true; + rs.FillMode = D3D11_FILL_SOLID; + + RenderParams.pDevice->CreateRasterizerState(&rs, &pRasterizerState.GetRawRef()); + } + } + + if (!pVB) + { + pVB = *new Buffer(&RenderParams); + + if (pVB) + { + const size_t vertexCount = 4; + + pVB->Data(Buffer_Vertex, NULL, vertexCount * sizeof(HASWVertex)); + HASWVertex* pVertices = (HASWVertex*)pVB->Map(0, vertexCount * sizeof(HASWVertex), Map_Discard); + OVR_ASSERT(pVertices); + + if (pVertices) + { + const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0); + const float left = -1.0f; // We currently draw this in normalized device coordinates with an stereo translation + const float top = -1.1f; // applied as a vertex shader uniform. In the future when we have a more formal graphics + const float right = 1.0f; // API abstraction we may move this draw to an overlay layer or to a more formal + const float bottom = 0.9f; // model/mesh scheme with a perspective projection. + + // See warning in LoadTextureTgaData() about this TGA being loaded "upside down", i.e. UV origin is at bottom-left. + pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); + pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); + pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); + pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f); + + pVB->Unmap(pVertices); + } + } + } +} + + +// Note: If we are drawing this warning onto the eye texture before distortion, the "time warp" functionality +// will cause the warning to shake on the screen when the user moves their head. One solution is to disable +// time warping while the warning or any screen-static GUI elements are present. + +void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) +{ + if (RenderEnabled && eyeTexture) + { + // We need to render to the eyeTexture with the texture viewport. + // Setup rendering to the texture. + ovrD3D11Texture* eyeTextureD3D = const_cast(reinterpret_cast(eyeTexture)); + OVR_ASSERT(eyeTextureD3D->Texture.Header.API == ovrRenderAPI_D3D11); + + // Load the graphics if not loaded already. + if (!pVB) + LoadGraphics(); + + // Calculate ortho projection. + GetOrthoProjection(RenderState, OrthoProjection); + + // Save settings + // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location. + Ptr pBlendStateSaved; + FLOAT blendFactorSaved[4]; + UINT blendSampleMaskSaved; + RenderParams.pContext->OMGetBlendState(&pBlendStateSaved.GetRawRef(), blendFactorSaved, &blendSampleMaskSaved); + + Ptr pRasterizerStateSaved; + RenderParams.pContext->RSGetState(&pRasterizerStateSaved.GetRawRef()); + + Ptr pTextureRenderTargetViewSaved; + Ptr pDepthStencilViewSaved; + RenderParams.pContext->OMGetRenderTargets(1, &pTextureRenderTargetViewSaved.GetRawRef(), &pDepthStencilViewSaved.GetRawRef()); + + D3D11_VIEWPORT d3dViewportSaved[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE]; + UINT viewportCountSaved = OVR_ARRAY_COUNT(d3dViewportSaved); + RenderParams.pContext->RSGetViewports(&viewportCountSaved, d3dViewportSaved); + + UINT stencilRefSaved; + Ptr pDepthStencilStateSaved; + RenderParams.pContext->OMGetDepthStencilState(&pDepthStencilStateSaved.GetRawRef(), &stencilRefSaved); + + Ptr pInputLayoutSaved; + RenderParams.pContext->IAGetInputLayout(&pInputLayoutSaved.GetRawRef()); + + Ptr pVertexBufferSaved; + UINT vertexStrideSaved[1]; + UINT vertexOffsetSaved[1]; + RenderParams.pContext->IAGetVertexBuffers(0, 1, &pVertexBufferSaved.GetRawRef(), vertexStrideSaved, vertexOffsetSaved); + + D3D11_PRIMITIVE_TOPOLOGY topologySaved; + RenderParams.pContext->IAGetPrimitiveTopology(&topologySaved); + + + // Set our settings + RenderParams.pContext->OMSetBlendState(pBlendState, NULL, 0xffffffff); + RenderParams.pContext->RSSetState(pRasterizerState); + + // We can't necessarily use a NULL D3D11_RENDER_TARGET_VIEW_DESC argument to CreateRenderTargetView, because we are rendering to + // a texture that somebody else created and which may have been created in a typeless format (e.g. DXGI_FORMAT_R8G8B8A8_TYPELESS). + // So what we do is check to see if the texture format is a typeless format and if see we pass a suitable D3D11_RENDER_TARGET_VIEW_DESC + // to CreateRenderTargetView instead of NULL. + D3D11_TEXTURE2D_DESC texture2DDesc; + eyeTextureD3D->D3D11.pTexture->GetDesc(&texture2DDesc); + + D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc; + memset(&renderTargetViewDesc, 0, sizeof(renderTargetViewDesc)); + renderTargetViewDesc.Format = GetFullyTypedDXGIFormat(texture2DDesc.Format); // DXGI_FORMAT. If this is a typeless format then GetFullyTypedFormat converts it to a fully typed format. + renderTargetViewDesc.ViewDimension = (texture2DDesc.SampleDesc.Count > 1) ? D3D11_RTV_DIMENSION_TEXTURE2DMS : D3D11_RTV_DIMENSION_TEXTURE2D; + renderTargetViewDesc.Texture2D.MipSlice = 0; + Ptr pTextureRenderTargetView; + HRESULT hResult = RenderParams.pDevice->CreateRenderTargetView(eyeTextureD3D->D3D11.pTexture, (renderTargetViewDesc.Format == texture2DDesc.Format) ? NULL : &renderTargetViewDesc, &pTextureRenderTargetView.GetRawRef()); + + if (SUCCEEDED(hResult)) + { + RenderParams.pContext->OMSetRenderTargets(1, &pTextureRenderTargetView.GetRawRef(), NULL); // We currently don't bind a depth buffer. + + D3D11_VIEWPORT D3DViewport; + + OVR_DISABLE_MSVC_WARNING(4244) // conversion from int to float + D3DViewport.TopLeftX = eyeTextureD3D->Texture.Header.RenderViewport.Pos.x; + D3DViewport.TopLeftY = eyeTextureD3D->Texture.Header.RenderViewport.Pos.y; + D3DViewport.Width = eyeTextureD3D->Texture.Header.RenderViewport.Size.w; + D3DViewport.Height = eyeTextureD3D->Texture.Header.RenderViewport.Size.h; + D3DViewport.MinDepth = 0; + D3DViewport.MaxDepth = 1; + RenderParams.pContext->RSSetViewports(1, &D3DViewport); + OVR_RESTORE_MSVC_WARNING() + + // We don't set up a world/view/projection matrix because we are using + // normalized device coordinates below. + + // We don't set the depth state because we aren't using it. + // RenderParams.pContext->OMSetDepthStencilState(, 0); + + ShaderFill fill(pShaderSet); + fill.SetInputLayout(pVertexInputLayout); + if (pTexture) + fill.SetTexture(0, pTexture, Shader_Pixel); + + const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f); + pShaderSet->SetUniform2f("Scale", scale, scale / 2.f); // X and Y scale. Y is a fixed proportion to X in order to give a certain aspect ratio. + pShaderSet->SetUniform4f("Color", 1.f, 1.f, 1.f, 1.f); + pShaderSet->SetUniform2f("PositionOffset", OrthoProjection[eye].GetTranslation().x, 0.0f); + + RenderParams.pContext->IASetInputLayout((ID3D11InputLayout*)fill.GetInputLayout()); + + ID3D11Buffer* vertexBuffer = pVB->GetBuffer(); + UINT vertexStride = sizeof(HASWVertex); + UINT vertexOffset = 0; + RenderParams.pContext->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); + + ShaderBase* vShaderBase = (ShaderBase*)pShaderSet->GetShader(OVR::CAPI::D3D11::Shader_Vertex); + unsigned char* vertexData = vShaderBase->UniformData; + + if (vertexData) + { + UniformBufferArray[OVR::CAPI::D3D11::Shader_Vertex]->Data(OVR::CAPI::D3D11::Buffer_Uniform, vertexData, vShaderBase->UniformsSize); + vShaderBase->SetUniformBuffer(UniformBufferArray[OVR::CAPI::D3D11::Shader_Vertex]); + } + + for (int i = (OVR::CAPI::D3D11::Shader_Vertex + 1); i < OVR::CAPI::D3D11::Shader_Count; i++) + { + if (pShaderSet->GetShader(i)) + { + ((ShaderBase*)pShaderSet->GetShader(i))->UpdateBuffer(UniformBufferArray[i]); + ((ShaderBase*)pShaderSet->GetShader(i))->SetUniformBuffer(UniformBufferArray[i]); + } + } + + RenderParams.pContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + fill.Set(Prim_TriangleStrip); + + RenderParams.pContext->Draw(4, 0); + } + else + { + HSWDISPLAY_LOG(("[HSWDisplay D3D11] CreateRenderTargetView() failed")); + } + + + // Restore settings + RenderParams.pContext->IASetPrimitiveTopology(topologySaved); + RenderParams.pContext->IASetVertexBuffers(0, 1, &pVertexBufferSaved.GetRawRef(), &vertexStrideSaved[0], &vertexOffsetSaved[0]); + RenderParams.pContext->IASetInputLayout(pInputLayoutSaved); + RenderParams.pContext->OMSetDepthStencilState(pDepthStencilStateSaved, stencilRefSaved); + RenderParams.pContext->RSSetViewports(viewportCountSaved, d3dViewportSaved); + RenderParams.pContext->OMSetRenderTargets(1, &pTextureRenderTargetViewSaved.GetRawRef(), pDepthStencilViewSaved); + RenderParams.pContext->RSSetState(pRasterizerStateSaved); + RenderParams.pContext->OMSetBlendState(pBlendStateSaved, blendFactorSaved, blendSampleMaskSaved); + } +} + +}}} // namespace OVR::CAPI::D3D11 diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h index ca896b0..f25827b 100644 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_HSWDisplay.h @@ -1,41 +1,72 @@ -/************************************************************************************ - -Filename : CAPI_D3D11_HSWDisplay.h -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_CAPI_D3D11_HSWDisplay_h -#define OVR_CAPI_D3D11_HSWDisplay_h - -#if !defined(OVR_D3D_VERSION) || ((OVR_D3D_VERSION != 10) && (OVR_D3D_VERSION != 11)) - #error This header expects OVR_D3D_VERSION to be defined, to 10 or 11. -#endif - -// Due to the similarities between DX10 and DX11, there is a shared implementation of the headers and source -// which is differentiated only by the OVR_D3D_VERSION define. This define causes D3D_NS (D3D namespace) to -// be defined to either D3D10 or D3D11, as well as other similar effects. -#include "CAPI_D3D1X_HSWDisplay.h" - - -#endif // OVR_CAPI_D3D11_HSWDisplay_h - +/************************************************************************************ + +Filename : CAPI_D3D11_HSWDisplay.h +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_D3D11_HSWDisplay_h +#define OVR_CAPI_D3D11_HSWDisplay_h + +#include "../CAPI_HSWDisplay.h" +#include "CAPI_D3D11_Util.h" + +namespace OVR { namespace CAPI { namespace D3D11 { + +class HSWDisplay : public CAPI::HSWDisplay +{ +public: + HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); + + // Must be called before use. apiConfig is such that: + // const ovrD3D11Config* config = (const ovrD3D11Config*)apiConfig; or + bool Initialize(const ovrRenderAPIConfig* apiConfig); + void Shutdown(); + void DisplayInternal(); + void DismissInternal(); + + // Draws the warning to the eye texture(s). This must be done at the end of a + // frame but prior to executing the distortion rendering of the eye textures. + void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture); + +protected: + void LoadGraphics(); + void UnloadGraphics(); + + RenderParams RenderParams; + Ptr pSamplerState; + Ptr pTexture; + Ptr pVB; + Ptr UniformBufferArray[Shader_Count]; + Ptr pShaderSet; + Ptr pVertexInputLayout; + Ptr pBlendState; + Ptr pRasterizerState; + Matrix4f OrthoProjection[ovrEye_Count]; + +private: + OVR_NON_COPYABLE(HSWDisplay) +}; + +}}} // namespace OVR::CAPI::D3D11 + +#endif // OVR_CAPI_D3D11_HSWDisplay_h diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.cpp new file mode 100644 index 0000000..36f1de0 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.cpp @@ -0,0 +1,758 @@ +/************************************************************************************ + +Filename : CAPI_D3D11_Util.cpp +Content : D3DX11 utility classes for rendering +Created : September 10, 2012 +Authors : Andrew Reisse + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_D3D11_Util.h" + +namespace OVR { namespace CAPI { namespace D3D11 { + + +//------------------------------------------------------------------------------------- +// ***** ShaderFill + +void ShaderFill::Set(PrimitiveType prim) const +{ + Shaders->Set(prim); + + for(int i = 0; i < 8; ++i) + { + if ( VsTextures[i] != NULL ) + { + VsTextures[i]->Set(i, Shader_Vertex); + } + } + + for(int i = 0; i < 8; ++i) + { + if ( CsTextures[i] != NULL ) + { + CsTextures[i]->Set(i, Shader_Compute); + } + } + + for(int i = 0; i < 8; ++i) + { + if ( PsTextures[i] != NULL ) + { + PsTextures[i]->Set(i, Shader_Fragment); + } + } +} + + +//------------------------------------------------------------------------------------- +// ***** Buffer + +Buffer::~Buffer() +{ +} + +bool Buffer::Data(int use, const void *buffer, size_t size, int computeBufferStride /*=-1*/) +{ + HRESULT hr; + + if (D3DBuffer && Size >= size) + { + if (Dynamic) + { + if (!buffer) + return true; + + void* v = Map(0, size, Map_Discard); + if (v) + { + memcpy(v, buffer, size); + Unmap(v); + return true; + } + } + else + { + OVR_ASSERT (!(use & Buffer_ReadOnly)); + pParams->pContext->UpdateSubresource(D3DBuffer, 0, NULL, buffer, 0, 0); + return true; + } + } + if (D3DBuffer) + { + D3DBuffer = NULL; + Size = 0; + Use = 0; + Dynamic = false; + } + D3DSrv = NULL; + D3DUav = NULL; + + D3D11_BUFFER_DESC desc; + memset(&desc, 0, sizeof(desc)); + if (use & Buffer_ReadOnly) + { + desc.Usage = D3D11_USAGE_IMMUTABLE; + desc.CPUAccessFlags = 0; + } + else + { + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + Dynamic = true; + } + + switch(use & Buffer_TypeMask) + { + case Buffer_Vertex: desc.BindFlags = D3D11_BIND_VERTEX_BUFFER; break; + case Buffer_Index: desc.BindFlags = D3D11_BIND_INDEX_BUFFER; break; + case Buffer_Uniform: + desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + size = ((size + 15) & ~15); + break; + case Buffer_Compute: + // There's actually a bunch of options for buffers bound to a CS. + // Right now this is the most appropriate general-purpose one. Add more as needed. + + // NOTE - if you want D3D11_(CPU_ACCESS_WRITE), it MUST be either D3D11_(USAGE_DYNAMIC) or D3D11_(USAGE_STAGING). + // TODO: we want a resource that is rarely written to, in which case we'd need two surfaces - one a STAGING + // that the CPU writes to, and one a DEFAULT, and we CopyResource from one to the other. Hassle! + // Setting it as D3D11_(USAGE_DYNAMIC) will get the job done for now. + // Also for fun - you can't have a D3D11_(USAGE_DYNAMIC) buffer that is also a D3D11_(BIND_UNORDERED_ACCESS). + OVR_ASSERT ( !(use & Buffer_ReadOnly) ); + desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + desc.Usage = D3D11_USAGE_DYNAMIC; + desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + OVR_ASSERT ( computeBufferStride > 0 ); + desc.StructureByteStride = computeBufferStride; // sizeof(DistortionComputePin); + + Dynamic = true; + size = ((size + 15) & ~15); + break; + } + + desc.ByteWidth = (unsigned)size; + + D3D11_SUBRESOURCE_DATA sr; + sr.pSysMem = buffer; + sr.SysMemPitch = 0; + sr.SysMemSlicePitch = 0; + + D3DBuffer = NULL; + hr = pParams->pDevice->CreateBuffer(&desc, buffer ? &sr : NULL, &D3DBuffer.GetRawRef()); + OVR_D3D_CHECK_RET_FALSE(hr); + + Use = 0; + Size = 0; + + if ( ( use & Buffer_TypeMask ) == Buffer_Compute ) + { + hr = pParams->pDevice->CreateShaderResourceView ( D3DBuffer, NULL, &D3DSrv.GetRawRef() ); + OVR_D3D_CHECK_RET_FALSE(hr); + +#if 0 // Right now we do NOT ask for UAV access (see flags above). + hr = Ren->Device->CreateUnorderedAccessView ( D3DBuffer, NULL, &D3DUav.GetRawRef() ); + OVR_D3D_CHECK_RET_FALSE(hr); +#endif + } + + Use = use; + Size = desc.ByteWidth; + + return true; + +} + +void* Buffer::Map(size_t start, size_t size, int flags) +{ + OVR_UNUSED(size); + + D3D11_MAP mapFlags = D3D11_MAP_WRITE; + if (flags & Map_Discard) + mapFlags = D3D11_MAP_WRITE_DISCARD; + if (flags & Map_Unsynchronized) + mapFlags = D3D11_MAP_WRITE_NO_OVERWRITE; + + D3D11_MAPPED_SUBRESOURCE map; + if (SUCCEEDED(pParams->pContext->Map(D3DBuffer, 0, mapFlags, 0, &map))) + return ((char*)map.pData) + start; + + return NULL; +} + +bool Buffer::Unmap(void *m) +{ + OVR_UNUSED(m); + + pParams->pContext->Unmap(D3DBuffer, 0); + return true; +} + + +//------------------------------------------------------------------------------------- +// Shaders + +template<> bool ShaderImpl::Load(void* shader, size_t size) +{ + HRESULT hr = pParams->pDevice->CreateVertexShader(shader, size, nullptr, &D3DShader); + OVR_D3D_CHECK_RET_FALSE(hr); + return true; +} +template<> bool ShaderImpl::Load(void* shader, size_t size) +{ + HRESULT hr = pParams->pDevice->CreatePixelShader(shader, size, nullptr, &D3DShader); + OVR_D3D_CHECK_RET_FALSE(hr); + return true; +} +template<> bool ShaderImpl::Load(void* shader, size_t size) +{ + HRESULT hr = pParams->pDevice->CreateComputeShader(shader, size, nullptr, &D3DShader); + OVR_D3D_CHECK_RET_FALSE(hr); + return true; +} + +template<> void ShaderImpl::Set(PrimitiveType) const +{ + pParams->pContext->VSSetShader(D3DShader, nullptr, 0); +} +template<> void ShaderImpl::Set(PrimitiveType) const +{ + pParams->pContext->PSSetShader(D3DShader, nullptr, 0); +} +template<> void ShaderImpl::Set(PrimitiveType) const +{ + pParams->pContext->CSSetShader(D3DShader, nullptr, 0); +} + +template<> void ShaderImpl::SetUniformBuffer(Buffer* buffer, int i) +{ + pParams->pContext->VSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef()); +} +template<> void ShaderImpl::SetUniformBuffer(Buffer* buffer, int i) +{ + pParams->pContext->PSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef()); +} +template<> void ShaderImpl::SetUniformBuffer(Buffer* buffer, int i) +{ + pParams->pContext->CSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef()); +} + +//------------------------------------------------------------------------------------- +// ***** Shader Base + +ShaderBase::ShaderBase(RenderParams* rp, ShaderStage stage) : + Shader(stage), + pParams(rp), + UniformData(NULL), + UniformsSize(0), + UniformRefl(NULL), + UniformReflSize(0) +{ +} + +ShaderBase::~ShaderBase() +{ + if (UniformData) + { + OVR_FREE(UniformData); + UniformData = NULL; + } + + // UniformRefl does not need to be freed + UniformRefl = NULL; +} + +bool ShaderBase::SetUniform(const char* name, int n, const float* v) +{ + for(unsigned i = 0; i < UniformReflSize; i++) + { + if (!strcmp(UniformRefl[i].Name, name)) + { + memcpy(UniformData + UniformRefl[i].Offset, v, n * sizeof(float)); + return 1; + } + } + return 0; +} + +bool ShaderBase::SetUniformBool(const char* name, int n, const bool* v) +{ + OVR_UNUSED(n); + for(unsigned i = 0; i < UniformReflSize; i++) + { + if (!strcmp(UniformRefl[i].Name, name)) + { + memcpy(UniformData + UniformRefl[i].Offset, v, UniformRefl[i].Size); + return 1; + } + } + return 0; +} + +void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize) +{ + UniformsSize = 0; + if (UniformData) + { + OVR_FREE(UniformData); + UniformData = 0; + } + + if (!refl) + { + UniformRefl = NULL; + UniformReflSize = 0; + return; // no reflection data + } + + UniformRefl = refl; + UniformReflSize = reflSize; + + UniformsSize = UniformRefl[UniformReflSize-1].Offset + UniformRefl[UniformReflSize-1].Size; + UniformData = (unsigned char*)OVR_ALLOC(UniformsSize); +} + +void ShaderBase::UpdateBuffer(Buffer* buf) +{ + if (UniformsSize) + { + buf->Data(Buffer_Uniform, UniformData, UniformsSize); + } +} + + +//------------------------------------------------------------------------------------- +// ***** Texture +// +Texture::Texture(RenderParams* rp, int fmt, const Sizei texSize, + ID3D11SamplerState* sampler, int samples) + : pParams(rp), Tex(NULL), TexSv(NULL), TexRtv(NULL), TexDsv(NULL), + TextureSize(texSize), + Sampler(sampler), + Samples(samples) +{ + OVR_UNUSED(fmt); +} + + +Texture::Texture(RenderParams* rp, int format, const Sizei texSize, + ID3D11SamplerState* sampler, const void* data, int mipcount) + : pParams(rp), Tex(NULL), TexSv(NULL), TexRtv(NULL), TexDsv(NULL), + TextureSize(texSize), + Sampler(sampler), + Samples(1) +{ + OVR_ASSERT(rp->pDevice != NULL); + + OVR_UNUSED(mipcount); + + //if (format == Texture_DXT1 || format == Texture_DXT3 || format == Texture_DXT5) + //{ + // int convertedFormat; + // switch (format) + // { + // case Texture_DXT1: convertedFormat = DXGI_FORMAT_BC1_UNORM; break; + // case Texture_DXT3: convertedFormat = DXGI_FORMAT_BC2_UNORM; break; + // case Texture_DXT5: + // default: convertedFormat = DXGI_FORMAT_BC3_UNORM; break; + // } + // unsigned largestMipWidth = 0; + // unsigned largestMipHeight = 0; + // unsigned effectiveMipCount = mipcount; + // unsigned textureSize = 0; + + // D3D11_SUBRESOURCE_DATA* subresData = + // (D3D11_SUBRESOURCE_DATA*) OVR_ALLOC(sizeof(D3D11_SUBRESOURCE_DATA) * mipcount); + // GenerateSubresourceData(width, height, convertedFormat, imageDimUpperLimit, data, subresData, largestMipWidth, + // largestMipHeight, textureSize, effectiveMipCount); + // TotalTextureMemoryUsage += textureSize; + + // if (!Device || !subresData) + // { + // return NULL; + // } + + // Texture* NewTex = new Texture(this, format, largestMipWidth, largestMipHeight); + // // BCn/DXTn - no AA. + // Samples = 1; + + // D3D11_TEXTURE2D_DESC desc; + // desc.Width = largestMipWidth; + // desc.Height = largestMipHeight; + // desc.MipLevels = effectiveMipCount; + // desc.ArraySize = 1; + // desc.Format = static_cast(convertedFormat); + // desc.SampleDesc.Count = 1; + // desc.SampleDesc.Quality = 0; + // desc.Usage = D3D11_USAGE_DEFAULT; + // desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + // desc.CPUAccessFlags = 0; + // desc.MiscFlags = 0; + + // Tex = NULL; + // HRESULT hr = Device->CreateTexture2D(&desc, static_cast(subresData), + // &Tex.GetRawRef()); + // OVR_FREE(subresData); + // if (FAILED(hr)) + // { + // OVR_LOG_COM_ERROR(hr); + // } + + // if (SUCCEEDED(hr) && NewTex != 0) + // { + // D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; + // memset(&SRVDesc, 0, sizeof(SRVDesc)); + // SRVDesc.Format = static_cast(format); + // SRVDesc.ViewDimension = D3D_SRV_DIMENSION_TEXTURE2D; + // SRVDesc.Texture2D.MipLevels = desc.MipLevels; + + // TexSv = NULL; + // hr = Device->CreateShaderResourceView(Tex, NULL, &TexSv.GetRawRef()); + + // if (FAILED(hr)) + // { + // OVR_LOG_COM_ERROR(hr); + // Release(); + // return NULL; + // } + // return NewTex; + // } + + // return NULL; + //} + //else + { + int samples = (format & Texture_SamplesMask); + if (samples < 1) + { + samples = 1; + } + + bool createDepthSrv = (format & Texture_SampleDepth) > 0; + + DXGI_FORMAT d3dformat; + int bpp; + switch(format & Texture_TypeMask) + { + //case Texture_BGRA: + // bpp = 4; + // d3dformat = (format & Texture_SRGB) ? DXGI_FORMAT_B8G8R8A8_UNORM_SRGB : DXGI_FORMAT_B8G8R8A8_UNORM; + // break; + case Texture_RGBA: + bpp = 4; + //d3dformat = (format & Texture_SRGB) ? DXGI_FORMAT_R8G8B8A8_UNORM_SRGB : DXGI_FORMAT_R8G8B8A8_UNORM; + d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM; + break; + //case Texture_R: + // bpp = 1; + // d3dformat = DXGI_FORMAT_R8_UNORM; + // break; + //case Texture_A: + // bpp = 1; + // d3dformat = DXGI_FORMAT_A8_UNORM; + // break; + case Texture_Depth: + bpp = 0; + d3dformat = createDepthSrv ? DXGI_FORMAT_R32_TYPELESS : DXGI_FORMAT_D32_FLOAT; + break; + default: + bpp = 4; + d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM; + OVR_ASSERT(0); + } + + D3D11_TEXTURE2D_DESC dsDesc; + dsDesc.Width = texSize.w; + dsDesc.Height = texSize.h; + dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(texSize.w, texSize.h) : 1; + dsDesc.ArraySize = 1; + dsDesc.Format = d3dformat; + dsDesc.SampleDesc.Count = samples; + dsDesc.SampleDesc.Quality = 0; + dsDesc.Usage = D3D11_USAGE_DEFAULT; + dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE; + dsDesc.CPUAccessFlags = 0; + dsDesc.MiscFlags = 0; + + if (format & Texture_RenderTarget) + { + if ((format & Texture_TypeMask) == Texture_Depth) + { + dsDesc.BindFlags = createDepthSrv ? (dsDesc.BindFlags | D3D11_BIND_DEPTH_STENCIL) : D3D11_BIND_DEPTH_STENCIL; + } + else + { + dsDesc.BindFlags |= D3D11_BIND_RENDER_TARGET; + } + } + + Tex = NULL; + HRESULT hr = rp->pDevice->CreateTexture2D(&dsDesc, NULL, &Tex.GetRawRef()); + if (FAILED(hr)) + { + OVR_ASSERT(0); + //OVR_DEBUG_LOG_TEXT(("Failed to create 2D D3D texture.")); + Release(); + return; + } + if (dsDesc.BindFlags & D3D11_BIND_SHADER_RESOURCE) + { + if((dsDesc.BindFlags & D3D11_BIND_DEPTH_STENCIL) > 0 && createDepthSrv) + { + D3D11_SHADER_RESOURCE_VIEW_DESC depthSrv; + depthSrv.Format = DXGI_FORMAT_R32_FLOAT; + depthSrv.ViewDimension = samples > 1 ? D3D11_SRV_DIMENSION_TEXTURE2DMS : D3D11_SRV_DIMENSION_TEXTURE2D; + depthSrv.Texture2D.MostDetailedMip = 0; + depthSrv.Texture2D.MipLevels = dsDesc.MipLevels; + TexSv = NULL; + hr = rp->pDevice->CreateShaderResourceView(Tex, &depthSrv, &TexSv.GetRawRef()); + if (FAILED(hr)) + { + OVR_ASSERT(0); + } + } + else + { + TexSv = NULL; + hr = rp->pDevice->CreateShaderResourceView(Tex, NULL, &TexSv.GetRawRef()); + if (FAILED(hr)) + { + OVR_ASSERT(0); + } + } + } + + if (data) + { + rp->pContext->UpdateSubresource(Tex, 0, NULL, data, texSize.w * bpp, texSize.w * texSize.h * bpp); + if (format == (Texture_RGBA | Texture_GenMipmaps)) + { + int srcw = texSize.w, srch = texSize.h; + int level = 0; + uint8_t* mipmaps = NULL; + do + { + level++; + int mipw = srcw >> 1; + if (mipw < 1) + { + mipw = 1; + } + int miph = srch >> 1; + if (miph < 1) + { + miph = 1; + } + if (mipmaps == NULL) + { + mipmaps = (uint8_t*)OVR_ALLOC(mipw * miph * 4); + } + FilterRgba2x2(level == 1 ? (const uint8_t*)data : mipmaps, srcw, srch, mipmaps); + rp->pContext->UpdateSubresource(Tex, level, NULL, mipmaps, mipw * bpp, miph * bpp); + srcw = mipw; + srch = miph; + } + while(srcw > 1 || srch > 1); + + if (mipmaps != NULL) + { + OVR_FREE(mipmaps); + } + } + } + + if (format & Texture_RenderTarget) + { + if ((format & Texture_TypeMask) == Texture_Depth) + { + D3D11_DEPTH_STENCIL_VIEW_DESC depthDsv; + ZeroMemory(&depthDsv, sizeof(depthDsv)); + depthDsv.Format = DXGI_FORMAT_D32_FLOAT; + depthDsv.ViewDimension = samples > 1 ? D3D11_DSV_DIMENSION_TEXTURE2DMS : D3D11_DSV_DIMENSION_TEXTURE2D; + depthDsv.Texture2D.MipSlice = 0; + TexDsv = NULL; + hr = rp->pDevice->CreateDepthStencilView(Tex, createDepthSrv ? &depthDsv : NULL, &TexDsv.GetRawRef()); + if (FAILED(hr)) + { + OVR_ASSERT(0); + } + } + else + { + TexRtv = NULL; + hr = rp->pDevice->CreateRenderTargetView(Tex, NULL, &TexRtv.GetRawRef()); + if (FAILED(hr)) + { + OVR_ASSERT(0); + } + } + } + } +} + +Texture::~Texture() +{ +} + +void Texture::Set(int slot, ShaderStage stage) const +{ + ID3D11ShaderResourceView* texSv = TexSv.GetPtr(); + + switch(stage) + { + case Shader_Fragment: + pParams->pContext->PSSetShaderResources(slot, 1, &texSv); + pParams->pContext->PSSetSamplers(slot, 1, &Sampler.GetRawRef()); + break; + + case Shader_Vertex: + pParams->pContext->VSSetShaderResources(slot, 1, &texSv); + pParams->pContext->VSSetSamplers(slot, 1, &Sampler.GetRawRef()); + break; + + case Shader_Compute: + pParams->pContext->CSSetShaderResources(slot, 1, &texSv); + pParams->pContext->CSSetSamplers(slot, 1, &Sampler.GetRawRef()); + break; + + default: OVR_ASSERT ( false ); break; + } +} + + +//------------------------------------------------------------------------------------- +// ***** GpuTimer +// +#define D3DQUERY_EXEC(_context_, _query_, _command_, ...) _context_->_command_(_query_, __VA_ARGS__) + + +void GpuTimer::Init(ID3D11Device* device, ID3D11DeviceContext* content) +{ + D3dDevice = device; + Context = content; +} + +void GpuTimer::BeginQuery() +{ + HRESULT hr; + + if(GotoNextFrame(LastQueuedFrame) == LastTimedFrame) + { + OVR_ASSERT(false); // too many queries queued + return; + } + + LastQueuedFrame = GotoNextFrame(LastQueuedFrame); + + GpuQuerySets& newQuerySet = QuerySets[LastQueuedFrame]; + if(newQuerySet.DisjointQuery == NULL) + { + // Create the queries + D3D11_QUERY_DESC desc; + desc.Query = D3D11_QUERY_TIMESTAMP_DISJOINT; + desc.MiscFlags = 0; + hr = D3dDevice->CreateQuery(&desc, &newQuerySet.DisjointQuery); + OVR_D3D_CHECK_RET(hr); + + desc.Query = D3D11_QUERY_TIMESTAMP; + hr = D3dDevice->CreateQuery(&desc, &newQuerySet.TimeStartQuery); + OVR_D3D_CHECK_RET(hr); + hr = D3dDevice->CreateQuery(&desc, &newQuerySet.TimeEndQuery); + OVR_D3D_CHECK_RET(hr); + } + + OVR_ASSERT(!newQuerySet.QueryStarted); + OVR_ASSERT(!newQuerySet.QueryAwaitingTiming); + + + D3DQUERY_EXEC(Context, QuerySets[LastQueuedFrame].DisjointQuery, Begin, ); // First start a disjoint query + D3DQUERY_EXEC(Context, QuerySets[LastQueuedFrame].TimeStartQuery, End, ); // Insert start timestamp + + newQuerySet.QueryStarted = true; + newQuerySet.QueryAwaitingTiming = false; + //newQuerySet.QueryTimed = false; +} + +void GpuTimer::EndQuery() +{ + if(LastQueuedFrame > 0 && !QuerySets[LastQueuedFrame].QueryStarted) + return; + + GpuQuerySets& doneQuerySet = QuerySets[LastQueuedFrame]; + OVR_ASSERT(doneQuerySet.QueryStarted); + OVR_ASSERT(!doneQuerySet.QueryAwaitingTiming); + + // Insert the end timestamp + D3DQUERY_EXEC(Context, doneQuerySet.TimeEndQuery, End, ); + + // End the disjoint query + D3DQUERY_EXEC(Context, doneQuerySet.DisjointQuery, End, ); + + doneQuerySet.QueryStarted = false; + doneQuerySet.QueryAwaitingTiming = true; +} + +float GpuTimer::GetTiming(bool blockUntilValid) +{ + float time = -1.0f; + + // loop until we hit a query that is not ready yet, or we have read all queued queries + while(LastTimedFrame != LastQueuedFrame) + { + int timeTestFrame = GotoNextFrame(LastTimedFrame); + + GpuQuerySets& querySet = QuerySets[timeTestFrame]; + + OVR_ASSERT(!querySet.QueryStarted && querySet.QueryAwaitingTiming); + + UINT64 startTime = 0; + UINT64 endTime = 0; + D3D11_QUERY_DATA_TIMESTAMP_DISJOINT disjointData; + + if(blockUntilValid) + { + while(D3DQUERY_EXEC(Context, querySet.TimeStartQuery, GetData, &startTime, sizeof(startTime), 0) != S_OK); + while(D3DQUERY_EXEC(Context, querySet.TimeEndQuery, GetData, &endTime, sizeof(endTime), 0) != S_OK); + while(D3DQUERY_EXEC(Context, querySet.DisjointQuery, GetData, &disjointData, sizeof(disjointData), 0) != S_OK); + } + else + { +// Early return if we fail to get data for any of these + if(D3DQUERY_EXEC(Context, querySet.TimeStartQuery, GetData, &startTime, sizeof(startTime), 0) != S_OK) return time; + if(D3DQUERY_EXEC(Context, querySet.TimeEndQuery, GetData, &endTime, sizeof(endTime), 0) != S_OK) return time; + if(D3DQUERY_EXEC(Context, querySet.DisjointQuery, GetData, &disjointData, sizeof(disjointData), 0) != S_OK) return time; + } + + querySet.QueryAwaitingTiming = false; + LastTimedFrame = timeTestFrame; // successfully retrieved the timing data + + if(disjointData.Disjoint == false) + { + UINT64 delta = endTime - startTime; + float frequency = (float)(disjointData.Frequency); + time = (delta / frequency); + } + } + + return time; +} + +}}} // OVR::CAPI::D3D11 diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.h new file mode 100644 index 0000000..b4e5529 --- /dev/null +++ b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D11_Util.h @@ -0,0 +1,500 @@ +/************************************************************************************ + +Filename : CAPI_D3D11_Util.h +Content : D3D11 utility classes for rendering +Created : September 10, 2012 +Authors : Andrew Reisse + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_D3D11_Util_h +#define OVR_CAPI_D3D11_Util_h + +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_RefCount.h" +#include "Extras/OVR_Math.h" +#include "Util/Util_Direct3D.h" +#include // for _COM_SMARTPTR_TYPEDEF() + +namespace OVR { namespace CAPI { namespace D3D11 { + +class Buffer; + +// Rendering parameters/pointers describing D3DX rendering setup. +struct RenderParams +{ + ID3D11Device* pDevice; + ID3D11DeviceContext* pContext; + ID3D11RenderTargetView* pBackBufferRT; + ID3D11UnorderedAccessView* pBackBufferUAV; + IDXGISwapChain* pSwapChain; + Sizei BackBufferSize; + int Multisample; + UINT32 VidPnTargetId; // display miniport target id for tracing +}; + + +// Rendering primitive type used to render Model. +enum PrimitiveType +{ + Prim_Triangles, + Prim_Lines, + Prim_TriangleStrip, + Prim_Unknown, + Prim_Count +}; + +// Types of shaders that can be stored together in a ShaderSet. +enum ShaderStage +{ + Shader_Vertex = 0, + Shader_Fragment = 2, + Shader_Pixel = 2, + Shader_Compute = 3, // DX11+ only + Shader_Count = 4, +}; + +enum MapFlags +{ + Map_Discard = 1, + Map_Read = 2, // do not use + Map_Unsynchronized = 4, // like D3D11_MAP_NO_OVERWRITE +}; + + +// Buffer types used for uploading geometry & constants. +enum BufferUsage +{ + Buffer_Unknown = 0, + Buffer_Vertex = 1, + Buffer_Index = 2, + Buffer_Uniform = 4, + Buffer_Compute = 8, + Buffer_TypeMask = 0xff, + Buffer_ReadOnly = 0x100, // Buffer must be created with Data(). +}; + +enum TextureFormat +{ + Texture_RGBA = 0x0100, + Texture_Depth = 0x8000, + Texture_TypeMask = 0xff00, + Texture_SamplesMask = 0x00ff, + Texture_RenderTarget = 0x10000, + Texture_SampleDepth = 0x20000, + Texture_GenMipmaps = 0x40000, +}; + +// Texture sampling modes. +enum SampleMode +{ + Sample_Linear = 0, + Sample_Nearest = 1, + Sample_Anisotropic = 2, + Sample_FilterMask = 3, + + Sample_Repeat = 0, + Sample_Clamp = 4, + Sample_ClampBorder = 8, // If unsupported Clamp is used instead. + Sample_Mirror =12, + Sample_AddressMask =12, + + Sample_Count =16, +}; + +// Base class for vertex and pixel shaders. Stored in ShaderSet. +class Shader : public RefCountBase +{ + friend class ShaderSet; + +protected: + ShaderStage Stage; + +public: + Shader(ShaderStage s) : Stage(s) {} + virtual ~Shader() {} + + ShaderStage GetStage() const { return Stage; } + + virtual void Set(PrimitiveType) const { } + virtual void SetUniformBuffer(class Buffer* buffers, int i = 0) { OVR_UNUSED2(buffers, i); } + +protected: + virtual bool SetUniform(const char* name, int n, const float* v) { OVR_UNUSED3(name, n, v); return false; } + virtual bool SetUniformBool(const char* name, int n, const bool* v) { OVR_UNUSED3(name, n, v); return false; } +}; + + + +// A group of shaders, one per stage. +// A ShaderSet is applied to a RenderDevice for rendering with a given fill. +class ShaderSet : public RefCountBase +{ +protected: + Ptr Shaders[Shader_Count]; + +public: + ShaderSet() { } + ~ShaderSet() { } + + virtual void SetShader(Shader *s) + { + Shaders[s->GetStage()] = s; + } + virtual void UnsetShader(int stage) + { + Shaders[stage] = NULL; + } + Shader* GetShader(int stage) { return Shaders[stage]; } + + virtual void Set(PrimitiveType prim) const + { + for (int i = 0; i < Shader_Count; i++) + if (Shaders[i]) + Shaders[i]->Set(prim); + } + + // Set a uniform (other than the standard matrices). It is undefined whether the + // uniforms from one shader occupy the same space as those in other shaders + // (unless a buffer is used, then each buffer is independent). + virtual bool SetUniform(const char* name, int n, const float* v) + { + bool result = 0; + for (int i = 0; i < Shader_Count; i++) + if (Shaders[i]) + result |= Shaders[i]->SetUniform(name, n, v); + + return result; + } + bool SetUniform1f(const char* name, float x) + { + const float v[] = {x}; + return SetUniform(name, 1, v); + } + bool SetUniform2f(const char* name, float x, float y) + { + const float v[] = {x,y}; + return SetUniform(name, 2, v); + } + bool SetUniform3f(const char* name, float x, float y, float z) + { + const float v[] = {x,y,z}; + return SetUniform(name, 3, v); + } + bool SetUniform4f(const char* name, float x, float y, float z, float w = 1) + { + const float v[] = {x,y,z,w}; + return SetUniform(name, 4, v); + } + + bool SetUniformv(const char* name, const Vector3f& v) + { + const float a[] = {v.x,v.y,v.z,1}; + return SetUniform(name, 4, a); + } + + virtual bool SetUniform4x4f(const char* name, const Matrix4f& m) + { + Matrix4f mt = m.Transposed(); + return SetUniform(name, 16, &mt.M[0][0]); + } + virtual bool SetUniform3x3f(const char* name, const Matrix4f& m) + { + // float3x3 is actually stored the same way as float4x3, with the last items ignored by the code. + Matrix4f mt = m.Transposed(); + return SetUniform(name, 12, &mt.M[0][0]); + } + +}; + + +// Fill combines a ShaderSet (vertex, pixel) with textures, if any. +// Every model has a fill. +class ShaderFill : public RefCountBase +{ + Ptr Shaders; + Ptr PsTextures[8]; + Ptr VsTextures[8]; + Ptr CsTextures[8]; + void* InputLayout; // HACK this should be abstracted + +public: + ShaderFill(ShaderSet* sh) : Shaders(sh) { InputLayout = NULL; } + ShaderFill(ShaderSet& sh) : Shaders(sh) { InputLayout = NULL; } + + ShaderSet* GetShaders() const { return Shaders; } + void* GetInputLayout() const { return InputLayout; } + + virtual void Set(PrimitiveType prim = Prim_Unknown) const; + + virtual void SetTexture(int i, class Texture* tex, ShaderStage stage) + { + if (i < 8) + { + if(stage == Shader_Pixel) PsTextures[i] = tex; + else if(stage == Shader_Vertex) VsTextures[i] = tex; + else if(stage == Shader_Compute) CsTextures[i] = tex; + else OVR_ASSERT(false); + } + } + void SetInputLayout(void* newIL) { InputLayout = (void*)newIL; } +}; + + +class ShaderBase : public Shader +{ +public: + RenderParams* pParams; + unsigned char* UniformData; + int UniformsSize; + + enum VarType + { + VARTYPE_FLOAT, + VARTYPE_INT, + VARTYPE_BOOL, + }; + + struct Uniform + { + const char* Name; + VarType Type; + int Offset; + int Size; + }; + const Uniform* UniformRefl; + size_t UniformReflSize; + + ShaderBase(RenderParams* rp, ShaderStage stage); + ~ShaderBase(); + + ShaderStage GetStage() const { return Stage; } + + void InitUniforms(const Uniform* refl, size_t reflSize); + bool SetUniform(const char* name, int n, const float* v); + bool SetUniformBool(const char* name, int n, const bool* v); + + void UpdateBuffer(Buffer* b); +}; + + +template +class ShaderImpl : public ShaderBase +{ +public: + D3DShaderType* D3DShader; + + ShaderImpl(RenderParams* rp, void* s, size_t size, const Uniform* refl, size_t reflSize) : ShaderBase(rp, SStage) + { + Load(s, size); + InitUniforms(refl, reflSize); + } + ~ShaderImpl() + { + if (D3DShader) + D3DShader->Release(); + } + + // These functions have specializations. + bool Load(void* shader, size_t size); + void Set(PrimitiveType prim) const; + void SetUniformBuffer(Buffer* buffers, int i = 0); +}; + +typedef ShaderImpl VertexShader; +typedef ShaderImpl PixelShader; +typedef ShaderImpl ComputeShader; + + +class Buffer : public RefCountBase +{ +public: + RenderParams* pParams; + Ptr D3DBuffer; + Ptr D3DSrv; + Ptr D3DUav; + size_t Size; + int Use; + bool Dynamic; + +public: + Buffer(RenderParams* rp) : pParams(rp), D3DBuffer(), D3DSrv(), + D3DUav(), + Size(0), Use(0), Dynamic(false) {} + ~Buffer(); + + ID3D11Buffer* GetBuffer() const + { + return D3DBuffer; + } + + ID3D11ShaderResourceView* GetSrv() const + { + return D3DSrv; + } + + ID3D11UnorderedAccessView* GetUav() const + { + return D3DUav; + } + + virtual size_t GetSize() { return Size; } + virtual void* Map(size_t start, size_t size, int flags = 0); + virtual bool Unmap(void *m); + virtual bool Data(int use, const void* buffer, size_t size, int computeBufferStride = -1); +}; + + +class Texture : public RefCountBase +{ +public: + RenderParams* pParams; + Ptr Tex; + Ptr TexSv; + Ptr TexRtv; + Ptr TexDsv; + // TODO: add UAV... + mutable Ptr Sampler; + Sizei TextureSize; + int Samples; + + Texture(RenderParams* rp, int fmt, const Sizei texSize, + ID3D11SamplerState* sampler, int samples = 1); + Texture(RenderParams* rp, int fmt, const Sizei texSize, + ID3D11SamplerState* sampler, const void* data, int mipcount); + ~Texture(); + + void GenerateSubresourceData( + unsigned imageWidth, unsigned imageHeight, int format, unsigned imageDimUpperLimit, + const void* rawBytes, D3D11_SUBRESOURCE_DATA* subresData, + unsigned& largestMipWidth, unsigned& largestMipHeight, unsigned& byteSize, unsigned& effectiveMipCount); + + virtual Sizei GetSize() const { return TextureSize; } + virtual int GetSamples() const { return Samples; } + + // virtual void SetSampleMode(int sm); + + // Updates texture to point to specified resources + // - used for slave rendering. + void UpdatePlaceholderTexture(ID3D11Texture2D* texture, + ID3D11ShaderResourceView* psrv, + const Sizei& textureSize, const int sampleCount) + { + Tex = texture; + TexSv = psrv; + TexRtv.Clear(); + TexDsv.Clear(); + + TextureSize = textureSize; + Samples = sampleCount; + +#ifdef OVR_BUILD_DEBUG + D3D11_TEXTURE2D_DESC desc; + texture->GetDesc(&desc); + OVR_ASSERT(TextureSize == Sizei(desc.Width, desc.Height)); +#endif + } + + + virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const; + + int GetNumMipLevels(int w, int h) + { + int n = 1; + while(w > 1 || h > 1) + { + w >>= 1; + h >>= 1; + n++; + } + return n; + } + + void FilterRgba2x2(const uint8_t* src, int w, int h, uint8_t* dest) + { + for(int j = 0; j < (h & ~1); j += 2) + { + const uint8_t* psrc = src + (w * j * 4); + uint8_t* pdest = dest + ((w >> 1) * (j >> 1) * 4); + + for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4) + { + pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2; + pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2; + pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2; + pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2; + } + } + } +}; + + +class GpuTimer : public RefCountBase +{ +public: + GpuTimer() + : QuerySets(MaxNumQueryFrames) + , D3dDevice(NULL) + , Context(NULL) + , LastQueuedFrame(-1) + , LastTimedFrame(-1) + { } + + void Init(ID3D11Device* device, ID3D11DeviceContext* content); + + void BeginQuery(); + void EndQuery(); + + // Returns -1 if timing is invalid + float GetTiming(bool blockUntilValid); + +protected: + static const unsigned MaxNumQueryFrames = 10; + + int GotoNextFrame(int frame) + { + return (frame + 1) % MaxNumQueryFrames; + } + + _COM_SMARTPTR_TYPEDEF(ID3D11Query, __uuidof(ID3D11Query)); + + struct GpuQuerySets + { + ID3D11QueryPtr DisjointQuery; + ID3D11QueryPtr TimeStartQuery; + ID3D11QueryPtr TimeEndQuery; + bool QueryStarted; + bool QueryAwaitingTiming; + + GpuQuerySets() : QueryStarted(false), QueryAwaitingTiming(false) {} + }; + Array QuerySets; + + int LastQueuedFrame; + int LastTimedFrame; + + Ptr D3dDevice; + Ptr Context; +}; + +}}} // OVR::CAPI::D3D11 + +#endif // OVR_CAPI_D3D11_Util_h diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp deleted file mode 100644 index 04cfd07..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.cpp +++ /dev/null @@ -1,1414 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_DistortionRenderer.cpp -Content : Experimental distortion renderer -Created : November 11, 2013 -Authors : Volga Aksoy, Michael Antonov, Shariq Hashme - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "CAPI_D3D1X_DistortionRenderer.h" - -#include "../../OVR_CAPI_D3D.h" -#include "../CAPI_HMDState.h" -#include "../../Kernel/OVR_Color.h" - -namespace OVR { namespace CAPI { namespace D3D_NS { - -#include "Shaders/Distortion_vs.h" -#include "Shaders/Distortion_vs_refl.h" -#include "Shaders/Distortion_ps.h" -#include "Shaders/Distortion_ps_refl.h" -#include "Shaders/DistortionChroma_vs.h" -#include "Shaders/DistortionChroma_vs_refl.h" -#include "Shaders/DistortionChroma_ps.h" -#include "Shaders/DistortionChroma_ps_refl.h" -#include "Shaders/DistortionTimewarp_vs.h" -#include "Shaders/DistortionTimewarp_vs_refl.h" -#include "Shaders/DistortionTimewarpChroma_vs.h" -#include "Shaders/DistortionTimewarpChroma_vs_refl.h" -#include "Shaders/DistortionCS2x2.h" -#include "Shaders/DistortionCS2x2_refl.h" - -#include "Shaders/SimpleQuad_vs.h" -#include "Shaders/SimpleQuad_vs_refl.h" -#include "Shaders/SimpleQuad_ps.h" -#include "Shaders/SimpleQuad_ps_refl.h" - -#include -DEFINE_GUID(IID_OVRDXGISwapchain, 0x868f9b4f, 0xe427, 0x46ed, 0xb0, 0x94, 0x66, 0xd1, 0x3b, 0xb, 0x48, 0xf7); - -// Distortion pixel shader lookup. -// Bit 0: Chroma Correction -// Bit 1: Timewarp - -enum { - DistortionVertexShaderBitMask = 3, - DistortionVertexShaderCount = DistortionVertexShaderBitMask + 1, - DistortionPixelShaderBitMask = 1, - DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1, -}; - -struct PrecompiledShader -{ - const unsigned char* ShaderData; - size_t ShaderSize; - const ShaderBase::Uniform* ReflectionData; - size_t ReflectionSize; -}; - -// Do add a new distortion shader use these macros (with or w/o reflection) -#define PCS_NOREFL(shader) { shader, sizeof(shader), NULL, 0 } -#define PCS_REFL__(shader) { shader, sizeof(shader), shader ## _refl, sizeof( shader ## _refl )/sizeof(*(shader ## _refl)) } - - -static PrecompiledShader DistortionVertexShaderLookup[DistortionVertexShaderCount] = -{ - PCS_REFL__(Distortion_vs), - PCS_REFL__(DistortionChroma_vs), - PCS_REFL__(DistortionTimewarp_vs), - PCS_REFL__(DistortionTimewarpChroma_vs), -}; - -static PrecompiledShader DistortionPixelShaderLookup[DistortionPixelShaderCount] = -{ - PCS_NOREFL(Distortion_ps), - PCS_REFL__(DistortionChroma_ps) -}; - -enum -{ - DistortionComputeShader2x2 = 0, - DistortionComputeShader2x2Pentile, - DistortionComputeShaderCount -}; -static PrecompiledShader DistortionComputeShaderLookup[DistortionComputeShaderCount] = -{ - PCS_REFL__(DistortionCS2x2) -}; - - - -void DistortionShaderBitIndexCheck() -{ - OVR_COMPILER_ASSERT(ovrDistortionCap_Chromatic == 1); - OVR_COMPILER_ASSERT(ovrDistortionCap_TimeWarp == 2); -} - - - -struct DistortionVertex // Must match the VB description DistortionMeshVertexDesc -{ - Vector2f ScreenPosNDC; - Vector2f TanEyeAnglesR; - Vector2f TanEyeAnglesG; - Vector2f TanEyeAnglesB; - Color Col; -}; - -struct DistortionComputePin // Must match the ones declared in DistortionCS*.csh -{ - Vector2f TanEyeAnglesR; - Vector2f TanEyeAnglesG; - Vector2f TanEyeAnglesB; - Color Col; - int padding[1]; // Aligns to power-of-two boundary, increases performance significantly. -}; - - -// Vertex type; same format is used for all shapes for simplicity. -// Shapes are built by adding vertices to Model. -struct Vertex -{ - Vector3f Pos; - Color C; - float U, V; - Vector3f Norm; - - Vertex (const Vector3f& p, const Color& c = Color(64,0,0,255), - float u = 0, float v = 0, Vector3f n = Vector3f(1,0,0)) - : Pos(p), C(c), U(u), V(v), Norm(n) - {} - Vertex(float x, float y, float z, const Color& c = Color(64,0,0,255), - float u = 0, float v = 0) : Pos(x,y,z), C(c), U(u), V(v) - { } - - bool operator==(const Vertex& b) const - { - return Pos == b.Pos && C == b.C && U == b.U && V == b.V; - } -}; - - -//---------------------------------------------------------------------------- -// ***** D3D1X::DistortionRenderer - -DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, - const HMDRenderState& renderState) - : CAPI::DistortionRenderer(ovrRenderAPI_D3D11, hmd, timeManager, renderState) -{ - SrgbBackBuffer = false; - - EyeTextureSize[0] = Sizei(0); - EyeRenderViewport[0] = Recti(); - EyeTextureSize[1] = Sizei(0); - EyeRenderViewport[1] = Recti(); -} - -DistortionRenderer::~DistortionRenderer() -{ - destroy(); -} - -// static -CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState) -{ - return new DistortionRenderer(hmd, timeManager, renderState); -} - - -bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) -{ - const ovrD3D1X(Config)* config = (const ovrD3D1X(Config)*)apiConfig; - - if (!config) - { - // Cleanup - pEyeTextures[0].Clear(); - pEyeTextures[1].Clear(); - memset(&RParams, 0, sizeof(RParams)); - return true; - } - - if (!config->D3D_NS.pDevice || !config->D3D_NS.pBackBufferRT) - return false; - - if (System::DirectDisplayEnabled()) - { - Ptr ovrSwapChain; - if (config->D3D_NS.pSwapChain->QueryInterface(IID_OVRDXGISwapchain, (void**)&ovrSwapChain.GetRawRef()) == E_NOINTERFACE) - { - OVR_DEBUG_LOG_TEXT(("ovr_Initialize() or ovr_InitializeRenderingShim() wasn't called before DXGISwapChain was created.")); - } - } - - RParams.pDevice = config->D3D_NS.pDevice; - RParams.pContext = D3DSELECT_10_11(config->D3D_NS.pDevice, config->D3D_NS.pDeviceContext); - RParams.pBackBufferRT = config->D3D_NS.pBackBufferRT; -#if (OVR_D3D_VERSION>=11) - RParams.pBackBufferUAV = config->D3D_NS.pBackBufferUAV; -#else - RParams.pBackBufferUAV = NULL; -#endif - RParams.pSwapChain = config->D3D_NS.pSwapChain; - RParams.BackBufferSize = config->D3D_NS.Header.BackBufferSize; - RParams.Multisample = config->D3D_NS.Header.Multisample; - - GfxState = *new GraphicsState(RParams.pContext); - - D3D1X_(RENDER_TARGET_VIEW_DESC) backBufferDesc; - RParams.pBackBufferRT->GetDesc(&backBufferDesc); - SrgbBackBuffer = (backBufferDesc.Format == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) || - (backBufferDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB) || - (backBufferDesc.Format == DXGI_FORMAT_B8G8R8X8_UNORM_SRGB); - - -#if 0 // enable related section in DistortionChroma.psh shader - // aniso requires proper sRGB sampling - SampleMode hqFilter = (RState.DistortionCaps & ovrDistortionCap_HqDistortion) ? Sample_Anisotropic : Sample_Linear; -#else - SampleMode hqFilter = Sample_Linear; -#endif - - pEyeTextures[0] = *new Texture(&RParams, Texture_RGBA, Sizei(0), - getSamplerState(hqFilter|Sample_ClampBorder)); - pEyeTextures[1] = *new Texture(&RParams, Texture_RGBA, Sizei(0), - getSamplerState(hqFilter|Sample_ClampBorder)); - - initBuffersAndShaders(); - - // Rasterizer state - D3D1X_(RASTERIZER_DESC) rs; - memset(&rs, 0, sizeof(rs)); - rs.AntialiasedLineEnable = true; - rs.CullMode = D3D1X_(CULL_BACK); - rs.DepthClipEnable = true; - rs.FillMode = D3D1X_(FILL_SOLID); - Rasterizer = NULL; - RParams.pDevice->CreateRasterizerState(&rs, &Rasterizer.GetRawRef()); - - initOverdrive(); - - // TBD: Blend state.. not used? - // We'll want to turn off blending - -#if (OVR_D3D_VERSION == 11) - GpuProfiler.Init(RParams.pDevice, RParams.pContext); -#endif - - return true; -} - -void DistortionRenderer::initOverdrive() -{ - if(RState.DistortionCaps & ovrDistortionCap_Overdrive) - { - LastUsedOverdriveTextureIndex = 0; - - D3D1X_(RENDER_TARGET_VIEW_DESC) backBufferDesc; - RParams.pBackBufferRT->GetDesc(&backBufferDesc); - - for (int i = 0; i < NumOverdriveTextures; i++) - { - pOverdriveTextures[i] = *new Texture(&RParams, Texture_RGBA, RParams.BackBufferSize, - getSamplerState(Sample_Linear|Sample_ClampBorder)); - - D3D1X_(TEXTURE2D_DESC) dsDesc; - dsDesc.Width = RParams.BackBufferSize.w; - dsDesc.Height = RParams.BackBufferSize.h; - dsDesc.MipLevels = 1; - dsDesc.ArraySize = 1; - dsDesc.Format = backBufferDesc.Format; - dsDesc.SampleDesc.Count = 1; - dsDesc.SampleDesc.Quality = 0; - dsDesc.Usage = D3D1X_(USAGE_DEFAULT); - dsDesc.BindFlags = D3D1X_(BIND_SHADER_RESOURCE) | D3D1X_(BIND_RENDER_TARGET); - dsDesc.CPUAccessFlags = 0; - dsDesc.MiscFlags = 0; - - HRESULT hr = RParams.pDevice->CreateTexture2D(&dsDesc, NULL, &pOverdriveTextures[i]->Tex.GetRawRef()); - if (FAILED(hr)) - { - OVR_DEBUG_LOG_TEXT(("Failed to create overdrive texture.")); - // Remove overdrive flag since we failed to create the texture - LastUsedOverdriveTextureIndex = -1; // disables feature - break; - } - - RParams.pDevice->CreateShaderResourceView(pOverdriveTextures[i]->Tex, NULL, &pOverdriveTextures[i]->TexSv.GetRawRef()); - RParams.pDevice->CreateRenderTargetView(pOverdriveTextures[i]->Tex, NULL, &pOverdriveTextures[i]->TexRtv.GetRawRef()); - } - } - else - { - LastUsedOverdriveTextureIndex = -1; - } -} - -void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) -{ - const ovrD3D1X(Texture)* tex = (const ovrD3D1X(Texture)*)eyeTexture; - - if (eyeTexture) - { - // Use tex->D3D_NS.Header.RenderViewport to update UVs for rendering in case they changed. - // TBD: This may be optimized through some caching. - EyeTextureSize[eyeId] = tex->D3D_NS.Header.TextureSize; - EyeRenderViewport[eyeId] = tex->D3D_NS.Header.RenderViewport; - - const ovrEyeRenderDesc& erd = RState.EyeRenderDesc[eyeId]; - - ovrHmd_GetRenderScaleAndOffset(erd.Fov, - EyeTextureSize[eyeId], EyeRenderViewport[eyeId], - UVScaleOffset[eyeId]); - - if (RState.DistortionCaps & ovrDistortionCap_FlipInput) - { - UVScaleOffset[eyeId][0].y = -UVScaleOffset[eyeId][0].y; - UVScaleOffset[eyeId][1].y = 1.0f - UVScaleOffset[eyeId][1].y; - } - - pEyeTextures[eyeId]->UpdatePlaceholderTexture(tex->D3D_NS.pTexture, tex->D3D_NS.pSRView, - tex->D3D_NS.Header.TextureSize); - } -} - -void DistortionRenderer::renderEndFrame() -{ - renderDistortion(pEyeTextures[0], pEyeTextures[1]); - - if(RegisteredPostDistortionCallback) - RegisteredPostDistortionCallback(RParams.pContext); - - if(LatencyTest2Active) - { - renderLatencyPixel(LatencyTest2DrawColor); - } -} - -void DistortionRenderer::EndFrame(bool swapBuffers) -{ - // Don't spin if we are explicitly asked not to - if ((RState.DistortionCaps & ovrDistortionCap_TimeWarp) && - !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) - { - if (!TimeManager.NeedDistortionTimeMeasurement()) - { - // Wait for timewarp distortion if it is time and Gpu idle - FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); - - renderEndFrame(); - } - else - { - // If needed, measure distortion time so that TimeManager can better estimate - // latency-reducing time-warp wait timing. - WaitUntilGpuIdle(); - double distortionStartTime = ovr_GetTimeInSeconds(); - - renderEndFrame(); - - WaitUntilGpuIdle(); - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); - } - } - else - { - renderEndFrame(); - } - - if(LatencyTestActive) - { - renderLatencyQuad(LatencyTestDrawColor); - } - - if (swapBuffers) - { - if (RParams.pSwapChain) - { - UINT swapInterval = (RState.EnabledHmdCaps & ovrHmdCap_NoVSync) ? 0 : 1; - RParams.pSwapChain->Present(swapInterval, 0); - - // Force GPU to flush the scene, resulting in the lowest possible latency. - // It's critical that this flush is *after* present. - // With the display driver this flush is obsolete and theoretically should - // be a no-op. - // Doesn't need to be done if running through the Oculus driver. - if (RState.OurHMDInfo.InCompatibilityMode && - !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) - WaitUntilGpuIdle(); - } - else - { - // TBD: Generate error - swapbuffer option used with null swapchain. - } - } -} - - -void DistortionRenderer::WaitUntilGpuIdle() -{ - // Flush and Stall CPU while waiting for GPU to complete rendering all of the queued draw calls - D3D1x_QUERY_DESC queryDesc = { D3D1X_(QUERY_EVENT), 0 }; - Ptr query; - BOOL done = FALSE; - - if (RParams.pDevice->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK) - { - D3DSELECT_10_11(query->End(), - RParams.pContext->End(query)); - - // GetData will returns S_OK for both done == TRUE or FALSE. - // Exit on failure to avoid infinite loop. - do { } - while(!done && - !FAILED(D3DSELECT_10_11(query->GetData(&done, sizeof(BOOL), 0), - RParams.pContext->GetData(query, &done, sizeof(BOOL), 0))) - ); - } -} - -double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) -{ - RParams.pContext->Flush(); - return WaitTillTime(absTime); -} - -void DistortionRenderer::initBuffersAndShaders() -{ - if ( RState.DistortionCaps & ovrDistortionCap_ComputeShader ) - { - // Compute shader distortion grid. - // TODO - only do this if the CS is actually enabled? - for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) - { - // Compute shader setup of regular grid. - DistortionMeshVBs[eyeNum] = NULL; - DistortionMeshIBs[eyeNum] = NULL; - - // These constants need to match those declared in the shader in DistortionCS*.csh - const int gridSizeInPixels = 16; - const int pinsPerEdge = 128; - - - // TODO: clean up this mess! - HMDState* hmds = (HMDState*)HMD->Handle; - ovrEyeType eyeType = RState.EyeRenderDesc[eyeNum].Eye; - ovrFovPort fov = RState.EyeRenderDesc[eyeNum].Fov; - - const HmdRenderInfo& hmdri = hmds->RenderState.RenderInfo; - DistortionRenderDesc& distortion = hmds->RenderState.Distortion[eyeType]; - - - // Find the mapping from TanAngle space to target NDC space. - ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(fov); - - //const StereoEyeParams &stereoParams = ( eyeNum == 0 ) ? stereoParamsLeft : stereoParamsRight; - OVR_ASSERT ( gridSizeInPixels * (pinsPerEdge-1) > hmdri.ResolutionInPixels.w/2 ); - OVR_ASSERT ( gridSizeInPixels * (pinsPerEdge-1) > hmdri.ResolutionInPixels.h ); - DistortionComputePin Verts[pinsPerEdge*pinsPerEdge]; - // Vertices are laid out in a vertical scanline pattern, - // scanning right to left, then within each scan going top to bottom, like DK2. - // If we move to a different panel orientation, we may need to flip this around. - int vertexNum = 0; - for ( int x = 0; x < pinsPerEdge; x++ ) - { - for ( int y = 0; y < pinsPerEdge; y++ ) - { - int pixX = x * gridSizeInPixels; - int pixY = y * gridSizeInPixels; - #if 0 - // Simple version, ignoring pentile offsets - Vector2f screenPosNdc; - screenPosNdc.x = 2.0f * ( 0.5f - ( (float)pixX / (hmdri.ResolutionInPixels.w/2) ) ); // Note signs! - screenPosNdc.y = 2.0f * ( -0.5f + ( (float)pixY / hmdri.ResolutionInPixels.h ) ); // Note signs! - - DistortionMeshVertexData vertex = DistortionMeshMakeVertex ( screenPosNdc, - ( eyeNum == 1 ), - hmdri, - distortion, - eyeToSourceNDC ); - DistortionComputePin *pCurVert = &(Verts[vertexNum]); - pCurVert->TanEyeAnglesR = vertex.TanEyeAnglesR; - pCurVert->TanEyeAnglesG = vertex.TanEyeAnglesG; - pCurVert->TanEyeAnglesB = vertex.TanEyeAnglesB; - #else - // Pentile offsets are messy. - Vector2f screenPos[3]; // R=0, G=1, B=2 - DistortionMeshVertexData vertexRGB[3]; - screenPos[1] = Vector2f ( (float)pixX, (float)pixY ); - screenPos[0] = screenPos[1]; - screenPos[2] = screenPos[1]; - - if ( ( hmds->RenderState.EnabledHmdCaps & ovrHmdCap_DirectPentile ) != 0 ) - { - // Doing direct display, so enable the pentile offsets. - screenPos[0] = screenPos[1] + hmdri.PelOffsetR; - screenPos[2] = screenPos[1] + hmdri.PelOffsetB; - } - - for ( int i = 0; i < 3; i++ ) - { - Vector2f screenPosNdc; - screenPosNdc.x = 2.0f * ( 0.5f - ( screenPos[i].x / (hmdri.ResolutionInPixels.w/2) ) ); // Note signs! - screenPosNdc.y = 2.0f * ( -0.5f + ( screenPos[i].y / hmdri.ResolutionInPixels.h ) ); // Note signs! - vertexRGB[i] = DistortionMeshMakeVertex ( screenPosNdc, - ( eyeNum == 1 ), - hmdri, - distortion, - eyeToSourceNDC ); - } - // Most data (fade, TW interpolate, etc) comes from the green channel. - DistortionMeshVertexData vertex = vertexRGB[1]; - DistortionComputePin *pCurVert = &(Verts[vertexNum]); - pCurVert->TanEyeAnglesR = vertexRGB[0].TanEyeAnglesR; - pCurVert->TanEyeAnglesG = vertexRGB[1].TanEyeAnglesG; - pCurVert->TanEyeAnglesB = vertexRGB[2].TanEyeAnglesB; - #endif - - // vertex.Shade will go negative beyond the edges to produce correct intercept with the 0.0 plane. - // We want to preserve this, so bias and offset to fit [-1,+1] in a byte. - // The reverse wll be done in the shader. - float shade = Alg::Clamp ( vertex.Shade * 0.5f + 0.5f, 0.0f, 1.0f ); - pCurVert->Col.R = (OVR::UByte)( floorf ( shade * 255.999f ) ); - pCurVert->Col.G = pCurVert->Col.R; - pCurVert->Col.B = pCurVert->Col.R; - pCurVert->Col.A = (OVR::UByte)( floorf ( vertex.TimewarpLerp * 255.999f ) ); - - vertexNum++; - } - } - DistortionPinBuffer[eyeNum] = *new Buffer(&RParams); - DistortionPinBuffer[eyeNum]->Data ( Buffer_Compute, Verts, vertexNum * sizeof(Verts[0]), sizeof(Verts[0]) ); - } - - } - else - { - for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) - { - // Allocate & generate distortion mesh vertices. - DistortionPinBuffer[eyeNum] = NULL; - - ovrDistortionMesh meshData; - - // double startT = ovr_GetTimeInSeconds(); - - if (!ovrHmd_CreateDistortionMesh( HMD, - RState.EyeRenderDesc[eyeNum].Eye, - RState.EyeRenderDesc[eyeNum].Fov, - RState.DistortionCaps, - &meshData) ) - { - OVR_ASSERT(false); - continue; - } - - // double deltaT = ovr_GetTimeInSeconds() - startT; - // LogText("GenerateDistortion time = %f\n", deltaT); - - // Now parse the vertex data and create a render ready vertex buffer from it - DistortionVertex * pVBVerts = (DistortionVertex*)OVR_ALLOC ( sizeof(DistortionVertex) * meshData.VertexCount ); - DistortionVertex * pCurVBVert = pVBVerts; - ovrDistortionVertex* pCurOvrVert = meshData.pVertexData; - - for ( unsigned vertNum = 0; vertNum < meshData.VertexCount; vertNum++ ) - { - pCurVBVert->ScreenPosNDC.x = pCurOvrVert->ScreenPosNDC.x; - pCurVBVert->ScreenPosNDC.y = pCurOvrVert->ScreenPosNDC.y; - pCurVBVert->TanEyeAnglesR = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesR); - pCurVBVert->TanEyeAnglesG = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesG); - pCurVBVert->TanEyeAnglesB = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesB); - - // Convert [0.0f,1.0f] to [0,255] - if (RState.DistortionCaps & ovrDistortionCap_Vignette) - pCurVBVert->Col.R = (uint8_t)( Alg::Max ( pCurOvrVert->VignetteFactor, 0.0f ) * 255.99f ); - else - pCurVBVert->Col.R = 255; - - pCurVBVert->Col.G = pCurVBVert->Col.R; - pCurVBVert->Col.B = pCurVBVert->Col.R; - pCurVBVert->Col.A = (uint8_t)( pCurOvrVert->TimeWarpFactor * 255.99f ); - pCurOvrVert++; - pCurVBVert++; - } - - DistortionMeshVBs[eyeNum] = *new Buffer(&RParams); - DistortionMeshVBs[eyeNum]->Data(Buffer_Vertex | Buffer_ReadOnly, pVBVerts, sizeof(DistortionVertex)* meshData.VertexCount); - DistortionMeshIBs[eyeNum] = *new Buffer(&RParams); - DistortionMeshIBs[eyeNum]->Data(Buffer_Index | Buffer_ReadOnly, meshData.pIndexData, (sizeof(INT16)* meshData.IndexCount)); - - OVR_FREE ( pVBVerts ); - ovrHmd_DestroyDistortionMesh( &meshData ); - } - } - - - // Uniform buffers - for(int i = 0; i < Shader_Count; i++) - { - UniformBuffers[i] = *new Buffer(&RParams); - //MaxTextureSet[i] = 0; - } - - initShaders(); -} - -void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture) -{ - -#if (OVR_D3D_VERSION == 10) - RParams.pContext->GSSetShader(NULL); -#else // d3d 11 - RParams.pContext->HSSetShader(NULL, NULL, 0); - RParams.pContext->DSSetShader(NULL, NULL, 0); - RParams.pContext->GSSetShader(NULL, NULL, 0); -#endif - - RParams.pContext->RSSetState(Rasterizer); - - bool overdriveActive = IsOverdriveActive(); - int currOverdriveTextureIndex = -1; - - if(overdriveActive) - { - currOverdriveTextureIndex = (LastUsedOverdriveTextureIndex + 1) % NumOverdriveTextures; - ID3D1xRenderTargetView* distortionRtv = pOverdriveTextures[currOverdriveTextureIndex]->TexRtv.GetRawRef(); - ID3D1xRenderTargetView* mrtRtv[2] = {distortionRtv, RParams.pBackBufferRT}; - RParams.pContext->OMSetRenderTargets(2, mrtRtv, 0); - - RParams.pContext->ClearRenderTargetView(distortionRtv, RState.ClearColor); - } - else - { - RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0); - } - - // Not affected by viewport. - RParams.pContext->ClearRenderTargetView(RParams.pBackBufferRT, RState.ClearColor); - - setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); - - - for(int eyeNum = 0; eyeNum < 2; eyeNum++) - { - ShaderFill distortionShaderFill(DistortionShader); - distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture, Shader_Pixel); - - if(RState.DistortionCaps & ovrDistortionCap_HqDistortion) - { - static float aaDerivMult = 1.0f; - DistortionShader->SetUniform1f("AaDerivativeMult", aaDerivMult); - } - else - { - // 0.0 disables high quality anti-aliasing - DistortionShader->SetUniform1f("AaDerivativeMult", -1.0f); - } - - if(overdriveActive) - { - distortionShaderFill.SetTexture(1, pOverdriveTextures[LastUsedOverdriveTextureIndex], Shader_Pixel); - - float overdriveScaleRegularRise; - float overdriveScaleRegularFall; - GetOverdriveScales(overdriveScaleRegularRise, overdriveScaleRegularFall); - DistortionShader->SetUniform2f("OverdriveScales", overdriveScaleRegularRise, overdriveScaleRegularFall); - } - else - { - // -1.0f disables PLO - DistortionShader->SetUniform2f("OverdriveScales", -1.0f, -1.0f); - } - - distortionShaderFill.SetInputLayout(DistortionVertexIL); - - DistortionShader->SetUniform2f("EyeToSourceUVScale", UVScaleOffset[eyeNum][0].x, UVScaleOffset[eyeNum][0].y); - DistortionShader->SetUniform2f("EyeToSourceUVOffset", UVScaleOffset[eyeNum][1].x, UVScaleOffset[eyeNum][1].y); - - - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) - { - ovrMatrix4f timeWarpMatrices[2]; - ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, - RState.EyeRenderPoses[eyeNum], timeWarpMatrices); - - if (RState.DistortionCaps & ovrDistortionCap_ComputeShader) - { - DistortionShader->SetUniform3x3f("EyeRotationStart", Matrix4f(timeWarpMatrices[0])); - DistortionShader->SetUniform3x3f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1])); - } - else - { - // Can feed identity like matrices incase of concern over timewarp calculations - DistortionShader->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0])); - DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1])); - } - } - - - if (RState.DistortionCaps & ovrDistortionCap_ComputeShader) - { -#if (OVR_D3D_VERSION >= 11) - //RParams.pContext->CSCSSetShaderResources - //RParams.pContext->CSSetUnorderedAccessViews - //RParams.pContext->CSSetShader - //RParams.pContext->CSSetSamplers - //RParams.pContext->CSSetConstantBuffers - - - // These need to match the values used in the compiled shader - //const int gridSizeInPixels = 16; // GRID_SIZE_IN_PIXELS - //const int pinsPerEdge = 128; // PINS_PER_EDGE - const int nxnBlockSizeInPixels = 2; // NXN_BLOCK_SIZE_PIXELS - const int simdSquareSize = 16; // SIMD_SQUARE_SIZE - - const int invocationSizeInPixels = nxnBlockSizeInPixels * simdSquareSize; - - distortionShaderFill.SetTexture(0, eyeNum == 0 ? leftEyeTexture : rightEyeTexture, Shader_Compute); - - DistortionShader->SetUniform1f("RightEye", (float)eyeNum); - DistortionShader->SetUniform1f("UseOverlay", 0.0f); // No overlay supported here. - DistortionShader->SetUniform1f("FbSizePixelsX", (float)RParams.BackBufferSize.w); - - ShaderSet* shaders = distortionShaderFill.GetShaders(); - ShaderBase* cshader = ((ShaderBase*)shaders->GetShader(Shader_Compute)); - - ID3D1xUnorderedAccessView *uavRendertarget = RParams.pBackBufferUAV; - int SizeX = RParams.BackBufferSize.w/2; - int SizeY = RParams.BackBufferSize.h; - - int TileNumX = ( SizeX + (invocationSizeInPixels-1) ) / invocationSizeInPixels; - int TileNumY = ( SizeY + (invocationSizeInPixels-1) ) / invocationSizeInPixels; - - RParams.pContext->CSSetUnorderedAccessViews ( 0, 1, &uavRendertarget, NULL ); - - - // Incoming eye-buffer textures start at t0 onwards, so set this in slot #4 - // Subtlety - can't put this in slot 0 because fill->Set stops at the first NULL texture. - ID3D1xShaderResourceView *d3dSrv = DistortionPinBuffer[eyeNum]->GetSrv(); - RParams.pContext->CSSetShaderResources ( 4, 1, &d3dSrv ); - - // TODO: uniform/constant buffers - cshader->UpdateBuffer(UniformBuffers[Shader_Compute]); - cshader->SetUniformBuffer(UniformBuffers[Shader_Compute]); - - // Primitive type is ignored for CS. - // This call actually sets the textures and does pContext->CSSetShader(). Primitive type is ignored. - distortionShaderFill.Set ( Prim_Unknown ); - - RParams.pContext->Dispatch ( TileNumX, TileNumY, 1 ); -#else - OVR_ASSERT ( !"No compute shaders on DX10" ); -#endif - } - else - { - renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], - NULL, 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles); - } - } - - LastUsedOverdriveTextureIndex = currOverdriveTextureIndex; - - // Re-activate to only draw on back buffer - if(overdriveActive) - { - RParams.pContext->OMSetRenderTargets(1, &RParams.pBackBufferRT, 0); - } -} - -void DistortionRenderer::createDrawQuad() -{ - const int numQuadVerts = 4; - LatencyTesterQuadVB = *new Buffer(&RParams); - if(!LatencyTesterQuadVB) - { - return; - } - - LatencyTesterQuadVB->Data(Buffer_Vertex, NULL, numQuadVerts * sizeof(Vertex)); - Vertex* vertices = (Vertex*)LatencyTesterQuadVB->Map(0, numQuadVerts * sizeof(Vertex), Map_Discard); - if(!vertices) - { - OVR_ASSERT(false); // failed to lock vertex buffer - return; - } - - const float left = -1.0f; - const float top = -1.0f; - const float right = 1.0f; - const float bottom = 1.0f; - - vertices[0] = Vertex(Vector3f(left, top, 0.0f), Color(255, 255, 255, 255)); - vertices[1] = Vertex(Vector3f(left, bottom, 0.0f), Color(255, 255, 255, 255)); - vertices[2] = Vertex(Vector3f(right, top, 0.0f), Color(255, 255, 255, 255)); - vertices[3] = Vertex(Vector3f(right, bottom, 0.0f), Color(255, 255, 255, 255)); - - LatencyTesterQuadVB->Unmap(vertices); -} - -void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor) -{ - const int numQuadVerts = 4; - - if(!LatencyTesterQuadVB) - { - createDrawQuad(); - } - - ShaderFill quadFill(SimpleQuadShader); - quadFill.SetInputLayout(SimpleQuadVertexIL); - - setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); - - float testerLuminance = (float)latencyTesterDrawColor[0] / 255.99f; - if(SrgbBackBuffer) - { - testerLuminance = pow(testerLuminance, 2.2f); - } - - SimpleQuadShader->SetUniform2f("Scale", 0.3f, 0.3f); - SimpleQuadShader->SetUniform4f("Color", testerLuminance, testerLuminance, testerLuminance, 1.0f); - - for(int eyeNum = 0; eyeNum < 2; eyeNum++) - { - SimpleQuadShader->SetUniform2f("PositionOffset", eyeNum == 0 ? -0.5f : 0.5f, 0.0f); - renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip); - } -} - -void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelColor) -{ - const int numQuadVerts = 4; - - if(!LatencyTesterQuadVB) - { - createDrawQuad(); - } - - ShaderFill quadFill(SimpleQuadShader); - quadFill.SetInputLayout(SimpleQuadVertexIL); - - setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); - - Vector3f testerColor = Vector3f((float)latencyTesterPixelColor[0] / 255.99f, - (float)latencyTesterPixelColor[1] / 255.99f, - (float)latencyTesterPixelColor[2] / 255.99f); - if(SrgbBackBuffer) - { - // 2.2 gamma is close enough for our purposes of matching sRGB - testerColor.x = pow(testerColor.x, 2.2f); - testerColor.y = pow(testerColor.y, 2.2f); - testerColor.z = pow(testerColor.z, 2.2f); - } - -#ifdef OVR_BUILD_DEBUG - SimpleQuadShader->SetUniform4f("Color", testerColor.x, testerColor.y, testerColor.z, 1.0f); - - Vector2f scale(20.0f / RParams.BackBufferSize.w, 20.0f / RParams.BackBufferSize.h); -#else - // sending in as gray scale - SimpleQuadShader->SetUniform4f("Color", testerColor.x, testerColor.x, testerColor.x, 1.0f); - - Vector2f scale(1.0f / RParams.BackBufferSize.w, 1.0f / RParams.BackBufferSize.h); -#endif - SimpleQuadShader->SetUniform2f("Scale", scale.x, scale.y); - SimpleQuadShader->SetUniform2f("PositionOffset", 1.0f-scale.x, 1.0f-scale.y); - renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, NULL, 0, numQuadVerts, Prim_TriangleStrip); -} - -void DistortionRenderer::renderPrimitives( - const ShaderFill* fill, - Buffer* vertices, Buffer* indices, - Matrix4f* viewMatrix, int offset, int count, - PrimitiveType rprim) -{ - OVR_ASSERT(fill->GetInputLayout() != 0); - RParams.pContext->IASetInputLayout((ID3D1xInputLayout*)fill->GetInputLayout()); - - if (indices) - { - RParams.pContext->IASetIndexBuffer(indices->GetBuffer(), DXGI_FORMAT_R16_UINT, 0); - } - - ID3D1xBuffer* vertexBuffer = vertices->GetBuffer(); - UINT vertexStride = sizeof(Vertex); - UINT vertexOffset = offset; - RParams.pContext->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); - - ShaderSet* shaders = ((ShaderFill*)fill)->GetShaders(); - - ShaderBase* vshader = ((ShaderBase*)shaders->GetShader(Shader_Vertex)); - unsigned char* vertexData = vshader->UniformData; - if (vertexData) - { - // TODO: some VSes don't start with StandardUniformData! - if ( viewMatrix ) - { - StandardUniformData* stdUniforms = (StandardUniformData*) vertexData; - stdUniforms->View = viewMatrix->Transposed(); - stdUniforms->Proj = StdUniforms.Proj; - } - UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize); - vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]); - } - - for(int i = Shader_Vertex + 1; i < Shader_Count; i++) - { - if (shaders->GetShader(i)) - { - ((ShaderBase*)shaders->GetShader(i))->UpdateBuffer(UniformBuffers[i]); - ((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]); - } - } - - D3D1X_(PRIMITIVE_TOPOLOGY) prim; - switch(rprim) - { - case Prim_Triangles: - prim = D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLELIST); - break; - case Prim_Lines: - prim = D3D1X_(PRIMITIVE_TOPOLOGY_LINELIST); - break; - case Prim_TriangleStrip: - prim = D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - break; - default: - OVR_ASSERT(0); - return; - } - RParams.pContext->IASetPrimitiveTopology(prim); - - fill->Set(rprim); - - if (indices) - { - RParams.pContext->DrawIndexed(count, 0, 0); - } - else - { - RParams.pContext->Draw(count, 0); - } -} - -void DistortionRenderer::setViewport(const Recti& vp) -{ - D3D1x_VIEWPORT d3dvp; - - d3dvp.Width = D3DSELECT_10_11(vp.w, (float)vp.w); - d3dvp.Height = D3DSELECT_10_11(vp.h, (float)vp.h); - d3dvp.TopLeftX = D3DSELECT_10_11(vp.x, (float)vp.x); - d3dvp.TopLeftY = D3DSELECT_10_11(vp.y, (float)vp.y); - d3dvp.MinDepth = 0; - d3dvp.MaxDepth = 1; - RParams.pContext->RSSetViewports(1, &d3dvp); -} - - - -// Must match struct DistortionVertex -static D3D1X_(INPUT_ELEMENT_DESC) DistortionMeshVertexDesc[] = -{ - {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0}, - {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D1X_(INPUT_PER_VERTEX_DATA), 0}, - {"TexCoord", 1, DXGI_FORMAT_R32G32_FLOAT, 0, 16, D3D1X_(INPUT_PER_VERTEX_DATA), 0}, - {"TexCoord", 2, DXGI_FORMAT_R32G32_FLOAT, 0, 24, D3D1X_(INPUT_PER_VERTEX_DATA), 0}, - {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 32, D3D1X_(INPUT_PER_VERTEX_DATA), 0}, -}; - -static D3D1X_(INPUT_ELEMENT_DESC) SimpleQuadMeshVertexDesc[] = -{ - {"Position", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D1X_(INPUT_PER_VERTEX_DATA), 0}, -}; - - - -// TODO: this is D3D specific -void DistortionRenderer::initShaders() -{ -#if OVR_D3D_VERSION>=11 - if ( ( RState.DistortionCaps & ovrDistortionCap_ComputeShader ) != 0 ) - { - // Compute shader - DistortionShader = *new ShaderSet; - - int shaderNum = DistortionComputeShader2x2; - if ( ( RState.EnabledHmdCaps & ovrHmdCap_DirectPentile ) != 0 ) - { - shaderNum = DistortionComputeShader2x2Pentile; - } - - PrecompiledShader psShaderByteCode = DistortionComputeShaderLookup[shaderNum]; - Ptr cs = *new D3D_NS::ComputeShader( - &RParams, - (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize, - psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize); - - DistortionShader->SetShader(cs); - } - else -#endif - { - // Vertex + pixel distortion shader. - PrecompiledShader vsShaderByteCode = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & RState.DistortionCaps]; - Ptr vtxShader = *new D3D_NS::VertexShader( - &RParams, - (void*)vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize, - vsShaderByteCode.ReflectionData, vsShaderByteCode.ReflectionSize); - - DistortionVertexIL = NULL; - ID3D1xInputLayout** objRef = &DistortionVertexIL.GetRawRef(); - - HRESULT validate = RParams.pDevice->CreateInputLayout( - DistortionMeshVertexDesc, sizeof(DistortionMeshVertexDesc) / sizeof(DistortionMeshVertexDesc[0]), - vsShaderByteCode.ShaderData, vsShaderByteCode.ShaderSize, objRef); - OVR_UNUSED(validate); - - DistortionShader = *new ShaderSet; - DistortionShader->SetShader(vtxShader); - - PrecompiledShader psShaderByteCode = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & RState.DistortionCaps]; - - Ptr ps = *new D3D_NS::PixelShader( - &RParams, - (void*)psShaderByteCode.ShaderData, psShaderByteCode.ShaderSize, - psShaderByteCode.ReflectionData, psShaderByteCode.ReflectionSize); - - DistortionShader->SetShader(ps); - } - - { - Ptr vtxShader = *new D3D_NS::VertexShader( - &RParams, - (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs), - SimpleQuad_vs_refl, sizeof(SimpleQuad_vs_refl) / sizeof(SimpleQuad_vs_refl[0])); - //NULL, 0); - - SimpleQuadVertexIL = NULL; - ID3D1xInputLayout** objRef = &SimpleQuadVertexIL.GetRawRef(); - - HRESULT validate = RParams.pDevice->CreateInputLayout( - SimpleQuadMeshVertexDesc, sizeof(SimpleQuadMeshVertexDesc) / sizeof(SimpleQuadMeshVertexDesc[0]), - (void*)SimpleQuad_vs, sizeof(SimpleQuad_vs), objRef); - OVR_UNUSED(validate); - - SimpleQuadShader = *new ShaderSet; - SimpleQuadShader->SetShader(vtxShader); - - Ptr ps = *new D3D_NS::PixelShader( - &RParams, - (void*)SimpleQuad_ps, sizeof(SimpleQuad_ps), - SimpleQuad_ps_refl, sizeof(SimpleQuad_ps_refl) / sizeof(SimpleQuad_ps_refl[0])); - - SimpleQuadShader->SetShader(ps); - } -} - - - -ID3D1xSamplerState* DistortionRenderer::getSamplerState(int sm) -{ - if (SamplerStates[sm]) - return SamplerStates[sm]; - - D3D1X_(SAMPLER_DESC) ss; - memset(&ss, 0, sizeof(ss)); - if (sm & Sample_Clamp) - ss.AddressU = ss.AddressV = ss.AddressW = D3D1X_(TEXTURE_ADDRESS_CLAMP); - else if (sm & Sample_ClampBorder) - ss.AddressU = ss.AddressV = ss.AddressW = D3D1X_(TEXTURE_ADDRESS_BORDER); - else - ss.AddressU = ss.AddressV = ss.AddressW = D3D1X_(TEXTURE_ADDRESS_WRAP); - - if (sm & Sample_Nearest) - { - ss.Filter = D3D1X_(FILTER_MIN_MAG_MIP_POINT); - } - else if (sm & Sample_Anisotropic) - { - ss.Filter = D3D1X_(FILTER_ANISOTROPIC); - ss.MaxAnisotropy = 4; - } - else - { - ss.Filter = D3D1X_(FILTER_MIN_MAG_MIP_LINEAR); - } - ss.MaxLOD = 15; - RParams.pDevice->CreateSamplerState(&ss, &SamplerStates[sm].GetRawRef()); - return SamplerStates[sm]; -} - - -void DistortionRenderer::destroy() -{ - for(int eyeNum = 0; eyeNum < 2; eyeNum++) - { - DistortionMeshVBs[eyeNum].Clear(); - DistortionMeshIBs[eyeNum].Clear(); - DistortionPinBuffer[eyeNum].Clear(); - } - - DistortionVertexIL.Clear(); - - if (DistortionShader) - { - DistortionShader->UnsetShader(Shader_Vertex); - DistortionShader->UnsetShader(Shader_Pixel); - DistortionShader->UnsetShader(Shader_Compute); - DistortionShader.Clear(); - } - - LatencyTesterQuadVB.Clear(); -} - - -DistortionRenderer::GraphicsState::GraphicsState(ID3D1xDeviceContext* c) -: context(c) -, memoryCleared(TRUE) -, rasterizerState(NULL) -//samplerStates[] -, inputLayoutState(NULL) -//psShaderResourceState[] -//vsShaderResourceState[] -//psConstantBuffersState[] -//vsConstantBuffersState[] -//renderTargetViewState[] -, depthStencilViewState(NULL) -, omBlendState(NULL) -//omBlendFactorState[] -, omSampleMaskState(0xffffffff) -, primitiveTopologyState(D3D_PRIMITIVE_TOPOLOGY_UNDEFINED) -, iaIndexBufferPointerState(NULL) -, iaIndexBufferFormatState(DXGI_FORMAT_UNKNOWN) -, iaIndexBufferOffsetState(0) -//iaVertexBufferPointersState[] -//iaVertexBufferStridesState[] -//iaVertexBufferOffsetsState[] -, currentPixelShader(NULL) -, currentVertexShader(NULL) -, currentGeometryShader(NULL) -#if (OVR_D3D_VERSION == 11) -, currentHullShader(NULL) -, currentDomainShader(NULL) -, currentComputeShader(NULL) -#endif -{ - for (int i = 0; i < D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) - { - psSamplerStates[i] = NULL; - vsSamplerStates[i] = NULL; -#if (OVR_D3D_VERSION == 11) - csSamplerStates[i] = NULL; -#endif - } - - for (int i = 0; i < D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - { - psShaderResourceState[i] = NULL; - vsShaderResourceState[i] = NULL; -#if (OVR_D3D_VERSION == 11) - csShaderResourceState[i] = NULL; -#endif - } - - for (int i = 0; i < D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - { - psConstantBuffersState[i] = NULL; - vsConstantBuffersState[i] = NULL; -#if (OVR_D3D_VERSION == 11) - csConstantBuffersState[i] = NULL; -#endif - } - - for (int i = 0; i < D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - renderTargetViewState[i] = NULL; -#if (OVR_D3D_VERSION == 11) - csUnorderedAccessViewState[i] = NULL; -#endif - } - - for (int i = 0; i < 4; i++) - omBlendFactorState[i] = NULL; - - for (int i = 0; i < D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - { - iaVertexBufferPointersState[i] = NULL; - iaVertexBufferStridesState[i] = NULL; - iaVertexBufferOffsetsState[i] = NULL; - } -} - -#define SAFE_RELEASE(x) if ( (x) != NULL ) { (x)->Release(); (x)=NULL; } - -void DistortionRenderer::GraphicsState::clearMemory() -{ - SAFE_RELEASE ( rasterizerState ); - - for (int i = 0; i < D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT; ++i) - { - SAFE_RELEASE ( psSamplerStates[i] ); - SAFE_RELEASE ( vsSamplerStates[i] ); -#if (OVR_D3D_VERSION == 11) - SAFE_RELEASE ( csSamplerStates[i] ); -#endif - } - - SAFE_RELEASE ( inputLayoutState ); - - for (int i = 0; i < D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT; i++) - { - SAFE_RELEASE ( psShaderResourceState[i] ); - SAFE_RELEASE ( vsShaderResourceState[i] ); -#if (OVR_D3D_VERSION == 11) - SAFE_RELEASE ( csShaderResourceState[i] ); -#endif - } - - for (int i = 0; i < D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT; i++) - { - SAFE_RELEASE ( psConstantBuffersState[i] ); - SAFE_RELEASE ( vsConstantBuffersState[i] ); -#if (OVR_D3D_VERSION == 11) - SAFE_RELEASE ( csConstantBuffersState[i] ); -#endif - } - - for (int i = 0; i < D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - SAFE_RELEASE ( renderTargetViewState[i] ); -#if (OVR_D3D_VERSION == 11) - SAFE_RELEASE ( csUnorderedAccessViewState[i] ); -#endif - } - - SAFE_RELEASE ( depthStencilViewState ); - SAFE_RELEASE ( omBlendState ); - SAFE_RELEASE ( iaIndexBufferPointerState ); - - for (int i = 0; i < D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT; i++) - { - SAFE_RELEASE ( iaVertexBufferPointersState[i] ); - } - - SAFE_RELEASE ( currentPixelShader ); - SAFE_RELEASE ( currentVertexShader ); - SAFE_RELEASE ( currentGeometryShader ); - -#if (OVR_D3D_VERSION == 11) - SAFE_RELEASE ( currentHullShader ); - SAFE_RELEASE ( currentDomainShader ); - SAFE_RELEASE ( currentComputeShader ); -#endif - - memoryCleared = TRUE; -} - -#undef SAFE_RELEASE - -DistortionRenderer::GraphicsState::~GraphicsState() -{ - clearMemory(); -} - - -void DistortionRenderer::GraphicsState::Save() -{ - if (!memoryCleared) - clearMemory(); - - memoryCleared = FALSE; - - context->RSGetState(&rasterizerState); - context->IAGetInputLayout(&inputLayoutState); - - context->PSGetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, psShaderResourceState); - context->PSGetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, psSamplerStates); - context->PSGetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, psConstantBuffersState); - - context->VSGetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, vsShaderResourceState); - context->VSGetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, vsSamplerStates); - context->VSGetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, vsConstantBuffersState); - -#if (OVR_D3D_VERSION == 11) - context->CSGetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, csShaderResourceState); - context->CSGetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, csSamplerStates); - context->CSGetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, csConstantBuffersState); - context->CSGetUnorderedAccessViews(0, D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT, csUnorderedAccessViewState); -#endif - - context->OMGetRenderTargets(D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT, renderTargetViewState, &depthStencilViewState); - - context->OMGetBlendState(&omBlendState, omBlendFactorState, &omSampleMaskState); - - context->IAGetPrimitiveTopology(&primitiveTopologyState); - - context->IAGetIndexBuffer(&iaIndexBufferPointerState, &iaIndexBufferFormatState, &iaIndexBufferOffsetState); - - context->IAGetVertexBuffers(0, D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, iaVertexBufferPointersState, iaVertexBufferStridesState, iaVertexBufferOffsetsState); - -#if (OVR_D3D_VERSION == 10) - context->PSGetShader(¤tPixelShader); - context->VSGetShader(¤tVertexShader); - context->GSGetShader(¤tGeometryShader); -#else // Volga says class instance interfaces are very new and almost no one uses them - context->PSGetShader(¤tPixelShader, NULL, NULL); - context->VSGetShader(¤tVertexShader, NULL, NULL); - context->GSGetShader(¤tGeometryShader, NULL, NULL); - context->HSGetShader(¤tHullShader, NULL, NULL); - context->DSGetShader(¤tDomainShader, NULL, NULL); - context->CSGetShader(¤tComputeShader, NULL, NULL); - /* maybe above doesn't work; then do something with this (must test on dx11) - ID3D11ClassInstance* blank_array[0]; - UINT blank_uint = 0; - context->PSGetShader(¤tPixelShader, blank_array, blank_uint); - context->VSGetShader(¤tVertexShader, blank_array, blank_uint); - context->GSGetShader(¤tGeometryShader, blank_array, blank_uint); - context->HSGetShader(¤tHullShader, blank_array, blank_uint); - context->DSGetShader(¤tDomainShader, blank_array, blank_uint); - context->CSGetShader(¤tComputeShader, blank_array, blank_uint); - */ -#endif -} - - -void DistortionRenderer::GraphicsState::Restore() -{ - if (rasterizerState != NULL) - context->RSSetState(rasterizerState); - - if (inputLayoutState != NULL) - context->IASetInputLayout(inputLayoutState); - - context->PSSetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, psSamplerStates); - if (psShaderResourceState != NULL) - context->PSSetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, psShaderResourceState); - if (psConstantBuffersState != NULL) - context->PSSetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, psConstantBuffersState); - - context->VSSetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, vsSamplerStates); - if (vsShaderResourceState != NULL) - context->VSSetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, vsShaderResourceState); - if (vsConstantBuffersState != NULL) - context->VSSetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, vsConstantBuffersState); - -#if (OVR_D3D_VERSION == 11) - context->CSSetSamplers(0, D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT, csSamplerStates); - if (csShaderResourceState != NULL) - context->CSSetShaderResources(0, D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, csShaderResourceState); - if (csConstantBuffersState != NULL) - context->CSSetConstantBuffers(0, D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT, csConstantBuffersState); - if (csUnorderedAccessViewState != NULL) - context->CSSetUnorderedAccessViews(0, D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT, csUnorderedAccessViewState, NULL); -#endif - - if (depthStencilViewState != NULL || renderTargetViewState != NULL) - context->OMSetRenderTargets(D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT, renderTargetViewState, depthStencilViewState); - - if (omBlendState != NULL) - context->OMSetBlendState(omBlendState, omBlendFactorState, omSampleMaskState); - - context->IASetPrimitiveTopology(primitiveTopologyState); - - if (iaIndexBufferPointerState != NULL) - context->IASetIndexBuffer(iaIndexBufferPointerState, iaIndexBufferFormatState, iaIndexBufferOffsetState); - - if (iaVertexBufferPointersState != NULL) - context->IASetVertexBuffers(0, D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT, iaVertexBufferPointersState, iaVertexBufferStridesState, iaVertexBufferOffsetsState); - -#if (OVR_D3D_VERSION == 10) - if (currentPixelShader != NULL) - context->PSSetShader(currentPixelShader); - if (currentVertexShader != NULL) - context->VSSetShader(currentVertexShader); - if (currentGeometryShader != NULL) - context->GSSetShader(currentGeometryShader); -#else - if (currentPixelShader != NULL) - context->PSSetShader(currentPixelShader, NULL, 0); - if (currentVertexShader != NULL) - context->VSSetShader(currentVertexShader, NULL, 0); - if (currentGeometryShader != NULL) - context->GSSetShader(currentGeometryShader, NULL, 0); - if (currentHullShader != NULL) - context->HSSetShader(currentHullShader, NULL, 0); - if (currentDomainShader != NULL) - context->DSSetShader(currentDomainShader, NULL, 0); - if (currentComputeShader != NULL) - context->CSSetShader(currentComputeShader, NULL, 0); -#endif - clearMemory(); -} - -}}} // OVR::CAPI::D3D1X diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h deleted file mode 100644 index 0bbf049..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_DistortionRenderer.h +++ /dev/null @@ -1,202 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_DistortionRenderer.h -Content : Experimental distortion renderer -Created : November 11, 2013 -Authors : Volga Aksoy - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -// No include guard, since this fill will be multiply-included. -//#ifndef OVR_CAPI_D3D1X_DistortionRenderer_h - -#include "CAPI_D3D1X_Util.h" -#include "../CAPI_DistortionRenderer.h" - -#include "../../Kernel/OVR_Log.h" - -namespace OVR { namespace CAPI { namespace D3D_NS { - - -// ***** D3D1X::DistortionRenderer - -// Implementation of DistortionRenderer for D3D10/11. - -class DistortionRenderer : public CAPI::DistortionRenderer -{ -public: - DistortionRenderer(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState); - ~DistortionRenderer(); - - - // Creation function for the device. - static CAPI::DistortionRenderer* Create(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState); - - - // ***** Public DistortionRenderer interface - - virtual bool Initialize(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; - - virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture); - - virtual void EndFrame(bool swapBuffers); - - // TBD: Make public? - void WaitUntilGpuIdle(); - - // Similar to ovr_WaitTillTime but it also flushes GPU. - // Note, it exits when time expires, even if GPU is not in idle state yet. - double FlushGpuAndWaitTillTime(double absTime); - -protected: - - class GraphicsState : public CAPI::DistortionRenderer::GraphicsState - { - public: - GraphicsState(ID3D1xDeviceContext* context); - virtual ~GraphicsState(); - virtual void clearMemory(); - virtual void Save(); - virtual void Restore(); - - protected: - ID3D1xDeviceContext* context; - BOOL memoryCleared; - - ID3D1xRasterizerState* rasterizerState; - ID3D1xInputLayout* inputLayoutState; - - ID3D1xShaderResourceView* psShaderResourceState[D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - ID3D1xSamplerState* psSamplerStates[D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT]; - ID3D1xBuffer* psConstantBuffersState[D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - - ID3D1xShaderResourceView* vsShaderResourceState[D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - ID3D1xSamplerState* vsSamplerStates[D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT]; - ID3D1xBuffer* vsConstantBuffersState[D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - -#if (OVR_D3D_VERSION == 11) - ID3D1xShaderResourceView* csShaderResourceState[D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]; - ID3D1xSamplerState* csSamplerStates[D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT]; - ID3D1xBuffer* csConstantBuffersState[D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT]; - ID3D1xUnorderedAccessView* csUnorderedAccessViewState[D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT]; -#endif - - ID3D1xRenderTargetView* renderTargetViewState[D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT]; - ID3D1xDepthStencilView* depthStencilViewState; - - ID3D1xBlendState* omBlendState; - FLOAT omBlendFactorState[4]; - UINT omSampleMaskState; - - D3D1x_PRIMITIVE_TOPOLOGY primitiveTopologyState; - - ID3D1xBuffer* iaIndexBufferPointerState; - DXGI_FORMAT iaIndexBufferFormatState; - UINT iaIndexBufferOffsetState; - - ID3D1xBuffer* iaVertexBufferPointersState[D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - UINT iaVertexBufferStridesState[D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - UINT iaVertexBufferOffsetsState[D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT]; - - ID3D1xPixelShader* currentPixelShader; - ID3D1xVertexShader* currentVertexShader; - ID3D1xGeometryShader* currentGeometryShader; -#if (OVR_D3D_VERSION == 11) - ID3D11HullShader* currentHullShader; - ID3D11DomainShader* currentDomainShader; - ID3D11ComputeShader* currentComputeShader; -#endif - - }; - -private: - // Helpers - void initBuffersAndShaders(); - void initShaders(); - void initFullscreenQuad(); - void initOverdrive(); - void destroy(); - - void setViewport(const Recti& vp); - - void renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture); - - void renderPrimitives(const ShaderFill* fill, Buffer* vertices, Buffer* indices, - Matrix4f* viewMatrix, int offset, int count, - PrimitiveType rprim); - - void renderEndFrame(); - - void createDrawQuad(); - void renderLatencyQuad(unsigned char* latencyTesterDrawColor); - void renderLatencyPixel(unsigned char* latencyTesterPixelColor); - - // Create or get cached D3D sampler based on flags. - ID3D1xSamplerState* getSamplerState(int sm); - - - //// TBD: Should we be using oe from RState instead? - //unsigned DistortionCaps; - - // Back buffer is properly set as an SRGB format? - bool SrgbBackBuffer; - - // D3DX device and utility variables. - RenderParams RParams; - Ptr pEyeTextures[2]; - - // U,V scale and offset needed for timewarp. - ovrVector2f UVScaleOffset[2][2]; - ovrSizei EyeTextureSize[2]; - ovrRecti EyeRenderViewport[2]; - - Ptr pOverdriveTextures[NumOverdriveTextures]; - - //Ptr mpFullScreenVertexBuffer; - - Ptr DistortionMeshVBs[2]; // one per-eye - Ptr DistortionMeshIBs[2]; // one per-eye - Ptr DistortionPinBuffer[2]; // one per-eye - - Ptr DistortionShader; - Ptr DistortionVertexIL; - - struct StandardUniformData - { - Matrix4f Proj; - Matrix4f View; - } StdUniforms; - Ptr UniformBuffers[Shader_Count]; - - Ptr SamplerStates[Sample_Count]; - Ptr Rasterizer; - - Ptr LatencyTesterQuadVB; - Ptr SimpleQuadShader; - Ptr SimpleQuadVertexIL; - - GpuTimer GpuProfiler; -}; - -}}} // OVR::CAPI::D3D1X diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp deleted file mode 100644 index 61f915f..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.cpp +++ /dev/null @@ -1,595 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_HSWDisplay.cpp -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -// This file is intended to be #included by CAPI_D3D10_HSWDisplay.cpp or CAPI_D3D11_HSWDisplay.cpp, -// which define OVR_D3D_VERSION to 10 or 11 respectively. -#if defined(OVR_D3D_VERSION) && ((OVR_D3D_VERSION == 10) || (OVR_D3D_VERSION == 11)) - -#define _WINSOCKAPI_ // Prevents from #including , as we need the app to use instead. -#include "../../Kernel/OVR_Types.h" -#include "../../OVR_CAPI_D3D.h" // OVR_D3D_VERSION will have been defined by who included us. -#include "CAPI_D3D1X_HSWDisplay.h" -#include "../../Kernel/OVR_File.h" -#include "../../Kernel/OVR_SysFile.h" -#include "../../Kernel/OVR_Math.h" -#include "../../Kernel/OVR_Allocator.h" -#include "../../Kernel/OVR_Color.h" - -// We currently borrow the SimpleQuad shaders -#include "Shaders/SimpleTexturedQuad_vs.h" -#include "Shaders/SimpleTexturedQuad_vs_refl.h" -#include "Shaders/SimpleTexturedQuad_ps.h" -#include "Shaders/SimpleTexturedQuad_ps_refl.h" - - -/* -#include - -ID3D10Blob* CompileShader(const char* profile, const char* src, const char* mainName = "main") -{ - ID3D10Blob* shader = NULL; - ID3D10Blob* errors = NULL; - HRESULT hr = D3DCompile(src, strlen(src), NULL, NULL, NULL, mainName, profile, 0, 0, &shader, &errors); - - OVR_ASSERT(SUCCEEDED(hr)); - if (FAILED(hr)) - { - shader = NULL; - OVR_DEBUG_LOG(("Compiling D3D shader for %s failed\n%s\n\n%s", profile, src, errors->GetBufferPointer())); - } - - if (errors) - errors->Release(); - - return shader; -} -*/ - - - -// For a given DXGI format: if the format is a typeless one then this function returns a -// suitable typed one. If the format is a typed one then this function returns it as-is. -static DXGI_FORMAT GetFullyTypedDXGIFormat(DXGI_FORMAT textureFormat) -{ - // http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx - - DXGI_FORMAT fullyTypedFormat = textureFormat; - - switch(textureFormat) - { - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - return DXGI_FORMAT_R32G32B32A32_FLOAT; // or DXGI_FORMAT_R32G32B32A32_UINT, DXGI_FORMAT_R32G32B32A32_SINT - - case DXGI_FORMAT_R32G32B32_TYPELESS: - return DXGI_FORMAT_R32G32B32_FLOAT; // or DXGI_FORMAT_R32G32B32_UINT, DXGI_FORMAT_R32G32B32_SINT - - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - return DXGI_FORMAT_R16G16B16A16_UNORM; // or DXGI_FORMAT_R16G16B16A16_FLOAT, DXGI_FORMAT_R16G16B16A16_UINT, DXGI_FORMAT_R16G16B16A16_SNORM, DXGI_FORMAT_R16G16B16A16_SINT - - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - return DXGI_FORMAT_R8G8B8A8_UNORM; // or DXGI_FORMAT_R8G8B8A8_UNORM_SRGB, DXGI_FORMAT_R8G8B8A8_UINT, DXGI_FORMAT_R8G8B8A8_SNORM, DXGI_FORMAT_R8G8B8A8_SINT - - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB; - - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB; - - // Others which we don't currently support: - //case DXGI_FORMAT_R32G32_TYPELESS: - //case DXGI_FORMAT_R32G8X24_TYPELESS: - //case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - //case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - //case DXGI_FORMAT_R10G10B10A2_TYPELESS: - //case DXGI_FORMAT_R16G16_TYPELESS: - //case DXGI_FORMAT_R32_TYPELESS: - //case DXGI_FORMAT_R24G8_TYPELESS: - //case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - //case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - //case DXGI_FORMAT_R8G8_TYPELESS: - //case DXGI_FORMAT_R16_TYPELESS: - //case DXGI_FORMAT_R8_TYPELESS: - //case DXGI_FORMAT_BC1_TYPELESS: - //case DXGI_FORMAT_BC2_TYPELESS: - //case DXGI_FORMAT_BC3_TYPELESS: - //case DXGI_FORMAT_BC4_TYPELESS: - //case DXGI_FORMAT_BC5_TYPELESS: - //case DXGI_FORMAT_BC6H_TYPELESS: - //case DXGI_FORMAT_BC7_TYPELESS: - } - - return fullyTypedFormat; -} - - - -namespace OVR { namespace CAPI { - -// To do Need to move LoadTextureTgaData to a shared location. -uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height); - - -namespace D3D_NS { - -// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. -Texture* LoadTextureTga(RenderParams& rParams, ID3D1xSamplerState* pSamplerState, OVR::File* f, uint8_t alpha) -{ - OVR::CAPI::D3D_NS::Texture* pTexture = NULL; - - int width, height; - const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); - - if (pRGBA) - { - pTexture = new OVR::CAPI::D3D_NS::Texture(&rParams, OVR::CAPI::D3D_NS::Texture_RGBA, OVR::Sizei(0,0), pSamplerState, 1); - - // Create the D3D texture - D3D1X_(TEXTURE2D_DESC) dsDesc; - dsDesc.Width = width; - dsDesc.Height = height; - dsDesc.MipLevels = 1; - dsDesc.ArraySize = 1; - dsDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - dsDesc.SampleDesc.Count = 1; - dsDesc.SampleDesc.Quality = 0; - dsDesc.Usage = D3D1X_(USAGE_DEFAULT); - dsDesc.BindFlags = D3D1X_(BIND_SHADER_RESOURCE); - dsDesc.CPUAccessFlags = 0; - dsDesc.MiscFlags = 0; - - HRESULT hr = rParams.pDevice->CreateTexture2D(&dsDesc, NULL, &pTexture->Tex.GetRawRef()); - - if (SUCCEEDED(hr)) - { - if (dsDesc.BindFlags & D3D1X_(BIND_SHADER_RESOURCE)) - rParams.pDevice->CreateShaderResourceView(pTexture->Tex, NULL, &pTexture->TexSv.GetRawRef()); - - rParams.pContext->UpdateSubresource(pTexture->Tex, 0, NULL, pRGBA, width * 4, width * height * 4); - } - else - { - OVR_DEBUG_LOG_TEXT(("[LoadTextureTga] CreateTexture2D failed")); - pTexture->Release(); - } - - OVR_FREE(const_cast(pRGBA)); - } - - return pTexture; -} - - -// Loads a texture from a memory image of a TGA file. -Texture* LoadTextureTga(RenderParams& rParams, ID3D1xSamplerState* pSamplerState, const uint8_t* pData, int dataSize, uint8_t alpha) -{ - MemoryFile memoryFile("", pData, dataSize); - - return LoadTextureTga(rParams, pSamplerState, &memoryFile, alpha); -} - - -// Loads a texture from a disk TGA file. -Texture* LoadTextureTga(RenderParams& rParams, ID3D1xSamplerState* pSamplerState, const char* pFilePath, uint8_t alpha) -{ - SysFile sysFile; - - if(sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) - return LoadTextureTga(rParams, pSamplerState, &sysFile, alpha); - - return NULL; -} - - - -// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h -struct HASWVertex -{ - Vector3f Pos; - Color C; - float U, V; - - HASWVertex(const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) - : Pos(p), C(c), U(u), V(v) - {} - - HASWVertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) - : Pos(x,y,z), C(c), U(u), V(v) - {} - - bool operator==(const HASWVertex& b) const - { - return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V); - } -}; - - - -// The texture below may conceivably be shared between HSWDisplay instances. However, -// beware that sharing may not be possible if two HMDs are using different locales -// simultaneously. As of this writing it's not clear if that can occur in practice. - -HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) - : OVR::CAPI::HSWDisplay(api, hmd, renderState), - RenderParams() -{ -} - -bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) -{ - #if (OVR_D3D_VERSION == 10) - const ovrD3D10Config* config = reinterpret_cast(apiConfig); - #else - const ovrD3D11Config* config = reinterpret_cast(apiConfig); - #endif - - if(config) - { - RenderParams.pDevice = config->D3D_NS.pDevice; -#if (OVR_D3D_VERSION == 10) - RenderParams.pContext = config->D3D10.pDevice; - RenderParams.pBackBufferUAV = NULL; -#else - RenderParams.pContext = config->D3D11.pDeviceContext; - RenderParams.pBackBufferUAV = config->D3D_NS.pBackBufferUAV; -#endif - RenderParams.pBackBufferRT = config->D3D_NS.pBackBufferRT; - RenderParams.pSwapChain = config->D3D_NS.pSwapChain; - RenderParams.BackBufferSize = config->D3D_NS.Header.BackBufferSize; - RenderParams.Multisample = config->D3D_NS.Header.Multisample; - - // We may want to create RasterizerState, or alternatively let the DistortionRenderer handle it. - } - // else do any necessary cleanup - - return true; -} - -void HSWDisplay::Shutdown() -{ - UnloadGraphics(); -} - - -void HSWDisplay::DisplayInternal() -{ - HSWDISPLAY_LOG(("[HSWDisplay D3D1x] DisplayInternal()")); - // We may want to call LoadGraphics here instead of within Render. -} - - -void HSWDisplay::DismissInternal() -{ - HSWDISPLAY_LOG(("[HSWDisplay D3D1x] DismissInternal()")); - UnloadGraphics(); -} - - -void HSWDisplay::UnloadGraphics() -{ - //RenderParams: nothing to do. - pSamplerState.Clear(); - pTexture.Clear(); - pVB.Clear(); - for(size_t i = 0; i < OVR_ARRAY_COUNT(UniformBufferArray); i++) - UniformBufferArray[i].Clear(); - pShaderSet.Clear(); - pVertexInputLayout.Clear(); - pBlendState.Clear(); - pRasterizerState.Clear(); - // OrthoProjection: No need to clear. -} - -void HSWDisplay::LoadGraphics() -{ - // Load the graphics if not loaded already. - if(!pSamplerState) - { - D3D1X_(SAMPLER_DESC) sDesc; - - memset(&sDesc, 0, sizeof(sDesc)); - sDesc.Filter = D3D1X_(FILTER_MIN_MAG_MIP_LINEAR); - sDesc.AddressU = D3D1X_(TEXTURE_ADDRESS_CLAMP); - sDesc.AddressV = D3D1X_(TEXTURE_ADDRESS_CLAMP); - sDesc.AddressW = D3D1X_(TEXTURE_ADDRESS_CLAMP); - - RenderParams.pDevice->CreateSamplerState(&sDesc, &pSamplerState.GetRawRef()); - } - - #if defined(OVR_BUILD_DEBUG) - if(!pTexture) - pTexture = *LoadTextureTga(RenderParams, pSamplerState, "C:\\TestPath\\TestFile.tga", 255); - #endif - - if(!pTexture) // To do: Add support for .dds files, which would be significantly smaller than the size of the tga. - { - size_t textureSize; - const uint8_t* TextureData = GetDefaultTexture(textureSize); - pTexture = *LoadTextureTga(RenderParams, pSamplerState, TextureData, (int)textureSize, 255); - } - - if(!UniformBufferArray[0]) - { - for(size_t i = 0; i < OVR_ARRAY_COUNT(UniformBufferArray); i++) - UniformBufferArray[i] = *new Buffer(&RenderParams); - } - - if(!pShaderSet) - { - pShaderSet = *new ShaderSet; - - // Setup the vertex shader - const D3D1X_(INPUT_ELEMENT_DESC) VertexDescription[] = { - { "Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(HASWVertex, Pos), D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, - { "Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(HASWVertex, C), D3D1X_(INPUT_PER_VERTEX_DATA), 0 }, - { "TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(HASWVertex, U), D3D1X_(INPUT_PER_VERTEX_DATA), 0 } - }; - - Ptr vs = *new D3D_NS::VertexShader(&RenderParams, (void*)SimpleTexturedQuad_vs, sizeof(SimpleTexturedQuad_vs), SimpleTexturedQuad_vs_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_vs_refl)); - pVertexInputLayout = NULL; // Make sure it's cleared in case it wasn't. - ID3D1xInputLayout** ppD3DInputLayout = &pVertexInputLayout.GetRawRef(); - HRESULT hResult = RenderParams.pDevice->CreateInputLayout(VertexDescription, OVR_ARRAY_COUNT(VertexDescription), SimpleTexturedQuad_vs, sizeof(SimpleTexturedQuad_vs), ppD3DInputLayout); - OVR_ASSERT(SUCCEEDED(hResult)); - if(SUCCEEDED(hResult)) - pShaderSet->SetShader(vs); - - // Setup the pixel shader - Ptr ps = *new D3D_NS::PixelShader(&RenderParams, (void*)SimpleTexturedQuad_ps, sizeof(SimpleTexturedQuad_ps), SimpleTexturedQuad_ps_refl, OVR_ARRAY_COUNT(SimpleTexturedQuad_ps_refl)); - pShaderSet->SetShader(ps); - - if(!pBlendState) - { - D3D1X_(BLEND_DESC) bm; - memset(&bm, 0, sizeof(bm)); - #if (OVR_D3D_VERSION == 10) - bm.BlendEnable[0] = TRUE; - bm.BlendOp = bm.BlendOpAlpha = D3D1X_(BLEND_OP_ADD); - bm.SrcBlend = bm.SrcBlendAlpha = D3D1X_(BLEND_SRC_ALPHA); - bm.DestBlend = bm.DestBlendAlpha = D3D1X_(BLEND_INV_SRC_ALPHA); - bm.RenderTargetWriteMask[0] = D3D1X_(COLOR_WRITE_ENABLE_ALL); - #else - bm.RenderTarget[0].BlendEnable = TRUE; - bm.RenderTarget[0].BlendOp = bm.RenderTarget[0].BlendOpAlpha = D3D1X_(BLEND_OP_ADD); - bm.RenderTarget[0].SrcBlend = bm.RenderTarget[0].SrcBlendAlpha = D3D1X_(BLEND_SRC_ALPHA); - bm.RenderTarget[0].DestBlend = bm.RenderTarget[0].DestBlendAlpha = D3D1X_(BLEND_INV_SRC_ALPHA); - bm.RenderTarget[0].RenderTargetWriteMask = D3D1X_(COLOR_WRITE_ENABLE_ALL); - #endif - - RenderParams.pDevice->CreateBlendState(&bm, &pBlendState.GetRawRef()); - } - - if(!pRasterizerState) - { - D3D1X_(RASTERIZER_DESC) rs; - memset(&rs, 0, sizeof(rs)); - rs.AntialiasedLineEnable = true; - rs.CullMode = D3D1X_(CULL_BACK); - rs.DepthClipEnable = true; - rs.FillMode = D3D1X_(FILL_SOLID); - - RenderParams.pDevice->CreateRasterizerState(&rs, &pRasterizerState.GetRawRef()); - } - } - - if(!pVB) - { - pVB = *new Buffer(&RenderParams); - - if(pVB) - { - const size_t vertexCount = 4; - - pVB->Data(Buffer_Vertex, NULL, vertexCount * sizeof(HASWVertex)); - HASWVertex* pVertices = (HASWVertex*)pVB->Map(0, vertexCount * sizeof(HASWVertex), Map_Discard); - OVR_ASSERT(pVertices); - - if(pVertices) - { - const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0); - const float left = -1.0f; // We currently draw this in normalized device coordinates with an stereo translation - const float top = -1.1f; // applied as a vertex shader uniform. In the future when we have a more formal graphics - const float right = 1.0f; // API abstraction we may move this draw to an overlay layer or to a more formal - const float bottom = 0.9f; // model/mesh scheme with a perspective projection. - - pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); - pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); - pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); - pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f); - - pVB->Unmap(pVertices); - } - } - } -} - - -// Note: If we are drawing this warning onto the eye texture before distortion, the "time warp" functionality -// will cause the warning to shake on the screen when the user moves their head. One solution is to disable -// time warping while the warning or any screen-static GUI elements are present. - -void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) -{ - if(RenderEnabled && eyeTexture) - { - // We need to render to the eyeTexture with the texture viewport. - // Setup rendering to the texture. - ovrD3D1X(Texture)* eyeTextureD3D = const_cast(reinterpret_cast(eyeTexture)); - OVR_ASSERT(eyeTextureD3D->Texture.Header.API == ((OVR_D3D_VERSION == 10) ? ovrRenderAPI_D3D10 : ovrRenderAPI_D3D11)); - - // D3D10 is currently disabled while we track down a bug that results in a black screen. - //if(eyeTextureD3D->Texture.Header.API == ovrRenderAPI_D3D10) - // return; - - // Load the graphics if not loaded already. - if(!pVB) - LoadGraphics(); - - // Calculate ortho projection. - GetOrthoProjection(RenderState, OrthoProjection); - - // Save settings - // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location. - Ptr pBlendStateSaved; - FLOAT blendFactorSaved[4]; - UINT blendSampleMaskSaved; - RenderParams.pContext->OMGetBlendState(&pBlendStateSaved.GetRawRef(), blendFactorSaved, &blendSampleMaskSaved); - - Ptr pRasterizerStateSaved; - RenderParams.pContext->RSGetState(&pRasterizerStateSaved.GetRawRef()); - - Ptr pTextureRenderTargetViewSaved; - Ptr pDepthStencilViewSaved; - RenderParams.pContext->OMGetRenderTargets(1, &pTextureRenderTargetViewSaved.GetRawRef(), &pDepthStencilViewSaved.GetRawRef()); - - #ifndef D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE // D3D10 doesn't define this, so we pretend that it does. - #define D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE 4 - #endif - D3D1x_VIEWPORT d3dViewportSaved[D3D1X_(VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE)]; - UINT viewportCountSaved = OVR_ARRAY_COUNT(d3dViewportSaved); - RenderParams.pContext->RSGetViewports(&viewportCountSaved, d3dViewportSaved); - - UINT stencilRefSaved; - Ptr pDepthStencilStateSaved; - RenderParams.pContext->OMGetDepthStencilState(&pDepthStencilStateSaved.GetRawRef(), &stencilRefSaved); - - Ptr pInputLayoutSaved; - RenderParams.pContext->IAGetInputLayout(&pInputLayoutSaved.GetRawRef()); - - Ptr pVertexBufferSaved; - UINT vertexStrideSaved[1]; - UINT vertexOffsetSaved[1]; - RenderParams.pContext->IAGetVertexBuffers(0, 1, &pVertexBufferSaved.GetRawRef(), vertexStrideSaved, vertexOffsetSaved); - - D3D1X_(PRIMITIVE_TOPOLOGY) topologySaved; - RenderParams.pContext->IAGetPrimitiveTopology(&topologySaved); - - - // Set our settings - RenderParams.pContext->OMSetBlendState(pBlendState, NULL, 0xffffffff); - RenderParams.pContext->RSSetState(pRasterizerState); - - // We can't necessarily use a NULL D3D11_RENDER_TARGET_VIEW_DESC argument to CreateRenderTargetView, because we are rendering to - // a texture that somebody else created and which may have been created in a typeless format (e.g. DXGI_FORMAT_R8G8B8A8_TYPELESS). - // So what we do is check to see if the texture format is a typeless format and if see we pass a suitable D3D11_RENDER_TARGET_VIEW_DESC - // to CreateRenderTargetView instead of NULL. - D3D1X_(TEXTURE2D_DESC) texture2DDesc; - eyeTextureD3D->D3D_NS.pTexture->GetDesc(&texture2DDesc); - - D3D1X_(RENDER_TARGET_VIEW_DESC) renderTargetViewDesc; - memset(&renderTargetViewDesc, 0, sizeof(renderTargetViewDesc)); - renderTargetViewDesc.Format = GetFullyTypedDXGIFormat(texture2DDesc.Format); // DXGI_FORMAT. If this is a typeless format then GetFullyTypedFormat converts it to a fully typed format. - renderTargetViewDesc.ViewDimension = (texture2DDesc.SampleDesc.Count > 1) ? D3D1X_(RTV_DIMENSION_TEXTURE2DMS) : D3D1X_(RTV_DIMENSION_TEXTURE2D); - renderTargetViewDesc.Texture2D.MipSlice = 0; - Ptr pTextureRenderTargetView; - HRESULT hResult = RenderParams.pDevice->CreateRenderTargetView(eyeTextureD3D->D3D_NS.pTexture, (renderTargetViewDesc.Format == texture2DDesc.Format) ? NULL : &renderTargetViewDesc, &pTextureRenderTargetView.GetRawRef()); - - if(SUCCEEDED(hResult)) - { - RenderParams.pContext->OMSetRenderTargets(1, &pTextureRenderTargetView.GetRawRef(), NULL); // We currently don't bind a depth buffer. - - D3D1x_VIEWPORT D3DViewport; - - OVR_DISABLE_MSVC_WARNING(4244) // conversion from int to float - D3DViewport.TopLeftX = eyeTextureD3D->Texture.Header.RenderViewport.Pos.x; - D3DViewport.TopLeftY = eyeTextureD3D->Texture.Header.RenderViewport.Pos.y; - D3DViewport.Width = eyeTextureD3D->Texture.Header.RenderViewport.Size.w; - D3DViewport.Height = eyeTextureD3D->Texture.Header.RenderViewport.Size.h; - D3DViewport.MinDepth = 0; - D3DViewport.MaxDepth = 1; - RenderParams.pContext->RSSetViewports(1, &D3DViewport); - OVR_RESTORE_MSVC_WARNING() - - // We don't set up a world/view/projection matrix because we are using - // normalized device coordinates below. - - // We don't set the depth state because we aren't using it. - // RenderParams.pContext->OMSetDepthStencilState(, 0); - - ShaderFill fill(pShaderSet); - fill.SetInputLayout(pVertexInputLayout); - if(pTexture) - fill.SetTexture(0, pTexture, Shader_Pixel); - - const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f); - pShaderSet->SetUniform2f("Scale", scale, scale / 2.f); // X and Y scale. Y is a fixed proportion to X in order to give a certain aspect ratio. - pShaderSet->SetUniform4f("Color", 1.f, 1.f, 1.f, 1.f); - pShaderSet->SetUniform2f("PositionOffset", OrthoProjection[eye].GetTranslation().x, 0.0f); - - RenderParams.pContext->IASetInputLayout((ID3D1xInputLayout*)fill.GetInputLayout()); - - ID3D1xBuffer* vertexBuffer = pVB->GetBuffer(); - UINT vertexStride = sizeof(HASWVertex); - UINT vertexOffset = 0; - RenderParams.pContext->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset); - - ShaderBase* vShaderBase = (ShaderBase*)pShaderSet->GetShader(OVR::CAPI::D3D_NS::Shader_Vertex); - unsigned char* vertexData = vShaderBase->UniformData; - - if (vertexData) - { - UniformBufferArray[OVR::CAPI::D3D_NS::Shader_Vertex]->Data(OVR::CAPI::D3D_NS::Buffer_Uniform, vertexData, vShaderBase->UniformsSize); - vShaderBase->SetUniformBuffer(UniformBufferArray[OVR::CAPI::D3D_NS::Shader_Vertex]); - } - - for (int i = (OVR::CAPI::D3D_NS::Shader_Vertex + 1); i < OVR::CAPI::D3D_NS::Shader_Count; i++) - { - if (pShaderSet->GetShader(i)) - { - ((ShaderBase*)pShaderSet->GetShader(i))->UpdateBuffer(UniformBufferArray[i]); - ((ShaderBase*)pShaderSet->GetShader(i))->SetUniformBuffer(UniformBufferArray[i]); - } - } - - RenderParams.pContext->IASetPrimitiveTopology(D3D1X_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP)); - fill.Set(Prim_TriangleStrip); - - RenderParams.pContext->Draw(4, 0); - } - else - { - HSWDISPLAY_LOG(("[HSWDisplay D3D1x] CreateRenderTargetView() failed")); - } - - - // Restore settings - RenderParams.pContext->IASetPrimitiveTopology(topologySaved); - RenderParams.pContext->IASetVertexBuffers(0, 1, &pVertexBufferSaved.GetRawRef(), &vertexStrideSaved[0], &vertexOffsetSaved[0]); - RenderParams.pContext->IASetInputLayout(pInputLayoutSaved); - RenderParams.pContext->OMSetDepthStencilState(pDepthStencilStateSaved, stencilRefSaved); - RenderParams.pContext->RSSetViewports(viewportCountSaved, d3dViewportSaved); - RenderParams.pContext->OMSetRenderTargets(1, &pTextureRenderTargetViewSaved.GetRawRef(), pDepthStencilViewSaved); - RenderParams.pContext->RSSetState(pRasterizerStateSaved); - RenderParams.pContext->OMSetBlendState(pBlendStateSaved, blendFactorSaved, blendSampleMaskSaved); - } -} - -}}} // namespace OVR::CAPI::D3D_NS - - -#endif // OVR_D3D_VERSION - - - - diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h deleted file mode 100644 index 2c5762d..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_HSWDisplay.h +++ /dev/null @@ -1,84 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_HSWDisplay.h -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -// Do not use include guards, as this file is #included separately by both -// CAPI_D3D10_HSWDisplay.h and CAPI_D3D11_HSWDisplay.h with OVR_D3D_VERSION defined -// to either 10 or 11. Only those two headers should #include this one. -//#ifndef OVR_CAPI_D3D1X_HSWDisplay_h -//#define OVR_CAPI_D3D1X_HSWDisplay_h - -//#if !defined(OVR_CAPI_D3D10_HSWDisplay_h) && !defined(OVR_CAPI_D3D11_HSWDisplay_h) -// #error This header is expected to be compiled only by these two headers. -//#endif -#if !defined(OVR_D3D_VERSION) || ((OVR_D3D_VERSION != 10) && (OVR_D3D_VERSION != 11)) - #error This header expects OVR_D3D_VERSION to be defined, to 10 or 11. -#endif - -#include "../CAPI_HSWDisplay.h" -#include "CAPI_D3D1X_Util.h" - - -namespace OVR { namespace CAPI { namespace D3D_NS { - - class HSWDisplay : public CAPI::HSWDisplay - { - public: - HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); - - // Must be called before use. apiConfig is such that: - // const ovrD3D11Config* config = (const ovrD3D11Config*)apiConfig; or - bool Initialize(const ovrRenderAPIConfig* apiConfig); - void Shutdown(); - void DisplayInternal(); - void DismissInternal(); - - // Draws the warning to the eye texture(s). This must be done at the end of a - // frame but prior to executing the distortion rendering of the eye textures. - void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture); - - protected: - void LoadGraphics(); - void UnloadGraphics(); - - OVR::CAPI::D3D_NS::RenderParams RenderParams; - Ptr pSamplerState; - Ptr pTexture; - Ptr pVB; - Ptr UniformBufferArray[OVR::CAPI::D3D_NS::Shader_Count]; - Ptr pShaderSet; - Ptr pVertexInputLayout; - Ptr pBlendState; - Ptr pRasterizerState; - Matrix4f OrthoProjection[ovrEye_Count]; - - private: - OVR_NON_COPYABLE(HSWDisplay) - }; - -}}} // namespace OVR::CAPI::D3D_NS - - - diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp deleted file mode 100644 index f95fb3c..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.cpp +++ /dev/null @@ -1,533 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_Util.cpp -Content : D3DX10 utility classes for rendering -Created : September 10, 2012 -Authors : Andrew Reisse - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "CAPI_D3D1X_Util.h" - -#include - -namespace OVR { namespace CAPI { namespace D3D_NS { - - -//------------------------------------------------------------------------------------- -// ***** ShaderFill - -void ShaderFill::Set(PrimitiveType prim) const -{ - Shaders->Set(prim); - - for(int i = 0; i < 8; ++i) - { - if ( VsTextures[i] != NULL ) - { - VsTextures[i]->Set(i, Shader_Vertex); - } - } - - for(int i = 0; i < 8; ++i) - { - if ( CsTextures[i] != NULL ) - { - CsTextures[i]->Set(i, Shader_Compute); - } - } - - for(int i = 0; i < 8; ++i) - { - if ( PsTextures[i] != NULL ) - { - PsTextures[i]->Set(i, Shader_Fragment); - } - } -} - - -//------------------------------------------------------------------------------------- -// ***** Buffer - -Buffer::~Buffer() -{ -} - -bool Buffer::Data(int use, const void *buffer, size_t size, int computeBufferStride /*=-1*/) -{ - if (D3DBuffer && Size >= size) - { - if (Dynamic) - { - if (!buffer) - return true; - - void* v = Map(0, size, Map_Discard); - if (v) - { - memcpy(v, buffer, size); - Unmap(v); - return true; - } - } - else - { - OVR_ASSERT (!(use & Buffer_ReadOnly)); - pParams->pContext->UpdateSubresource(D3DBuffer, 0, NULL, buffer, 0, 0); - return true; - } - } - if (D3DBuffer) - { - D3DBuffer = NULL; - Size = 0; - Use = 0; - Dynamic = false; - } - D3DSrv = NULL; -#if (OVR_D3D_VERSION >= 11) - D3DUav = NULL; -#endif - - D3D1X_(BUFFER_DESC) desc; - memset(&desc, 0, sizeof(desc)); - if (use & Buffer_ReadOnly) - { - desc.Usage = D3D1X_(USAGE_IMMUTABLE); - desc.CPUAccessFlags = 0; - } - else - { - desc.Usage = D3D1X_(USAGE_DYNAMIC); - desc.CPUAccessFlags = D3D1X_(CPU_ACCESS_WRITE); - Dynamic = true; - } - - switch(use & Buffer_TypeMask) - { - case Buffer_Vertex: desc.BindFlags = D3D1X_(BIND_VERTEX_BUFFER); break; - case Buffer_Index: desc.BindFlags = D3D1X_(BIND_INDEX_BUFFER); break; - case Buffer_Uniform: - desc.BindFlags = D3D1X_(BIND_CONSTANT_BUFFER); - size = ((size + 15) & ~15); - break; - case Buffer_Compute: -#if (OVR_D3D_VERSION >= 11) - // There's actually a bunch of options for buffers bound to a CS. - // Right now this is the most appropriate general-purpose one. Add more as needed. - - // NOTE - if you want D3D1X_(CPU_ACCESS_WRITE), it MUST be either D3D1X_(USAGE_DYNAMIC) or D3D1X_(USAGE_STAGING). - // TODO: we want a resource that is rarely written to, in which case we'd need two surfaces - one a STAGING - // that the CPU writes to, and one a DEFAULT, and we CopyResource from one to the other. Hassle! - // Setting it as D3D1X_(USAGE_DYNAMIC) will get the job done for now. - // Also for fun - you can't have a D3D1X_(USAGE_DYNAMIC) buffer that is also a D3D1X_(BIND_UNORDERED_ACCESS). - OVR_ASSERT ( !(use & Buffer_ReadOnly) ); - desc.BindFlags = D3D1X_(BIND_SHADER_RESOURCE); - desc.Usage = D3D1X_(USAGE_DYNAMIC); - desc.MiscFlags = D3D1X_(RESOURCE_MISC_BUFFER_STRUCTURED); - desc.CPUAccessFlags = D3D1X_(CPU_ACCESS_WRITE); - OVR_ASSERT ( computeBufferStride > 0 ); - desc.StructureByteStride = computeBufferStride; // sizeof(DistortionComputePin); - - Dynamic = true; - size = ((size + 15) & ~15); -#else - OVR_UNUSED ( computeBufferStride ); - OVR_ASSERT ( false ); // No compute shaders in DX10 -#endif - break; - } - - desc.ByteWidth = (unsigned)size; - - D3D1X_(SUBRESOURCE_DATA) sr; - sr.pSysMem = buffer; - sr.SysMemPitch = 0; - sr.SysMemSlicePitch = 0; - - D3DBuffer = NULL; - HRESULT hr = pParams->pDevice->CreateBuffer(&desc, buffer ? &sr : NULL, &D3DBuffer.GetRawRef()); - if (SUCCEEDED(hr)) - { - Use = use; - Size = desc.ByteWidth; - } - else - { - OVR_ASSERT ( false ); - return false; - } - - if ( ( use & Buffer_TypeMask ) == Buffer_Compute ) - { - HRESULT hres = pParams->pDevice->CreateShaderResourceView ( D3DBuffer, NULL, &D3DSrv.GetRawRef() ); - if ( SUCCEEDED(hres) ) - { -#if (OVR_D3D_VERSION >= 11) -#if 0 // Right now we do NOT ask for UAV access (see flags above). - hres = Ren->Device->CreateUnorderedAccessView ( D3DBuffer, NULL, &D3DUav.GetRawRef() ); - if ( SUCCEEDED(hres) ) - { - // All went well. - } -#endif -#endif - } - - if ( !SUCCEEDED(hres) ) - { - OVR_ASSERT ( false ); - Use = 0; - Size = 0; - return false; - } - } - - return true; - -} - -void* Buffer::Map(size_t start, size_t size, int flags) -{ - OVR_UNUSED(size); - - D3D1X_(MAP) mapFlags = D3D1X_(MAP_WRITE); - if (flags & Map_Discard) - mapFlags = D3D1X_(MAP_WRITE_DISCARD); - if (flags & Map_Unsynchronized) - mapFlags = D3D1X_(MAP_WRITE_NO_OVERWRITE); - -#if (OVR_D3D_VERSION == 10) - void* map; - if (SUCCEEDED(D3DBuffer->Map(mapFlags, 0, &map))) - return ((char*)map) + start; -#else - D3D11_MAPPED_SUBRESOURCE map; - if (SUCCEEDED(pParams->pContext->Map(D3DBuffer, 0, mapFlags, 0, &map))) - return ((char*)map.pData) + start; -#endif - - return NULL; -} - -bool Buffer::Unmap(void *m) -{ - OVR_UNUSED(m); - - D3DSELECT_10_11( D3DBuffer->Unmap(), - pParams->pContext->Unmap(D3DBuffer, 0) ); - return true; -} - - -//------------------------------------------------------------------------------------- -// Shaders - -template<> bool ShaderImpl::Load(void* shader, size_t size) -{ - return SUCCEEDED(pParams->pDevice->CreateVertexShader(shader, size D3D11_COMMA_0, &D3DShader)); -} -template<> bool ShaderImpl::Load(void* shader, size_t size) -{ - return SUCCEEDED(pParams->pDevice->CreatePixelShader(shader, size D3D11_COMMA_0, &D3DShader)); -} -#if (OVR_D3D_VERSION>=11) -template<> bool ShaderImpl::Load(void* shader, size_t size) -{ - return SUCCEEDED(pParams->pDevice->CreateComputeShader(shader, size D3D11_COMMA_0, &D3DShader)); -} -#endif - -template<> void ShaderImpl::Set(PrimitiveType) const -{ - pParams->pContext->VSSetShader(D3DShader D3D11_COMMA_0 D3D11_COMMA_0 ); -} -template<> void ShaderImpl::Set(PrimitiveType) const -{ - pParams->pContext->PSSetShader(D3DShader D3D11_COMMA_0 D3D11_COMMA_0 ) ; -} -#if (OVR_D3D_VERSION>=11) -template<> void ShaderImpl::Set(PrimitiveType) const -{ - pParams->pContext->CSSetShader(D3DShader D3D11_COMMA_0 D3D11_COMMA_0 ) ; -} -#endif - -template<> void ShaderImpl::SetUniformBuffer(Buffer* buffer, int i) -{ - pParams->pContext->VSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef()); -} -template<> void ShaderImpl::SetUniformBuffer(Buffer* buffer, int i) -{ - pParams->pContext->PSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef()); -} -#if (OVR_D3D_VERSION>=11) -template<> void ShaderImpl::SetUniformBuffer(Buffer* buffer, int i) -{ - pParams->pContext->CSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef()); -} -#endif - -//------------------------------------------------------------------------------------- -// ***** Shader Base - -ShaderBase::ShaderBase(RenderParams* rp, ShaderStage stage) : - Shader(stage), - pParams(rp), - UniformData(NULL), - UniformsSize(0), - UniformRefl(NULL), - UniformReflSize(0) -{ -} - -ShaderBase::~ShaderBase() -{ - if (UniformData) - { - OVR_FREE(UniformData); - UniformData = NULL; - } - - // UniformRefl does not need to be freed - UniformRefl = NULL; -} - -bool ShaderBase::SetUniform(const char* name, int n, const float* v) -{ - for(unsigned i = 0; i < UniformReflSize; i++) - { - if (!strcmp(UniformRefl[i].Name, name)) - { - memcpy(UniformData + UniformRefl[i].Offset, v, n * sizeof(float)); - return 1; - } - } - return 0; -} - -bool ShaderBase::SetUniformBool(const char* name, int n, const bool* v) -{ - OVR_UNUSED(n); - for(unsigned i = 0; i < UniformReflSize; i++) - { - if (!strcmp(UniformRefl[i].Name, name)) - { - memcpy(UniformData + UniformRefl[i].Offset, v, UniformRefl[i].Size); - return 1; - } - } - return 0; -} - -void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize) -{ - if(!refl) - { - UniformRefl = NULL; - UniformReflSize = 0; - - UniformsSize = 0; - if (UniformData) - { - OVR_FREE(UniformData); - UniformData = 0; - } - return; // no reflection data - } - - UniformRefl = refl; - UniformReflSize = reflSize; - - UniformsSize = UniformRefl[UniformReflSize-1].Offset + UniformRefl[UniformReflSize-1].Size; - UniformData = (unsigned char*)OVR_ALLOC(UniformsSize); -} - -void ShaderBase::UpdateBuffer(Buffer* buf) -{ - if (UniformsSize) - { - buf->Data(Buffer_Uniform, UniformData, UniformsSize); - } -} - - -//------------------------------------------------------------------------------------- -// ***** Texture -// -Texture::Texture(RenderParams* rp, int fmt, const Sizei texSize, - ID3D1xSamplerState* sampler, int samples) - : pParams(rp), Tex(NULL), TexSv(NULL), TexRtv(NULL), TexDsv(NULL), - TextureSize(texSize), - Sampler(sampler), - Samples(samples) -{ - OVR_UNUSED(fmt); -} - -Texture::~Texture() -{ -} - -void Texture::Set(int slot, ShaderStage stage) const -{ - ID3D1xShaderResourceView* texSv = TexSv.GetPtr(); - - switch(stage) - { - case Shader_Fragment: - pParams->pContext->PSSetShaderResources(slot, 1, &texSv); - pParams->pContext->PSSetSamplers(slot, 1, &Sampler.GetRawRef()); - break; - - case Shader_Vertex: - pParams->pContext->VSSetShaderResources(slot, 1, &texSv); - pParams->pContext->VSSetSamplers(slot, 1, &Sampler.GetRawRef()); - break; - -#if (OVR_D3D_VERSION >= 11) - case Shader_Compute: - pParams->pContext->CSSetShaderResources(slot, 1, &texSv); - pParams->pContext->CSSetSamplers(slot, 1, &Sampler.GetRawRef()); - break; -#endif - default: OVR_ASSERT ( false ); break; - } -} - - -//------------------------------------------------------------------------------------- -// ***** GpuTimer -// -#if (OVR_D3D_VERSION == 11) -#define D3DQUERY_EXEC(_context_, _query_, _command_, ...) _context_->_command_(_query_, __VA_ARGS__) -#else -#define D3DQUERY_EXEC(_context_, _query_, _command_, ...) _query_->_command_(__VA_ARGS__) -#endif - - -void GpuTimer::Init(ID3D1xDevice* device, ID3D1xDeviceContext* content) -{ - D3dDevice = device; - Context = content; -} - -void GpuTimer::BeginQuery() -{ - if(GotoNextFrame(LastQueuedFrame) == LastTimedFrame) - { - OVR_ASSERT(false); // too many queries queued - return; - } - - LastQueuedFrame = GotoNextFrame(LastQueuedFrame); - - GpuQuerySets& newQuerySet = QuerySets[LastQueuedFrame]; - if(newQuerySet.DisjointQuery == NULL) - { - // Create the queries - D3D1x_QUERY_DESC desc; - desc.Query = D3D1X_(QUERY_TIMESTAMP_DISJOINT); - desc.MiscFlags = 0; - VERIFY_HRESULT(D3dDevice->CreateQuery(&desc, &newQuerySet.DisjointQuery)); - - desc.Query = D3D1X_(QUERY_TIMESTAMP); - VERIFY_HRESULT(D3dDevice->CreateQuery(&desc, &newQuerySet.TimeStartQuery)); - VERIFY_HRESULT(D3dDevice->CreateQuery(&desc, &newQuerySet.TimeEndQuery)); - } - - OVR_ASSERT(!newQuerySet.QueryStarted); - OVR_ASSERT(!newQuerySet.QueryAwaitingTiming); - - - D3DQUERY_EXEC(Context, QuerySets[LastQueuedFrame].DisjointQuery, Begin, ); // First start a disjoint query - D3DQUERY_EXEC(Context, QuerySets[LastQueuedFrame].TimeStartQuery, End, ); // Insert start timestamp - - newQuerySet.QueryStarted = true; - newQuerySet.QueryAwaitingTiming = false; - //newQuerySet.QueryTimed = false; -} - -void GpuTimer::EndQuery() -{ - if(LastQueuedFrame > 0 && !QuerySets[LastQueuedFrame].QueryStarted) - return; - - GpuQuerySets& doneQuerySet = QuerySets[LastQueuedFrame]; - OVR_ASSERT(doneQuerySet.QueryStarted); - OVR_ASSERT(!doneQuerySet.QueryAwaitingTiming); - - // Insert the end timestamp - D3DQUERY_EXEC(Context, doneQuerySet.TimeEndQuery, End, ); - - // End the disjoint query - D3DQUERY_EXEC(Context, doneQuerySet.DisjointQuery, End, ); - - doneQuerySet.QueryStarted = false; - doneQuerySet.QueryAwaitingTiming = true; -} - -float GpuTimer::GetTiming(bool blockUntilValid) -{ - float time = -1.0f; - - // loop until we hit a query that is not ready yet, or we have read all queued queries - while(LastTimedFrame != LastQueuedFrame) - { - int timeTestFrame = GotoNextFrame(LastTimedFrame); - - GpuQuerySets& querySet = QuerySets[timeTestFrame]; - - OVR_ASSERT(!querySet.QueryStarted && querySet.QueryAwaitingTiming); - - UINT64 startTime = 0; - UINT64 endTime = 0; - D3D1X_(QUERY_DATA_TIMESTAMP_DISJOINT) disjointData; - - if(blockUntilValid) - { - while(D3DQUERY_EXEC(Context, querySet.TimeStartQuery, GetData, &startTime, sizeof(startTime), 0) != S_OK); - while(D3DQUERY_EXEC(Context, querySet.TimeEndQuery, GetData, &endTime, sizeof(endTime), 0) != S_OK); - while(D3DQUERY_EXEC(Context, querySet.DisjointQuery, GetData, &disjointData, sizeof(disjointData), 0) != S_OK); - } - else - { -// Early return if we fail to get data for any of these - if(D3DQUERY_EXEC(Context, querySet.TimeStartQuery, GetData, &startTime, sizeof(startTime), 0) != S_OK) return time; - if(D3DQUERY_EXEC(Context, querySet.TimeEndQuery, GetData, &endTime, sizeof(endTime), 0) != S_OK) return time; - if(D3DQUERY_EXEC(Context, querySet.DisjointQuery, GetData, &disjointData, sizeof(disjointData), 0) != S_OK) return time; - } - - querySet.QueryAwaitingTiming = false; - LastTimedFrame = timeTestFrame; // successfully retrieved the timing data - - if(disjointData.Disjoint == false) - { - UINT64 delta = endTime - startTime; - float frequency = (float)(disjointData.Frequency); - time = (delta / frequency); - } - } - - return time; -} - -}}} // OVR::CAPI::D3DX diff --git a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h b/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h deleted file mode 100644 index dc5dc8d..0000000 --- a/LibOVR/Src/CAPI/D3D1X/CAPI_D3D1X_Util.h +++ /dev/null @@ -1,572 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_Util.h -Content : D3DX 10/11 utility classes for rendering -Created : September 10, 2012 -Authors : Andrew Reisse - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -// ***** IMPORTANT: -// This file can be included twice, once with OVR_D3D_VERSION=10 and -// once with OVR_D3D_VERSION=11. - - -#ifndef OVR_D3D_VERSION -#error define OVR_D3D_VERSION to 10 or 11 -#endif - -// Custom include guard, allowing one of each D3D10/11. -#if (OVR_D3D_VERSION == 10 && !defined(INC_OVR_CAPI_D3D10_Util_h)) || \ - (OVR_D3D_VERSION == 11 && !defined(INC_OVR_CAPI_D3D11_Util_h)) - -#include "../../Kernel/OVR_String.h" -#include "../../Kernel/OVR_Array.h" -#include "../../Kernel/OVR_Math.h" - -#if defined(OVR_OS_WIN32) -#define WIN32_LEAN_AND_MEAN -#include -#include // for _COM_SMARTPTR_TYPEDEF() - -#undef D3D_NS // namespace -#undef D3D1X_ -#undef ID3D1X // interface prefix -#undef ovrD3D1X // ovrD3D10Config, etc. -#undef D3D11_COMMA_0 // Injects on ", 0" for D3D11 only -#undef D3DSELECT_10_11 -#undef IID_ID3D1xShaderReflection - -#if (OVR_D3D_VERSION == 10) - - #define INC_OVR_CAPI_D3D10_Util_h - #define D3D_NS D3D10 - #define D3D1X_(x) D3D10_##x - #define ID3D1X(x) ID3D10##x - #define ovrD3D1X(x) ovrD3D10##x - #define D3DSELECT_10_11(a10, a11) a10 - #define D3D11_COMMA_0 - #define IID_ID3D1xShaderReflection IID_ID3D10ShaderReflection - #include // avoids warning? - #include - -#else // (OVR_D3D_VERSION == 11) - - #define INC_OVR_CAPI_D3D11_Util_h - #define D3D_NS D3D11 - #define D3D1X_(x) D3D11_##x - #define ID3D1X(x) ID3D11##x - #define ovrD3D1X(x) ovrD3D11##x - #define D3DSELECT_10_11(a10, a11) a11 - #define D3D11_COMMA_0 , 0 - #define IID_ID3D1xShaderReflection IID_ID3D11ShaderReflection - #include - #include -#endif -#endif - - -namespace OVR { namespace CAPI { namespace D3D_NS { - -// D3D Namespace-local types. -typedef ID3D1X(Device) ID3D1xDevice; -typedef ID3D1X(RenderTargetView) ID3D1xRenderTargetView; -typedef ID3D1X(Texture2D) ID3D1xTexture2D; -typedef ID3D1X(ShaderResourceView) ID3D1xShaderResourceView; -typedef ID3D1X(DepthStencilView) ID3D1xDepthStencilView; -typedef ID3D1X(DepthStencilState) ID3D1xDepthStencilState; -typedef ID3D1X(InputLayout) ID3D1xInputLayout; -typedef ID3D1X(Buffer) ID3D1xBuffer; -typedef ID3D1X(VertexShader) ID3D1xVertexShader; -typedef ID3D1X(PixelShader) ID3D1xPixelShader; -typedef ID3D1X(GeometryShader) ID3D1xGeometryShader; -#if (OVR_D3D_VERSION>=11) -typedef ID3D1X(UnorderedAccessView) ID3D1xUnorderedAccessView; -typedef ID3D1X(ComputeShader) ID3D1xComputeShader; -#else -// Typedeffing as int saves a lot of checking against DX version numbers when just copying around pointers. -typedef int ID3D1xUnorderedAccessView; -#endif -typedef ID3D1X(BlendState) ID3D1xBlendState; -typedef ID3D1X(RasterizerState) ID3D1xRasterizerState; -typedef ID3D1X(SamplerState) ID3D1xSamplerState; -typedef ID3D1X(Query) ID3D1xQuery; -typedef ID3D1X(ShaderReflection) ID3D1xShaderReflection; -typedef ID3D1X(ShaderReflectionVariable) ID3D1xShaderReflectionVariable; -typedef ID3D1X(ShaderReflectionConstantBuffer) ID3D1xShaderReflectionConstantBuffer; -typedef D3D1X_(VIEWPORT) D3D1x_VIEWPORT; -typedef D3D1X_(QUERY_DESC) D3D1x_QUERY_DESC; -typedef D3D1X_(SHADER_BUFFER_DESC) D3D1x_SHADER_BUFFER_DESC; -typedef D3D1X_(SHADER_VARIABLE_DESC) D3D1x_SHADER_VARIABLE_DESC; -typedef D3D1X_(PRIMITIVE_TOPOLOGY) D3D1x_PRIMITIVE_TOPOLOGY; -static const int D3D1x_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT = D3D1X_(COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT); -static const int D3D1x_COMMONSHADER_SAMPLER_SLOT_COUNT = D3D1X_(COMMONSHADER_SAMPLER_SLOT_COUNT); -static const int D3D1x_SIMULTANEOUS_RENDER_TARGET_COUNT = D3D1X_(SIMULTANEOUS_RENDER_TARGET_COUNT); -static const int D3D1x_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT = D3D1X_(IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT); -static const int D3D1x_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT = D3D1X_(COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT); - -// Blob is the same -typedef ID3D10Blob ID3D1xBlob; - -#if (OVR_D3D_VERSION == 10) - typedef ID3D10Device ID3D1xDeviceContext; -#else - typedef ID3D11DeviceContext ID3D1xDeviceContext; -#endif - - -// Assert on HRESULT failure -inline void VERIFY_HRESULT(HRESULT hr) -{ - if (FAILED(hr)) - OVR_ASSERT(false); -} - -class Buffer; - -// Rendering parameters/pointers describing D3DX rendering setup. -struct RenderParams -{ - ID3D1xDevice* pDevice; - ID3D1xDeviceContext* pContext; - ID3D1xRenderTargetView* pBackBufferRT; - ID3D1xUnorderedAccessView* pBackBufferUAV; - IDXGISwapChain* pSwapChain; - Sizei BackBufferSize; - int Multisample; -}; - - -// Rendering primitive type used to render Model. -enum PrimitiveType -{ - Prim_Triangles, - Prim_Lines, - Prim_TriangleStrip, - Prim_Unknown, - Prim_Count -}; - -// Types of shaders that can be stored together in a ShaderSet. -enum ShaderStage -{ - Shader_Vertex = 0, - Shader_Fragment = 2, - Shader_Pixel = 2, - Shader_Compute = 3, // DX11+ only - Shader_Count = 4, -}; - -enum MapFlags -{ - Map_Discard = 1, - Map_Read = 2, // do not use - Map_Unsynchronized = 4, // like D3D11_MAP_NO_OVERWRITE -}; - - -// Buffer types used for uploading geometry & constants. -enum BufferUsage -{ - Buffer_Unknown = 0, - Buffer_Vertex = 1, - Buffer_Index = 2, - Buffer_Uniform = 4, - Buffer_Compute = 8, - Buffer_TypeMask = 0xff, - Buffer_ReadOnly = 0x100, // Buffer must be created with Data(). -}; - -enum TextureFormat -{ - Texture_RGBA = 0x0100, - Texture_Depth = 0x8000, - Texture_TypeMask = 0xff00, - Texture_SamplesMask = 0x00ff, - Texture_RenderTarget = 0x10000, - Texture_GenMipmaps = 0x20000, -}; - -// Texture sampling modes. -enum SampleMode -{ - Sample_Linear = 0, - Sample_Nearest = 1, - Sample_Anisotropic = 2, - Sample_FilterMask = 3, - - Sample_Repeat = 0, - Sample_Clamp = 4, - Sample_ClampBorder = 8, // If unsupported Clamp is used instead. - Sample_AddressMask =12, - - Sample_Count =13, -}; - -// Base class for vertex and pixel shaders. Stored in ShaderSet. -class Shader : public RefCountBase -{ - friend class ShaderSet; - -protected: - ShaderStage Stage; - -public: - Shader(ShaderStage s) : Stage(s) {} - virtual ~Shader() {} - - ShaderStage GetStage() const { return Stage; } - - virtual void Set(PrimitiveType) const { } - virtual void SetUniformBuffer(class Buffer* buffers, int i = 0) { OVR_UNUSED2(buffers, i); } - -protected: - virtual bool SetUniform(const char* name, int n, const float* v) { OVR_UNUSED3(name, n, v); return false; } - virtual bool SetUniformBool(const char* name, int n, const bool* v) { OVR_UNUSED3(name, n, v); return false; } -}; - - - -// A group of shaders, one per stage. -// A ShaderSet is applied to a RenderDevice for rendering with a given fill. -class ShaderSet : public RefCountBase -{ -protected: - Ptr Shaders[Shader_Count]; - -public: - ShaderSet() { } - ~ShaderSet() { } - - virtual void SetShader(Shader *s) - { - Shaders[s->GetStage()] = s; - } - virtual void UnsetShader(int stage) - { - Shaders[stage] = NULL; - } - Shader* GetShader(int stage) { return Shaders[stage]; } - - virtual void Set(PrimitiveType prim) const - { - for (int i = 0; i < Shader_Count; i++) - if (Shaders[i]) - Shaders[i]->Set(prim); - } - - // Set a uniform (other than the standard matrices). It is undefined whether the - // uniforms from one shader occupy the same space as those in other shaders - // (unless a buffer is used, then each buffer is independent). - virtual bool SetUniform(const char* name, int n, const float* v) - { - bool result = 0; - for (int i = 0; i < Shader_Count; i++) - if (Shaders[i]) - result |= Shaders[i]->SetUniform(name, n, v); - - return result; - } - bool SetUniform1f(const char* name, float x) - { - const float v[] = {x}; - return SetUniform(name, 1, v); - } - bool SetUniform2f(const char* name, float x, float y) - { - const float v[] = {x,y}; - return SetUniform(name, 2, v); - } - bool SetUniform3f(const char* name, float x, float y, float z) - { - const float v[] = {x,y,z}; - return SetUniform(name, 3, v); - } - bool SetUniform4f(const char* name, float x, float y, float z, float w = 1) - { - const float v[] = {x,y,z,w}; - return SetUniform(name, 4, v); - } - - bool SetUniformv(const char* name, const Vector3f& v) - { - const float a[] = {v.x,v.y,v.z,1}; - return SetUniform(name, 4, a); - } - - virtual bool SetUniform4x4f(const char* name, const Matrix4f& m) - { - Matrix4f mt = m.Transposed(); - return SetUniform(name, 16, &mt.M[0][0]); - } - virtual bool SetUniform3x3f(const char* name, const Matrix4f& m) - { - // float3x3 is actually stored the same way as float4x3, with the last items ignored by the code. - Matrix4f mt = m.Transposed(); - return SetUniform(name, 12, &mt.M[0][0]); - } - -}; - - -// Fill combines a ShaderSet (vertex, pixel) with textures, if any. -// Every model has a fill. -class ShaderFill : public RefCountBase -{ - Ptr Shaders; - Ptr PsTextures[8]; - Ptr VsTextures[8]; - Ptr CsTextures[8]; - void* InputLayout; // HACK this should be abstracted - -public: - ShaderFill(ShaderSet* sh) : Shaders(sh) { InputLayout = NULL; } - ShaderFill(ShaderSet& sh) : Shaders(sh) { InputLayout = NULL; } - - ShaderSet* GetShaders() const { return Shaders; } - void* GetInputLayout() const { return InputLayout; } - - virtual void Set(PrimitiveType prim = Prim_Unknown) const; - - virtual void SetTexture(int i, class Texture* tex, ShaderStage stage) - { - if (i < 8) - { - if(stage == Shader_Pixel) PsTextures[i] = tex; - else if(stage == Shader_Vertex) VsTextures[i] = tex; - else if(stage == Shader_Compute) CsTextures[i] = tex; - else OVR_ASSERT(false); - } - } - void SetInputLayout(void* newIL) { InputLayout = (void*)newIL; } -}; - - -class ShaderBase : public Shader -{ -public: - RenderParams* pParams; - unsigned char* UniformData; - int UniformsSize; - - enum VarType - { - VARTYPE_FLOAT, - VARTYPE_INT, - VARTYPE_BOOL, - }; - - struct Uniform - { - const char* Name; - VarType Type; - int Offset; - int Size; - }; - const Uniform* UniformRefl; - size_t UniformReflSize; - - ShaderBase(RenderParams* rp, ShaderStage stage); - ~ShaderBase(); - - ShaderStage GetStage() const { return Stage; } - - void InitUniforms(const Uniform* refl, size_t reflSize); - bool SetUniform(const char* name, int n, const float* v); - bool SetUniformBool(const char* name, int n, const bool* v); - - void UpdateBuffer(Buffer* b); -}; - - -template -class ShaderImpl : public ShaderBase -{ -public: - D3DShaderType* D3DShader; - - ShaderImpl(RenderParams* rp, void* s, size_t size, const Uniform* refl, size_t reflSize) : ShaderBase(rp, SStage) - { - Load(s, size); - InitUniforms(refl, reflSize); - } - ~ShaderImpl() - { - if (D3DShader) - D3DShader->Release(); - } - - // These functions have specializations. - bool Load(void* shader, size_t size); - void Set(PrimitiveType prim) const; - void SetUniformBuffer(Buffer* buffers, int i = 0); -}; - -typedef ShaderImpl VertexShader; -typedef ShaderImpl PixelShader; -#if (OVR_D3D_VERSION>=11) -typedef ShaderImpl ComputeShader; -#endif - - -class Buffer : public RefCountBase -{ -public: - RenderParams* pParams; - Ptr D3DBuffer; - Ptr D3DSrv; -#if (OVR_D3D_VERSION >= 11) - Ptr D3DUav; -#endif - size_t Size; - int Use; - bool Dynamic; - -public: - Buffer(RenderParams* rp) : pParams(rp), D3DBuffer(), D3DSrv(), -#if (OVR_D3D_VERSION >= 11) - D3DUav(), -#endif - Size(0), Use(0), Dynamic(false) {} - ~Buffer(); - - ID3D1xBuffer* GetBuffer() const - { - return D3DBuffer; - } - - ID3D1xShaderResourceView* GetSrv() const - { - return D3DSrv; - } - -#if (OVR_D3D_VERSION >= 11) - ID3D1xUnorderedAccessView* GetUav() const - { - return D3DUav; - } -#endif - - virtual size_t GetSize() { return Size; } - virtual void* Map(size_t start, size_t size, int flags = 0); - virtual bool Unmap(void *m); - virtual bool Data(int use, const void* buffer, size_t size, int computeBufferStride = -1); -}; - - -class Texture : public RefCountBase -{ -public: - RenderParams* pParams; - Ptr Tex; - Ptr TexSv; - Ptr TexRtv; - Ptr TexDsv; - // TODO: add UAV... - mutable Ptr Sampler; - Sizei TextureSize; - int Samples; - - Texture(RenderParams* rp, int fmt, const Sizei texSize, - ID3D1xSamplerState* sampler, int samples = 1); - ~Texture(); - - virtual Sizei GetSize() const { return TextureSize; } - virtual int GetSamples() const { return Samples; } - - // virtual void SetSampleMode(int sm); - - // Updates texture to point to specified resources - // - used for slave rendering. - void UpdatePlaceholderTexture(ID3D1xTexture2D* texture, - ID3D1xShaderResourceView* psrv, - const Sizei& textureSize) - { - Tex = texture; - TexSv = psrv; - TexRtv.Clear(); - TexDsv.Clear(); - - TextureSize = textureSize; - -#ifdef OVR_BUILD_DEBUG - D3D1X_(TEXTURE2D_DESC) desc; - texture->GetDesc(&desc); - OVR_ASSERT(TextureSize == Sizei(desc.Width, desc.Height)); -#endif - } - - - virtual void Set(int slot, ShaderStage stage = Shader_Fragment) const; - -}; - - -class GpuTimer : public RefCountBase -{ -public: - GpuTimer() - : QuerySets(MaxNumQueryFrames) - , D3dDevice(NULL) - , Context(NULL) - , LastQueuedFrame(-1) - , LastTimedFrame(-1) - { } - - void Init(ID3D1xDevice* device, ID3D1xDeviceContext* content); - - void BeginQuery(); - void EndQuery(); - - // Returns -1 if timing is invalid - float GetTiming(bool blockUntilValid); - -protected: - static const unsigned MaxNumQueryFrames = 10; - - int GotoNextFrame(int frame) - { - return (frame + 1) % MaxNumQueryFrames; - } - - _COM_SMARTPTR_TYPEDEF(ID3D1xQuery, __uuidof(ID3D1xQuery)); - - struct GpuQuerySets - { - ID3D1xQueryPtr DisjointQuery; - ID3D1xQueryPtr TimeStartQuery; - ID3D1xQueryPtr TimeEndQuery; - bool QueryStarted; - bool QueryAwaitingTiming; - - GpuQuerySets() : QueryStarted(false), QueryAwaitingTiming(false) {} - }; - Array QuerySets; - - int LastQueuedFrame; - int LastTimedFrame; - - Ptr D3dDevice; - Ptr Context; -}; - -}}} // OVR::CAPI::D3D1X - -#endif // INC_OVR_CAPI_D3D10/11_Util_h diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h deleted file mode 100644 index 78cbb03..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2.h +++ /dev/null @@ -1,887 +0,0 @@ -#ifndef DISTORTIONCS2X2_H -#define DISTORTIONCS2X2_H - -static const unsigned char DistortionCS2x2[] = { - 0x44, 0x58, 0x42, 0x43, 0x08, 0x74, 0x15, 0x37, 0x48, 0x1d, 0x2c, 0xce, - 0x36, 0x3e, 0x2c, 0x71, 0x9b, 0xf3, 0x13, 0xa6, 0x01, 0x00, 0x00, 0x00, - 0x34, 0x29, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0xa8, 0x05, 0x00, 0x00, 0xb8, 0x05, 0x00, 0x00, 0xc8, 0x05, 0x00, 0x00, - 0x98, 0x28, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x6c, 0x05, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1c, 0x01, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0x53, 0x43, 0x00, 0x01, 0x00, 0x00, - 0x38, 0x05, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, - 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xdc, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe3, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x07, 0x01, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x00, 0x48, - 0x6d, 0x64, 0x53, 0x70, 0x63, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, - 0x00, 0x55, 0x6e, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x6f, 0x72, 0x6d, - 0x65, 0x64, 0x47, 0x72, 0x69, 0x64, 0x50, 0x69, 0x6e, 0x73, 0x00, 0x46, - 0x72, 0x61, 0x6d, 0x65, 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x00, 0x24, - 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0x13, 0x01, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf1, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xb4, 0x02, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xec, 0x02, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xc8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xf5, 0x02, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x34, 0x03, 0x00, 0x00, - 0x88, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x10, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x48, 0x03, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x64, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0x88, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x2c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x64, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x97, 0x03, 0x00, 0x00, - 0xec, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa8, 0x03, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xd0, 0x03, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa8, 0x03, 0x00, 0x00, 0xcc, 0x03, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x00, 0x00, 0x00, 0x00, 0xd9, 0x03, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x50, 0x61, 0x64, 0x64, - 0x69, 0x6e, 0x67, 0x31, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, - 0x34, 0x00, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xbd, 0x02, 0x00, 0x00, 0x50, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x32, - 0x00, 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x55, 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0x66, 0x6c, 0x6f, 0x61, - 0x74, 0x32, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x03, 0x00, 0x00, 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, - 0x72, 0x63, 0x65, 0x55, 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, - 0x45, 0x79, 0x65, 0x52, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x78, - 0x33, 0x00, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x59, 0x03, 0x00, 0x00, 0x45, 0x79, 0x65, 0x52, 0x6f, 0x74, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x00, 0x55, 0x73, 0x65, 0x4f, 0x76, - 0x65, 0x72, 0x6c, 0x61, 0x79, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x00, - 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x03, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x52, 0x69, 0x67, 0x68, 0x74, 0x45, 0x79, 0x65, - 0x00, 0x46, 0x62, 0x53, 0x69, 0x7a, 0x65, 0x50, 0x69, 0x78, 0x65, 0x6c, - 0x73, 0x58, 0x00, 0xab, 0x10, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x14, 0x05, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x24, 0x45, 0x6c, 0x65, - 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x44, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x74, - 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x65, 0x50, 0x69, - 0x6e, 0x00, 0x54, 0x61, 0x6e, 0x45, 0x79, 0x65, 0x41, 0x6e, 0x67, 0x6c, - 0x65, 0x73, 0x52, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x03, 0x00, 0x00, 0x54, 0x61, 0x6e, 0x45, 0x79, 0x65, 0x41, 0x6e, - 0x67, 0x6c, 0x65, 0x73, 0x47, 0x00, 0x54, 0x61, 0x6e, 0x45, 0x79, 0x65, - 0x41, 0x6e, 0x67, 0x6c, 0x65, 0x73, 0x42, 0x00, 0x43, 0x6f, 0x6c, 0x6f, - 0x72, 0x00, 0x69, 0x6e, 0x74, 0x00, 0xab, 0xab, 0x00, 0x00, 0x02, 0x00, - 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x82, 0x04, 0x00, 0x00, 0x50, 0x61, 0x64, 0x64, - 0x69, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x02, 0x00, 0x01, 0x00, 0x01, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x82, 0x04, 0x00, 0x00, 0x2e, 0x04, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x60, 0x04, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x6e, 0x04, 0x00, 0x00, 0x3c, 0x04, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x7c, 0x04, 0x00, 0x00, 0x88, 0x04, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0xac, 0x04, 0x00, 0x00, 0xb4, 0x04, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, - 0x00, 0x00, 0x05, 0x00, 0xd8, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x19, 0x04, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, - 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, - 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, - 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, - 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x4f, 0x53, 0x47, 0x4e, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x53, 0x48, 0x45, 0x58, 0xc8, 0x22, 0x00, 0x00, - 0x50, 0x00, 0x05, 0x00, 0xb2, 0x08, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, - 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0xa2, 0x00, 0x00, 0x04, - 0x00, 0x70, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x9c, 0x18, 0x00, 0x04, 0x00, 0xe0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x02, 0x32, 0x00, 0x02, 0x00, - 0x68, 0x00, 0x00, 0x02, 0x19, 0x00, 0x00, 0x00, 0x9b, 0x00, 0x00, 0x04, - 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x48, 0x09, 0x92, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x04, 0x02, 0x00, 0x02, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x2b, 0x00, 0x38, 0x05, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xc6, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x18, 0x0a, - 0x32, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x96, 0x05, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3d, - 0x00, 0x00, 0x80, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x41, 0x00, 0x38, 0x05, 0x72, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x16, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x05, - 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, 0x40, 0x08, 0x82, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x0e, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x41, 0x00, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x40, 0x08, - 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x40, 0x05, 0x82, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x29, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x38, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa7, 0x00, 0x20, 0x8b, 0x02, 0x03, 0x01, 0x80, 0x83, 0x99, 0x19, 0x00, - 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x46, 0x72, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x56, 0x00, 0x40, 0x05, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x43, - 0x38, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0xa7, 0x00, 0x20, 0x8b, - 0x02, 0x03, 0x01, 0x80, 0x83, 0x99, 0x19, 0x00, 0x72, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x46, 0x72, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x56, 0x00, 0x40, 0x05, - 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x43, 0x38, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, - 0x00, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0xbf, 0xa7, 0x00, 0x20, 0x8b, 0x02, 0x03, 0x01, 0x80, - 0x83, 0x99, 0x19, 0x00, 0x72, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x1a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x46, 0x72, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x2a, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0xff, 0x00, 0x00, 0x00, 0x56, 0x00, 0x40, 0x05, 0x82, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x43, 0x38, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, - 0xa7, 0x00, 0x20, 0x8b, 0x02, 0x03, 0x01, 0x80, 0x83, 0x99, 0x19, 0x00, - 0x72, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x46, 0x72, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, - 0x56, 0x00, 0x40, 0x05, 0x82, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x43, - 0x38, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x31, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x31, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x31, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x3c, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x31, 0x00, 0x40, 0x07, 0x82, 0x00, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x40, 0x07, - 0x82, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x1f, 0x00, 0x04, 0x03, 0x3a, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0d, 0x72, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3d, 0x00, 0x00, 0x80, 0x3d, 0x00, 0x00, 0x80, 0x3d, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x72, 0x00, 0x10, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x70, 0x3f, 0x00, 0x00, 0x00, 0x00, - 0x31, 0x00, 0x00, 0x08, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x0a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3f, 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1b, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x09, - 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x8b, - 0x02, 0x03, 0x01, 0x80, 0x83, 0x99, 0x19, 0x00, 0xf2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x55, 0x00, 0x08, 0x07, 0x12, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x56, 0x00, 0x08, 0x05, - 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x8b, 0x02, 0x03, 0x01, 0x80, - 0x83, 0x99, 0x19, 0x00, 0xf2, 0x00, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x55, 0x00, 0x20, 0x07, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x56, 0x00, 0x20, 0x05, 0x42, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x28, 0x0a, 0x52, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x06, 0x02, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x7f, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x43, - 0x00, 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x8b, 0x02, 0x03, 0x01, 0x80, - 0x83, 0x99, 0x19, 0x00, 0xf2, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x1a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x55, 0x00, 0x08, 0x07, 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x2a, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x56, 0x00, 0x08, 0x05, 0x12, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0xa7, 0x00, 0x00, 0x8b, 0x02, 0x03, 0x01, 0x80, 0x83, 0x99, 0x19, 0x00, - 0xf2, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x55, 0x00, 0x10, 0x07, - 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x56, 0x00, 0x10, 0x05, 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x1a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x18, 0x0a, - 0x32, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x43, - 0x00, 0x00, 0x7f, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0xb2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x03, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0x72, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x81, 0x00, 0x00, 0x05, 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x2a, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x05, - 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0xf6, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x04, 0x10, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x04, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x04, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x46, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xe6, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0xe6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x46, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0xe6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0xb2, 0x00, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x46, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x46, 0x03, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0xa6, 0x0a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x81, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x05, - 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x05, 0x42, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x04, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x04, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x04, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x46, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xe6, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x46, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0xe6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x46, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0xe6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0xb2, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x46, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x46, 0x03, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xe2, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x89, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x96, 0x07, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x81, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x05, - 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x04, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, - 0x10, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x04, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x04, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xe6, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x46, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0xe6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x46, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0xe6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x09, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x72, 0x00, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, - 0xb2, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x46, 0x88, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x46, 0x03, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xe2, 0x00, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x06, 0x89, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x96, 0x07, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x46, 0x82, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0x72, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, - 0x72, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x72, 0x00, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0x72, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x81, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x2a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x05, - 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x05, 0x42, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x04, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x04, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x04, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x46, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xe6, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0xf2, 0x00, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x46, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0xe6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x46, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0xe6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x0b, 0xf2, 0x00, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x06, 0x0a, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x0a, 0x10, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x56, 0x0f, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x06, 0x0a, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0x52, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xf6, 0x0f, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x56, 0x07, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0x52, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x56, 0x07, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0x06, 0x02, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0x52, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x56, 0x07, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, 0x06, 0x02, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0x52, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x56, 0x07, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, 0x06, 0x02, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, - 0x17, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, 0x0e, 0x00, 0x00, 0x00, - 0x56, 0x0f, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x17, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, - 0x0c, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x17, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x17, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x17, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x17, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x17, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0xe6, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0xe6, 0x0e, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0xe6, 0x0e, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0xe6, 0x0e, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, 0x11, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x8d, 0xc2, 0x00, 0x00, 0x80, - 0x43, 0x55, 0x15, 0x00, 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x17, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x8d, - 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, 0x22, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x8d, 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, - 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x13, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x20, 0x00, 0x07, 0x72, 0x00, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x8d, - 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, 0x12, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, 0x17, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x8d, 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, - 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x8d, 0xc2, 0x00, 0x00, 0x80, - 0x43, 0x55, 0x15, 0x00, 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0xe6, 0x0a, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x20, 0x00, 0x07, - 0x72, 0x00, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x1a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3d, 0x00, 0x00, 0x00, 0x08, 0x22, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x56, 0x0f, 0x10, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x56, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x06, 0x0a, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x0a, 0x10, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0xd6, 0x05, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0x32, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xd6, 0x05, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0x32, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xd6, 0x05, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0x32, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xf6, 0x0f, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0xd6, 0x05, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x0e, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x15, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x12, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x09, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x16, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x16, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x15, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x12, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x8d, - 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, 0x12, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x8d, 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, - 0x22, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x8d, 0xc2, 0x00, 0x00, 0x80, - 0x43, 0x55, 0x15, 0x00, 0x42, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x46, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x20, 0x00, 0x07, - 0x72, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x8d, 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, - 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0xc6, 0x79, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x8d, 0xc2, 0x00, 0x00, 0x80, - 0x43, 0x55, 0x15, 0x00, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xe6, 0x0a, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xc6, 0x79, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x8d, - 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, 0x82, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xc6, 0x79, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x38, 0x20, 0x00, 0x07, 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x56, 0x05, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x86, 0x03, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x00, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x07, 0xf2, 0xe0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xd6, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x82, 0x00, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x07, 0xf2, 0xe0, 0x11, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe6, 0x0f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x13, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x08, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x02, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x00, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x07, 0xf2, 0xe0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x16, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa4, 0x00, 0x00, 0x07, 0xf2, 0xe0, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x26, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x01, 0x3e, 0x00, 0x00, 0x01, - 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, - 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x79, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2_refl.h deleted file mode 100644 index 27db6d3..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionCS2x2_refl.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef DistortionCS2x2_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionCS2x2_refl[] = -{ - { "Padding1", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 64 }, - { "Padding2", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 64, 64 }, - { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 128, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 136, 8 }, - { "EyeRotationStart", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 144, 44 }, - { "EyeRotationEnd", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 192, 44 }, - { "UseOverlay", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 236, 4 }, - { "RightEye", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 240, 4 }, - { "FbSizePixelsX", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 244, 4 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.h deleted file mode 100644 index 5bc4599..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.h +++ /dev/null @@ -1,256 +0,0 @@ -#ifndef DISTORTIONCHROMA_PS_H -#define DISTORTIONCHROMA_PS_H - -static const unsigned char DistortionChroma_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0xb7, 0x5b, 0x09, 0xd5, 0x8c, 0xb3, 0xcf, 0xc9, - 0x86, 0xe0, 0x0c, 0x3b, 0x65, 0x14, 0x61, 0x56, 0x01, 0x00, 0x00, 0x00, - 0xa4, 0x0b, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0xbc, 0x01, 0x00, 0x00, 0x60, 0x02, 0x00, 0x00, 0xac, 0x02, 0x00, 0x00, - 0x28, 0x0b, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x80, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, - 0x4c, 0x01, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xa3, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, - 0x72, 0x65, 0x00, 0x4c, 0x61, 0x73, 0x74, 0x54, 0x65, 0x78, 0x74, 0x75, - 0x72, 0x65, 0x00, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, - 0xb7, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x18, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x28, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x3c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x4f, 0x76, 0x65, 0x72, 0x64, 0x72, 0x69, 0x76, 0x65, 0x53, 0x63, 0x61, - 0x6c, 0x65, 0x73, 0x00, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x61, 0x44, 0x65, - 0x72, 0x69, 0x76, 0x61, 0x74, 0x69, 0x76, 0x65, 0x4d, 0x75, 0x6c, 0x74, - 0x00, 0xab, 0xab, 0xab, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, - 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, - 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, - 0x49, 0x53, 0x47, 0x4e, 0x9c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x03, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x06, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x0c, 0x0c, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, - 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, - 0x44, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xab, 0xab, - 0x53, 0x48, 0x44, 0x52, 0x74, 0x08, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x1d, 0x02, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, - 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, - 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x64, 0x20, 0x00, 0x04, 0x32, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, - 0x12, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, - 0x62, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, - 0xc2, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, - 0x08, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x0b, 0x32, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x26, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1f, 0x00, 0x04, 0x03, 0x0a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x05, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x14, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x05, - 0xf2, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x14, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x80, 0x81, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x80, 0x81, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xa6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x96, 0x15, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xe6, 0x1a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x22, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0x09, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, - 0xf2, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0xab, 0xaa, 0xaa, 0xbe, - 0xab, 0xaa, 0xaa, 0xbe, 0x00, 0x00, 0x20, 0xbf, 0x00, 0x00, 0x20, 0xbf, - 0x96, 0x19, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, - 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0xab, 0xaa, 0xaa, 0xbe, - 0xab, 0xaa, 0xaa, 0xbe, 0x00, 0x00, 0x20, 0xbf, 0x00, 0x00, 0x20, 0xbf, - 0x46, 0x14, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, - 0xf2, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0xe6, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0xab, 0xaa, 0xaa, 0xbe, - 0xab, 0xaa, 0xaa, 0xbe, 0x00, 0x00, 0x20, 0xbf, 0x00, 0x00, 0x20, 0xbf, - 0xe6, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x12, 0x00, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x07, 0x72, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x46, 0x02, 0x10, 0x00, 0x07, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, 0xd2, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x80, 0x40, 0x06, 0x09, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xd2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, - 0xf2, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3f, - 0x00, 0x00, 0x20, 0x3f, 0xab, 0xaa, 0xaa, 0x3e, 0xab, 0xaa, 0xaa, 0x3e, - 0x96, 0x19, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, - 0xf2, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3f, - 0x00, 0x00, 0x20, 0x3f, 0xab, 0xaa, 0xaa, 0x3e, 0xab, 0xaa, 0xaa, 0x3e, - 0x46, 0x14, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0c, - 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x20, 0x3f, - 0x00, 0x00, 0x20, 0x3f, 0xab, 0xaa, 0xaa, 0x3e, 0xab, 0xaa, 0xaa, 0x3e, - 0xe6, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x12, 0x00, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x09, 0xd2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x09, 0x10, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xe6, 0x0a, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0xe6, 0x0a, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0xe6, 0x0a, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xd2, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x09, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x0a, 0xd2, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x3e, 0x4b, 0x00, 0x00, 0x05, - 0x72, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x86, 0x03, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x01, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x96, 0x15, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0xe6, 0x1a, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x22, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x15, 0x00, 0x00, 0x01, 0x38, 0x00, 0x00, 0x07, 0xd2, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x04, 0x03, - 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x00, 0x00, 0x05, - 0x32, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x2d, 0x00, 0x00, 0x07, 0xf2, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x07, 0x72, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x86, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x00, 0x00, 0x0b, - 0x72, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x06, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x56, 0x85, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x72, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x32, 0x20, 0x00, 0x09, - 0x72, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x86, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x82, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x12, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, 0x05, - 0x72, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x86, 0x03, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x15, 0x00, 0x00, 0x01, 0x36, 0x00, 0x00, 0x05, 0x72, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x86, 0x03, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, - 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, - 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1b, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.psh b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.psh index c69fce0..3232cee 100644 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.psh +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps.psh @@ -23,9 +23,12 @@ limitations under the License. Texture2D Texture : register(t0); Texture2D LastTexture : register(t1); +Texture2D OverdriveLut : register(t2); SamplerState Linear : register(s0); +// unused - SamplerState Linear2 : register(s1); +SamplerState OverdriveSampler : register(s2); -float2 OverdriveScales; +float3 OverdriveScales; float AaDerivativeMult; // Fast approximate gamma to linear conversion when averaging colors @@ -124,12 +127,24 @@ void main(in float4 oPosition : SV_Position, { float3 oldColor = LastTexture.Load(int3(oPosition.xy, 0)).rgb; - float3 adjustedScales; - adjustedScales.x = newColor.x > oldColor.x ? OverdriveScales.x : OverdriveScales.y; - adjustedScales.y = newColor.y > oldColor.y ? OverdriveScales.x : OverdriveScales.y; - adjustedScales.z = newColor.z > oldColor.z ? OverdriveScales.x : OverdriveScales.y; - - float3 overdriveColor = saturate(newColor + (newColor - oldColor) * adjustedScales); + float3 overdriveColor; + + // x < 1.5 means "use analytical model instead of LUT" + if(OverdriveScales.x < 1.5) + { + float3 adjustedScales; + adjustedScales.x = newColor.x > oldColor.x ? OverdriveScales.y : OverdriveScales.z; + adjustedScales.y = newColor.y > oldColor.y ? OverdriveScales.y : OverdriveScales.z; + adjustedScales.z = newColor.z > oldColor.z ? OverdriveScales.y : OverdriveScales.z; + overdriveColor = saturate(newColor + (newColor - oldColor) * adjustedScales); + } + else + { + overdriveColor.r = OverdriveLut.Sample(OverdriveSampler, float2(newColor.r, oldColor.r)).r; + overdriveColor.g = OverdriveLut.Sample(OverdriveSampler, float2(newColor.g, oldColor.g)).g; + overdriveColor.b = OverdriveLut.Sample(OverdriveSampler, float2(newColor.b, oldColor.b)).b; + } + outColor1 = float4(overdriveColor, 1.0); } } diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps_refl.h deleted file mode 100644 index fff0da3..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_ps_refl.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef DistortionChroma_ps_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionChroma_ps_refl[] = -{ - { "OverdriveScales", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "AaDerivativeMult", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 4 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.h deleted file mode 100644 index 5ffc945..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef DISTORTIONCHROMA_VS_H -#define DISTORTIONCHROMA_VS_H - -static const unsigned char DistortionChroma_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0x8e, 0x20, 0x97, 0xab, 0xce, 0xc8, 0x74, 0x3e, - 0xfe, 0xeb, 0x97, 0xa0, 0xe6, 0xca, 0x72, 0xa1, 0x01, 0x00, 0x00, 0x00, - 0x64, 0x04, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x38, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x7c, 0x02, 0x00, 0x00, - 0xe8, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, - 0xc8, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, - 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, - 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x4d, 0x69, 0x63, 0x72, - 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, - 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, - 0x49, 0x53, 0x47, 0x4e, 0x98, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0f, 0x01, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, - 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x9c, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, - 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, - 0x53, 0x48, 0x44, 0x52, 0x64, 0x01, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x59, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x12, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0xc2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, - 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x11, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa6, 0x8b, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0xc2, 0x20, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x06, 0x84, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x14, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0xa6, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h deleted file mode 100644 index 7feb789..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionChroma_vs_refl.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef DistortionChroma_vs_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionChroma_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.h deleted file mode 100644 index 418b740..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.h +++ /dev/null @@ -1,214 +0,0 @@ -#ifndef DISTORTIONTIMEWARPCHROMA_VS_H -#define DISTORTIONTIMEWARPCHROMA_VS_H - -static const unsigned char DistortionTimewarpChroma_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0x46, 0xb0, 0x5a, 0x1b, 0xfd, 0x8c, 0xdb, 0xa9, - 0x8d, 0x82, 0x83, 0x1f, 0xd6, 0x4f, 0x4a, 0x8f, 0x01, 0x00, 0x00, 0x00, - 0xac, 0x09, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x98, 0x01, 0x00, 0x00, 0x38, 0x02, 0x00, 0x00, 0xdc, 0x02, 0x00, 0x00, - 0x30, 0x09, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x5c, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, - 0x2b, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, - 0x3c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1c, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, - 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x45, 0x79, 0x65, 0x52, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, - 0x00, 0xab, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x79, 0x65, 0x52, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x00, 0x4d, - 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, - 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, - 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, - 0x49, 0x53, 0x47, 0x4e, 0x98, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0f, 0x09, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x8f, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, - 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x9c, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, - 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, - 0x53, 0x48, 0x44, 0x52, 0x4c, 0x06, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x93, 0x01, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x92, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0xc2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x1f, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x32, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x16, 0x85, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x16, 0x85, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x92, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x82, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x22, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, - 0x42, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x96, 0x05, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0xa6, 0x0a, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0x62, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa6, 0x8b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, - 0xc2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, - 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, - 0x22, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x0f, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0x32, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x11, 0x00, 0x00, 0x07, - 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x07, 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x07, - 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x0a, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0xc2, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x06, 0x04, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, - 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.vsh b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.vsh index 7e5512b..1f62785 100644 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.vsh +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs.vsh @@ -1,8 +1,8 @@ /************************************************************************************ -Filename : DistortionTimewarpChroma_vs.vsh +Filename : DistortionPositionTimewarpChroma_vs.vsh -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); you may not use the Oculus VR Rift SDK except in compliance with the License, @@ -21,46 +21,84 @@ limitations under the License. ************************************************************************************/ +Texture2DMS DepthTexture1x : register(t0); +Texture2DMS DepthTexture2x : register(t1); +Texture2DMS DepthTexture4x : register(t2); + +float depthMsaaSamples = -1.0; // -1 means it's disabled + float2 EyeToSourceUVScale; float2 EyeToSourceUVOffset; float4x4 EyeRotationStart; float4x4 EyeRotationEnd; +// DepthProjector values can also be calculated as: +// float DepthProjectorX = FarClip / (FarClip - NearClip); +// float DepthProjectorY = (-FarClip * NearClip) / (FarClip - NearClip); +float2 DepthProjector; +float2 DepthDimSize; + +float4 PositionFromDepth(float2 inTexCoord) +{ + float2 eyeToSourceTexCoord = inTexCoord * EyeToSourceUVScale + EyeToSourceUVOffset; + float linearDepth = 1.0; + + if(depthMsaaSamples > 0.0) + { + float depth; + if(depthMsaaSamples <= 1.5) + depth = DepthTexture1x.Load(int2(eyeToSourceTexCoord * DepthDimSize), 0).x; + else if(depthMsaaSamples <= 2.5) + depth = DepthTexture2x.Load(int2(eyeToSourceTexCoord * DepthDimSize), 0).x; + else + depth = DepthTexture4x.Load(int2(eyeToSourceTexCoord * DepthDimSize), 0).x; + + linearDepth = DepthProjector.y / (depth - DepthProjector.x); + } + + float4 retVal = float4(inTexCoord, 1, 1); + retVal.xyz *= linearDepth; + return retVal; +} + float2 TimewarpTexCoordToWarpedPos(float2 inTexCoord, float4x4 rotMat) { // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. // Apply the 3x3 timewarp rotation to these vectors. - float3 transformed = float3( mul ( rotMat, float4(inTexCoord.xy, 1, 1) ).xyz); + float4 inputPos = PositionFromDepth(inTexCoord); + float3 transformed = float3( mul ( rotMat, inputPos ).xyz); + // Project them back onto the Z=1 plane of the rendered images. float2 flattened = transformed.xy / transformed.z; + // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) return flattened * EyeToSourceUVScale + EyeToSourceUVOffset; } -void main(in float2 Position : POSITION, - in float4 Color : COLOR0, - in float2 TexCoord0 : TEXCOORD0, - in float2 TexCoord1 : TEXCOORD1, - in float2 TexCoord2 : TEXCOORD2, - out float4 oPosition : SV_Position, - out float1 oColor : COLOR, - out float2 oTexCoord0 : TEXCOORD0, - out float2 oTexCoord1 : TEXCOORD1, - out float2 oTexCoord2 : TEXCOORD2) +void main( in float2 Position : POSITION, + in float4 Color : COLOR0, + in float2 TexCoord0 : TEXCOORD0, + in float2 TexCoord1 : TEXCOORD1, + in float2 TexCoord2 : TEXCOORD2, + out float4 oPosition : SV_Position, + out float1 oColor : COLOR, + out float2 oTexCoord0 : TEXCOORD0, + out float2 oTexCoord1 : TEXCOORD1, + out float2 oTexCoord2 : TEXCOORD2) { oPosition.x = Position.x; oPosition.y = Position.y; oPosition.z = 0.5; oPosition.w = 1.0; - + float timewarpLerpFactor = Color.a; float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor); // warped positions are a bit more involved, hence a separate function - oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot); + oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot); oTexCoord1 = TimewarpTexCoordToWarpedPos(TexCoord1, lerpedEyeRot); oTexCoord2 = TimewarpTexCoordToWarpedPos(TexCoord2, lerpedEyeRot); - oColor = Color.r; // Used for vignette fade. + oColor = Color.r; // Used for vignette fade. } diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs_refl.h deleted file mode 100644 index 38a168f..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarpChroma_vs_refl.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef DistortionTimewarpChroma_vs_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionTimewarpChroma_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, - { "EyeRotationStart", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 16, 64 }, - { "EyeRotationEnd", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 80, 64 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.h deleted file mode 100644 index 26fc0e2..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.h +++ /dev/null @@ -1,167 +0,0 @@ -#ifndef DISTORTIONTIMEWARP_VS_H -#define DISTORTIONTIMEWARP_VS_H - -static const unsigned char DistortionTimewarp_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0x96, 0x74, 0x01, 0x0e, 0x69, 0xc5, 0xe0, 0xbd, - 0x73, 0x27, 0xa6, 0x54, 0x7e, 0xee, 0xb9, 0xb6, 0x01, 0x00, 0x00, 0x00, - 0x7c, 0x07, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x98, 0x01, 0x00, 0x00, 0x08, 0x02, 0x00, 0x00, 0x7c, 0x02, 0x00, 0x00, - 0x00, 0x07, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x5c, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, - 0x2b, 0x01, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, - 0x3c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf8, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1c, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, - 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x45, 0x79, 0x65, 0x52, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x72, 0x74, - 0x00, 0xab, 0xab, 0xab, 0x03, 0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x79, 0x65, 0x52, - 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x6e, 0x64, 0x00, 0x4d, - 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, - 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, - 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, - 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0f, 0x09, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, - 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, - 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, - 0x53, 0x48, 0x44, 0x52, 0x7c, 0x04, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x1f, 0x01, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x92, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x68, 0x00, 0x00, 0x02, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x22, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x42, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0x82, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, - 0x82, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x80, - 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x1f, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x32, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x00, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x11, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x62, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x81, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x81, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x12, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x12, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x62, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x22, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x22, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x52, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x56, 0x84, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x42, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0a, 0x42, 0x00, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x92, 0x00, 0x10, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x80, 0x41, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x56, 0x81, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, - 0x82, 0x00, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x1a, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x11, 0x00, 0x00, 0x07, 0x42, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x0e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0x82, 0x00, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x3a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x3a, 0x00, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00, 0x0a, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x07, - 0x22, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x00, 0x07, 0x32, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x96, 0x05, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, 0x62, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xa6, 0x8b, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.vsh b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.vsh deleted file mode 100644 index d594042..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs.vsh +++ /dev/null @@ -1,63 +0,0 @@ -/************************************************************************************ - -Filename : DistortionTimewarp_vs.vsh - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -float2 EyeToSourceUVScale; -float2 EyeToSourceUVOffset; -float4x4 EyeRotationStart; -float4x4 EyeRotationEnd; - -float2 TimewarpTexCoordToWarpedPos(float2 inTexCoord, float4x4 rotMat) -{ - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - // Apply the 3x3 timewarp rotation to these vectors. - float3 transformed = float3( mul ( rotMat, float4(inTexCoord,1,1) ).xyz); - // Project them back onto the Z=1 plane of the rendered images. - float2 flattened = transformed.xy / transformed.z; - // Scale them into ([0,0.5],[0,1]) or ([0.5,0],[0,1]) UV lookup space (depending on eye) - return flattened * EyeToSourceUVScale + EyeToSourceUVOffset; - -} - -void main(in float2 Position : POSITION, - in float4 Color : COLOR0, - in float2 TexCoord0 : TEXCOORD0, - out float4 oPosition : SV_Position, - out float1 oColor : COLOR, - out float2 oTexCoord0 : TEXCOORD0) -{ - - oPosition.x = Position.x; - oPosition.y = Position.y; - oPosition.z = 0.5; - oPosition.w = 1.0; - - float timewarpLerpFactor = Color.a; - float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, timewarpLerpFactor); - - // Warped positions are a bit more involved, hence a separate function - oTexCoord0 = TimewarpTexCoordToWarpedPos(TexCoord0, lerpedEyeRot); - oColor = Color.r; // Used for vignette fade. -} - - diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs_refl.h deleted file mode 100644 index eab6baf..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/DistortionTimewarp_vs_refl.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef DistortionTimewarp_vs_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform DistortionTimewarp_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, - { "EyeRotationStart", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 16, 64 }, - { "EyeRotationEnd", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 80, 64 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.h b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.h deleted file mode 100644 index 8d7867a..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps.h +++ /dev/null @@ -1,65 +0,0 @@ -#ifndef DISTORTION_PS_H -#define DISTORTION_PS_H - -static const unsigned char Distortion_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0x9d, 0x0b, 0x61, 0x6e, 0xd2, 0x1b, 0xc9, 0x8e, - 0x12, 0xdf, 0xf7, 0xa6, 0xae, 0xfe, 0x1e, 0x39, 0x01, 0x00, 0x00, 0x00, - 0xac, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0xd8, 0x00, 0x00, 0x00, 0x4c, 0x01, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, - 0x30, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x9c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, - 0x6b, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x63, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, - 0x61, 0x72, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, 0x00, 0x4d, - 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, - 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, - 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, - 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, - 0x49, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x01, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x06, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, - 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, - 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, - 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xab, 0xab, - 0x53, 0x48, 0x44, 0x52, 0xa8, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x2a, 0x00, 0x00, 0x00, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, - 0x12, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, - 0x62, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, - 0x01, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x96, 0x15, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, 0x72, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, - 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x80, 0x3f, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, - 0x74, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h deleted file mode 100644 index 8a613f5..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_ps_refl.h +++ /dev/null @@ -1 +0,0 @@ -// No data available for shader reflection Distortion_ps_refl \ No newline at end of file diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.h b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.h deleted file mode 100644 index 52b9413..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef DISTORTION_VS_H -#define DISTORTION_VS_H - -static const unsigned char Distortion_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0xfd, 0x23, 0xd7, 0xc6, 0x1a, 0x85, 0x42, 0xd8, - 0xf1, 0xf2, 0x06, 0x88, 0x86, 0xf0, 0xd9, 0xc7, 0x01, 0x00, 0x00, 0x00, - 0x7c, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x38, 0x01, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, - 0xc8, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, - 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xb4, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x56, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, - 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x79, 0x65, 0x54, 0x6f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x55, - 0x56, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x00, 0x4d, 0x69, 0x63, 0x72, - 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, - 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, - 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0f, 0x01, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, - 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x0e, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x06, 0x09, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, - 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, - 0x53, 0x48, 0x44, 0x52, 0xdc, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x37, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x12, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x12, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, - 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0x12, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0a, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0x62, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x81, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x06, 0x11, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa6, 0x8b, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, - 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.vsh b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.vsh deleted file mode 100644 index d947772..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs.vsh +++ /dev/null @@ -1,41 +0,0 @@ -/************************************************************************************ - -Filename : Distortion_vs.vsh - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -float2 EyeToSourceUVScale; -float2 EyeToSourceUVOffset; - -void main(in float2 Position : POSITION, - in float4 Color : COLOR0, - in float2 TexCoord0 : TEXCOORD0, - out float4 oPosition : SV_Position, - out float1 oColor : COLOR, - out float2 oTexCoord0 : TEXCOORD0) -{ - oPosition.x = Position.x; - oPosition.y = Position.y; - oPosition.z = 0.5; - oPosition.w = 1.0; - oTexCoord0 = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; - oColor = Color.r; // Used for vignette fade. -} - diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs_refl.h deleted file mode 100644 index b3e86ac..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/Distortion_vs_refl.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef Distortion_vs_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform Distortion_vs_refl[] = -{ - { "EyeToSourceUVScale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.h deleted file mode 100644 index 00f928d..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef SIMPLEQUAD_PS_H -#define SIMPLEQUAD_PS_H - -static const unsigned char SimpleQuad_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0x8c, 0x53, 0x2f, 0x7c, 0x3d, 0xea, 0xa5, 0xb6, - 0x05, 0xb7, 0xe0, 0x83, 0x67, 0x16, 0x9c, 0x93, 0x01, 0x00, 0x00, 0x00, - 0x08, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x44, 0x01, 0x00, 0x00, - 0x8c, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xc4, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, - 0x3c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00, - 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, - 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, - 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, - 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, - 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x53, 0x47, 0x4e, - 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, - 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, 0x74, 0x00, 0xab, 0xab, - 0x53, 0x48, 0x44, 0x52, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x06, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, - 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h deleted file mode 100644 index 7980b65..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_ps_refl.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SimpleQuad_ps_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform SimpleQuad_ps_refl[] = -{ - { "Color", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 16 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.h deleted file mode 100644 index e68903f..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef SIMPLEQUAD_VS_H -#define SIMPLEQUAD_VS_H - -static const unsigned char SimpleQuad_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0xd5, 0x40, 0x5f, 0xa6, 0x2d, 0x0a, 0xd9, 0x2a, - 0x84, 0x41, 0x9e, 0x1f, 0xab, 0xa5, 0xa9, 0x2c, 0x01, 0x00, 0x00, 0x00, - 0xa8, 0x02, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x38, 0x01, 0x00, 0x00, 0x6c, 0x01, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, - 0x2c, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, - 0xc8, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, - 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, - 0xb8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0xab, - 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x4d, 0x69, 0x63, 0x72, - 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, - 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, - 0x49, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x00, 0xab, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x53, 0x48, 0x44, 0x52, - 0x84, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, 0x21, 0x00, 0x00, 0x00, - 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0b, - 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, 0xc2, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x00, 0x80, 0x3f, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h deleted file mode 100644 index 23bb021..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleQuad_vs_refl.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef SimpleQuad_vs_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform SimpleQuad_vs_refl[] = -{ - { "PositionOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "Scale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.h deleted file mode 100644 index 39fda03..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef SIMPLETEXTUREDQUAD_PS_H -#define SIMPLETEXTUREDQUAD_PS_H - -static const unsigned char SimpleTexturedQuad_ps[] = { - 0x44, 0x58, 0x42, 0x43, 0xbe, 0x17, 0xf1, 0xab, 0xc8, 0x62, 0x4c, 0x11, - 0xe8, 0x29, 0xb0, 0x5b, 0x0b, 0xf8, 0x73, 0x38, 0x01, 0x00, 0x00, 0x00, - 0x44, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x54, 0x01, 0x00, 0x00, 0xc8, 0x01, 0x00, 0x00, 0xfc, 0x01, 0x00, 0x00, - 0xc8, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x18, 0x01, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xff, 0xff, 0x00, 0x01, 0x00, 0x00, - 0xe4, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x8a, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x4c, 0x69, 0x6e, 0x65, 0x61, 0x72, 0x53, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, - 0x65, 0x00, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, - 0x92, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0xab, 0xab, 0x01, 0x00, 0x03, 0x00, - 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, - 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, - 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, - 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, - 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, - 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, - 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x61, 0x72, 0x67, 0x65, - 0x74, 0x00, 0xab, 0xab, 0x53, 0x48, 0x44, 0x52, 0xc4, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, - 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, - 0x38, 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x09, - 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x07, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h deleted file mode 100644 index 578cc45..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_ps_refl.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef SimpleTexturedQuad_ps_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform SimpleTexturedQuad_ps_refl[] = -{ - { "Color", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 16 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.h deleted file mode 100644 index 8e18f8e..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef SIMPLETEXTUREDQUAD_VS_H -#define SIMPLETEXTUREDQUAD_VS_H - -static const unsigned char SimpleTexturedQuad_vs[] = { - 0x44, 0x58, 0x42, 0x43, 0xe3, 0x2d, 0x41, 0xb3, 0xee, 0x4c, 0x7d, 0xb3, - 0x80, 0x0d, 0x3a, 0x0c, 0xb6, 0x80, 0x5e, 0xb1, 0x01, 0x00, 0x00, 0x00, - 0x7c, 0x03, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, - 0x38, 0x01, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x1c, 0x02, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xfc, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x1c, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0xff, 0x00, 0x01, 0x00, 0x00, - 0xc8, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, - 0x3c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xb0, 0x00, 0x00, 0x00, - 0xb8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, - 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x66, 0x66, 0x73, - 0x65, 0x74, 0x00, 0xab, 0x01, 0x00, 0x03, 0x00, 0x01, 0x00, 0x02, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x00, 0xab, 0xab, - 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x80, 0x3f, 0x4d, 0x69, 0x63, 0x72, - 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, - 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, - 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, - 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, - 0x49, 0x53, 0x47, 0x4e, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x07, 0x03, 0x00, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0f, 0x0f, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x03, 0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, - 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, - 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x6c, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x62, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, - 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, - 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, - 0x53, 0x48, 0x44, 0x52, 0xdc, 0x00, 0x00, 0x00, 0x40, 0x00, 0x01, 0x00, - 0x37, 0x00, 0x00, 0x00, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, - 0x32, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, - 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x00, 0x0b, 0x32, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x46, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x8a, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x80, 0x20, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x08, - 0xc2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, - 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x36, 0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x46, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, - 0x53, 0x54, 0x41, 0x54, 0x74, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h b/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h deleted file mode 100644 index 5adb8a0..0000000 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/SimpleTexturedQuad_vs_refl.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef SimpleTexturedQuad_vs_refl - -const OVR::CAPI::D3D_NS::ShaderBase::Uniform SimpleTexturedQuad_vs_refl[] = -{ - { "PositionOffset", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "Scale", OVR::CAPI::D3D_NS::ShaderBase::VARTYPE_FLOAT, 8, 8 }, -}; - -#endif diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/genComputeShaderHeader.bat b/LibOVR/Src/CAPI/D3D1X/Shaders/genComputeShaderHeader.bat index 784bc86..0a67677 100644 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/genComputeShaderHeader.bat +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/genComputeShaderHeader.bat @@ -3,13 +3,16 @@ pushd %~dp0 echo Compiling shader and packing into header: %~2 setlocal -set PATH=%PATH%;"%DXSDK_DIR%Utilities\bin\x86\" fxc.exe /nologo /E main /T cs_5_0 /Fo "%1" %2 bin2header.exe "%1" echo Generating shader reflection data for %1 ShaderReflector "%1" "%1_refl.h" +echo /* Concatenating shader reflector output:*/ >> "%1.h" +type "%1_refl.h" >> "%1.h" +del "%1_refl.h" + del "%1" endlocal popd diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/genPixelShaderHeader.bat b/LibOVR/Src/CAPI/D3D1X/Shaders/genPixelShaderHeader.bat index 76f17c2..5b108dc 100644 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/genPixelShaderHeader.bat +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/genPixelShaderHeader.bat @@ -3,13 +3,16 @@ pushd %~dp0 echo Compiling shader and packing into header: %~2 setlocal -set PATH=%PATH%;"%DXSDK_DIR%Utilities\bin\x86\" -fxc.exe /nologo /E main /T ps_4_0 /Fo "%1" %2 +fxc.exe /nologo /E main /T ps_4_1 /Fo "%1" %2 bin2header.exe "%1" echo Generating shader reflection data for %1 ShaderReflector "%1" "%1_refl.h" +echo /* Concatenating shader reflector output:*/ >> "%1.h" +type "%1_refl.h" >> "%1.h" +del "%1_refl.h" + del "%1" endlocal popd diff --git a/LibOVR/Src/CAPI/D3D1X/Shaders/genVertexShaderHeader.bat b/LibOVR/Src/CAPI/D3D1X/Shaders/genVertexShaderHeader.bat index 7085775..aa264d9 100644 --- a/LibOVR/Src/CAPI/D3D1X/Shaders/genVertexShaderHeader.bat +++ b/LibOVR/Src/CAPI/D3D1X/Shaders/genVertexShaderHeader.bat @@ -3,13 +3,16 @@ pushd %~dp0 echo Compiling shader and packing into header: %~2 setlocal -set PATH=%PATH%;"%DXSDK_DIR%Utilities\bin\x86\" -fxc.exe /nologo /E main /T vs_4_0 /Fo "%1" %2 +fxc.exe /nologo /E main /T vs_4_1 /Fo "%1" %2 bin2header.exe "%1" echo Generating shader reflection data for %1 ShaderReflector "%1" "%1_refl.h" +echo /* Concatenating shader reflector output:*/ >> "%1.h" +type "%1_refl.h" >> "%1.h" +del "%1_refl.h" + del "%1" endlocal popd diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp index 05508ea..d7706ae 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.cpp @@ -1,409 +1,436 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_DistortionRenderer.cpp -Content : Experimental distortion renderer -Created : March 7th, 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "CAPI_D3D9_DistortionRenderer.h" -#define OVR_D3D_VERSION 9 -#include "../../OVR_CAPI_D3D.h" - -#include -DEFINE_GUID(IID_OVRDirect3DDevice9EX, 0xe6d58f10, 0xffa1, 0x4748, 0x85, 0x9f, 0xbc, 0xd7, 0xea, 0xe8, 0xfc, 0x1); - -namespace OVR { namespace CAPI { namespace D3D9 { - - -///QUESTION : Why not just a normal constructor? -CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState) -{ - return new DistortionRenderer(hmd, timeManager, renderState); -} - -DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, - const HMDRenderState& renderState) - : CAPI::DistortionRenderer(ovrRenderAPI_D3D9, hmd, timeManager, renderState), - Device(NULL), - SwapChain(NULL), - VertexDecl(NULL), - PixelShader(NULL), - VertexShader(NULL), - VertexShaderTimewarp(NULL), - //screenSize(), - ResolutionInPixels(0,0) - //eachEye[] -{ - ScreenSize.w = 0; - ScreenSize.h = 0; - InitLatencyTester(renderState); - - for (int i = 0; i < 2; ++i) - { - eachEye[i].dxIndices = nullptr; - eachEye[i].dxVerts = nullptr; - } -} - - -/**********************************************/ -DistortionRenderer::~DistortionRenderer() -{ - //Release any memory - if (eachEye[0].dxIndices) - { - eachEye[0].dxIndices->Release(); - } - if (eachEye[0].dxVerts) - { - eachEye[0].dxVerts->Release(); - } - if (eachEye[1].dxIndices) - { - eachEye[1].dxIndices->Release(); - } - if (eachEye[1].dxVerts) - { - eachEye[1].dxVerts->Release(); - } -} - - -/******************************************************************************/ -bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) -{ - ///QUESTION - what is returned bool for??? Are we happy with this true, if not config. - const ovrD3D9Config * config = (const ovrD3D9Config*)apiConfig; - if (!config) return true; - if (!config->D3D9.pDevice) return false; - - if (System::DirectDisplayEnabled()) - { - Ptr ovrDevice; - if (config->D3D9.pDevice->QueryInterface(IID_OVRDirect3DDevice9EX, (void**)&ovrDevice.GetRawRef()) == E_NOINTERFACE) - { - OVR_DEBUG_LOG_TEXT(("ovr_Initialize() or ovr_InitializeRenderingShim() wasn't called before the D3D9 device was created.")); - } - } - - //Glean all the required variables from the input structures - Device = config->D3D9.pDevice; - SwapChain = config->D3D9.pSwapChain; - ScreenSize = config->D3D9.Header.BackBufferSize; - - GfxState = *new GraphicsState(Device, RState.DistortionCaps); - - CreateVertexDeclaration(); - CreateDistortionShaders(); - CreateDistortionModels(); - - return true; -} - -void DistortionRenderer::InitLatencyTester(const HMDRenderState& RenderState) -{ - ResolutionInPixels = RenderState.OurHMDInfo.ResolutionInPixels; -} - - -/**************************************************************/ -void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) -{ - //Doesn't do a lot in here?? - const ovrD3D9Texture* tex = (const ovrD3D9Texture*)eyeTexture; - - //Write in values - eachEye[eyeId].texture = tex->D3D9.pTexture; - - // Its only at this point we discover what the viewport of the texture is. - // because presumably we allow users to realtime adjust the resolution. - eachEye[eyeId].TextureSize = tex->D3D9.Header.TextureSize; - eachEye[eyeId].RenderViewport = tex->D3D9.Header.RenderViewport; - - const ovrEyeRenderDesc& erd = RState.EyeRenderDesc[eyeId]; - - ovrHmd_GetRenderScaleAndOffset( erd.Fov, - eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, - eachEye[eyeId].UVScaleOffset ); - - if (RState.DistortionCaps & ovrDistortionCap_FlipInput) - { - eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y; - eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y; - } -} - -void DistortionRenderer::renderEndFrame() -{ - RenderBothDistortionMeshes(); - - if(RegisteredPostDistortionCallback) - RegisteredPostDistortionCallback(Device); - - if (LatencyTest2Active) - { - renderLatencyPixel(LatencyTest2DrawColor); - } -} - -/******************************************************************/ -void DistortionRenderer::EndFrame(bool swapBuffers) -{ - ///QUESTION : Clear the screen? - ///QUESTION : Ensure the screen is the render target - - // Don't spin if we are explicitly asked not to - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp && - !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) - { - if (!TimeManager.NeedDistortionTimeMeasurement()) - { - // Wait for timewarp distortion if it is time and Gpu idle - FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); - - renderEndFrame(); - } - else - { - // If needed, measure distortion time so that TimeManager can better estimate - // latency-reducing time-warp wait timing. - WaitUntilGpuIdle(); - double distortionStartTime = ovr_GetTimeInSeconds(); - - renderEndFrame(); - - WaitUntilGpuIdle(); - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); - } - } - else - { - renderEndFrame(); - } - - if (LatencyTestActive) - { - renderLatencyQuad(LatencyTestDrawColor); - } - - if (swapBuffers) - { - if (SwapChain) - { - SwapChain->Present(NULL, NULL, NULL, NULL, 0); - } - else - { - Device->Present( NULL, NULL, NULL, NULL ); - } - - // Force GPU to flush the scene, resulting in the lowest possible latency. - // It's critical that this flush is *after* present. - // Doesn't need to be done if running through the Oculus driver. - if (RState.OurHMDInfo.InCompatibilityMode && - !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) - { - WaitUntilGpuIdle(); - } - } -} - - -void DistortionRenderer::WaitUntilGpuIdle() -{ - if(Device) - { - IDirect3DQuery9* pEventQuery=NULL ; - Device->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery) ; - - if(pEventQuery!=NULL) - { - pEventQuery->Issue(D3DISSUE_END) ; - while(S_FALSE == pEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)){} - pEventQuery->Release(); - } - } -} - -double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) -{ - double initialTime = ovr_GetTimeInSeconds(); - if (initialTime >= absTime) - return 0.0; - - WaitUntilGpuIdle(); - - return WaitTillTime(absTime); -} - - -//----------------------------------------------------------------------------- -// Latency Tester Quad - -static void ConvertSRGB(unsigned char c[3]) -{ - for (int i = 0; i < 3; ++i) - { - double d = (double)c[i]; - double ds = d / 255.; - - if (ds <= 0.04045) - { - d /= 12.92; - } - else - { - d = 255. * pow((ds + 0.055) / 1.055, 2.4); - } - - int color = (int)d; - if (color < 0) - { - color = 0; - } - else if (color > 255) - { - color = 255; - } - - c[i] = (unsigned char)color; - } -} - -void DistortionRenderer::renderLatencyQuad(unsigned char* color) -{ - D3DRECT rect = { ResolutionInPixels.w / 4, ResolutionInPixels.h / 4, ResolutionInPixels.w * 3 / 4, ResolutionInPixels.h * 3 / 4 }; - unsigned char c[3] = { color[0], color[1], color[2] }; - - if (RState.DistortionCaps & ovrDistortionCap_SRGB) - { - ConvertSRGB(c); - } - - Device->Clear(1, &rect, D3DCLEAR_TARGET, D3DCOLOR_RGBA(c[0], c[1], c[2], 255), 1, 0); -} - -#ifdef OVR_BUILD_DEBUG -#define OVR_LATENCY_PIXEL_SIZE 20 -#else -#define OVR_LATENCY_PIXEL_SIZE 5 -#endif - -void DistortionRenderer::renderLatencyPixel(unsigned char* color) -{ - D3DRECT rect = { ResolutionInPixels.w - OVR_LATENCY_PIXEL_SIZE, 0, ResolutionInPixels.w, OVR_LATENCY_PIXEL_SIZE }; - unsigned char c[3] = { color[0], color[1], color[2] }; - - if (RState.DistortionCaps & ovrDistortionCap_SRGB) - { - ConvertSRGB(c); - } - - Device->Clear(1, &rect, D3DCLEAR_TARGET, D3DCOLOR_RGBA(c[0], c[1], c[2], 255), 1, 0); -} - - -//----------------------------------------------------------------------------- -// GraphicsState - -DistortionRenderer::GraphicsState::GraphicsState(IDirect3DDevice9* d, unsigned distortionCaps) -: Device(d) -, NumSavedStates(0) -, DistortionCaps(distortionCaps) -{ - #if defined(OVR_BUILD_DEBUG) - memset(SavedState, 0, sizeof(SavedState)); - #endif -} - -void DistortionRenderer::GraphicsState::RecordAndSetState(int which, int type, DWORD newValue) -{ - SavedStateType * sst = &SavedState[NumSavedStates++]; - sst->which = which; - sst->type = type; - if (which == 0) - { - Device->GetSamplerState(0, (D3DSAMPLERSTATETYPE)type, &sst->valueToRevertTo); - Device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)type, newValue); - } - else - { - Device->GetRenderState((D3DRENDERSTATETYPE)type, &sst->valueToRevertTo); - Device->SetRenderState((D3DRENDERSTATETYPE)type, newValue); - } -} - -void DistortionRenderer::GraphicsState::Save() -{ - //Record and set rasterizer and sampler states. - - NumSavedStates=0; - - RecordAndSetState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); - RecordAndSetState(0, D3DSAMP_BORDERCOLOR, 0x000000 ); - RecordAndSetState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); - RecordAndSetState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); - RecordAndSetState(0, D3DSAMP_SRGBTEXTURE, (DistortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); - - RecordAndSetState(1, D3DRS_MULTISAMPLEANTIALIAS, FALSE ); - RecordAndSetState(1, D3DRS_DITHERENABLE, FALSE ); - RecordAndSetState(1, D3DRS_ZENABLE, FALSE ); - RecordAndSetState(1, D3DRS_ZWRITEENABLE, TRUE ); - RecordAndSetState(1, D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); - RecordAndSetState(1, D3DRS_CULLMODE , D3DCULL_CCW ); - RecordAndSetState(1, D3DRS_ALPHABLENDENABLE , FALSE ); - RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); - RecordAndSetState(1, D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ); - RecordAndSetState(1, D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA ); - RecordAndSetState(1, D3DRS_FILLMODE, D3DFILL_SOLID ); - RecordAndSetState(1, D3DRS_ALPHATESTENABLE, FALSE); - RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); - RecordAndSetState(1, D3DRS_LIGHTING, FALSE ); - RecordAndSetState(1, D3DRS_FOGENABLE, FALSE ); - RecordAndSetState(1, D3DRS_SRGBWRITEENABLE, (DistortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); -} - - -void DistortionRenderer::GraphicsState::Restore() -{ - for (int i = 0; i < NumSavedStates; i++) - { - SavedStateType * sst = &SavedState[i]; - if (sst->which == 0) - { - Device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)sst->type, sst->valueToRevertTo); - } - else - { - Device->SetRenderState((D3DRENDERSTATETYPE)sst->type, sst->valueToRevertTo); - } - } -} - - -}}} // OVR::CAPI::D3D1X - - +/************************************************************************************ + +Filename : CAPI_D3D11_DistortionRenderer.cpp +Content : Experimental distortion renderer +Created : March 7th, 2014 +Authors : Tom Heath + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_D3D9_DistortionRenderer.h" +#include "OVR_CAPI_D3D.h" + +#include +DEFINE_GUID(IID_OVRDirect3DDevice9EX, 0xe6d58f10, 0xffa1, 0x4748, 0x85, 0x9f, 0xbc, 0xd7, 0xea, 0xe8, 0xfc, 0x1); + +OVR_DISABLE_MSVC_WARNING(4996) // Disable deprecation warning + +namespace OVR { namespace CAPI { namespace D3D9 { + + +///QUESTION : Why not just a normal constructor? +CAPI::DistortionRenderer* DistortionRenderer::Create() +{ + return new DistortionRenderer(); +} + +DistortionRenderer::DistortionRenderer() : + Device(NULL), + SwapChain(NULL), + VertexDecl(NULL), + PixelShader(NULL), + VertexShader(NULL), + VertexShaderTimewarp(NULL), + //screenSize(), + ResolutionInPixels(0,0) + //eachEye[] +{ + ScreenSize.w = 0; + ScreenSize.h = 0; + + for (int i = 0; i < 2; ++i) + { + eachEye[i].dxIndices = nullptr; + eachEye[i].dxVerts = nullptr; + } +} + + +/**********************************************/ +DistortionRenderer::~DistortionRenderer() +{ + //Release any memory + if (eachEye[0].dxIndices) + { + eachEye[0].dxIndices->Release(); + } + if (eachEye[0].dxVerts) + { + eachEye[0].dxVerts->Release(); + } + if (eachEye[1].dxIndices) + { + eachEye[1].dxIndices->Release(); + } + if (eachEye[1].dxVerts) + { + eachEye[1].dxVerts->Release(); + } +} + + +/******************************************************************************/ +bool DistortionRenderer::initializeRenderer(const ovrRenderAPIConfig* apiConfig) +{ + initLatencyTester(); + + ///QUESTION - what is returned bool for??? Are we happy with this true, if not config. + const ovrD3D9Config * config = (const ovrD3D9Config*)apiConfig; + if (!config) return true; + if (!config->D3D9.pDevice) return false; + + if (Display::GetDirectDisplayInitialized()) + { + Ptr ovrDevice; + if (config->D3D9.pDevice->QueryInterface(IID_OVRDirect3DDevice9EX, (void**)&ovrDevice.GetRawRef()) == E_NOINTERFACE) + { + OVR_DEBUG_LOG_TEXT(("ovr_Initialize() or ovr_InitializeRenderingShim() wasn't called before the D3D9 device was created.")); + } + } + + //Glean all the required variables from the input structures + Device = config->D3D9.pDevice; + SwapChain = config->D3D9.pSwapChain; + ScreenSize = config->D3D9.Header.BackBufferSize; + + GfxState = *new GraphicsState(Device, RenderState->DistortionCaps); + + CreateVertexDeclaration(); + CreateDistortionShaders(); + return CreateDistortionModels(); +} + +void DistortionRenderer::initLatencyTester() +{ + ResolutionInPixels = RenderState->OurHMDInfo.ResolutionInPixels; +} + + +/**************************************************************/ +void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) +{ + if (eyeTexture) + { + //Doesn't do a lot in here?? + const ovrD3D9Texture* tex = (const ovrD3D9Texture*)eyeTexture; + + //Write in values + eachEye[eyeId].texture = tex->D3D9.pTexture; + + // Its only at this point we discover what the viewport of the texture is. + // because presumably we allow users to realtime adjust the resolution. + eachEye[eyeId].TextureSize = tex->D3D9.Header.TextureSize; + eachEye[eyeId].RenderViewport = tex->D3D9.Header.RenderViewport; + + const ovrEyeRenderDesc& erd = RenderState->EyeRenderDesc[eyeId]; + + ovrHmd_GetRenderScaleAndOffset(erd.Fov, + eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, + eachEye[eyeId].UVScaleOffset); + + if (RenderState->DistortionCaps & ovrDistortionCap_FlipInput) + { + eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y; + eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y; + } + } +} + +void DistortionRenderer::SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) +{ + SubmitEye(eyeId, eyeColorTexture); + + OVR_UNUSED(eyeDepthTexture); +} + +void DistortionRenderer::renderEndFrame() +{ + RenderBothDistortionMeshes(); + + if(RegisteredPostDistortionCallback) + RegisteredPostDistortionCallback(Device); + + if (LatencyTest2Active) + { + renderLatencyPixel(LatencyTest2DrawColor); + } +} + +/******************************************************************/ +void DistortionRenderer::EndFrame(uint32_t frameIndex, bool swapBuffers) +{ + ///QUESTION : Clear the screen? + ///QUESTION : Ensure the screen is the render target + + // D3D9 does not provide any frame timing information. + Timing->CalculateTimewarpTiming(frameIndex); + + // Don't spin if we are explicitly asked not to + if ( (RenderState->DistortionCaps & ovrDistortionCap_TimeWarp) && + (RenderState->DistortionCaps & ovrDistortionCap_TimewarpJitDelay) && + !(RenderState->DistortionCaps & ovrDistortionCap_ProfileNoSpinWaits)) + { + if (!Timing->NeedDistortionTimeMeasurement()) + { + FlushGpuAndWaitTillTime(Timing->GetTimewarpTiming()->JIT_TimewarpTime); + + renderEndFrame(); + } + else + { + // If needed, measure distortion time so that TimeManager can better estimate + // latency-reducing time-warp wait timing. + WaitUntilGpuIdle(); + double distortionStartTime = ovr_GetTimeInSeconds(); + + renderEndFrame(); + + WaitUntilGpuIdle(); + Timing->AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + } + } + else + { + renderEndFrame(); + } + + if (LatencyTestActive) + { + renderLatencyQuad(LatencyTestDrawColor); + } + + if (swapBuffers) + { + if (SwapChain) + { + SwapChain->Present(NULL, NULL, NULL, NULL, 0); + } + else + { + Device->Present( NULL, NULL, NULL, NULL ); + } + + // Force GPU to flush the scene, resulting in the lowest possible latency. + // It's critical that this flush is *after* present. + // Doesn't need to be done if running through the Oculus driver. + if (RenderState->OurHMDInfo.InCompatibilityMode && + !(RenderState->DistortionCaps & ovrDistortionCap_ProfileNoSpinWaits)) + { + WaitUntilGpuIdle(); + } + } +} + + +void DistortionRenderer::WaitUntilGpuIdle() +{ + if(Device) + { + IDirect3DQuery9* pEventQuery=NULL ; + Device->CreateQuery(D3DQUERYTYPE_EVENT, &pEventQuery) ; + + if(pEventQuery!=NULL) + { + pEventQuery->Issue(D3DISSUE_END) ; + while(S_FALSE == pEventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH)){} + pEventQuery->Release(); + } + } +} + +double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) +{ + double initialTime = ovr_GetTimeInSeconds(); + if (initialTime >= absTime) + return 0.0; + + WaitUntilGpuIdle(); + + return WaitTillTime(absTime); +} + + +//----------------------------------------------------------------------------- +// Latency Tester Quad + +static void ConvertSRGB(unsigned char c[3]) +{ + for (int i = 0; i < 3; ++i) + { + double d = (double)c[i]; + double ds = d / 255.; + + if (ds <= 0.04045) + { + d /= 12.92; + } + else + { + d = 255. * pow((ds + 0.055) / 1.055, 2.4); + } + + int color = (int)d; + if (color < 0) + { + color = 0; + } + else if (color > 255) + { + color = 255; + } + + c[i] = (unsigned char)color; + } +} + +void DistortionRenderer::renderLatencyQuad(unsigned char* color) +{ + D3DRECT rect = { ResolutionInPixels.w / 4, ResolutionInPixels.h / 4, ResolutionInPixels.w * 3 / 4, ResolutionInPixels.h * 3 / 4 }; + unsigned char c[3] = { color[0], color[1], color[2] }; + + if (RenderState->DistortionCaps & ovrDistortionCap_SRGB) + { + ConvertSRGB(c); + } + + Device->Clear(1, &rect, D3DCLEAR_TARGET, D3DCOLOR_RGBA(c[0], c[1], c[2], 255), 1, 0); +} + +#ifdef OVR_BUILD_DEBUG +#define OVR_LATENCY_PIXEL_SIZE 20 +#else +#define OVR_LATENCY_PIXEL_SIZE 5 +#endif + +void DistortionRenderer::renderLatencyPixel(unsigned char* color) +{ + D3DRECT rect; + + if (RenderState->RenderInfo.OffsetLatencyTester) + { + // TBD: Is this correct? + rect.x1 = ResolutionInPixels.w / 2; + rect.y1 = 0; + } + else + { + rect.x1 = ResolutionInPixels.w - OVR_LATENCY_PIXEL_SIZE; + rect.y1 = 0; + } + + rect.x2 = rect.x1 + OVR_LATENCY_PIXEL_SIZE; + rect.y2 = rect.y1 + OVR_LATENCY_PIXEL_SIZE; + + // TBD: Does (RenderState->RenderInfo.RotateCCW90) affect this? + + unsigned char c[3] = { color[0], color[1], color[2] }; + + if (RenderState->DistortionCaps & ovrDistortionCap_SRGB) + { + ConvertSRGB(c); + } + + Device->Clear(1, &rect, D3DCLEAR_TARGET, D3DCOLOR_RGBA(c[0], c[1], c[2], 255), 1, 0); +} + + +//----------------------------------------------------------------------------- +// GraphicsState + +DistortionRenderer::GraphicsState::GraphicsState(IDirect3DDevice9* d, unsigned distortionCaps) +: Device(d) +, NumSavedStates(0) +, DistortionCaps(distortionCaps) +{ + #if defined(OVR_BUILD_DEBUG) + memset(SavedState, 0, sizeof(SavedState)); + #endif +} + +void DistortionRenderer::GraphicsState::RecordAndSetState(int which, int type, DWORD newValue) +{ + SavedStateType * sst = &SavedState[NumSavedStates++]; + sst->which = which; + sst->type = type; + if (which == 0) + { + Device->GetSamplerState(0, (D3DSAMPLERSTATETYPE)type, &sst->valueToRevertTo); + Device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)type, newValue); + } + else + { + Device->GetRenderState((D3DRENDERSTATETYPE)type, &sst->valueToRevertTo); + Device->SetRenderState((D3DRENDERSTATETYPE)type, newValue); + } +} + +void DistortionRenderer::GraphicsState::Save() +{ + //Record and set rasterizer and sampler states. + + NumSavedStates=0; + + RecordAndSetState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR ); + RecordAndSetState(0, D3DSAMP_BORDERCOLOR, 0x000000 ); + RecordAndSetState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER ); + RecordAndSetState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER ); + RecordAndSetState(0, D3DSAMP_SRGBTEXTURE, (DistortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); + + RecordAndSetState(1, D3DRS_MULTISAMPLEANTIALIAS, FALSE ); + RecordAndSetState(1, D3DRS_DITHERENABLE, FALSE ); + RecordAndSetState(1, D3DRS_ZENABLE, FALSE ); + RecordAndSetState(1, D3DRS_ZWRITEENABLE, TRUE ); + RecordAndSetState(1, D3DRS_ZFUNC, D3DCMP_LESSEQUAL ); + RecordAndSetState(1, D3DRS_CULLMODE , D3DCULL_CCW ); + RecordAndSetState(1, D3DRS_ALPHABLENDENABLE , FALSE ); + RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); + RecordAndSetState(1, D3DRS_SRCBLEND , D3DBLEND_SRCALPHA ); + RecordAndSetState(1, D3DRS_DESTBLEND , D3DBLEND_INVSRCALPHA ); + RecordAndSetState(1, D3DRS_FILLMODE, D3DFILL_SOLID ); + RecordAndSetState(1, D3DRS_ALPHATESTENABLE, FALSE); + RecordAndSetState(1, D3DRS_DEPTHBIAS , 0 ); + RecordAndSetState(1, D3DRS_LIGHTING, FALSE ); + RecordAndSetState(1, D3DRS_FOGENABLE, FALSE ); + RecordAndSetState(1, D3DRS_SRGBWRITEENABLE, (DistortionCaps & ovrDistortionCap_SRGB) ? TRUE : FALSE ); +} + + +void DistortionRenderer::GraphicsState::Restore() +{ + for (int i = 0; i < NumSavedStates; i++) + { + SavedStateType * sst = &SavedState[i]; + if (sst->which == 0) + { + Device->SetSamplerState(0, (D3DSAMPLERSTATETYPE)sst->type, sst->valueToRevertTo); + } + else + { + Device->SetRenderState((D3DRENDERSTATETYPE)sst->type, sst->valueToRevertTo); + } + } +} + + +}}} // OVR::CAPI::D3D11 + +OVR_RESTORE_MSVC_WARNING() diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h index 55c7d29..b289c34 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_DistortionRenderer.h @@ -1,142 +1,137 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_DistortionRenderer.h -Content : Experimental distortion renderer -Created : March 7, 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "../../Kernel/OVR_Types.h" - -#if defined (OVR_OS_WIN32) -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#if defined(OVR_DEFINE_NEW) -#define new OVR_DEFINE_NEW -#endif - -#include "../CAPI_DistortionRenderer.h" - - -namespace OVR { namespace CAPI { namespace D3D9 { - - -//Implementation of DistortionRenderer for D3D9. -/***************************************************/ -class DistortionRenderer : public CAPI::DistortionRenderer -{ -public: - DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, const HMDRenderState& renderState); - ~DistortionRenderer(); - - // Creation function for the device. - static CAPI::DistortionRenderer* Create(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState); - - // ***** Public DistortionRenderer interface - virtual bool Initialize(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; - - virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture); - - virtual void EndFrame(bool swapBuffers); - - // TBD: Make public? - void WaitUntilGpuIdle(); - - // Similar to ovr_WaitTillTime but it also flushes GPU. - // Note, it exits when time expires, even if GPU is not in idle state yet. - double FlushGpuAndWaitTillTime(double absTime); - -protected: - - class GraphicsState : public CAPI::DistortionRenderer::GraphicsState - { - public: - GraphicsState(IDirect3DDevice9* d, unsigned distortionCaps); - virtual void Save(); - virtual void Restore(); - - protected: - void RecordAndSetState(int which, int type, DWORD newValue); - - //Structure to store our state changes - static const int MAX_SAVED_STATES=100; - struct SavedStateType - { - int which; //0 for samplerstate, 1 for renderstate - int type; - DWORD valueToRevertTo; - } SavedState[MAX_SAVED_STATES]; - - //Keep track of how many we've done, for reverting - int NumSavedStates; - IDirect3DDevice9* Device; - unsigned DistortionCaps; - }; - -private: - - //Functions - void CreateDistortionShaders(void); - void CreateDistortionModels(void); - void CreateVertexDeclaration(void); - void RenderBothDistortionMeshes(); - void RecordAndSetState(int which, int type, DWORD newValue); - void RevertAllStates(void); - - void renderEndFrame(); - - // Latency tester - void InitLatencyTester(const HMDRenderState& renderState); - void renderLatencyQuad(unsigned char* latencyTesterDrawColor); - void renderLatencyPixel(unsigned char* latencyTesterPixelColor); - - //Data, structures and pointers - IDirect3DDevice9 * Device; - IDirect3DSwapChain9 * SwapChain; - IDirect3DVertexDeclaration9 * VertexDecl; - IDirect3DPixelShader9 * PixelShader; - IDirect3DVertexShader9 * VertexShader; - IDirect3DVertexShader9 * VertexShaderTimewarp; - ovrSizei ScreenSize; - - // Latency tester - Size ResolutionInPixels; - - struct FOR_EACH_EYE - { - FOR_EACH_EYE() : dxVerts(NULL), dxIndices(NULL), numVerts(0), numIndices(0), texture(NULL), /*UVScaleOffset[],*/ TextureSize(0, 0), RenderViewport(0, 0, 0, 0) { } - - IDirect3DVertexBuffer9 * dxVerts; - IDirect3DIndexBuffer9 * dxIndices; - int numVerts; - int numIndices; - IDirect3DTexture9 * texture; - ovrVector2f UVScaleOffset[2]; - Sizei TextureSize; - Recti RenderViewport; - } eachEye[2]; -}; - -}}} // OVR::CAPI::D3D9 +/************************************************************************************ + +Filename : CAPI_D3D11_DistortionRenderer.h +Content : Experimental distortion renderer +Created : March 7, 2014 +Authors : Tom Heath + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Kernel/OVR_Types.h" +#include "Util/Util_Direct3D.h" + +#if defined(OVR_DEFINE_NEW) +#define new OVR_DEFINE_NEW +#endif + +#include "../CAPI_DistortionRenderer.h" + + +namespace OVR { namespace CAPI { namespace D3D9 { + + +//Implementation of DistortionRenderer for D3D9. +/***************************************************/ +class DistortionRenderer : public CAPI::DistortionRenderer +{ +public: + DistortionRenderer(); + ~DistortionRenderer(); + + // Creation function for the device. + static CAPI::DistortionRenderer* Create(); + + // ***** Public DistortionRenderer interface + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture) OVR_OVERRIDE; + virtual void SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) OVR_OVERRIDE; + + virtual void EndFrame(uint32_t frameIndex, bool swapBuffers); + + // TBD: Make public? + void WaitUntilGpuIdle(); + + // Similar to ovr_WaitTillTime but it also flushes GPU. + // Note, it exits when time expires, even if GPU is not in idle state yet. + double FlushGpuAndWaitTillTime(double absTime); + +protected: + virtual bool initializeRenderer(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; + + class GraphicsState : public CAPI::DistortionRenderer::GraphicsState + { + public: + GraphicsState(IDirect3DDevice9* d, unsigned distortionCaps); + virtual void Save(); + virtual void Restore(); + + protected: + void RecordAndSetState(int which, int type, DWORD newValue); + + //Structure to store our state changes + static const int MAX_SAVED_STATES=100; + struct SavedStateType + { + int which; //0 for samplerstate, 1 for renderstate + int type; + DWORD valueToRevertTo; + } SavedState[MAX_SAVED_STATES]; + + //Keep track of how many we've done, for reverting + int NumSavedStates; + IDirect3DDevice9* Device; + unsigned DistortionCaps; + }; + +private: + + //Functions + void CreateDistortionShaders(); + bool CreateDistortionModels(); + void CreateVertexDeclaration(); + void RenderBothDistortionMeshes(); + void RecordAndSetState(int which, int type, DWORD newValue); + void RevertAllStates(); + + void renderEndFrame(); + + // Latency tester + void initLatencyTester(); + void renderLatencyQuad(unsigned char* latencyTesterDrawColor); + void renderLatencyPixel(unsigned char* latencyTesterPixelColor); + + //Data, structures and pointers + IDirect3DDevice9 * Device; + IDirect3DSwapChain9 * SwapChain; + IDirect3DVertexDeclaration9 * VertexDecl; + IDirect3DPixelShader9 * PixelShader; + IDirect3DVertexShader9 * VertexShader; + IDirect3DVertexShader9 * VertexShaderTimewarp; + ovrSizei ScreenSize; + + // Latency tester + Size ResolutionInPixels; + + struct FOR_EACH_EYE + { + FOR_EACH_EYE() : dxVerts(NULL), dxIndices(NULL), numVerts(0), numIndices(0), texture(NULL), /*UVScaleOffset[],*/ TextureSize(0, 0), RenderViewport(0, 0, 0, 0) { } + + IDirect3DVertexBuffer9 * dxVerts; + IDirect3DIndexBuffer9 * dxIndices; + int numVerts; + int numIndices; + IDirect3DTexture9 * texture; + ovrVector2f UVScaleOffset[2]; + Sizei TextureSize; + Recti RenderViewport; + } eachEye[2]; +}; + + +}}} // namespace OVR::CAPI::D3D9 diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp index 2be55c1..3795485 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.cpp @@ -1,430 +1,425 @@ -/************************************************************************************ - -Filename : CAPI_D3D9_HSWDisplay.cpp -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#define OVR_D3D_VERSION 9 -#include "CAPI_D3D9_HSWDisplay.h" -#include "../../OVR_CAPI_D3D.h" -#undef OVR_D3D_VERSION - -#include -#include "../../Kernel/OVR_File.h" -#include "../../Kernel/OVR_SysFile.h" -#include "../../Kernel/OVR_Math.h" -#include "../../Kernel/OVR_Allocator.h" -#include "../../Kernel/OVR_Color.h" - - -namespace OVR { namespace CAPI { - - -// To do Need to move LoadTextureTgaData to a shared location. -uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height); - - -namespace D3D9 { - -// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. -IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, OVR::File* f, uint8_t alpha) -{ - IDirect3DTexture9* pTexture = NULL; - - int width, height; - const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); - - if (pRGBA) - { - // We don't have access to D3DX9 and so we currently have to do this manually instead of calling a D3DX9 utility function. - Ptr pTextureSysmem; - HRESULT hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTextureSysmem.GetRawRef(), NULL); - - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_SYSTEMMEM) failed. %d (%x)", hResult, hResult)); } - else - { - // Lock the texture so we can write this frame's texel data - D3DLOCKED_RECT lock; - hResult = pTextureSysmem->LockRect(0, &lock, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_NO_DIRTY_UPDATE); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("LockRect failed. %d (%x)", hResult, hResult)); } - else - { - // Four bytes per pixel. Pitch bytes per row (will be >= w * 4). - uint8_t* pRow = (uint8_t*)lock.pBits; - const uint8_t* pSource = pRGBA; - - for(int y = 0; y < height; y++, pRow += lock.Pitch, pSource += (width * 4)) - { - uint8_t* pDest = pRow; - - for(int x = 0, xEnd = width * 4; x < xEnd; x += 4) - { - pDest[x + 0] = pSource[x + 2]; - pDest[x + 1] = pSource[x + 1]; - pDest[x + 2] = pSource[x + 0]; - pDest[x + 3] = pSource[x + 3]; - } - } - - pTextureSysmem->UnlockRect(0); - - hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_DEFAULT) failed. %d (%x)", hResult, hResult)); } - else - { - hResult = rParams.Device->UpdateTexture(pTextureSysmem, pTexture); - if(FAILED(hResult)) - { - HSWDISPLAY_LOG(("UpdateTexture failed. %d (%x)", hResult, hResult)); - pTexture->Release(); - pTexture = NULL; - } - } - } - } - - OVR_FREE(const_cast(pRGBA)); - } - - return pTexture; -} - - -// Loads a texture from a memory image of a TGA file. -IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const uint8_t* pData, int dataSize, uint8_t alpha) -{ - MemoryFile memoryFile("", pData, dataSize); - - return LoadTextureTga(rParams, &memoryFile, alpha); -} - - -// Loads a texture from a disk TGA file. -IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const char* pFilePath, uint8_t alpha) -{ - SysFile sysFile; - - if(sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) - return LoadTextureTga(rParams, &sysFile, alpha); - - return NULL; -} - - - -// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h -struct HASWVertex -{ - Vector3f Pos; - Color C; - float U, V; - - HASWVertex(const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) - : Pos(p), C(c), U(u), V(v) - {} - - HASWVertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) - : Pos(x,y,z), C(c), U(u), V(v) - {} - - bool operator==(const HASWVertex& b) const - { - return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V); - } -}; - -#define HASWVertexD3D9Format (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) - - -// The texture below may conceivably be shared between HSWDisplay instances. However, -// beware that sharing may not be possible if two HMDs are using different locales -// simultaneously. As of this writing it's not clear if that can occur in practice. - -HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) - : OVR::CAPI::HSWDisplay(api, hmd, renderState) - , RenderParams() -{ -} - -bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) -{ - const ovrD3D9Config* config = reinterpret_cast(apiConfig); - - if(config) - { - RenderParams.Device = config->D3D9.pDevice; - RenderParams.SwapChain = config->D3D9.pSwapChain; - RenderParams.ScreenSize = config->D3D9.Header.BackBufferSize; - } - else - { - UnloadGraphics(); - } - - return true; -} - -void HSWDisplay::Shutdown() -{ - UnloadGraphics(); -} - -void HSWDisplay::DisplayInternal() -{ - HSWDISPLAY_LOG(("[HSWDisplay D3D9] DisplayInternal()")); - // We may want to call LoadGraphics here instead of within Render. -} - -void HSWDisplay::DismissInternal() -{ - HSWDISPLAY_LOG(("[HSWDisplay D3D9] DismissInternal()")); - UnloadGraphics(); -} - - -void HSWDisplay::UnloadGraphics() -{ - // RenderParams: No need to clear. - pTexture.Clear(); - pVB.Clear(); - // OrthoProjection: No need to clear. -} - - -void HSWDisplay::LoadGraphics() -{ - // As of this writing, we don't yet have an abstraction for Textures, Buffers, and Shaders like we do for D3D11, D3D11, and OpenGL. - #if defined(OVR_BUILD_DEBUG) - if(!pTexture) - pTexture = *LoadTextureTga(RenderParams, "C:\\TestPath\\TestFile.tga", 255); - #endif - - if(!pTexture) - { - D3DCAPS9 caps; - RenderParams.Device->GetDeviceCaps(&caps); - - if(caps.TextureCaps & (D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_POW2)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Square textures allowed only.")); } - - size_t textureSize; - const uint8_t* TextureData = GetDefaultTexture(textureSize); - pTexture = *LoadTextureTga(RenderParams, TextureData, (int)textureSize, 255); - OVR_ASSERT(pTexture); - } - - if(!pVB) - { - HRESULT hResult = RenderParams.Device->CreateVertexBuffer(4 * sizeof(HASWVertex), NULL, HASWVertexD3D9Format, D3DPOOL_MANAGED, &pVB.GetRawRef(), NULL); - - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] CreateVertexBuffer failed. %d (%x)", hResult, hResult)); } - else - { - void* pVerticesVoid; - hResult = pVB->Lock(0, 0, (void**)&pVerticesVoid, 0); - - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Lock failed. %d (%x)", hResult, hResult)); } - else - { - HASWVertex* pVertices = reinterpret_cast(pVerticesVoid); - - const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0); - const float left = -1.0f; - const float top = -1.1f; - const float right = +1.0f; - const float bottom = +0.9f; - - pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); // To do: Make this branchless - pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); - pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); - pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f); - - pVB->Unlock(); - } - } - } -} - - -void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) -{ - if(RenderEnabled && eyeTexture) - { - // Note: The D3D9 implementation below is entirely fixed-function and isn't yet using shaders. - // For the time being this is sufficient, but future designs will likely necessitate moving - // to a system that uses programmable shaders. - - // We need to render to the eyeTexture with the texture viewport. - // Setup rendering to the texture. - ovrD3D9Texture* eyeTextureD3D9 = const_cast(reinterpret_cast(eyeTexture)); - OVR_ASSERT(eyeTextureD3D9->Texture.Header.API == ovrRenderAPI_D3D9); - - - // Save previous state. - // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location. - DWORD fvfSaved; - RenderParams.Device->GetFVF(&fvfSaved); - - Ptr pVBDSaved; - UINT vbOffsetSaved; - UINT vbStrideSaved; - RenderParams.Device->GetStreamSource(0, &pVBDSaved.GetRawRef(), &vbOffsetSaved, &vbStrideSaved); - - Ptr pTexture0Saved; - RenderParams.Device->GetTexture(0, &pTexture0Saved.GetRawRef()); - Ptr pTexture1Saved; - RenderParams.Device->GetTexture(1, &pTexture1Saved.GetRawRef()); - - D3DMATRIX worldMatrixSaved, viewMatrixSaved, projectionMatrixSaved, texture0MatrixSaved; - RenderParams.Device->GetTransform(D3DTS_WORLD, &worldMatrixSaved); - RenderParams.Device->GetTransform(D3DTS_VIEW, &viewMatrixSaved); - RenderParams.Device->GetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); - RenderParams.Device->GetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); - - Ptr pVertexShaderSaved; - RenderParams.Device->GetVertexShader(&pVertexShaderSaved.GetRawRef()); - - Ptr pPixelShaderSaved; - RenderParams.Device->GetPixelShader(&pPixelShaderSaved.GetRawRef()); - - D3DVIEWPORT9 viewportSaved; - RenderParams.Device->GetViewport(&viewportSaved); - - Ptr pRenderTargetSaved; - RenderParams.Device->GetRenderTarget(0, &pRenderTargetSaved.GetRawRef()); - - - // Load the graphics if not loaded already. - if(!pTexture) - LoadGraphics(); - - // Calculate ortho projection. - GetOrthoProjection(RenderState, OrthoProjection); - - HRESULT hResult = RenderParams.Device->BeginScene(); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] BeginScene failed. %d (%x)", hResult, hResult)); } - - Ptr pDestSurface; - hResult = eyeTextureD3D9->D3D9.pTexture->GetSurfaceLevel(0, &pDestSurface.GetRawRef()); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] GetSurfaceLevel failed. %d (%x)", hResult, hResult)); } - - hResult = RenderParams.Device->SetRenderTarget(0, pDestSurface); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetRenderTarget failed. %d (%x)", hResult, hResult)); } - - D3DVIEWPORT9 D3DViewport; - D3DViewport.X = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.x; - D3DViewport.Y = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.y; - D3DViewport.Width = eyeTextureD3D9->Texture.Header.RenderViewport.Size.w; - D3DViewport.Height = eyeTextureD3D9->Texture.Header.RenderViewport.Size.h; - D3DViewport.MinZ = 0; - D3DViewport.MaxZ = 1; - hResult = RenderParams.Device->SetViewport(&D3DViewport); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetViewport failed. %d (%x)", hResult, hResult)); } - - hResult = RenderParams.Device->SetTexture(0, pTexture); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetTexture failed. %d (%x)", hResult, hResult)); } - - RenderParams.Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - - RenderParams.Device->SetVertexShader(NULL); - RenderParams.Device->SetPixelShader(NULL); - - hResult = RenderParams.Device->SetStreamSource(0, pVB, 0, sizeof(HASWVertex)); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetStreamSource failed. %d (%x)", hResult, hResult)); } - - RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - RenderParams.Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - RenderParams.Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - RenderParams.Device->SetRenderState(D3DRS_LIGHTING, FALSE); - RenderParams.Device->SetRenderState(D3DRS_ZENABLE, FALSE); - RenderParams.Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - RenderParams.Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - RenderParams.Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); - RenderParams.Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); - - const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f); - Matrix4f identityMatrix = Matrix4f::Identity(); - Vector3f translation = OrthoProjection[eye].GetTranslation(); - Matrix4f orthoStereoMatrix( - scale, 0, 0, 0, - 0, scale / 2, 0, 0, - 0, 0, HSWDISPLAY_DISTANCE, 0, - translation.x, translation.y, translation.z, 1 - ); - RenderParams.Device->SetTransform(D3DTS_WORLD, reinterpret_cast(&identityMatrix)); - RenderParams.Device->SetTransform(D3DTS_VIEW, reinterpret_cast(&identityMatrix)); - RenderParams.Device->SetTransform(D3DTS_PROJECTION, reinterpret_cast(&orthoStereoMatrix)); - RenderParams.Device->SetTransform(D3DTS_TEXTURE0, reinterpret_cast(&identityMatrix)); - - hResult = RenderParams.Device->SetFVF(HASWVertexD3D9Format); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetFVF failed. %d (%x)", hResult, hResult)); } - - hResult = RenderParams.Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] DrawPrimitive failed. %d (%x)", hResult, hResult)); } - - hResult = RenderParams.Device->EndScene(); - if(FAILED(hResult)) - { HSWDISPLAY_LOG(("[HSWDisplay D3D9] EndScene failed. %d (%x)", hResult, hResult)); } - - - // Restore previous state. - RenderParams.Device->SetRenderTarget(0, pRenderTargetSaved); - RenderParams.Device->SetViewport(&viewportSaved); - RenderParams.Device->SetPixelShader(pPixelShaderSaved); - RenderParams.Device->SetVertexShader(pVertexShaderSaved); - RenderParams.Device->SetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); - RenderParams.Device->SetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); - RenderParams.Device->SetTransform(D3DTS_VIEW, &viewMatrixSaved); - RenderParams.Device->SetTransform(D3DTS_WORLD, &worldMatrixSaved); - RenderParams.Device->SetTexture(0, pTexture0Saved); - RenderParams.Device->SetTexture(1, pTexture1Saved); - RenderParams.Device->SetStreamSource(0, pVBDSaved, vbOffsetSaved, vbStrideSaved); - RenderParams.Device->SetFVF(fvfSaved); - } -} - - -}}} // namespace OVR::CAPI::D3D9 - - - - - - - +/************************************************************************************ + +Filename : CAPI_D3D9_HSWDisplay.cpp +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_D3D9_HSWDisplay.h" +#include "OVR_CAPI_D3D.h" +#include "Util/Util_Direct3D.h" +#include "Kernel/OVR_File.h" +#include "Kernel/OVR_SysFile.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Color.h" +#include "Extras/OVR_Math.h" + + +OVR_DISABLE_MSVC_WARNING(4996) // Disable deprecation warning + +namespace OVR { namespace CAPI { + + +// To do Need to move LoadTextureTgaData to a shared location. +uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height); + + +namespace D3D9 { + +// This is a temporary function implementation, and it functionality needs to be implemented in a more generic way. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, OVR::File* f, uint8_t alpha) +{ + IDirect3DTexture9* pTexture = NULL; + + int width, height; + const uint8_t* pRGBA = LoadTextureTgaData(f, alpha, width, height); + + if (pRGBA) + { + // We don't have access to D3DX9 and so we currently have to do this manually instead of calling a D3DX9 utility function. + Ptr pTextureSysmem; + HRESULT hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTextureSysmem.GetRawRef(), NULL); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_SYSTEMMEM) failed. %d (%x)", hResult, hResult)); } + else + { + // Lock the texture so we can write this frame's texel data + D3DLOCKED_RECT lock; + hResult = pTextureSysmem->LockRect(0, &lock, NULL, D3DLOCK_NOSYSLOCK | D3DLOCK_NO_DIRTY_UPDATE); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("LockRect failed. %d (%x)", hResult, hResult)); } + else + { + // Four bytes per pixel. Pitch bytes per row (will be >= w * 4). + uint8_t* pRow = (uint8_t*)lock.pBits; + const uint8_t* pSource = pRGBA; + + for(int y = 0; y < height; y++, pRow += lock.Pitch, pSource += (width * 4)) + { + uint8_t* pDest = pRow; + + for(int x = 0, xEnd = width * 4; x < xEnd; x += 4) + { + pDest[x + 0] = pSource[x + 2]; + pDest[x + 1] = pSource[x + 1]; + pDest[x + 2] = pSource[x + 0]; + pDest[x + 3] = pSource[x + 3]; + } + } + + pTextureSysmem->UnlockRect(0); + + hResult = rParams.Device->CreateTexture((UINT)width, (UINT)height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pTexture, NULL); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("CreateTexture(D3DPOOL_DEFAULT) failed. %d (%x)", hResult, hResult)); } + else + { + hResult = rParams.Device->UpdateTexture(pTextureSysmem, pTexture); + if(FAILED(hResult)) + { + HSWDISPLAY_LOG(("UpdateTexture failed. %d (%x)", hResult, hResult)); + pTexture->Release(); + pTexture = NULL; + } + } + } + } + + OVR_FREE(const_cast(pRGBA)); + } + + return pTexture; +} + + +// Loads a texture from a memory image of a TGA file. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const uint8_t* pData, int dataSize, uint8_t alpha) +{ + MemoryFile memoryFile("", pData, dataSize); + + return LoadTextureTga(rParams, &memoryFile, alpha); +} + + +// Loads a texture from a disk TGA file. +IDirect3DTexture9* LoadTextureTga(HSWRenderParams& rParams, const char* pFilePath, uint8_t alpha) +{ + SysFile sysFile; + + if(sysFile.Open(pFilePath, FileConstants::Open_Read | FileConstants::Open_Buffered)) + return LoadTextureTga(rParams, &sysFile, alpha); + + return NULL; +} + + + +// To do: This needs to be promoted to a central version, possibly in CAPI_HSWDisplay.h +struct HASWVertex +{ + Vector3f Pos; + Color C; + float U, V; + + HASWVertex(const Vector3f& p, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) + : Pos(p), C(c), U(u), V(v) + {} + + HASWVertex(float x, float y, float z, const Color& c = Color(64,0,0,255), float u = 0, float v = 0) + : Pos(x,y,z), C(c), U(u), V(v) + {} + + bool operator==(const HASWVertex& b) const + { + return (Pos == b.Pos) && (C == b.C) && (U == b.U) && (V == b.V); + } +}; + +#define HASWVertexD3D9Format (D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1) + + +// The texture below may conceivably be shared between HSWDisplay instances. However, +// beware that sharing may not be possible if two HMDs are using different locales +// simultaneously. As of this writing it's not clear if that can occur in practice. + +HSWDisplay::HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState) + : OVR::CAPI::HSWDisplay(api, hmd, renderState) + , RenderParams() +{ +} + +bool HSWDisplay::Initialize(const ovrRenderAPIConfig* apiConfig) +{ + const ovrD3D9Config* config = reinterpret_cast(apiConfig); + + if(config) + { + RenderParams.Device = config->D3D9.pDevice; + RenderParams.SwapChain = config->D3D9.pSwapChain; + RenderParams.ScreenSize = config->D3D9.Header.BackBufferSize; + } + else + { + UnloadGraphics(); + } + + return true; +} + +void HSWDisplay::Shutdown() +{ + UnloadGraphics(); +} + +void HSWDisplay::DisplayInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D9] DisplayInternal()")); + // We may want to call LoadGraphics here instead of within Render. +} + +void HSWDisplay::DismissInternal() +{ + HSWDISPLAY_LOG(("[HSWDisplay D3D9] DismissInternal()")); + UnloadGraphics(); +} + + +void HSWDisplay::UnloadGraphics() +{ + // RenderParams: No need to clear. + pTexture.Clear(); + pVB.Clear(); + // OrthoProjection: No need to clear. +} + + +void HSWDisplay::LoadGraphics() +{ + // As of this writing, we don't yet have an abstraction for Textures, Buffers, and Shaders like we do for D3D11, D3D11, and OpenGL. + #if defined(OVR_BUILD_DEBUG) + if(!pTexture) + pTexture = *LoadTextureTga(RenderParams, "C:\\TestPath\\TestFile.tga", 255); + #endif + + if(!pTexture) + { + D3DCAPS9 caps; + RenderParams.Device->GetDeviceCaps(&caps); + + if(caps.TextureCaps & (D3DPTEXTURECAPS_SQUAREONLY | D3DPTEXTURECAPS_POW2)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Square textures allowed only.")); } + + size_t textureSize; + const uint8_t* TextureData = GetDefaultTexture(textureSize); + pTexture = *LoadTextureTga(RenderParams, TextureData, (int)textureSize, 255); + OVR_ASSERT(pTexture); + } + + if(!pVB) + { + HRESULT hResult = RenderParams.Device->CreateVertexBuffer(4 * sizeof(HASWVertex), NULL, HASWVertexD3D9Format, D3DPOOL_MANAGED, &pVB.GetRawRef(), NULL); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] CreateVertexBuffer failed. %d (%x)", hResult, hResult)); } + else + { + void* pVerticesVoid; + hResult = pVB->Lock(0, 0, (void**)&pVerticesVoid, 0); + + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] Lock failed. %d (%x)", hResult, hResult)); } + else + { + HASWVertex* pVertices = reinterpret_cast(pVerticesVoid); + + const bool flip = ((RenderState.DistortionCaps & ovrDistortionCap_FlipInput) != 0); + const float left = -1.0f; + const float top = -1.1f; + const float right = +1.0f; + const float bottom = +0.9f; + + // See warning in LoadTextureTgaData() about this TGA being loaded "upside down", i.e. UV origin is at bottom-left. + pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); // To do: Make this branchless + pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); + pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); + pVertices[3] = HASWVertex(right, bottom, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 0.f : 1.f); + + pVB->Unlock(); + } + } + } +} + + +void HSWDisplay::RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture) +{ + if(RenderEnabled && eyeTexture) + { + // Note: The D3D9 implementation below is entirely fixed-function and isn't yet using shaders. + // For the time being this is sufficient, but future designs will likely necessitate moving + // to a system that uses programmable shaders. + + // We need to render to the eyeTexture with the texture viewport. + // Setup rendering to the texture. + ovrD3D9Texture* eyeTextureD3D9 = const_cast(reinterpret_cast(eyeTexture)); + OVR_ASSERT(eyeTextureD3D9->Texture.Header.API == ovrRenderAPI_D3D9); + + + // Save previous state. + // To do: Merge this saved state with that done by DistortionRenderer::GraphicsState::Save(), and put them in a shared location. + DWORD fvfSaved; + RenderParams.Device->GetFVF(&fvfSaved); + + Ptr pVBDSaved; + UINT vbOffsetSaved; + UINT vbStrideSaved; + RenderParams.Device->GetStreamSource(0, &pVBDSaved.GetRawRef(), &vbOffsetSaved, &vbStrideSaved); + + Ptr pTexture0Saved; + RenderParams.Device->GetTexture(0, &pTexture0Saved.GetRawRef()); + Ptr pTexture1Saved; + RenderParams.Device->GetTexture(1, &pTexture1Saved.GetRawRef()); + + D3DMATRIX worldMatrixSaved, viewMatrixSaved, projectionMatrixSaved, texture0MatrixSaved; + RenderParams.Device->GetTransform(D3DTS_WORLD, &worldMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_VIEW, &viewMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); + RenderParams.Device->GetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); + + Ptr pVertexShaderSaved; + RenderParams.Device->GetVertexShader(&pVertexShaderSaved.GetRawRef()); + + Ptr pPixelShaderSaved; + RenderParams.Device->GetPixelShader(&pPixelShaderSaved.GetRawRef()); + + D3DVIEWPORT9 viewportSaved; + RenderParams.Device->GetViewport(&viewportSaved); + + Ptr pRenderTargetSaved; + RenderParams.Device->GetRenderTarget(0, &pRenderTargetSaved.GetRawRef()); + + + // Load the graphics if not loaded already. + if(!pTexture) + LoadGraphics(); + + // Calculate ortho projection. + GetOrthoProjection(RenderState, OrthoProjection); + + HRESULT hResult = RenderParams.Device->BeginScene(); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] BeginScene failed. %d (%x)", hResult, hResult)); } + + Ptr pDestSurface; + hResult = eyeTextureD3D9->D3D9.pTexture->GetSurfaceLevel(0, &pDestSurface.GetRawRef()); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] GetSurfaceLevel failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->SetRenderTarget(0, pDestSurface); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetRenderTarget failed. %d (%x)", hResult, hResult)); } + + D3DVIEWPORT9 D3DViewport; + D3DViewport.X = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.x; + D3DViewport.Y = eyeTextureD3D9->Texture.Header.RenderViewport.Pos.y; + D3DViewport.Width = eyeTextureD3D9->Texture.Header.RenderViewport.Size.w; + D3DViewport.Height = eyeTextureD3D9->Texture.Header.RenderViewport.Size.h; + D3DViewport.MinZ = 0; + D3DViewport.MaxZ = 1; + hResult = RenderParams.Device->SetViewport(&D3DViewport); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetViewport failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->SetTexture(0, pTexture); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetTexture failed. %d (%x)", hResult, hResult)); } + + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + RenderParams.Device->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); + + RenderParams.Device->SetVertexShader(NULL); + RenderParams.Device->SetPixelShader(NULL); + + hResult = RenderParams.Device->SetStreamSource(0, pVB, 0, sizeof(HASWVertex)); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetStreamSource failed. %d (%x)", hResult, hResult)); } + + RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + RenderParams.Device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + RenderParams.Device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + RenderParams.Device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + RenderParams.Device->SetRenderState(D3DRS_LIGHTING, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ZENABLE, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + RenderParams.Device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + RenderParams.Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); + RenderParams.Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); + + const float scale = HSWDISPLAY_SCALE * ((RenderState.OurHMDInfo.HmdType == HmdType_DK1) ? 0.70f : 1.f); + Matrix4f identityMatrix = Matrix4f::Identity(); + Vector3f translation = OrthoProjection[eye].GetTranslation(); + Matrix4f orthoStereoMatrix( + scale, 0, 0, 0, + 0, scale / 2, 0, 0, + 0, 0, HSWDISPLAY_DISTANCE, 0, + translation.x, translation.y, translation.z, 1 + ); + RenderParams.Device->SetTransform(D3DTS_WORLD, reinterpret_cast(&identityMatrix)); + RenderParams.Device->SetTransform(D3DTS_VIEW, reinterpret_cast(&identityMatrix)); + RenderParams.Device->SetTransform(D3DTS_PROJECTION, reinterpret_cast(&orthoStereoMatrix)); + RenderParams.Device->SetTransform(D3DTS_TEXTURE0, reinterpret_cast(&identityMatrix)); + + hResult = RenderParams.Device->SetFVF(HASWVertexD3D9Format); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] SetFVF failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] DrawPrimitive failed. %d (%x)", hResult, hResult)); } + + hResult = RenderParams.Device->EndScene(); + if(FAILED(hResult)) + { HSWDISPLAY_LOG(("[HSWDisplay D3D9] EndScene failed. %d (%x)", hResult, hResult)); } + + + // Restore previous state. + RenderParams.Device->SetRenderTarget(0, pRenderTargetSaved); + RenderParams.Device->SetViewport(&viewportSaved); + RenderParams.Device->SetPixelShader(pPixelShaderSaved); + RenderParams.Device->SetVertexShader(pVertexShaderSaved); + RenderParams.Device->SetTransform(D3DTS_TEXTURE0, &texture0MatrixSaved); + RenderParams.Device->SetTransform(D3DTS_PROJECTION, &projectionMatrixSaved); + RenderParams.Device->SetTransform(D3DTS_VIEW, &viewMatrixSaved); + RenderParams.Device->SetTransform(D3DTS_WORLD, &worldMatrixSaved); + RenderParams.Device->SetTexture(0, pTexture0Saved); + RenderParams.Device->SetTexture(1, pTexture1Saved); + RenderParams.Device->SetStreamSource(0, pVBDSaved, vbOffsetSaved, vbStrideSaved); + RenderParams.Device->SetFVF(fvfSaved); + } +} + + +}}} // namespace OVR::CAPI::D3D9 + +OVR_RESTORE_MSVC_WARNING() diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h index b1d7191..9ad682a 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_HSWDisplay.h @@ -1,82 +1,76 @@ -/************************************************************************************ - -Filename : CAPI_D3D9_HSWDisplay.h -Content : Implements Health and Safety Warning system. -Created : July 7, 2014 -Authors : Paul Pedriana - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_CAPI_D3D9_HSWDisplay_h -#define OVR_CAPI_D3D9_HSWDisplay_h - -#if !defined(OVR_D3D_VERSION) || (OVR_D3D_VERSION != 9) - #error This header expects OVR_D3D_VERSION to be defined, to 9. -#endif - -#include "../CAPI_HSWDisplay.h" -#include "../D3D1X/CAPI_D3D1X_Util.h" -#include - - -namespace OVR { namespace CAPI { namespace D3D9 { - - // There currently isn't a D3D9::RenderParams, as D3D9 support is currently only very basic. - struct HSWRenderParams - { - IDirect3DDevice9* Device; - IDirect3DSwapChain9* SwapChain; - ovrSizei ScreenSize; - }; - - class HSWDisplay : public CAPI::HSWDisplay - { - public: - HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); - - // Must be called before use. apiConfig is such that: - // const ovrD3D9Config* config = (const ovrD3D9Config*)apiConfig; or - bool Initialize(const ovrRenderAPIConfig* apiConfig); - void Shutdown(); - void DisplayInternal(); - void DismissInternal(); - - // Draws the warning to the eye texture(s). This must be done at the end of a - // frame but prior to executing the distortion rendering of the eye textures. - void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture); - - protected: - void LoadGraphics(); - void UnloadGraphics(); - - D3D9::HSWRenderParams RenderParams; - Ptr pTexture; - Ptr pVB; - Matrix4f OrthoProjection[2]; // Projection for 2D. - - private: - OVR_NON_COPYABLE(HSWDisplay) - }; - -}}} // namespace OVR::CAPI::D3D9 - - -#endif // OVR_CAPI_D3D9_HSWDisplay_h - +/************************************************************************************ + +Filename : CAPI_D3D9_HSWDisplay.h +Content : Implements Health and Safety Warning system. +Created : July 7, 2014 +Authors : Paul Pedriana + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CAPI_D3D9_HSWDisplay_h +#define OVR_CAPI_D3D9_HSWDisplay_h + +#include "../CAPI_HSWDisplay.h" +#include "Util/Util_Direct3D.h" + +namespace OVR { namespace CAPI { namespace D3D9 { + + // There currently isn't a D3D9::RenderParams, as D3D9 support is currently only very basic. + struct HSWRenderParams + { + IDirect3DDevice9* Device; + IDirect3DSwapChain9* SwapChain; + ovrSizei ScreenSize; + }; + + class HSWDisplay : public CAPI::HSWDisplay + { + public: + HSWDisplay(ovrRenderAPIType api, ovrHmd hmd, const HMDRenderState& renderState); + + // Must be called before use. apiConfig is such that: + // const ovrD3D9Config* config = (const ovrD3D9Config*)apiConfig; or + bool Initialize(const ovrRenderAPIConfig* apiConfig); + void Shutdown(); + void DisplayInternal(); + void DismissInternal(); + + // Draws the warning to the eye texture(s). This must be done at the end of a + // frame but prior to executing the distortion rendering of the eye textures. + void RenderInternal(ovrEyeType eye, const ovrTexture* eyeTexture); + + protected: + void LoadGraphics(); + void UnloadGraphics(); + + D3D9::HSWRenderParams RenderParams; + Ptr pTexture; + Ptr pVB; + Matrix4f OrthoProjection[2]; // Projection for 2D. + + private: + OVR_NON_COPYABLE(HSWDisplay) + }; + +}}} // namespace OVR::CAPI::D3D9 + + +#endif // OVR_CAPI_D3D9_HSWDisplay_h + diff --git a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp index 0c6cd45..2f90539 100644 --- a/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp +++ b/LibOVR/Src/CAPI/D3D9/CAPI_D3D9_Util.cpp @@ -1,273 +1,286 @@ -/************************************************************************************ - -Filename : CAPI_D3D1X_Util.cpp -Content : D3D9 utility functions for rendering -Created : March 7 , 2014 -Authors : Tom Heath - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "CAPI_D3D9_DistortionRenderer.h" -#define OVR_D3D_VERSION 9 -#include "../../OVR_CAPI_D3D.h" - - -namespace OVR { namespace CAPI { namespace D3D9 { - - -#define PRECOMPILE_FLAG 0 -#if !PRECOMPILE_FLAG -//To make these, you need to run it with PRECOMPILE_FLAG, which also uses them, so good for debugging. -//Then cut and paste these from the output window. -//Then turn off the flag. -DWORD precompiledVertexShaderSrc[96] = {4294836736,3080190,1111577667,28,130,4294836736,2,28,33024,123,68,131074,655361,88,0,104,2,131073,88,0,1415936325,1970230127,1432707954,1717981014,7628147,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597136755,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147614720,2416902145,33554463,2147483653,2416902146,33554463,2147549189,2416902147,33554463,2147614725,2416902148,33554433,2147680256,2699296768,67108868,3758292992,2162425856,2430861314,2699296770,67108868,3758292993,2162425856,2430861315,2699296770,67108868,3758292994,2162425856,2430861316,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919105,65535,}; -DWORD precompiledVertexShaderTimewarpSrc[310] = {4294836992,4587518,1111577667,28,222,4294836992,4,28,33024,215,108,1310722,5373956,124,0,140,262146,1179652,124,0,157,131074,655361,180,0,196,2,131073,180,0,1382381893,1952543855,1164865385,2868929646,196611,262148,1,0,1382381893,1952543855,1399746409,1953653108,1702446336,1867738964,1701016181,1716475477,1952805734,2880154368,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597202291,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147549184,2416902145,33554463,2147614720,2416902146,33554463,2147483653,2416902147,33554463,2147549189,2416902148,33554463,2147614725,2416902149,33554463,2147483648,3759079424,33554463,2147483653,3758292993,33554463,2147549189,3758292994,33554463,2147614725,3758292995,33554463,2147680261,3758161924,33554433,2147549184,2695495684,50331650,2147549185,2164260864,2695495700,33554433,2147614720,2695495685,50331650,2147614721,2169831424,2695495701,33554433,2147745792,2695495686,50331650,2147745793,2175401984,2695495702,33554433,2148007936,2695495687,50331650,2148007937,2180972544,2695495703,67108868,2148466688,2415919105,2162425857,2162425856,67108868,2148466689,2416181251,2689597441,2684682241,50331657,2147549186,2162425856,2162425857,33554438,2147549186,2147483650,33554433,2147680259,2699296772,50331650,2147876866,2177892355,2697986068,67108868,2147549187,2415919105,2158624770,2689925124,67108868,2147549188,2415919105,2153054210,2684354564,33554433,2147680261,2699296773,50331650,2147876866,2177105925,2697199637,67108868,2147614723,2415919105,2153054210,2689925125,67108868,2147614724,2415919105,2158624770,2684354565,33554433,2147680261,2699296774,50331650,2147811333,2177171461,2697265174,67108868,2147745795,2415919105,2147483653,2689925126,67108868,2147745796,2415919105,2158624773,2684354566,33554433,2147680261,2699296775,50331650,2148073477,2166685701,2686779415,67108868,2148007939,2415919105,2147483653,2689925127,67108868,2148007940,2415919105,2164195333,2684354567,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331653,2147680257,2147483650,2162425861,33554433,2147680258,2699296768,67108868,3758292993,2162425858,2162425857,2699296770,67108868,2148466689,2416181252,2689597441,2684682241,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331657,2147549185,2162425856,2162425857,33554438,2147549185,2147483649,50331653,2147680257,2147483649,2162425861,67108868,3758292994,2162425858,2162425857,2699296770,67108868,2148466689,2416181253,2689597441,2684682241,50331657,2147549188,2162425860,2162425857,50331657,2147614724,2162425859,2162425857,50331657,2147549184,2162425856,2162425857,33554438,2147549184,2147483648,50331653,2147680256,2147483648,2162425860,67108868,3758292995,2162425858,2162425856,2699296770,67108868,3759079424,2416181248,2689597441,2686779393,33554433,3758161924,2415919106,65535,}; -DWORD precompiledPixelShaderSrc[84] = {4294902528,2228222,1111577667,28,79,4294902528,1,28,33024,72,48,3,131073,56,0,1954047316,6648437,786436,65537,1,0,861893488,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337600,1065353216,0,0,0,33554463,2147483653,2416115712,33554463,2147549189,2416115713,33554463,2147614725,2416115714,33554463,2147680261,2415984643,33554463,2415919104,2685339648,50331714,2148466688,2430861312,2699298816,67108868,2148073472,2147483648,2690908160,2686779392,50331714,2148466689,2430861313,2699298816,33554433,2147614720,2153054209,50331714,2148466689,2430861314,2699298816,33554433,2147745792,2158624769,50331653,2148468736,2162425856,2415919107,65535,}; - -#else -#include "d3dcompiler.h" -#pragma comment(lib, "C:\\Program Files (x86)\\Microsoft DirectX SDK (June 2010)\\Lib\\x86\\D3DCompiler.lib") -/***************************************************************************/ -const char* VertexShaderSrc = - - "float2 EyeToSourceUVScale : register(c0); \n" - "float2 EyeToSourceUVOffset : register(c2); \n" - - "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n" - " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n" - " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" - " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n" - " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n" - " out float oVignette : TEXCOORD3) \n" - "{ \n" - " oTexCoord0 = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; \n" - " oTexCoord1 = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; \n" - " oTexCoord2 = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; \n" - " oVignette = Vignette; \n" - " oPosition = float4(Position.xy, 0.5, 1.0); \n" - "}"; - -/***************************************************************************/ -const char* VertexShaderTimewarpSrc = - - "float2 EyeToSourceUVScale : register(c0); \n" - "float2 EyeToSourceUVOffset : register(c2); \n" - "float4x4 EyeRotationStart : register(c4); \n" - "float4x4 EyeRotationEnd : register(c20); \n" - - "float2 TimewarpTexCoord(float2 TexCoord, float4x4 rotMat) \n" - "{ \n" - " float3 transformed = float3( mul ( rotMat, float4(TexCoord.xy, 1, 1) ).xyz); \n" - " float2 flattened = (transformed.xy / transformed.z); \n" - " return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset); \n" - "} \n" - "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n" - " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n" - " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" - " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n" - " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n" - " out float oVignette : TEXCOORD3) \n" - "{ \n" - " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, TimeWarp); \n" - " oTexCoord0 = TimewarpTexCoord(TexCoord0,lerpedEyeRot); \n" - " oTexCoord1 = TimewarpTexCoord(TexCoord1,lerpedEyeRot); \n" - " oTexCoord2 = TimewarpTexCoord(TexCoord2,lerpedEyeRot); \n" - " oVignette = Vignette; \n" - " oPosition = float4(Position.xy, 0.5, 1.0); \n" - "}"; - -/***************************************************************************/ -const char* PixelShaderSrc = - - " sampler2D Texture : register(s0); \n" - - "float4 main(in float4 oPosition : SV_Position, in float2 oTexCoord0 : TEXCOORD0, \n" - " in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2, \n" - " in float oVignette : TEXCOORD3) \n" - " : SV_Target \n" - "{ \n" - " float R = tex2D(Texture,oTexCoord0).r; \n" - " float G = tex2D(Texture,oTexCoord1).g; \n" - " float B = tex2D(Texture,oTexCoord2).b; \n" - " return (oVignette*float4(R,G,B,1)); \n" - "}"; - -/*************************************************************/ -ID3DBlob* ShaderCompile(char * shaderName, const char * shaderSrcString, const char * profile) -{ - ID3DBlob* pShaderCode = NULL; - ID3DBlob* pErrorMsg = NULL; - - if (FAILED(D3DCompile(shaderSrcString, strlen(shaderSrcString),NULL,NULL,NULL, - "main",profile,D3DCOMPILE_OPTIMIZATION_LEVEL3,0, - &pShaderCode,&pErrorMsg))) - MessageBoxA(NULL,(char *) pErrorMsg->GetBufferPointer(),"", MB_OK); - if (pErrorMsg) pErrorMsg->Release(); - - //Now write out blob - char tempString[1000]; - int numDWORDs = ((int)pShaderCode->GetBufferSize())/4; - DWORD * ptr = (DWORD *)pShaderCode->GetBufferPointer(); - sprintf_s(tempString,"DWORD %s[%d] = {",shaderName,numDWORDs); - OutputDebugStringA(tempString); - for (int i = 0;i < numDWORDs; i++) - { - sprintf_s(tempString,"%lu,",ptr[i]); - OutputDebugStringA(tempString); - } - OutputDebugStringA("};\n"); - - return(pShaderCode); -} -#endif - -/***********************************************************/ -void DistortionRenderer::CreateDistortionShaders(void) -{ -#if PRECOMPILE_FLAG - ID3DBlob * pShaderCode; - pShaderCode = ShaderCompile("precompiledVertexShaderSrc",VertexShaderSrc,"vs_2_0"); - Device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &VertexShader ); - pShaderCode->Release(); - - pShaderCode = ShaderCompile("precompiledVertexShaderTimewarpSrc",VertexShaderTimewarpSrc,"vs_3_0"); - Device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &VertexShaderTimewarp ); - pShaderCode->Release(); - - pShaderCode = ShaderCompile("precompiledPixelShaderSrc",PixelShaderSrc,"ps_3_0"); - Device->CreatePixelShader( ( DWORD* )pShaderCode->GetBufferPointer(), &PixelShader ); - pShaderCode->Release(); -#else - Device->CreateVertexShader( precompiledVertexShaderSrc, &VertexShader ); - Device->CreateVertexShader( precompiledVertexShaderTimewarpSrc, &VertexShaderTimewarp ); - Device->CreatePixelShader( precompiledPixelShaderSrc, &PixelShader ); -#endif -} - - -/***************************************************/ -void DistortionRenderer::CreateVertexDeclaration(void) -{ - static const D3DVERTEXELEMENT9 VertexElements[7] = { - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - { 0, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 }, - { 0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 2 }, - { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, - { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, - { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, - D3DDECL_END() }; - Device->CreateVertexDeclaration( VertexElements, &VertexDecl ); -} - - -/******************************************************/ -void DistortionRenderer::CreateDistortionModels(void) -{ - //Make the distortion models - for (int eye=0;eye<2;eye++) - { - FOR_EACH_EYE * e = &eachEye[eye]; - ovrDistortionMesh meshData; - ovrHmd_CreateDistortionMesh(HMD, - RState.EyeRenderDesc[eye].Eye, - RState.EyeRenderDesc[eye].Fov, - RState.DistortionCaps, - &meshData); - - e->numVerts = meshData.VertexCount; - e->numIndices = meshData.IndexCount; - - Device->CreateVertexBuffer( (e->numVerts)*sizeof(ovrDistortionVertex),0, 0, - D3DPOOL_MANAGED, &e->dxVerts, NULL ); - ovrDistortionVertex * dxv; e->dxVerts->Lock( 0, 0, (void**)&dxv, 0 ); - for (int v=0;vnumVerts;v++) dxv[v] = meshData.pVertexData[v]; - e->dxVerts->Unlock(); - - Device->CreateIndexBuffer( (e->numIndices)*sizeof(u_short),0, D3DFMT_INDEX16, - D3DPOOL_MANAGED, &e->dxIndices, NULL ); - unsigned short* dxi; e->dxIndices->Lock( 0, 0, (void**)&dxi, 0 ); - for (int i=0;inumIndices;i++) dxi[i] = meshData.pIndexData[i]; - e->dxIndices->Unlock(); - - ovrHmd_DestroyDistortionMesh( &meshData ); - } -} - -/**********************************************************/ -void DistortionRenderer::RenderBothDistortionMeshes(void) -{ - Device->BeginScene(); - - D3DCOLOR clearColor = D3DCOLOR_RGBA( - (int)(RState.ClearColor[0] * 255.0f), - (int)(RState.ClearColor[1] * 255.0f), - (int)(RState.ClearColor[2] * 255.0f), - (int)(RState.ClearColor[3] * 255.0f)); - - Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, clearColor, 0, 0); - - for (int eye=0; eye<2; eye++) - { - FOR_EACH_EYE * e = &eachEye[eye]; - D3DVIEWPORT9 vp; - vp.X=0; vp.Y=0; - vp.Width=ScreenSize.w; vp.Height=ScreenSize.h; - vp.MinZ=0; vp.MaxZ = 1; - - Device->SetViewport(&vp); - Device->SetStreamSource( 0, e->dxVerts,0, sizeof(ovrDistortionVertex) ); - Device->SetVertexDeclaration( VertexDecl ); - Device->SetIndices( e->dxIndices ); - Device->SetPixelShader( PixelShader ); - Device->SetTexture( 0, e->texture); - - //Choose which vertex shader, with associated additional inputs - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) - { - Device->SetVertexShader( VertexShaderTimewarp ); - - ovrMatrix4f timeWarpMatrices[2]; - ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eye, - RState.EyeRenderPoses[eye], timeWarpMatrices); - - //Need to transpose the matrices - timeWarpMatrices[0] = Matrix4f(timeWarpMatrices[0]).Transposed(); - timeWarpMatrices[1] = Matrix4f(timeWarpMatrices[1]).Transposed(); - - // Feed identity like matrices in until we get proper timewarp calculation going on - Device->SetVertexShaderConstantF(4, (float *) &timeWarpMatrices[0],4); - Device->SetVertexShaderConstantF(20,(float *) &timeWarpMatrices[1],4); - } - else - { - Device->SetVertexShader( VertexShader ); - } - - //Set up vertex shader constants - Device->SetVertexShaderConstantF( 0, ( FLOAT* )&(e->UVScaleOffset[0]), 1 ); - Device->SetVertexShaderConstantF( 2, ( FLOAT* )&(e->UVScaleOffset[1]), 1 ); - - Device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,e->numVerts,0,e->numIndices/3); - } - - Device->EndScene(); -} - -}}} +/************************************************************************************ + +Filename : CAPI_D3D11_Util.cpp +Content : D3D9 utility functions for rendering +Created : March 7 , 2014 +Authors : Tom Heath + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_D3D9_DistortionRenderer.h" +#include "OVR_CAPI_D3D.h" + + +namespace OVR { namespace CAPI { namespace D3D9 { + + +#define PRECOMPILE_FLAG 0 +#if !PRECOMPILE_FLAG +//To make these, you need to run it with PRECOMPILE_FLAG, which also uses them, so good for debugging. +//Then cut and paste these from the output window. +//Then turn off the flag. +DWORD precompiledVertexShaderSrc[96] = {4294836736,3080190,1111577667,28,130,4294836736,2,28,33024,123,68,131074,655361,88,0,104,2,131073,88,0,1415936325,1970230127,1432707954,1717981014,7628147,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597136755,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147614720,2416902145,33554463,2147483653,2416902146,33554463,2147549189,2416902147,33554463,2147614725,2416902148,33554433,2147680256,2699296768,67108868,3758292992,2162425856,2430861314,2699296770,67108868,3758292993,2162425856,2430861315,2699296770,67108868,3758292994,2162425856,2430861316,2699296770,67108868,3222208512,2416181248,2689597441,2686779393,33554433,3758161923,2415919105,65535,}; +DWORD precompiledVertexShaderTimewarpSrc[310] = {4294836992,4587518,1111577667,28,222,4294836992,4,28,33024,215,108,1310722,5373956,124,0,140,262146,1179652,124,0,157,131074,655361,180,0,196,2,131073,180,0,1382381893,1952543855,1164865385,2868929646,196611,262148,1,0,1382381893,1952543855,1399746409,1953653108,1702446336,1867738964,1701016181,1716475477,1952805734,2880154368,196609,131073,1,0,1415936325,1970230127,1432707954,1633899350,1979737452,1597202291,1766654000,1936683619,544499311,539578920,1280527432,1634226976,544367972,1886220099,1919249513,841890080,892939833,825437746,2868916529,83886161,2685337601,1065353216,0,1056964608,0,33554463,2147483648,2416902144,33554463,2147549184,2416902145,33554463,2147614720,2416902146,33554463,2147483653,2416902147,33554463,2147549189,2416902148,33554463,2147614725,2416902149,33554463,2147483648,3759079424,33554463,2147483653,3758292993,33554463,2147549189,3758292994,33554463,2147614725,3758292995,33554463,2147680261,3758161924,33554433,2147549184,2695495684,50331650,2147549185,2164260864,2695495700,33554433,2147614720,2695495685,50331650,2147614721,2169831424,2695495701,33554433,2147745792,2695495686,50331650,2147745793,2175401984,2695495702,33554433,2148007936,2695495687,50331650,2148007937,2180972544,2695495703,67108868,2148466688,2415919105,2162425857,2162425856,67108868,2148466689,2416181251,2689597441,2684682241,50331657,2147549186,2162425856,2162425857,33554438,2147549186,2147483650,33554433,2147680259,2699296772,50331650,2147876866,2177892355,2697986068,67108868,2147549187,2415919105,2158624770,2689925124,67108868,2147549188,2415919105,2153054210,2684354564,33554433,2147680261,2699296773,50331650,2147876866,2177105925,2697199637,67108868,2147614723,2415919105,2153054210,2689925125,67108868,2147614724,2415919105,2158624770,2684354565,33554433,2147680261,2699296774,50331650,2147811333,2177171461,2697265174,67108868,2147745795,2415919105,2147483653,2689925126,67108868,2147745796,2415919105,2158624773,2684354566,33554433,2147680261,2699296775,50331650,2148073477,2166685701,2686779415,67108868,2148007939,2415919105,2147483653,2689925127,67108868,2148007940,2415919105,2164195333,2684354567,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331653,2147680257,2147483650,2162425861,33554433,2147680258,2699296768,67108868,3758292993,2162425858,2162425857,2699296770,67108868,2148466689,2416181252,2689597441,2684682241,50331657,2147549189,2162425860,2162425857,50331657,2147614725,2162425859,2162425857,50331657,2147549185,2162425856,2162425857,33554438,2147549185,2147483649,50331653,2147680257,2147483649,2162425861,67108868,3758292994,2162425858,2162425857,2699296770,67108868,2148466689,2416181253,2689597441,2684682241,50331657,2147549188,2162425860,2162425857,50331657,2147614724,2162425859,2162425857,50331657,2147549184,2162425856,2162425857,33554438,2147549184,2147483648,50331653,2147680256,2147483648,2162425860,67108868,3758292995,2162425858,2162425856,2699296770,67108868,3759079424,2416181248,2689597441,2686779393,33554433,3758161924,2415919106,65535,}; +DWORD precompiledPixelShaderSrc[84] = {4294902528,2228222,1111577667,28,79,4294902528,1,28,33024,72,48,3,131073,56,0,1954047316,6648437,786436,65537,1,0,861893488,1291858015,1869767529,1952870259,693250080,1397508128,1750278220,1919247457,1836008224,1701603696,775495794,959330610,858665525,3223857,83886161,2685337600,1065353216,0,0,0,33554463,2147483653,2416115712,33554463,2147549189,2416115713,33554463,2147614725,2416115714,33554463,2147680261,2415984643,33554463,2415919104,2685339648,50331714,2148466688,2430861312,2699298816,67108868,2148073472,2147483648,2690908160,2686779392,50331714,2148466689,2430861313,2699298816,33554433,2147614720,2153054209,50331714,2148466689,2430861314,2699298816,33554433,2147745792,2158624769,50331653,2148468736,2162425856,2415919107,65535,}; + +#else +#include "d3dcompiler.h" +#pragma comment(lib, "C:\\Program Files (x86)\\Microsoft DirectX SDK (June 2010)\\Lib\\x86\\D3DCompiler.lib") +/***************************************************************************/ +const char* VertexShaderSrc = + + "float2 EyeToSourceUVScale : register(c0); \n" + "float2 EyeToSourceUVOffset : register(c2); \n" + + "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n" + " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n" + " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" + " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n" + " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n" + " out float oVignette : TEXCOORD3) \n" + "{ \n" + " oTexCoord0 = EyeToSourceUVScale * TexCoord0 + EyeToSourceUVOffset; \n" + " oTexCoord1 = EyeToSourceUVScale * TexCoord1 + EyeToSourceUVOffset; \n" + " oTexCoord2 = EyeToSourceUVScale * TexCoord2 + EyeToSourceUVOffset; \n" + " oVignette = Vignette; \n" + " oPosition = float4(Position.xy, 0.5, 1.0); \n" + "}"; + +/***************************************************************************/ +const char* VertexShaderTimewarpSrc = + + "float2 EyeToSourceUVScale : register(c0); \n" + "float2 EyeToSourceUVOffset : register(c2); \n" + "float4x4 EyeRotationStart : register(c4); \n" + "float4x4 EyeRotationEnd : register(c20); \n" + + "float2 TimewarpTexCoord(float2 TexCoord, float4x4 rotMat) \n" + "{ \n" + " float3 transformed = float3( mul ( rotMat, float4(TexCoord.xy, 1, 1) ).xyz); \n" + " float2 flattened = (transformed.xy / transformed.z); \n" + " return(EyeToSourceUVScale * flattened + EyeToSourceUVOffset); \n" + "} \n" + "void main(in float2 Position : POSITION, in float TimeWarp : POSITION1, \n" + " in float Vignette : POSITION2, in float2 TexCoord0 : TEXCOORD0, \n" + " in float2 TexCoord1 : TEXCOORD1, in float2 TexCoord2 : TEXCOORD2, \n" + " out float4 oPosition : SV_Position, out float2 oTexCoord0 : TEXCOORD0, \n" + " out float2 oTexCoord1 : TEXCOORD1, out float2 oTexCoord2 : TEXCOORD2, \n" + " out float oVignette : TEXCOORD3) \n" + "{ \n" + " float4x4 lerpedEyeRot = lerp(EyeRotationStart, EyeRotationEnd, TimeWarp); \n" + " oTexCoord0 = TimewarpTexCoord(TexCoord0,lerpedEyeRot); \n" + " oTexCoord1 = TimewarpTexCoord(TexCoord1,lerpedEyeRot); \n" + " oTexCoord2 = TimewarpTexCoord(TexCoord2,lerpedEyeRot); \n" + " oVignette = Vignette; \n" + " oPosition = float4(Position.xy, 0.5, 1.0); \n" + "}"; + +/***************************************************************************/ +const char* PixelShaderSrc = + + " sampler2D Texture : register(s0); \n" + + "float4 main(in float4 oPosition : SV_Position, in float2 oTexCoord0 : TEXCOORD0, \n" + " in float2 oTexCoord1 : TEXCOORD1, in float2 oTexCoord2 : TEXCOORD2, \n" + " in float oVignette : TEXCOORD3) \n" + " : SV_Target \n" + "{ \n" + " float R = tex2D(Texture,oTexCoord0).r; \n" + " float G = tex2D(Texture,oTexCoord1).g; \n" + " float B = tex2D(Texture,oTexCoord2).b; \n" + " return (oVignette*float4(R,G,B,1)); \n" + "}"; + +/*************************************************************/ +ID3DBlob* ShaderCompile(char * shaderName, const char * shaderSrcString, const char * profile) +{ + ID3DBlob* pShaderCode = NULL; + ID3DBlob* pErrorMsg = NULL; + + if (FAILED(D3DCompile(shaderSrcString, strlen(shaderSrcString),NULL,NULL,NULL, + "main",profile,D3DCOMPILE_OPTIMIZATION_LEVEL3,0, + &pShaderCode,&pErrorMsg))) + MessageBoxA(NULL,(char *) pErrorMsg->GetBufferPointer(),"", MB_OK); + if (pErrorMsg) pErrorMsg->Release(); + + //Now write out blob + char tempString[1000]; + int numDWORDs = ((int)pShaderCode->GetBufferSize())/4; + DWORD * ptr = (DWORD *)pShaderCode->GetBufferPointer(); + sprintf_s(tempString,"DWORD %s[%d] = {",shaderName,numDWORDs); + OutputDebugStringA(tempString); + for (int i = 0;i < numDWORDs; i++) + { + sprintf_s(tempString,"%lu,",ptr[i]); + OutputDebugStringA(tempString); + } + OutputDebugStringA("};\n"); + + return(pShaderCode); +} +#endif + +/***********************************************************/ +void DistortionRenderer::CreateDistortionShaders(void) +{ +#if PRECOMPILE_FLAG + ID3DBlob * pShaderCode; + pShaderCode = ShaderCompile("precompiledVertexShaderSrc",VertexShaderSrc,"vs_2_0"); + Device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &VertexShader ); + pShaderCode->Release(); + + pShaderCode = ShaderCompile("precompiledVertexShaderTimewarpSrc",VertexShaderTimewarpSrc,"vs_3_0"); + Device->CreateVertexShader( ( DWORD* )pShaderCode->GetBufferPointer(), &VertexShaderTimewarp ); + pShaderCode->Release(); + + pShaderCode = ShaderCompile("precompiledPixelShaderSrc",PixelShaderSrc,"ps_3_0"); + Device->CreatePixelShader( ( DWORD* )pShaderCode->GetBufferPointer(), &PixelShader ); + pShaderCode->Release(); +#else + Device->CreateVertexShader( precompiledVertexShaderSrc, &VertexShader ); + Device->CreateVertexShader( precompiledVertexShaderTimewarpSrc, &VertexShaderTimewarp ); + Device->CreatePixelShader( precompiledPixelShaderSrc, &PixelShader ); +#endif +} + + +/***************************************************/ +void DistortionRenderer::CreateVertexDeclaration() +{ + static const D3DVERTEXELEMENT9 VertexElements[7] = { + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, + { 0, 8, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 1 }, + { 0, 12, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 2 }, + { 0, 16, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 }, + { 0, 24, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 }, + { 0, 32, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 2 }, + D3DDECL_END() }; + Device->CreateVertexDeclaration( VertexElements, &VertexDecl ); +} + + +/******************************************************/ +bool DistortionRenderer::CreateDistortionModels() +{ + //Make the distortion models + for (int eye=0;eye<2;eye++) + { + FOR_EACH_EYE * e = &eachEye[eye]; + ovrDistortionMesh meshData; + + if (!CalculateDistortionMeshFromFOV( + RenderState->RenderInfo, + RenderState->Distortion[eye], + (RenderState->EyeRenderDesc[eye].Eye == ovrEye_Left ? StereoEye_Left : StereoEye_Right), + RenderState->EyeRenderDesc[eye].Fov, + RenderState->DistortionCaps, + &meshData)) + { + OVR_ASSERT(false); + return false; + } + + e->numVerts = meshData.VertexCount; + e->numIndices = meshData.IndexCount; + + Device->CreateVertexBuffer( (e->numVerts)*sizeof(ovrDistortionVertex),0, 0, + D3DPOOL_MANAGED, &e->dxVerts, NULL ); + ovrDistortionVertex * dxv; e->dxVerts->Lock( 0, 0, (void**)&dxv, 0 ); + for (int v=0;vnumVerts;v++) dxv[v] = meshData.pVertexData[v]; + e->dxVerts->Unlock(); + + Device->CreateIndexBuffer( (e->numIndices)*sizeof(u_short),0, D3DFMT_INDEX16, + D3DPOOL_MANAGED, &e->dxIndices, NULL ); + unsigned short* dxi; e->dxIndices->Lock( 0, 0, (void**)&dxi, 0 ); + for (int i=0;inumIndices;i++) dxi[i] = meshData.pIndexData[i]; + e->dxIndices->Unlock(); + + ovrHmd_DestroyDistortionMesh( &meshData ); + } + + return true; +} + +/**********************************************************/ +void DistortionRenderer::RenderBothDistortionMeshes() +{ + Device->BeginScene(); + + D3DCOLOR clearColor = D3DCOLOR_RGBA( + (int)(RenderState->ClearColor[0] * 255.0f), + (int)(RenderState->ClearColor[1] * 255.0f), + (int)(RenderState->ClearColor[2] * 255.0f), + (int)(RenderState->ClearColor[3] * 255.0f)); + + Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, clearColor, 0, 0); + + for (int eyeNum = 0; eyeNum < 2; eyeNum++) + { + FOR_EACH_EYE * e = &eachEye[eyeNum]; + D3DVIEWPORT9 vp; + vp.X=0; vp.Y=0; + vp.Width=ScreenSize.w; vp.Height=ScreenSize.h; + vp.MinZ=0; vp.MaxZ = 1; + + Device->SetViewport(&vp); + Device->SetStreamSource( 0, e->dxVerts,0, sizeof(ovrDistortionVertex) ); + Device->SetVertexDeclaration( VertexDecl ); + Device->SetIndices( e->dxIndices ); + Device->SetPixelShader( PixelShader ); + Device->SetTexture( 0, e->texture); + + //Choose which vertex shader, with associated additional inputs + if (RenderState->DistortionCaps & ovrDistortionCap_TimeWarp) + { + Device->SetVertexShader( VertexShaderTimewarp ); + + Matrix4f startEndMatrices[2]; + double timewarpIMUTime = 0.; + CalculateOrientationTimewarpFromSensors( + RenderState->EyeRenderPoses[eyeNum].Orientation, + SensorReader, Timing->GetTimewarpTiming()->EyeStartEndTimes[eyeNum], + startEndMatrices, timewarpIMUTime); + Timing->SetTimewarpIMUTime(timewarpIMUTime); + + //Need to transpose the matrices + startEndMatrices[0].Transpose(); + startEndMatrices[1].Transpose(); + + // Feed identity like matrices in until we get proper timewarp calculation going on + Device->SetVertexShaderConstantF(4, (float *)&startEndMatrices[0], 4); + Device->SetVertexShaderConstantF(20, (float *)&startEndMatrices[1], 4); + } + else + { + Device->SetVertexShader( VertexShader ); + } + + //Set up vertex shader constants + Device->SetVertexShaderConstantF( 0, ( FLOAT* )&(e->UVScaleOffset[0]), 1 ); + Device->SetVertexShaderConstantF( 2, ( FLOAT* )&(e->UVScaleOffset[1]), 1 ); + + Device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST,0,0,e->numVerts,0,e->numIndices/3); + } + + Device->EndScene(); +} + + +}}} // namespace OVR::CAPI::D3D9 diff --git a/LibOVR/Src/CAPI/GL/CAPI_GLE.cpp b/LibOVR/Src/CAPI/GL/CAPI_GLE.cpp deleted file mode 100644 index c41d745..0000000 --- a/LibOVR/Src/CAPI/GL/CAPI_GLE.cpp +++ /dev/null @@ -1,7884 +0,0 @@ -/************************************************************************************ - -Filename : Render_GLE.cpp -Content : OpenGL Extensions support. Implements a stripped down glew-like - interface with some additional functionality. -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "CAPI_GLE.h" -#include "../../Kernel/OVR_Log.h" -#include - - -#if defined(_WIN32) - #if !defined(WINAPI) - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN 1 - #endif - #include - #endif - - #pragma comment(lib, "opengl32.lib") -#elif defined(__APPLE__) - #include - #include - #include - #include -#endif - - - -//namespace OVR -//{ - // OVRTypeof - // Acts the same as the C++11 decltype expression, though with reduced requirements. - #if !defined(OVRTypeof) - #if defined(_MSC_VER) - #define OVRTypeof(x) decltype(x) // VS2010+ unilaterally supports decltype - #else - #define OVRTypeof(x) __typeof__(x) // Other compilers support decltype, but usually not unless C++11 support is present and explicitly enabled. - #endif - #endif - - - // GLELoadProc - // Macro which implements dynamically looking up and assigning an OpenGL function. - // - // Example usage: - // GLELoadProc(glCopyTexSubImage3D, glCopyTexSubImage3D); - // Expands to: - // gleCopyTexSubImage3D = (OVRTypeof(gleCopyTexSubImage3D)) GLEGetProcAddress("glCopyTexSubImage3D"); - - #define GLELoadProc(var, name) var = (OVRTypeof(var))GLEGetProcAddress(#name) - - - // Disable some #defines, as we need to call these functions directly. - #if defined(GLE_HOOKING_ENABLED) - #if defined(_WIN32) - #undef wglGetProcAddress - extern "C" { GLAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc); } - #endif - - #undef glGetString - extern "C" { GLAPI const GLubyte * GLAPIENTRY glGetString(GLenum name); } - #endif - - - // Generic OpenGL GetProcAddress function interface. Maps to platform-specific functionality - // internally. On Windows this is equivalent to wglGetProcAddress as opposed to global GetProcAddress. - void* OVR::GLEGetProcAddress(const char* name) - { - #if defined(_WIN32) - return wglGetProcAddress(name); - - #elif defined(__APPLE__) - // Requires the OS 10.3 SDK or later. - static void* dlImage = NULL; - void* addr = nullptr; - - if(!dlImage) - dlImage = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); - - if(dlImage) - addr = dlsym(dlImage, name); - - return addr; - - #elif defined(__ANDROID__) - return eglGetProcAddress(name); - - #else - // This was glXGetProcAddressARB in GLX versions prior to v1.4, but that was ten years ago. - return (void*)glXGetProcAddress((const GLubyte*)name); - #endif - } - - - - // Current context functionality - static OVR::GLEContext* GLECurrentContext = NULL; - - OVR::GLEContext* OVR::GLEContext::GetCurrentContext() - { - return GLECurrentContext; - } - - void OVR::GLEContext::SetCurrentContext(OVR::GLEContext* p) - { - GLECurrentContext = p; - } - - - - OVR::GLEContext::GLEContext() - : MajorVersion(0) - , MinorVersion(0) - , WholeVersion(0) - , IsGLES(false) - , IsCoreProfile(false) - , EnableHookGetError(true) - , PlatformMajorVersion(0) - , PlatformMinorVersion(0) - , PlatformWholeVersion(0) - { - // The following sequence is not thread-safe. Two threads could set the context to this at the same time. - if(GetCurrentContext() == NULL) - SetCurrentContext(this); - } - - - OVR::GLEContext::~GLEContext() - { - // Currently empty - } - - - void OVR::GLEContext::Init() - { - PlatformInit(); - - if(!IsInitialized()) - { - InitVersion(); - InitExtensionLoad(); - InitExtensionSupport(); - } - } - - - bool OVR::GLEContext::IsInitialized() const - { - return (MajorVersion != 0); - } - - - void OVR::GLEContext::Shutdown() - { - // This memset is valid only if this class has no virtual functions (similar to concept of POD). - // We cannot assert this because restrictions prevent us from using C++11 type traits here. - memset(this, 0, sizeof(GLEContext)); - } - - - void OVR::GLEContext::PlatformInit() - { - if(!IsPlatformInitialized()) - { - InitPlatformExtensionLoad(); - InitPlatformExtensionSupport(); - InitPlatformVersion(); - } - } - - - bool OVR::GLEContext::IsPlatformInitialized() const - { - return (PlatformMajorVersion != 0); - } - - - void OVR::GLEContext::InitVersion() - { - const char* version = (const char*)glGetString(GL_VERSION); - int fields = 0, major = 0, minor = 0; - bool isGLES = false; - - OVR_ASSERT(version); - if (version) - { - OVR_DEBUG_LOG(("GL_VERSION: %s", (const char*)version)); - - // Skip all leading non-digits before reading %d. - // Example GL_VERSION strings: - // "1.5 ATI-1.4.18" - // "OpenGL ES-CM 3.2" - OVR_DISABLE_MSVC_WARNING(4996) // "scanf may be unsafe" - fields = sscanf(version, isdigit(*version) ? "%d.%d" : "%*[^0-9]%d.%d", &major, &minor); - isGLES = (strstr(version, "OpenGL ES") != NULL); - OVR_RESTORE_MSVC_WARNING() - } - else - { - LogText("Warning: GL_VERSION was NULL\n"); - } - - // If two fields were not found, - if (fields != 2) - { - static_assert(sizeof(major) == sizeof(GLint), "type mis-match"); - - glGetIntegerv(GL_MAJOR_VERSION, &major); - glGetIntegerv(GL_MINOR_VERSION, &minor); - } - - // Write version data - MajorVersion = major; - MinorVersion = minor; - WholeVersion = (major * 100) + minor; - - GLint profileMask = 0; - if(WholeVersion >= 302) - { - // Older NVidia drivers have a bug with this on at least Windows. - // https://www.opengl.org/discussion_boards/showthread.php/171380-NVIDIA-drivers-not-returning-the-right-profile-mas - // A workaround could be to check for the GL_ARB_compatibility extension, which indicates if OpenGL is in compatibility mode, - // and if not then we are in core profile mode. On Apple another solution would be to use NSOpeNGLPixelFormat - // NSOpenGLView::pixelFormat to get the core profile attribute. - glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask); - } - IsCoreProfile = (profileMask == GL_CONTEXT_CORE_PROFILE_BIT); // There's also GL_CONTEXT_COMPATIBILITY_PROFILE_BIT - IsGLES = isGLES; - } - - - void OVR::GLEContext::InitExtensionLoad() - { - // GL_VERSION_1_1 - // We don't load these but rather link to them directly. - - // GL_VERSION_1_2 - GLELoadProc(glCopyTexSubImage3D_Impl, glCopyTexSubImage3D); // This expands to a get proc address call (e.g. wglGetProcAddress on Windows). - GLELoadProc(glDrawRangeElements_Impl, glDrawRangeElements); - GLELoadProc(glTexImage3D_Impl, glTexImage3D); - GLELoadProc(glTexSubImage3D_Impl, glTexSubImage3D); - - // GL_VERSION_1_3 - GLELoadProc(glActiveTexture_Impl, glActiveTexture); - GLELoadProc(glClientActiveTexture_Impl, glClientActiveTexture); - GLELoadProc(glCompressedTexImage1D_Impl, glCompressedTexImage1D); - GLELoadProc(glCompressedTexImage2D_Impl, glCompressedTexImage2D); - GLELoadProc(glCompressedTexImage3D_Impl, glCompressedTexImage3D); - GLELoadProc(glCompressedTexSubImage1D_Impl, glCompressedTexSubImage1D); - GLELoadProc(glCompressedTexSubImage2D_Impl, glCompressedTexSubImage2D); - GLELoadProc(glCompressedTexSubImage3D_Impl, glCompressedTexSubImage3D); - GLELoadProc(glGetCompressedTexImage_Impl, glGetCompressedTexImage); - GLELoadProc(glLoadTransposeMatrixd_Impl, glLoadTransposeMatrixd); - GLELoadProc(glLoadTransposeMatrixf_Impl, glLoadTransposeMatrixf); - GLELoadProc(glMultTransposeMatrixd_Impl, glMultTransposeMatrixd); - GLELoadProc(glMultTransposeMatrixf_Impl, glMultTransposeMatrixf); - GLELoadProc(glMultiTexCoord1d_Impl, glMultiTexCoord1d); - GLELoadProc(glMultiTexCoord1dv_Impl, glMultiTexCoord1dv); - GLELoadProc(glMultiTexCoord1f_Impl, glMultiTexCoord1f); - GLELoadProc(glMultiTexCoord1fv_Impl, glMultiTexCoord1fv); - GLELoadProc(glMultiTexCoord1i_Impl, glMultiTexCoord1i); - GLELoadProc(glMultiTexCoord1iv_Impl, glMultiTexCoord1iv); - GLELoadProc(glMultiTexCoord1s_Impl, glMultiTexCoord1s); - GLELoadProc(glMultiTexCoord1sv_Impl, glMultiTexCoord1sv); - GLELoadProc(glMultiTexCoord2d_Impl, glMultiTexCoord2d); - GLELoadProc(glMultiTexCoord2dv_Impl, glMultiTexCoord2dv); - GLELoadProc(glMultiTexCoord2f_Impl, glMultiTexCoord2f); - GLELoadProc(glMultiTexCoord2fv_Impl, glMultiTexCoord2fv); - GLELoadProc(glMultiTexCoord2i_Impl, glMultiTexCoord2i); - GLELoadProc(glMultiTexCoord2iv_Impl, glMultiTexCoord2iv); - GLELoadProc(glMultiTexCoord2s_Impl, glMultiTexCoord2s); - GLELoadProc(glMultiTexCoord2sv_Impl, glMultiTexCoord2sv); - GLELoadProc(glMultiTexCoord3d_Impl, glMultiTexCoord3d); - GLELoadProc(glMultiTexCoord3dv_Impl, glMultiTexCoord3dv); - GLELoadProc(glMultiTexCoord3f_Impl, glMultiTexCoord3f); - GLELoadProc(glMultiTexCoord3fv_Impl, glMultiTexCoord3fv); - GLELoadProc(glMultiTexCoord3i_Impl, glMultiTexCoord3i); - GLELoadProc(glMultiTexCoord3iv_Impl, glMultiTexCoord3iv); - GLELoadProc(glMultiTexCoord3s_Impl, glMultiTexCoord3s); - GLELoadProc(glMultiTexCoord3sv_Impl, glMultiTexCoord3sv); - GLELoadProc(glMultiTexCoord4d_Impl, glMultiTexCoord4d); - GLELoadProc(glMultiTexCoord4dv_Impl, glMultiTexCoord4dv); - GLELoadProc(glMultiTexCoord4f_Impl, glMultiTexCoord4f); - GLELoadProc(glMultiTexCoord4fv_Impl, glMultiTexCoord4fv); - GLELoadProc(glMultiTexCoord4i_Impl, glMultiTexCoord4i); - GLELoadProc(glMultiTexCoord4iv_Impl, glMultiTexCoord4iv); - GLELoadProc(glMultiTexCoord4s_Impl, glMultiTexCoord4s); - GLELoadProc(glMultiTexCoord4sv_Impl, glMultiTexCoord4sv); - GLELoadProc(glSampleCoverage_Impl, glSampleCoverage); - - // GL_VERSION_1_4 - GLELoadProc(glBlendColor_Impl, glBlendColor); - GLELoadProc(glBlendEquation_Impl, glBlendEquation); - GLELoadProc(glBlendFuncSeparate_Impl, glBlendFuncSeparate); - GLELoadProc(glFogCoordPointer_Impl, glFogCoordPointer); - GLELoadProc(glFogCoordd_Impl, glFogCoordd); - GLELoadProc(glFogCoorddv_Impl, glFogCoorddv); - GLELoadProc(glFogCoordf_Impl, glFogCoordf); - GLELoadProc(glFogCoordfv_Impl, glFogCoordfv); - GLELoadProc(glMultiDrawArrays_Impl, glMultiDrawArrays); - GLELoadProc(glMultiDrawElements_Impl, glMultiDrawElements); - GLELoadProc(glPointParameterf_Impl, glPointParameterf); - GLELoadProc(glPointParameterfv_Impl, glPointParameterfv); - GLELoadProc(glPointParameteri_Impl, glPointParameteri); - GLELoadProc(glPointParameteriv_Impl, glPointParameteriv); - GLELoadProc(glSecondaryColor3b_Impl, glSecondaryColor3b); - GLELoadProc(glSecondaryColor3bv_Impl, glSecondaryColor3bv); - GLELoadProc(glSecondaryColor3d_Impl, glSecondaryColor3d); - GLELoadProc(glSecondaryColor3dv_Impl, glSecondaryColor3dv); - GLELoadProc(glSecondaryColor3f_Impl, glSecondaryColor3f); - GLELoadProc(glSecondaryColor3fv_Impl, glSecondaryColor3fv); - GLELoadProc(glSecondaryColor3i_Impl, glSecondaryColor3i); - GLELoadProc(glSecondaryColor3iv_Impl, glSecondaryColor3iv); - GLELoadProc(glSecondaryColor3s_Impl, glSecondaryColor3s); - GLELoadProc(glSecondaryColor3sv_Impl, glSecondaryColor3sv); - GLELoadProc(glSecondaryColor3ub_Impl, glSecondaryColor3ub); - GLELoadProc(glSecondaryColor3ubv_Impl, glSecondaryColor3ubv); - GLELoadProc(glSecondaryColor3ui_Impl, glSecondaryColor3ui); - GLELoadProc(glSecondaryColor3uiv_Impl, glSecondaryColor3uiv); - GLELoadProc(glSecondaryColor3us_Impl, glSecondaryColor3us); - GLELoadProc(glSecondaryColor3usv_Impl, glSecondaryColor3usv); - GLELoadProc(glSecondaryColorPointer_Impl, glSecondaryColorPointer); - GLELoadProc(glWindowPos2d_Impl, glWindowPos2d); - GLELoadProc(glWindowPos2dv_Impl, glWindowPos2dv); - GLELoadProc(glWindowPos2f_Impl, glWindowPos2f); - GLELoadProc(glWindowPos2fv_Impl, glWindowPos2fv); - GLELoadProc(glWindowPos2i_Impl, glWindowPos2i); - GLELoadProc(glWindowPos2iv_Impl, glWindowPos2iv); - GLELoadProc(glWindowPos2s_Impl, glWindowPos2s); - GLELoadProc(glWindowPos2sv_Impl, glWindowPos2sv); - GLELoadProc(glWindowPos3d_Impl, glWindowPos3d); - GLELoadProc(glWindowPos3dv_Impl, glWindowPos3dv); - GLELoadProc(glWindowPos3f_Impl, glWindowPos3f); - GLELoadProc(glWindowPos3fv_Impl, glWindowPos3fv); - GLELoadProc(glWindowPos3i_Impl, glWindowPos3i); - GLELoadProc(glWindowPos3iv_Impl, glWindowPos3iv); - GLELoadProc(glWindowPos3s_Impl, glWindowPos3s); - GLELoadProc(glWindowPos3sv_Impl, glWindowPos3sv); - - // GL_VERSION_1_5 - GLELoadProc(glBeginQuery_Impl, glBeginQuery); - GLELoadProc(glBindBuffer_Impl, glBindBuffer); - GLELoadProc(glBufferData_Impl, glBufferData); - GLELoadProc(glBufferSubData_Impl, glBufferSubData); - GLELoadProc(glDeleteBuffers_Impl, glDeleteBuffers); - GLELoadProc(glDeleteQueries_Impl, glDeleteQueries); - GLELoadProc(glEndQuery_Impl, glEndQuery); - GLELoadProc(glGenBuffers_Impl, glGenBuffers); - GLELoadProc(glGenQueries_Impl, glGenQueries); - GLELoadProc(glGetBufferParameteriv_Impl, glGetBufferParameteriv); - GLELoadProc(glGetBufferPointerv_Impl, glGetBufferPointerv); - GLELoadProc(glGetBufferSubData_Impl, glGetBufferSubData); - GLELoadProc(glGetQueryObjectiv_Impl, glGetQueryObjectiv); - GLELoadProc(glGetQueryObjectuiv_Impl, glGetQueryObjectuiv); - GLELoadProc(glGetQueryiv_Impl, glGetQueryiv); - GLELoadProc(glIsBuffer_Impl, glIsBuffer); - GLELoadProc(glIsQuery_Impl, glIsQuery); - GLELoadProc(glMapBuffer_Impl, glMapBuffer); - GLELoadProc(glUnmapBuffer_Impl, glUnmapBuffer); - - // GL_VERSION_2_0 - GLELoadProc(glAttachShader_Impl, glAttachShader); - GLELoadProc(glBindAttribLocation_Impl, glBindAttribLocation); - GLELoadProc(glBlendEquationSeparate_Impl, glBlendEquationSeparate); - GLELoadProc(glCompileShader_Impl, glCompileShader); - GLELoadProc(glCreateProgram_Impl, glCreateProgram); - GLELoadProc(glCreateShader_Impl, glCreateShader); - GLELoadProc(glDeleteProgram_Impl, glDeleteProgram); - GLELoadProc(glDeleteShader_Impl, glDeleteShader); - GLELoadProc(glDetachShader_Impl, glDetachShader); - GLELoadProc(glDisableVertexAttribArray_Impl, glDisableVertexAttribArray); - GLELoadProc(glDrawBuffers_Impl, glDrawBuffers); - GLELoadProc(glEnableVertexAttribArray_Impl, glEnableVertexAttribArray); - GLELoadProc(glGetActiveAttrib_Impl, glGetActiveAttrib); - GLELoadProc(glGetActiveUniform_Impl, glGetActiveUniform); - GLELoadProc(glGetAttachedShaders_Impl, glGetAttachedShaders); - GLELoadProc(glGetAttribLocation_Impl, glGetAttribLocation); - GLELoadProc(glGetProgramInfoLog_Impl, glGetProgramInfoLog); - GLELoadProc(glGetProgramiv_Impl, glGetProgramiv); - GLELoadProc(glGetShaderInfoLog_Impl, glGetShaderInfoLog); - GLELoadProc(glGetShaderSource_Impl, glGetShaderSource); - GLELoadProc(glGetShaderiv_Impl, glGetShaderiv); - GLELoadProc(glGetUniformLocation_Impl, glGetUniformLocation); - GLELoadProc(glGetUniformfv_Impl, glGetUniformfv); - GLELoadProc(glGetUniformiv_Impl, glGetUniformiv); - GLELoadProc(glGetVertexAttribPointerv_Impl, glGetVertexAttribPointerv); - GLELoadProc(glGetVertexAttribdv_Impl, glGetVertexAttribdv); - GLELoadProc(glGetVertexAttribfv_Impl, glGetVertexAttribfv); - GLELoadProc(glGetVertexAttribiv_Impl, glGetVertexAttribiv); - GLELoadProc(glIsProgram_Impl, glIsProgram); - GLELoadProc(glIsShader_Impl, glIsShader); - GLELoadProc(glLinkProgram_Impl, glLinkProgram); - GLELoadProc(glShaderSource_Impl, glShaderSource); - GLELoadProc(glStencilFuncSeparate_Impl, glStencilFuncSeparate); - GLELoadProc(glStencilMaskSeparate_Impl, glStencilMaskSeparate); - GLELoadProc(glStencilOpSeparate_Impl, glStencilOpSeparate); - GLELoadProc(glUniform1f_Impl, glUniform1f); - GLELoadProc(glUniform1fv_Impl, glUniform1fv); - GLELoadProc(glUniform1i_Impl, glUniform1i); - GLELoadProc(glUniform1iv_Impl, glUniform1iv); - GLELoadProc(glUniform2f_Impl, glUniform2f); - GLELoadProc(glUniform2fv_Impl, glUniform2fv); - GLELoadProc(glUniform2i_Impl, glUniform2i); - GLELoadProc(glUniform2iv_Impl, glUniform2iv); - GLELoadProc(glUniform3f_Impl, glUniform3f); - GLELoadProc(glUniform3fv_Impl, glUniform3fv); - GLELoadProc(glUniform3i_Impl, glUniform3i); - GLELoadProc(glUniform3iv_Impl, glUniform3iv); - GLELoadProc(glUniform4f_Impl, glUniform4f); - GLELoadProc(glUniform4fv_Impl, glUniform4fv); - GLELoadProc(glUniform4i_Impl, glUniform4i); - GLELoadProc(glUniform4iv_Impl, glUniform4iv); - GLELoadProc(glUniformMatrix2fv_Impl, glUniformMatrix2fv); - GLELoadProc(glUniformMatrix3fv_Impl, glUniformMatrix3fv); - GLELoadProc(glUniformMatrix4fv_Impl, glUniformMatrix4fv); - GLELoadProc(glUseProgram_Impl, glUseProgram); - GLELoadProc(glValidateProgram_Impl, glValidateProgram); - GLELoadProc(glVertexAttrib1d_Impl, glVertexAttrib1d); - GLELoadProc(glVertexAttrib1dv_Impl, glVertexAttrib1dv); - GLELoadProc(glVertexAttrib1f_Impl, glVertexAttrib1f); - GLELoadProc(glVertexAttrib1fv_Impl, glVertexAttrib1fv); - GLELoadProc(glVertexAttrib1s_Impl, glVertexAttrib1s); - GLELoadProc(glVertexAttrib1sv_Impl, glVertexAttrib1sv); - GLELoadProc(glVertexAttrib2d_Impl, glVertexAttrib2d); - GLELoadProc(glVertexAttrib2dv_Impl, glVertexAttrib2dv); - GLELoadProc(glVertexAttrib2f_Impl, glVertexAttrib2f); - GLELoadProc(glVertexAttrib2fv_Impl, glVertexAttrib2fv); - GLELoadProc(glVertexAttrib2s_Impl, glVertexAttrib2s); - GLELoadProc(glVertexAttrib2sv_Impl, glVertexAttrib2sv); - GLELoadProc(glVertexAttrib3d_Impl, glVertexAttrib3d); - GLELoadProc(glVertexAttrib3dv_Impl, glVertexAttrib3dv); - GLELoadProc(glVertexAttrib3f_Impl, glVertexAttrib3f); - GLELoadProc(glVertexAttrib3fv_Impl, glVertexAttrib3fv); - GLELoadProc(glVertexAttrib3s_Impl, glVertexAttrib3s); - GLELoadProc(glVertexAttrib3sv_Impl, glVertexAttrib3sv); - GLELoadProc(glVertexAttrib4Nbv_Impl, glVertexAttrib4Nbv); - GLELoadProc(glVertexAttrib4Niv_Impl, glVertexAttrib4Niv); - GLELoadProc(glVertexAttrib4Nsv_Impl, glVertexAttrib4Nsv); - GLELoadProc(glVertexAttrib4Nub_Impl, glVertexAttrib4Nub); - GLELoadProc(glVertexAttrib4Nubv_Impl, glVertexAttrib4Nubv); - GLELoadProc(glVertexAttrib4Nuiv_Impl, glVertexAttrib4Nuiv); - GLELoadProc(glVertexAttrib4Nusv_Impl, glVertexAttrib4Nusv); - GLELoadProc(glVertexAttrib4bv_Impl, glVertexAttrib4bv); - GLELoadProc(glVertexAttrib4d_Impl, glVertexAttrib4d); - GLELoadProc(glVertexAttrib4dv_Impl, glVertexAttrib4dv); - GLELoadProc(glVertexAttrib4f_Impl, glVertexAttrib4f); - GLELoadProc(glVertexAttrib4fv_Impl, glVertexAttrib4fv); - GLELoadProc(glVertexAttrib4iv_Impl, glVertexAttrib4iv); - GLELoadProc(glVertexAttrib4s_Impl, glVertexAttrib4s); - GLELoadProc(glVertexAttrib4sv_Impl, glVertexAttrib4sv); - GLELoadProc(glVertexAttrib4ubv_Impl, glVertexAttrib4ubv); - GLELoadProc(glVertexAttrib4uiv_Impl, glVertexAttrib4uiv); - GLELoadProc(glVertexAttrib4usv_Impl, glVertexAttrib4usv); - GLELoadProc(glVertexAttribPointer_Impl, glVertexAttribPointer); - - // GL_VERSION_2_1 - GLELoadProc(glUniformMatrix2x3fv_Impl, glUniformMatrix2x3fv); - GLELoadProc(glUniformMatrix2x4fv_Impl, glUniformMatrix2x4fv); - GLELoadProc(glUniformMatrix3x2fv_Impl, glUniformMatrix3x2fv); - GLELoadProc(glUniformMatrix3x4fv_Impl, glUniformMatrix3x4fv); - GLELoadProc(glUniformMatrix4x2fv_Impl, glUniformMatrix4x2fv); - GLELoadProc(glUniformMatrix4x3fv_Impl, glUniformMatrix4x3fv); - - // GL_VERSION_3_0 - GLELoadProc(glBeginConditionalRender_Impl, glBeginConditionalRender); - GLELoadProc(glBeginTransformFeedback_Impl, glBeginTransformFeedback); - GLELoadProc(glBindFragDataLocation_Impl, glBindFragDataLocation); - GLELoadProc(glClampColor_Impl, glClampColor); - GLELoadProc(glClearBufferfi_Impl, glClearBufferfi); - GLELoadProc(glClearBufferfv_Impl, glClearBufferfv); - GLELoadProc(glClearBufferiv_Impl, glClearBufferiv); - GLELoadProc(glClearBufferuiv_Impl, glClearBufferuiv); - GLELoadProc(glColorMaski_Impl, glColorMaski); - GLELoadProc(glDisablei_Impl, glDisablei); - GLELoadProc(glEnablei_Impl, glEnablei); - GLELoadProc(glEndConditionalRender_Impl, glEndConditionalRender); - GLELoadProc(glEndTransformFeedback_Impl, glEndTransformFeedback); - GLELoadProc(glBindBufferRange_Impl, glBindBufferRange); - GLELoadProc(glBindBufferBase_Impl, glBindBufferBase); - GLELoadProc(glGetBooleani_v_Impl, glGetBooleani_v); - GLELoadProc(glGetIntegeri_v_Impl, glGetIntegeri_v); - GLELoadProc(glGetFragDataLocation_Impl, glGetFragDataLocation); - GLELoadProc(glGetStringi_Impl, glGetStringi); - GLELoadProc(glGetTexParameterIiv_Impl, glGetTexParameterIiv); - GLELoadProc(glGetTexParameterIuiv_Impl, glGetTexParameterIuiv); - GLELoadProc(glGetTransformFeedbackVarying_Impl, glGetTransformFeedbackVarying); - GLELoadProc(glGetUniformuiv_Impl, glGetUniformuiv); - GLELoadProc(glGetVertexAttribIiv_Impl, glGetVertexAttribIiv); - GLELoadProc(glGetVertexAttribIuiv_Impl, glGetVertexAttribIuiv); - GLELoadProc(glIsEnabledi_Impl, glIsEnabledi); - GLELoadProc(glTexParameterIiv_Impl, glTexParameterIiv); - GLELoadProc(glTexParameterIuiv_Impl, glTexParameterIuiv); - GLELoadProc(glTransformFeedbackVaryings_Impl, glTransformFeedbackVaryings); - GLELoadProc(glUniform1ui_Impl, glUniform1ui); - GLELoadProc(glUniform1uiv_Impl, glUniform1uiv); - GLELoadProc(glUniform2ui_Impl, glUniform2ui); - GLELoadProc(glUniform2uiv_Impl, glUniform2uiv); - GLELoadProc(glUniform3ui_Impl, glUniform3ui); - GLELoadProc(glUniform3uiv_Impl, glUniform3uiv); - GLELoadProc(glUniform4ui_Impl, glUniform4ui); - GLELoadProc(glUniform4uiv_Impl, glUniform4uiv); - GLELoadProc(glVertexAttribI1i_Impl, glVertexAttribI1i); - GLELoadProc(glVertexAttribI1iv_Impl, glVertexAttribI1iv); - GLELoadProc(glVertexAttribI1ui_Impl, glVertexAttribI1ui); - GLELoadProc(glVertexAttribI1uiv_Impl, glVertexAttribI1uiv); - GLELoadProc(glVertexAttribI2i_Impl, glVertexAttribI2i); - GLELoadProc(glVertexAttribI2iv_Impl, glVertexAttribI2iv); - GLELoadProc(glVertexAttribI2ui_Impl, glVertexAttribI2ui); - GLELoadProc(glVertexAttribI2uiv_Impl, glVertexAttribI2uiv); - GLELoadProc(glVertexAttribI3i_Impl, glVertexAttribI3i); - GLELoadProc(glVertexAttribI3iv_Impl, glVertexAttribI3iv); - GLELoadProc(glVertexAttribI3ui_Impl, glVertexAttribI3ui); - GLELoadProc(glVertexAttribI3uiv_Impl, glVertexAttribI3uiv); - GLELoadProc(glVertexAttribI4bv_Impl, glVertexAttribI4bv); - GLELoadProc(glVertexAttribI4i_Impl, glVertexAttribI4i); - GLELoadProc(glVertexAttribI4iv_Impl, glVertexAttribI4iv); - GLELoadProc(glVertexAttribI4sv_Impl, glVertexAttribI4sv); - GLELoadProc(glVertexAttribI4ubv_Impl, glVertexAttribI4ubv); - GLELoadProc(glVertexAttribI4ui_Impl, glVertexAttribI4ui); - GLELoadProc(glVertexAttribI4uiv_Impl, glVertexAttribI4uiv); - GLELoadProc(glVertexAttribI4usv_Impl, glVertexAttribI4usv); - GLELoadProc(glVertexAttribIPointer_Impl, glVertexAttribIPointer); - - // GL_VERSION_3_1 - GLELoadProc(glDrawArraysInstanced_Impl, glDrawArraysInstanced); - GLELoadProc(glDrawElementsInstanced_Impl, glDrawElementsInstanced); - GLELoadProc(glPrimitiveRestartIndex_Impl, glPrimitiveRestartIndex); - GLELoadProc(glTexBuffer_Impl, glTexBuffer); - - // GL_VERSION_3_2 - GLELoadProc(glFramebufferTexture_Impl, glFramebufferTexture); - GLELoadProc(glGetBufferParameteri64v_Impl, glGetBufferParameteri64v); - GLELoadProc(glGetInteger64i_v_Impl, glGetInteger64i_v); - - // GL_VERSION_3_3 - GLELoadProc(glVertexAttribDivisor_Impl, glVertexAttribDivisor); - - // GL_VERSION_4_0 - GLELoadProc(glBlendEquationSeparatei_Impl, glBlendEquationSeparatei); - GLELoadProc(glBlendEquationi_Impl, glBlendEquationi); - GLELoadProc(glBlendFuncSeparatei_Impl, glBlendFuncSeparatei); - GLELoadProc(glBlendFunci_Impl, glBlendFunci); - GLELoadProc(glMinSampleShading_Impl, glMinSampleShading); - - // GL_AMD_debug_output - GLELoadProc(glDebugMessageCallbackAMD_Impl, glDebugMessageCallbackAMD); - GLELoadProc(glDebugMessageEnableAMD_Impl, glDebugMessageEnableAMD); - GLELoadProc(glDebugMessageInsertAMD_Impl, glDebugMessageInsertAMD); - GLELoadProc(glGetDebugMessageLogAMD_Impl, glGetDebugMessageLogAMD); - - #if defined(GLE_CGL_ENABLED) - // GL_APPLE_element_array - GLELoadProc(glDrawElementArrayAPPLE_Impl, glDrawElementArrayAPPLE); - GLELoadProc(glDrawRangeElementArrayAPPLE_Impl, glDrawRangeElementArrayAPPLE); - GLELoadProc(glElementPointerAPPLE_Impl, glElementPointerAPPLE); - GLELoadProc(glMultiDrawElementArrayAPPLE_Impl, glMultiDrawElementArrayAPPLE); - GLELoadProc(glMultiDrawRangeElementArrayAPPLE_Impl, glMultiDrawRangeElementArrayAPPLE); - - // GL_APPLE_fence - GLELoadProc(glDeleteFencesAPPLE_Impl, glDeleteFencesAPPLE); - GLELoadProc(glFinishFenceAPPLE_Impl, glFinishFenceAPPLE); - GLELoadProc(glFinishObjectAPPLE_Impl, glFinishObjectAPPLE); - GLELoadProc(glGenFencesAPPLE_Impl, glGenFencesAPPLE); - GLELoadProc(glIsFenceAPPLE_Impl, glIsFenceAPPLE); - GLELoadProc(glSetFenceAPPLE_Impl, glSetFenceAPPLE); - GLELoadProc(glTestFenceAPPLE_Impl, glTestFenceAPPLE); - GLELoadProc(glTestObjectAPPLE_Impl, glTestObjectAPPLE); - - // GL_APPLE_flush_buffer_range - GLELoadProc(glBufferParameteriAPPLE_Impl, glMultiDrawRangeElementArrayAPPLE); - GLELoadProc(glFlushMappedBufferRangeAPPLE_Impl, glFlushMappedBufferRangeAPPLE); - - // GL_APPLE_object_purgeable - GLELoadProc(glGetObjectParameterivAPPLE_Impl, glGetObjectParameterivAPPLE); - GLELoadProc(glObjectPurgeableAPPLE_Impl, glObjectPurgeableAPPLE); - GLELoadProc(glObjectUnpurgeableAPPLE_Impl, glObjectUnpurgeableAPPLE); - - // GL_APPLE_texture_range - GLELoadProc(glGetTexParameterPointervAPPLE_Impl, glGetTexParameterPointervAPPLE); - GLELoadProc(glTextureRangeAPPLE_Impl, glTextureRangeAPPLE); - - // GL_APPLE_vertex_array_object - GLELoadProc(glBindVertexArrayAPPLE_Impl, glBindVertexArrayAPPLE); - GLELoadProc(glDeleteVertexArraysAPPLE_Impl, glDeleteVertexArraysAPPLE); - GLELoadProc(glGenVertexArraysAPPLE_Impl, glGenVertexArraysAPPLE); - GLELoadProc(glIsVertexArrayAPPLE_Impl, glIsVertexArrayAPPLE); - - // GL_APPLE_vertex_array_range - GLELoadProc(glFlushVertexArrayRangeAPPLE_Impl, glFlushVertexArrayRangeAPPLE); - GLELoadProc(glVertexArrayParameteriAPPLE_Impl, glVertexArrayParameteriAPPLE); - GLELoadProc(glVertexArrayRangeAPPLE_Impl, glVertexArrayRangeAPPLE); - - // GL_APPLE_vertex_program_evaluators - GLELoadProc(glDisableVertexAttribAPPLE_Impl, glDisableVertexAttribAPPLE); - GLELoadProc(glEnableVertexAttribAPPLE_Impl, glEnableVertexAttribAPPLE); - GLELoadProc(glIsVertexAttribEnabledAPPLE_Impl, glIsVertexAttribEnabledAPPLE); - GLELoadProc(glMapVertexAttrib1dAPPLE_Impl, glMapVertexAttrib1dAPPLE); - GLELoadProc(glMapVertexAttrib1fAPPLE_Impl, glMapVertexAttrib1fAPPLE); - GLELoadProc(glMapVertexAttrib2dAPPLE_Impl, glMapVertexAttrib2dAPPLE); - GLELoadProc(glMapVertexAttrib2fAPPLE_Impl, glMapVertexAttrib2fAPPLE); - - #endif // GLE_CGL_ENABLED - - // GL_ARB_debug_output - GLELoadProc(glDebugMessageCallbackARB_Impl, glDebugMessageCallbackARB); - GLELoadProc(glDebugMessageControlARB_Impl, glDebugMessageControlARB); - GLELoadProc(glDebugMessageInsertARB_Impl, glDebugMessageInsertARB); - GLELoadProc(glGetDebugMessageLogARB_Impl, glGetDebugMessageLogARB); - - // GL_ARB_ES2_compatibility - GLELoadProc(glClearDepthf_Impl, glClearDepthf); - GLELoadProc(glDepthRangef_Impl, glDepthRangef); - GLELoadProc(glGetShaderPrecisionFormat_Impl, glGetShaderPrecisionFormat); - GLELoadProc(glReleaseShaderCompiler_Impl, glReleaseShaderCompiler); - GLELoadProc(glShaderBinary_Impl, glShaderBinary); - - // GL_ARB_framebuffer_object - GLELoadProc(glBindFramebuffer_Impl, glBindFramebuffer); - GLELoadProc(glBindRenderbuffer_Impl, glBindRenderbuffer); - GLELoadProc(glBlitFramebuffer_Impl, glBlitFramebuffer); - GLELoadProc(glCheckFramebufferStatus_Impl, glCheckFramebufferStatus); - GLELoadProc(glDeleteFramebuffers_Impl, glDeleteFramebuffers); - GLELoadProc(glDeleteRenderbuffers_Impl, glDeleteRenderbuffers); - GLELoadProc(glFramebufferRenderbuffer_Impl, glFramebufferRenderbuffer); - GLELoadProc(glFramebufferTexture1D_Impl, glFramebufferTexture1D); - GLELoadProc(glFramebufferTexture2D_Impl, glFramebufferTexture2D); - GLELoadProc(glFramebufferTexture3D_Impl, glFramebufferTexture3D); - GLELoadProc(glFramebufferTextureLayer_Impl, glFramebufferTextureLayer); - GLELoadProc(glGenFramebuffers_Impl, glGenFramebuffers); - GLELoadProc(glGenRenderbuffers_Impl, glGenRenderbuffers); - GLELoadProc(glGenerateMipmap_Impl, glGenerateMipmap); - GLELoadProc(glGetFramebufferAttachmentParameteriv_Impl, glGetFramebufferAttachmentParameteriv); - GLELoadProc(glGetRenderbufferParameteriv_Impl, glGetRenderbufferParameteriv); - GLELoadProc(glIsFramebuffer_Impl, glIsFramebuffer); - GLELoadProc(glIsRenderbuffer_Impl, glIsRenderbuffer); - GLELoadProc(glRenderbufferStorage_Impl, glRenderbufferStorage); - GLELoadProc(glRenderbufferStorageMultisample_Impl, glRenderbufferStorageMultisample); - - if(!glBindFramebuffer_Impl) // This will rarely if ever be the case in practice with modern computers and drivers. - { - // See if we can map GL_EXT_framebuffer_object to GL_ARB_framebuffer_object. The former is basically a subset of the latter, but we use only that subset. - GLELoadProc(glBindFramebuffer_Impl, glBindFramebufferEXT); - GLELoadProc(glBindRenderbuffer_Impl, glBindRenderbufferEXT); - //GLELoadProc(glBlitFramebuffer_Impl, glBlitFramebufferEXT (nonexistent)); - GLELoadProc(glCheckFramebufferStatus_Impl, glCheckFramebufferStatusEXT); - GLELoadProc(glDeleteFramebuffers_Impl, glDeleteFramebuffersEXT); - GLELoadProc(glDeleteRenderbuffers_Impl, glDeleteRenderbuffersEXT); - GLELoadProc(glFramebufferRenderbuffer_Impl, glFramebufferRenderbufferEXT); - GLELoadProc(glFramebufferTexture1D_Impl, glFramebufferTexture1DEXT); - GLELoadProc(glFramebufferTexture2D_Impl, glFramebufferTexture2DEXT); - GLELoadProc(glFramebufferTexture3D_Impl, glFramebufferTexture3DEXT); - //GLELoadProc(glFramebufferTextureLayer_Impl, glFramebufferTextureLayerEXT (nonexistent)); - GLELoadProc(glGenFramebuffers_Impl, glGenFramebuffersEXT); - GLELoadProc(glGenRenderbuffers_Impl, glGenRenderbuffersEXT); - GLELoadProc(glGenerateMipmap_Impl, glGenerateMipmapEXT); - GLELoadProc(glGetFramebufferAttachmentParameteriv_Impl, glGetFramebufferAttachmentParameterivEXT); - GLELoadProc(glGetRenderbufferParameteriv_Impl, glGetRenderbufferParameterivEXT); - GLELoadProc(glIsFramebuffer_Impl, glIsFramebufferEXT); - GLELoadProc(glIsRenderbuffer_Impl, glIsRenderbufferEXT); - GLELoadProc(glRenderbufferStorage_Impl, glRenderbufferStorageEXT); - //GLELoadProc(glRenderbufferStorageMultisample_Impl, glRenderbufferStorageMultisampleEXT (nonexistent)); - } - - // GL_ARB_texture_multisample - GLELoadProc(glGetMultisamplefv_Impl, glGetMultisamplefv); - GLELoadProc(glSampleMaski_Impl, glSampleMaski); - GLELoadProc(glTexImage2DMultisample_Impl, glTexImage2DMultisample); - GLELoadProc(glTexImage3DMultisample_Impl, glTexImage3DMultisample); - - // GL_ARB_timer_query - GLELoadProc(glGetQueryObjecti64v_Impl, glGetQueryObjecti64v); - GLELoadProc(glGetQueryObjectui64v_Impl, glGetQueryObjectui64v); - GLELoadProc(glQueryCounter_Impl, glQueryCounter); - - // GL_ARB_vertex_array_object - GLELoadProc(glBindVertexArray_Impl, glBindVertexArray); - GLELoadProc(glDeleteVertexArrays_Impl, glDeleteVertexArrays); - GLELoadProc(glGenVertexArrays_Impl, glGenVertexArrays); - GLELoadProc(glIsVertexArray_Impl, glIsVertexArray); - - #if defined(GLE_CGL_ENABLED) // Apple OpenGL... - if(WholeVersion < 302) // It turns out that Apple OpenGL versions prior to 3.2 have glBindVertexArray, etc. but they silently fail by default. So always use the APPLE version. - { - glBindVertexArray_Impl = glBindVertexArrayAPPLE_Impl; - glDeleteVertexArrays_Impl = glDeleteVertexArraysAPPLE_Impl; - glGenVertexArrays_Impl = (OVRTypeof(glGenVertexArrays_Impl)) glGenVertexArraysAPPLE_Impl; // There is a const cast of the arrays argument here due to a slight difference in the Apple behavior. For our purposes it should be OK. - glIsVertexArray_Impl = glIsVertexArrayAPPLE_Impl; - - if(glBindVertexArray_Impl) - gle_ARB_vertex_array_object = true; // We are routing the APPLE version through our version, with the assumption that we use the ARB version the same as we would use the APPLE version. - } - #endif - - // GL_EXT_draw_buffers2 - GLELoadProc(glColorMaskIndexedEXT_Impl, glColorMaskIndexedEXT); - GLELoadProc(glDisableIndexedEXT_Impl, glDisableIndexedEXT); - GLELoadProc(glEnableIndexedEXT_Impl, glEnableIndexedEXT); - GLELoadProc(glGetBooleanIndexedvEXT_Impl, glGetBooleanIndexedvEXT); - GLELoadProc(glGetIntegerIndexedvEXT_Impl, glGetIntegerIndexedvEXT); - GLELoadProc(glIsEnabledIndexedEXT_Impl, glIsEnabledIndexedEXT); - - // GL_KHR_debug - GLELoadProc(glDebugMessageCallback_Impl, glDebugMessageCallback); - GLELoadProc(glDebugMessageControl_Impl, glDebugMessageControl); - GLELoadProc(glDebugMessageInsert_Impl, glDebugMessageInsert); - GLELoadProc(glGetDebugMessageLog_Impl, glGetDebugMessageLog); - GLELoadProc(glGetObjectLabel_Impl, glGetObjectLabel); - GLELoadProc(glGetObjectPtrLabel_Impl, glGetObjectPtrLabel); - GLELoadProc(glObjectLabel_Impl, glObjectLabel); - GLELoadProc(glObjectPtrLabel_Impl, glObjectPtrLabel); - GLELoadProc(glPopDebugGroup_Impl, glPopDebugGroup); - GLELoadProc(glPushDebugGroup_Impl, glPushDebugGroup); - - // GL_WIN_swap_hint - GLELoadProc(glAddSwapHintRectWIN_Impl, glAddSwapHintRectWIN); - } - - - - OVR_DISABLE_MSVC_WARNING(4510 4512 4610) // default constructor could not be generated, - struct ValueStringPair - { - bool& IsPresent; - const char* ExtensionName; - }; - - - // Helper function for InitExtensionSupport. - static void CheckExtensions(ValueStringPair* pValueStringPairArray, size_t arrayCount, const char* extensions) - { - // We search the extesion list string for each of the individual extensions we are interested in. - // We do this by walking over the string and comparing each entry in turn to our array of entries of interest. - // Example string (with patholigical extra spaces): " ext1 ext2 ext3 " - - char extension[64]; - const char* p = extensions; // p points to the beginning of the current word - const char* pEnd; // pEnd points to one-past the last character of the current word. It is where the trailing '\0' of the string would be. - - while(*p) - { - while(*p == ' ') // Find the next word begin. - ++p; - - pEnd = p; - - while((*pEnd != '\0') && (*pEnd != ' ')) // Find the next word end. - ++pEnd; - - if(((pEnd - p) > 0) && ((size_t)(pEnd - p) < OVR_ARRAY_COUNT(extension))) - { - memcpy(extension, p, pEnd - p); // To consider: Revise this code to directly read from p/pEnd instead of doing a memcpy. - extension[pEnd - p] = '\0'; - - for(size_t i = 0; i < arrayCount; i++) // For each extension we are interested in... - { - ValueStringPair& vsp = pValueStringPairArray[i]; - - if(strcmp(extension, vsp.ExtensionName) == 0) // case-sensitive compare - pValueStringPairArray[i].IsPresent = true; - } - } - - p = pEnd; - } - } - - - void OVR::GLEContext::InitExtensionSupport() - { - // It may be better in the long run to use a member STL map. - // It would make this loading code cleaner, though it would make lookups slower. - - ValueStringPair vspArray[] = - { - { gle_AMD_debug_output, "GL_AMD_debug_output" }, - #if defined(GLE_CGL_ENABLED) - { gle_APPLE_aux_depth_stencil, "GL_APPLE_aux_depth_stencil" }, - { gle_APPLE_client_storage, "GL_APPLE_client_storage" }, - { gle_APPLE_element_array, "GL_APPLE_element_array" }, - { gle_APPLE_fence, "GL_APPLE_fence" }, - { gle_APPLE_float_pixels, "GL_APPLE_float_pixels" }, - { gle_APPLE_flush_buffer_range, "GL_APPLE_flush_buffer_range" }, - { gle_APPLE_object_purgeable, "GL_APPLE_object_purgeable" }, - { gle_APPLE_pixel_buffer, "GL_APPLE_pixel_buffer" }, - { gle_APPLE_rgb_422, "GL_APPLE_rgb_422" }, - { gle_APPLE_row_bytes, "GL_APPLE_row_bytes" }, - { gle_APPLE_specular_vector, "GL_APPLE_specular_vector" }, - { gle_APPLE_texture_range, "GL_APPLE_texture_range" }, - { gle_APPLE_transform_hint, "GL_APPLE_transform_hint" }, - { gle_APPLE_vertex_array_object, "GL_APPLE_vertex_array_object" }, - { gle_APPLE_vertex_array_range, "GL_APPLE_vertex_array_range" }, - { gle_APPLE_vertex_program_evaluators, "GL_APPLE_vertex_program_evaluators" }, - { gle_APPLE_ycbcr_422, "GL_APPLE_ycbcr_422" }, - #endif - { gle_ARB_debug_output, "GL_ARB_debug_output" }, - { gle_ARB_depth_buffer_float, "GL_ARB_depth_buffer_float" }, - { gle_ARB_ES2_compatibility, "GL_ARB_ES2_compatibility" }, - { gle_ARB_framebuffer_object, "GL_ARB_framebuffer_object" }, - { gle_ARB_framebuffer_object, "GL_EXT_framebuffer_object" }, // We map glBindFramebuffer, etc. to glBindFramebufferEXT, etc. if necessary - { gle_ARB_framebuffer_sRGB, "GL_ARB_framebuffer_sRGB" }, - { gle_ARB_texture_multisample, "GL_ARB_texture_multisample" }, - { gle_ARB_texture_non_power_of_two, "GL_ARB_texture_non_power_of_two" }, - { gle_ARB_texture_rectangle, "GL_ARB_texture_rectangle" }, - { gle_ARB_texture_rectangle, "GL_EXT_texture_rectangle" }, // We also check for GL_EXT_texture_rectangle and GL_NV_texture_rectangle. - { gle_ARB_texture_rectangle, "GL_NV_texture_rectangle" }, - { gle_ARB_timer_query, "GL_ARB_timer_query" }, - { gle_ARB_vertex_array_object, "GL_ARB_vertex_array_object" }, - { gle_EXT_draw_buffers2, "GL_EXT_draw_buffers2" }, - { gle_EXT_texture_compression_s3tc, "GL_EXT_texture_compression_s3tc" }, - { gle_EXT_texture_filter_anisotropic, "GL_EXT_texture_filter_anisotropic" }, - { gle_KHR_debug, "GL_KHR_debug" }, - { gle_WIN_swap_hint, "GL_WIN_swap_hint" } - // Windows WGL, Unix GLX, and Apple CGL extensions are handled below, as they require different calls from glGetString(GL_EXTENSIONS). - }; - - // We cannot use glGetString(GL_EXTENSIONS) when an OpenGL core profile is active, - // as it's deprecated in favor of using OpenGL 3+ glGetStringi. - const char* extensions = (MajorVersion < 3) ? (const char*)glGetString(GL_EXTENSIONS) : ""; - - if (extensions && *extensions) // If we have a space-delimited extension string to search for individual extensions... - { - OVR_DEBUG_LOG(("GL_EXTENSIONS: %s", (const char*)extensions)); - CheckExtensions(vspArray, OVR_ARRAY_COUNT(vspArray), extensions); // Call our shared helper function for this. - } - else - { - if(MajorVersion >= 3) // If glGetIntegerv(GL_NUM_EXTENSIONS, ...) is supported... - { - // In this case we need to match an array of individual extensions against an array of - // externsions provided by glGetStringi. This is an O(n^2) operation, but at least we - // are doing this only once on startup. There are a few tricks we can employ to speed - // up the logic below, but they may not be worth much. - - GLint extensionCount = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); - GLenum err = glGetError(); - - if(err == 0) - { - #ifdef OVR_BUILD_DEBUG - OVR::StringBuffer extensionsStr; - #endif - - for(GLint e = 0; e != extensionCount; ++e) // For each extension supported... - { - const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, (GLuint)e); - - if(extension) // glGetStringi returns NULL upon error. - { - #ifdef OVR_BUILD_DEBUG - extensionsStr.AppendFormat(" %s", extension); - #endif - - for(size_t i = 0; i < OVR_ARRAY_COUNT(vspArray); i++) // For each extension we are interested in... - { - ValueStringPair& vsp = vspArray[i]; - - if(strcmp(extension, vsp.ExtensionName) == 0) // case-sensitive compare - vspArray[i].IsPresent = true; - } - } - else - break; - } - - OVR_DEBUG_LOG(("GL_EXTENSIONS: %s", extensionsStr.ToCStr())); - } - } - // Else we have a problem: no means to read the extensions was successful. - } - - #if defined(GLE_CGL_ENABLED) - // The following are built into Apple OpenGL 3.2+ (declared in ) and not identified as extensions. - // On other platforms (e.g. Windows) these are identified as extensions and are detected above. - if(WholeVersion >= 302) - { - gle_ARB_depth_buffer_float = true; - gle_ARB_framebuffer_object = true; - gle_ARB_framebuffer_sRGB = true; - gle_ARB_texture_multisample = true; - gle_ARB_texture_non_power_of_two = true; - gle_ARB_texture_rectangle = true; - gle_ARB_vertex_array_object = true; - } - #endif - - } // GLEContext::InitExtensionSupport() - - - void OVR::GLEContext::InitPlatformVersion() - { - #if defined(GLE_GLX_ENABLED) - const char* pGLXVersion = glXGetClientString(glXGetCurrentDisplay(), GLX_VERSION); // To do: Use a better mechanism to get the desired display. - sscanf(pGLXVersion, "%d.%d", &PlatformMajorVersion, &PlatformMinorVersion); - - #elif defined(GLE_EGL_ENABLED) - const char* pEGLVersion = eglQueryString(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_VERSION); - sscanf(pEGLVersion, "%d.%d", &PlatformMajorVersion, &PlatformMinorVersion); - - #else - PlatformMajorVersion = 1; - PlatformMinorVersion = 0; - PlatformWholeVersion = 100; - #endif - } - - - void OVR::GLEContext::InitPlatformExtensionLoad() - { - #if defined(GLE_WGL_ENABLED) - // WGL - // We don't load these as function pointers but rather statically link to them. - // These need to be loaded via LoadLibrary instead of wglLoadLibrary. - - #if 0 - HINSTANCE hOpenGL = LoadLibraryW(L"Opengl32.dll"); - if(hOpenGL) - { - wglCopyContext_Impl = (OVRTypeof(wglCopyContext_Impl)) GetProcAddress(hOpenGL, "wglCopyContext"); - wglCreateContext_Impl = (OVRTypeof(wglCreateContext_Impl)) GetProcAddress(hOpenGL, "wglCreateContext"); - wglCreateLayerContext_Impl = (OVRTypeof(wglCreateLayerContext_Impl)) GetProcAddress(hOpenGL, "wglCreateLayerContext"); - wglDeleteContext_Impl = (OVRTypeof(wglDeleteContext_Impl)) GetProcAddress(hOpenGL, "wglDeleteContext"); - wglGetCurrentContext_Impl = (OVRTypeof(wglGetCurrentContext_Impl)) GetProcAddress(hOpenGL, "wglGetCurrentContext"); - wglGetCurrentDC_Impl = (OVRTypeof(wglGetCurrentDC_Impl)) GetProcAddress(hOpenGL, "wglGetCurrentDC"); - wglGetProcAddress_Impl = (OVRTypeof(wglGetProcAddress_Impl)) GetProcAddress(hOpenGL, "wglGetProcAddress"); - wglMakeCurrent_Impl = (OVRTypeof(wglMakeCurrent_Impl)) GetProcAddress(hOpenGL, "wglMakeCurrent"); - wglShareLists_Impl = (OVRTypeof(wglShareLists_Impl)) GetProcAddress(hOpenGL, "wglShareLists"); - wglUseFontBitmapsA_Impl = (OVRTypeof(wglUseFontBitmapsA_Impl)) GetProcAddress(hOpenGL, "wglUseFontBitmapsA"); - wglUseFontBitmapsW_Impl = (OVRTypeof(wglUseFontBitmapsW_Impl)) GetProcAddress(hOpenGL, "wglUseFontBitmapsW"); - wglUseFontOutlinesA_Impl = (OVRTypeof(wglUseFontOutlinesA_Impl)) GetProcAddress(hOpenGL, "wglUseFontOutlinesA"); - wglUseFontOutlinesW_Impl = (OVRTypeof(wglUseFontOutlinesW_Impl)) GetProcAddress(hOpenGL, "wglUseFontOutlinesW"); - wglDescribeLayerPlane_Impl = (OVRTypeof(wglDescribeLayerPlane_Impl)) GetProcAddress(hOpenGL, "wglDescribeLayerPlane"); - wglSetLayerPaletteEntries_Impl = (OVRTypeof(wglSetLayerPaletteEntries_Impl)) GetProcAddress(hOpenGL, "wglSetLayerPaletteEntries"); - wglGetLayerPaletteEntries_Impl = (OVRTypeof(wglGetLayerPaletteEntries_Impl)) GetProcAddress(hOpenGL, "wglGetLayerPaletteEntries"); - wglRealizeLayerPalette_Impl = (OVRTypeof(wglRealizeLayerPalette_Impl)) GetProcAddress(hOpenGL, "wglRealizeLayerPalette"); - wglSwapLayerBuffers_Impl = (OVRTypeof(wglSwapLayerBuffers_Impl)) GetProcAddress(hOpenGL, "wglSwapLayerBuffers"); - wglSwapMultipleBuffers_Impl = (OVRTypeof(wglSwapMultipleBuffers_Impl)) GetProcAddress(hOpenGL, "wglSwapMultipleBuffers"); - FreeLibrary(hOpenGL); - } - #endif - - // WGL_ARB_buffer_region - GLELoadProc(wglCreateBufferRegionARB_Impl, wglCreateBufferRegionARB); - GLELoadProc(wglDeleteBufferRegionARB_Impl, wglDeleteBufferRegionARB); - GLELoadProc(wglSaveBufferRegionARB_Impl, wglSaveBufferRegionARB); - GLELoadProc(wglRestoreBufferRegionARB_Impl, wglRestoreBufferRegionARB); - - // WGL_ARB_extensions_string - GLELoadProc(wglGetExtensionsStringARB_Impl, wglGetExtensionsStringARB); - - // WGL_ARB_pixel_format - GLELoadProc(wglGetPixelFormatAttribivARB_Impl, wglGetPixelFormatAttribivARB); - GLELoadProc(wglGetPixelFormatAttribfvARB_Impl, wglGetPixelFormatAttribfvARB); - GLELoadProc(wglChoosePixelFormatARB_Impl, wglChoosePixelFormatARB); - - // WGL_ARB_make_current_read - GLELoadProc(wglMakeContextCurrentARB_Impl, wglMakeContextCurrentARB); - GLELoadProc(wglGetCurrentReadDCARB_Impl, wglGetCurrentReadDCARB); - - // WGL_ARB_pbuffer - GLELoadProc(wglCreatePbufferARB_Impl, wglCreatePbufferARB); - GLELoadProc(wglGetPbufferDCARB_Impl, wglGetPbufferDCARB); - GLELoadProc(wglReleasePbufferDCARB_Impl, wglReleasePbufferDCARB); - GLELoadProc(wglDestroyPbufferARB_Impl, wglDestroyPbufferARB); - GLELoadProc(wglQueryPbufferARB_Impl, wglQueryPbufferARB); - - // WGL_ARB_render_texture - GLELoadProc(wglBindTexImageARB_Impl, wglBindTexImageARB); - GLELoadProc(wglReleaseTexImageARB_Impl, wglReleaseTexImageARB); - GLELoadProc(wglSetPbufferAttribARB_Impl, wglSetPbufferAttribARB); - - // WGL_NV_present_video - GLELoadProc(wglEnumerateVideoDevicesNV_Impl, wglEnumerateVideoDevicesNV); - GLELoadProc(wglBindVideoDeviceNV_Impl, wglBindVideoDeviceNV); - GLELoadProc(wglQueryCurrentContextNV_Impl, wglQueryCurrentContextNV); - - // WGL_ARB_create_context - GLELoadProc(wglCreateContextAttribsARB_Impl, wglCreateContextAttribsARB); - - // WGL_EXT_extensions_string - GLELoadProc(wglGetExtensionsStringEXT_Impl, wglGetExtensionsStringEXT); - - // WGL_EXT_swap_control - GLELoadProc(wglGetSwapIntervalEXT_Impl, wglGetSwapIntervalEXT); - GLELoadProc(wglSwapIntervalEXT_Impl, wglSwapIntervalEXT); - - // WGL_OML_sync_control - GLELoadProc(wglGetSyncValuesOML_Impl, wglGetSyncValuesOML); - GLELoadProc(wglGetMscRateOML_Impl, wglGetMscRateOML); - GLELoadProc(wglSwapBuffersMscOML_Impl, wglSwapBuffersMscOML); - GLELoadProc(wglSwapLayerBuffersMscOML_Impl, wglSwapLayerBuffersMscOML); - GLELoadProc(wglWaitForMscOML_Impl, wglWaitForMscOML); - GLELoadProc(wglWaitForSbcOML_Impl, wglWaitForSbcOML); - - // WGL_NV_video_output - GLELoadProc(wglGetVideoDeviceNV_Impl, wglGetVideoDeviceNV); - GLELoadProc(wglReleaseVideoDeviceNV_Impl, wglReleaseVideoDeviceNV); - GLELoadProc(wglBindVideoImageNV_Impl, wglBindVideoImageNV); - GLELoadProc(wglReleaseVideoImageNV_Impl, wglReleaseVideoImageNV); - GLELoadProc(wglSendPbufferToVideoNV_Impl, wglSendPbufferToVideoNV); - GLELoadProc(wglGetVideoInfoNV_Impl, wglGetVideoInfoNV); - - // WGL_NV_swap_group - GLELoadProc(wglJoinSwapGroupNV_Impl, wglJoinSwapGroupNV); - GLELoadProc(wglBindSwapBarrierNV_Impl, wglBindSwapBarrierNV); - GLELoadProc(wglQuerySwapGroupNV_Impl, wglQuerySwapGroupNV); - GLELoadProc(wglQueryMaxSwapGroupsNV_Impl, wglQueryMaxSwapGroupsNV); - GLELoadProc(wglQueryFrameCountNV_Impl, wglQueryFrameCountNV); - GLELoadProc(wglResetFrameCountNV_Impl, wglResetFrameCountNV); - - // WGL_NV_video_capture - GLELoadProc(wglBindVideoCaptureDeviceNV_Impl, wglBindVideoCaptureDeviceNV); - GLELoadProc(wglEnumerateVideoCaptureDevicesNV_Impl, wglEnumerateVideoCaptureDevicesNV); - GLELoadProc(wglLockVideoCaptureDeviceNV_Impl, wglLockVideoCaptureDeviceNV); - GLELoadProc(wglQueryVideoCaptureDeviceNV_Impl, wglQueryVideoCaptureDeviceNV); - GLELoadProc(wglReleaseVideoCaptureDeviceNV_Impl, wglReleaseVideoCaptureDeviceNV); - - // WGL_NV_copy_image - GLELoadProc(wglCopyImageSubDataNV_Impl, wglCopyImageSubDataNV); - - // WGL_NV_DX_interop - GLELoadProc(wglDXCloseDeviceNV_Impl, wglDXCloseDeviceNV); - GLELoadProc(wglDXLockObjectsNV_Impl, wglDXLockObjectsNV); - GLELoadProc(wglDXObjectAccessNV_Impl, wglDXObjectAccessNV); - GLELoadProc(wglDXOpenDeviceNV_Impl, wglDXOpenDeviceNV); - GLELoadProc(wglDXRegisterObjectNV_Impl, wglDXRegisterObjectNV); - GLELoadProc(wglDXSetResourceShareHandleNV_Impl, wglDXSetResourceShareHandleNV); - GLELoadProc(wglDXUnlockObjectsNV_Impl, wglDXUnlockObjectsNV); - GLELoadProc(wglDXUnregisterObjectNV_Impl, wglDXUnregisterObjectNV); - - #elif defined(GLE_GLX_ENABLED) - // GLX_VERSION_1_1 - // We don't create any pointers_Impl, because we assume these functions are always present. - - // GLX_VERSION_1_2 - GLELoadProc(glXGetCurrentDisplay_Impl, glXGetCurrentDisplay); - - // GLX_VERSION_1_3 - GLELoadProc(glXChooseFBConfig_Impl, glXChooseFBConfig); - GLELoadProc(glXCreateNewContext_Impl, glXCreateNewContext); - GLELoadProc(glXCreatePbuffer_Impl, glXCreatePbuffer); - GLELoadProc(glXCreatePixmap_Impl, glXCreatePixmap); - GLELoadProc(glXCreateWindow_Impl, glXCreateWindow); - GLELoadProc(glXDestroyPbuffer_Impl, glXDestroyPbuffer); - GLELoadProc(glXDestroyPixmap_Impl, glXDestroyPixmap); - GLELoadProc(glXDestroyWindow_Impl, glXDestroyWindow); - GLELoadProc(glXGetCurrentReadDrawable_Impl, glXGetCurrentReadDrawable); - GLELoadProc(glXGetFBConfigAttrib_Impl, glXGetFBConfigAttrib); - GLELoadProc(glXGetFBConfigs_Impl, glXGetFBConfigs); - GLELoadProc(glXGetSelectedEvent_Impl, glXGetSelectedEvent); - GLELoadProc(glXGetVisualFromFBConfig_Impl, glXGetVisualFromFBConfig); - GLELoadProc(glXMakeContextCurrent_Impl, glXMakeContextCurrent); - GLELoadProc(glXQueryContext_Impl, glXQueryContext); - GLELoadProc(glXQueryDrawable_Impl, glXQueryDrawable); - GLELoadProc(glXSelectEvent_Impl, glXSelectEvent); - - // GLX_VERSION_1_4 - // Nothing to declare - - // GLX_ARB_create_context - GLELoadProc(glXCreateContextAttribsARB_Impl, glXCreateContextAttribsARB); - - // GLX_EXT_swap_control - GLELoadProc(glXSwapIntervalEXT_Impl, glXSwapIntervalEXT); - - // GLX_OML_sync_control - GLELoadProc(glXGetMscRateOML_Impl, glXGetMscRateOML); - GLELoadProc(glXGetSyncValuesOML_Impl, glXGetSyncValuesOML); - GLELoadProc(glXGetSyncValuesOML_Impl, glXSwapBuffersMscOML); - GLELoadProc(glXSwapBuffersMscOML_Impl, glXSwapBuffersMscOML); - GLELoadProc(glXWaitForSbcOML_Impl, glXWaitForSbcOML); - - // GLX_MESA_swap_control - GLELoadProc(glXGetSwapIntervalMESA_Impl, glXGetSwapIntervalMESA); - GLELoadProc(glXSwapIntervalMESA_Impl, glXSwapIntervalMESA); - #endif - } - - - void OVR::GLEContext::InitPlatformExtensionSupport() - { - #if defined(GLE_WGL_ENABLED) - // We need to use wglGetExtensionsStringARB or wglGetExtensionsStringEXT as opposed to above with glGetString(GL_EXTENSIONS). - ValueStringPair vspWGLArray[] = - { - { gle_WGL_ARB_buffer_region, "WGL_ARB_buffer_region" } - ,{ gle_WGL_ARB_create_context, "WGL_ARB_create_context" } - ,{ gle_WGL_ARB_create_context_profile, "WGL_ARB_create_context_profile" } - ,{ gle_WGL_ARB_create_context_robustness, "WGL_ARB_create_context_robustness" } - ,{ gle_WGL_ARB_extensions_string, "WGL_ARB_extensions_string" } - ,{ gle_WGL_ARB_framebuffer_sRGB, "WGL_ARB_framebuffer_sRGB" } - ,{ gle_WGL_ARB_framebuffer_sRGB, "WGL_EXT_framebuffer_sRGB" } // We map the EXT to the ARB. - ,{ gle_WGL_ARB_make_current_read, "WGL_ARB_make_current_read" } - ,{ gle_WGL_ARB_pbuffer, "WGL_ARB_pbuffer" } - ,{ gle_WGL_ARB_pixel_format, "WGL_ARB_pixel_format" } - ,{ gle_WGL_ARB_pixel_format_float, "WGL_ARB_pixel_format_float" } - ,{ gle_WGL_ARB_render_texture, "WGL_ARB_render_texture" } - ,{ gle_WGL_ATI_render_texture_rectangle, "WGL_ATI_render_texture_rectangle" } - ,{ gle_WGL_EXT_extensions_string, "WGL_EXT_extensions_string" } - ,{ gle_WGL_EXT_swap_control, "WGL_EXT_swap_control" } - ,{ gle_WGL_NV_copy_image, "WGL_NV_copy_image" } - ,{ gle_WGL_NV_DX_interop, "WGL_NV_DX_interop" } - ,{ gle_WGL_NV_DX_interop2, "WGL_NV_DX_interop2" } - ,{ gle_WGL_NV_present_video, "WGL_NV_present_video" } - ,{ gle_WGL_NV_render_texture_rectangle, "WGL_NV_render_texture_rectangle" } - ,{ gle_WGL_NV_swap_group, "WGL_NV_swap_group" } - ,{ gle_WGL_NV_video_capture, "WGL_NV_video_capture" } - ,{ gle_WGL_NV_video_output, "WGL_NV_video_output" } - ,{ gle_WGL_OML_sync_control, "WGL_OML_sync_control" } - }; - - const char* extensions = NULL; - - if(wglGetExtensionsStringARB_Impl) - extensions = wglGetExtensionsStringARB_Impl(wglGetCurrentDC()); // To do: Use a better mechanism to get the desired HDC. - else if(wglGetExtensionsStringEXT_Impl) - extensions = wglGetExtensionsStringEXT_Impl(); - - if (extensions && *extensions) - { - OVR_DEBUG_LOG(("WGL_EXTENSIONS: %s", (const char*)extensions)); - CheckExtensions(vspWGLArray, OVR_ARRAY_COUNT(vspWGLArray), extensions); - } - - #elif defined(GLE_GLX_ENABLED) - ValueStringPair vspGLXArray[] = - { - { gle_GLX_ARB_create_context, "GLX_ARB_create_context" } - ,{ gle_GLX_ARB_create_context_profile, "GLX_ARB_create_context_profile" } - ,{ gle_GLX_ARB_create_context_robustness, "GLX_ARB_create_context_robustness" } - ,{ gle_GLX_EXT_swap_control, "GLX_EXT_swap_control" } - ,{ gle_GLX_OML_sync_control, "GLX_OML_sync_control" } - ,{ gle_MESA_swap_control, "GLX_MESA_swap_control" } - }; - - const char* extensions = glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); // To do: Use a better mechanism to get the desired display. - - if (extensions && *extensions) - { - OVR_DEBUG_LOG(("GLX_EXTENSIONS: %s", (const char*)extensions)); - CheckExtensions(vspGLXArray, OVR_ARRAY_COUNT(vspGLXArray), extensions); - } - #endif - } - - - #if defined(GLE_HOOKING_ENABLED) - - #undef glGetError - extern "C" { GLAPI GLenum GLAPIENTRY glGetError(); } - - // Disabled until such time as it might be useful to enable for debug purposes. - //void OVR::GLEContext::PreHook(const char* functionName) - //{ - // if(EnableHookGetError) - // { - // int err = glGetError(); - // - // for(int i = 0; (i < 6) && (err != GL_NO_ERROR); i++) // 6 is an arbitrary cap to prevent infinite looping which would occur if the current GL context is invalid. - // { - // OVR_DEBUG_LOG(("GL Error prior to hook: %d (%#x) from %s", err, err, functionName ? functionName : "OpenGL")); OVR_UNUSED(functionName); - // err = glGetError(); - // } - // } - //} - - void OVR::GLEContext::PostHook(const char* functionName) - { - if(EnableHookGetError) - { - // OpenGL Standard regarding error state: To allow for distributed implementations, there may be several error flags. If any single error flag has recorded an error, the value of that flag - // is returned and that flag is reset to GL_NO_ERROR when glGetError is called. If more than one flag has recorded an error, glGetError returns and - // clears an arbitrary error flag value. Thus, glGetError should always be called in a loop, until it returns GL_NO_ERROR, if all error flags are to be reset. - int err = glGetError(); - - for(int i = 0; (i < 6) && (err != GL_NO_ERROR); i++) // 6 is an arbitrary cap to prevent infinite looping which would occur if the current GL context is invalid. - { - OVR_DEBUG_LOG(("GL Error: %d (%#x) from %s", err, err, functionName ? functionName : "OpenGL")); OVR_UNUSED(functionName); - err = glGetError(); - } - } - } - - - // OpenGL 1.1 link-based functions - #undef glAccum // Undefine the macro from our header so that we can directly call the real version of this function. - extern "C" { GLAPI void GLAPIENTRY glAccum(GLenum op, GLfloat value); } - void OVR::GLEContext::glAccum_Hook(GLenum op, GLfloat value) - { - glAccum(op, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glAlphaFunc - extern "C" { GLAPI void GLAPIENTRY glAlphaFunc(GLenum func, GLclampf ref); } - void OVR::GLEContext::glAlphaFunc_Hook(GLenum func, GLclampf ref) - { - glAlphaFunc(func, ref); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glAreTexturesResident - extern "C" { GLAPI GLboolean GLAPIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences); } - GLboolean OVR::GLEContext::glAreTexturesResident_Hook(GLsizei n, const GLuint *textures, GLboolean *residences) - { - GLboolean b = glAreTexturesResident(n, textures, residences); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef glArrayElement - extern "C" { GLAPI void GLAPIENTRY glArrayElement(GLint i); } - void OVR::GLEContext::glArrayElement_Hook(GLint i) - { - glArrayElement(i); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glBegin - extern "C" { GLAPI void GLAPIENTRY glBegin(GLenum mode); } - void OVR::GLEContext::glBegin_Hook(GLenum mode) - { - glBegin(mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glBindTexture - extern "C" { GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture); } - void OVR::GLEContext::glBindTexture_Hook(GLenum target, GLuint texture) - { - glBindTexture(target, texture); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glBitmap - extern "C" { GLAPI void GLAPIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); } - void OVR::GLEContext::glBitmap_Hook(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) - { - glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glBlendFunc - extern "C" { GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor); } - void OVR::GLEContext::glBlendFunc_Hook(GLenum sfactor, GLenum dfactor) - { - glBlendFunc(sfactor, dfactor); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glCallList - extern "C" { GLAPI void GLAPIENTRY glCallList(GLuint list); } - void OVR::GLEContext::glCallList_Hook(GLuint list) - { - glCallList(list); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glCallLists - extern "C" { GLAPI void GLAPIENTRY glCallLists(GLsizei n, GLenum type, const void *lists); } - void OVR::GLEContext::glCallLists_Hook(GLsizei n, GLenum type, const void *lists) - { - glCallLists(n, type, lists); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glClear - extern "C" { GLAPI void GLAPIENTRY glClear(GLbitfield mask); } - void OVR::GLEContext::glClear_Hook(GLbitfield mask) - { - glClear(mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glClearAccum - extern "C" { GLAPI void GLAPIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); } - void OVR::GLEContext::glClearAccum_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) - { - glClearAccum(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glClearColor - extern "C" { GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); } - void OVR::GLEContext::glClearColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) - { - glClearColor(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glClearDepth - extern "C" { GLAPI void GLAPIENTRY glClearDepth(GLclampd depth); } - void OVR::GLEContext::glClearDepth_Hook(GLclampd depth) - { - glClearDepth(depth); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glClearIndex - extern "C" { GLAPI void GLAPIENTRY glClearIndex(GLfloat c); } - void OVR::GLEContext::glClearIndex_Hook(GLfloat c) - { - glClearIndex(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glClearStencil - extern "C" { GLAPI void GLAPIENTRY glClearStencil(GLint s); } - void OVR::GLEContext::glClearStencil_Hook(GLint s) - { - glClearStencil(s); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glClipPlane - extern "C" { GLAPI void GLAPIENTRY glClipPlane(GLenum plane, const GLdouble *equation); } - void OVR::GLEContext::glClipPlane_Hook(GLenum plane, const GLdouble *equation) - { - glClipPlane(plane, equation); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3b - extern "C" { GLAPI void GLAPIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue); } - void OVR::GLEContext::glColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue) - { - glColor3b(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3bv - extern "C" { GLAPI void GLAPIENTRY glColor3bv(const GLbyte *v); } - void OVR::GLEContext::glColor3bv_Hook(const GLbyte *v) - { - glColor3bv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3d - extern "C" { GLAPI void GLAPIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue); } - void OVR::GLEContext::glColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue) - { - glColor3d(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3dv - extern "C" { GLAPI void GLAPIENTRY glColor3dv(const GLdouble *v); } - void OVR::GLEContext::glColor3dv_Hook(const GLdouble *v) - { - glColor3dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3f - extern "C" { GLAPI void GLAPIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue); } - void OVR::GLEContext::glColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue) - { - glColor3f(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3fv - extern "C" { GLAPI void GLAPIENTRY glColor3fv(const GLfloat *v); } - void OVR::GLEContext::glColor3fv_Hook(const GLfloat *v) - { - glColor3fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3i - extern "C" { GLAPI void GLAPIENTRY glColor3i(GLint red, GLint green, GLint blue); } - void OVR::GLEContext::glColor3i_Hook(GLint red, GLint green, GLint blue) - { - glColor3i(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3iv - extern "C" { GLAPI void GLAPIENTRY glColor3iv(const GLint *v); } - void OVR::GLEContext::glColor3iv_Hook(const GLint *v) - { - glColor3iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3s - extern "C" { GLAPI void GLAPIENTRY glColor3s(GLshort red, GLshort green, GLshort blue); } - void OVR::GLEContext::glColor3s_Hook(GLshort red, GLshort green, GLshort blue) - { - glColor3s(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3sv - extern "C" { GLAPI void GLAPIENTRY glColor3sv(const GLshort *v); } - void OVR::GLEContext::glColor3sv_Hook(const GLshort *v) - { - glColor3sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3ub - extern "C" { GLAPI void GLAPIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue); } - void OVR::GLEContext::glColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue) - { - glColor3ub(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3ubv - extern "C" { GLAPI void GLAPIENTRY glColor3ubv(const GLubyte *v); } - void OVR::GLEContext::glColor3ubv_Hook(const GLubyte *v) - { - glColor3ubv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3ui - extern "C" { GLAPI void GLAPIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue); } - void OVR::GLEContext::glColor3ui_Hook(GLuint red, GLuint green, GLuint blue) - { - glColor3ui(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3uiv - extern "C" { GLAPI void GLAPIENTRY glColor3uiv(const GLuint *v); } - void OVR::GLEContext::glColor3uiv_Hook(const GLuint *v) - { - glColor3uiv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3us - extern "C" { GLAPI void GLAPIENTRY glColor3us(GLushort red, GLushort green, GLushort blue); } - void OVR::GLEContext::glColor3us_Hook(GLushort red, GLushort green, GLushort blue) - { - glColor3us(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor3usv - extern "C" { GLAPI void GLAPIENTRY glColor3usv(const GLushort *v); } - void OVR::GLEContext::glColor3usv_Hook(const GLushort *v) - { - glColor3usv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4b - extern "C" { GLAPI void GLAPIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); } - void OVR::GLEContext::glColor4b_Hook(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) - { - glColor4b(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4bv - extern "C" { GLAPI void GLAPIENTRY glColor4bv(const GLbyte *v); } - void OVR::GLEContext::glColor4bv_Hook(const GLbyte *v) - { - glColor4bv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4d - extern "C" { GLAPI void GLAPIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); } - void OVR::GLEContext::glColor4d_Hook(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) - { - glColor4d(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4dv - extern "C" { GLAPI void GLAPIENTRY glColor4dv(const GLdouble *v); } - void OVR::GLEContext::glColor4dv_Hook(const GLdouble *v) - { - glColor4dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4f - extern "C" { GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); } - void OVR::GLEContext::glColor4f_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) - { - glColor4f(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4fv - extern "C" { GLAPI void GLAPIENTRY glColor4fv(const GLfloat *v); } - void OVR::GLEContext::glColor4fv_Hook(const GLfloat *v) - { - glColor4fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4i - extern "C" { GLAPI void GLAPIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha); } - void OVR::GLEContext::glColor4i_Hook(GLint red, GLint green, GLint blue, GLint alpha) - { - glColor4i(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4iv - extern "C" { GLAPI void GLAPIENTRY glColor4iv(const GLint *v); } - void OVR::GLEContext::glColor4iv_Hook(const GLint *v) - { - glColor4iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4s - extern "C" { GLAPI void GLAPIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha); } - void OVR::GLEContext::glColor4s_Hook(GLshort red, GLshort green, GLshort blue, GLshort alpha) - { - glColor4s(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4sv - extern "C" { GLAPI void GLAPIENTRY glColor4sv(const GLshort *v); } - void OVR::GLEContext::glColor4sv_Hook(const GLshort *v) - { - glColor4sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4ub - extern "C" { GLAPI void GLAPIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); } - void OVR::GLEContext::glColor4ub_Hook(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) - { - glColor4ub(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4ubv - extern "C" { GLAPI void GLAPIENTRY glColor4ubv(const GLubyte *v); } - void OVR::GLEContext::glColor4ubv_Hook(const GLubyte *v) - { - glColor4ubv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4ui - extern "C" { GLAPI void GLAPIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha); } - void OVR::GLEContext::glColor4ui_Hook(GLuint red, GLuint green, GLuint blue, GLuint alpha) - { - glColor4ui(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4uiv - extern "C" { GLAPI void GLAPIENTRY glColor4uiv(const GLuint *v); } - void OVR::GLEContext::glColor4uiv_Hook(const GLuint *v) - { - glColor4uiv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4us - extern "C" { GLAPI void GLAPIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha); } - void OVR::GLEContext::glColor4us_Hook(GLushort red, GLushort green, GLushort blue, GLushort alpha) - { - glColor4us(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColor4usv - extern "C" { GLAPI void GLAPIENTRY glColor4usv(const GLushort *v); } - void OVR::GLEContext::glColor4usv_Hook(const GLushort *v) - { - glColor4usv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColorMask - extern "C" { GLAPI void GLAPIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); } - void OVR::GLEContext::glColorMask_Hook(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) - { - glColorMask(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColorMaterial - extern "C" { GLAPI void GLAPIENTRY glColorMaterial(GLenum face, GLenum mode); } - void OVR::GLEContext::glColorMaterial_Hook(GLenum face, GLenum mode) - { - glColorMaterial(face, mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glColorPointer - extern "C" { GLAPI void GLAPIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); } - void OVR::GLEContext::glColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer) - { - glColorPointer(size, type, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glCopyPixels - extern "C" { GLAPI void GLAPIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); } - void OVR::GLEContext::glCopyPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) - { - glCopyPixels(x, y, width, height, type); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glCopyTexImage1D - extern "C" { GLAPI void GLAPIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); } - void OVR::GLEContext::glCopyTexImage1D_Hook(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border) - { - glCopyTexImage1D(target, level, internalFormat, x, y, width, border); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glCopyTexImage2D - extern "C" { GLAPI void GLAPIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); } - void OVR::GLEContext::glCopyTexImage2D_Hook(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) - { - glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glCopyTexSubImage1D - extern "C" { GLAPI void GLAPIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); } - void OVR::GLEContext::glCopyTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) - { - glCopyTexSubImage1D(target, level, xoffset, x, y, width); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glCopyTexSubImage2D - extern "C" { GLAPI void GLAPIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); } - void OVR::GLEContext::glCopyTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) - { - glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glCullFace - extern "C" { GLAPI void GLAPIENTRY glCullFace(GLenum mode); } - void OVR::GLEContext::glCullFace_Hook(GLenum mode) - { - glCullFace(mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDeleteLists - extern "C" { GLAPI void GLAPIENTRY glDeleteLists(GLuint list, GLsizei range); } - void OVR::GLEContext::glDeleteLists_Hook(GLuint list, GLsizei range) - { - glDeleteLists(list, range); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDeleteTextures - extern "C" { GLAPI void GLAPIENTRY glDeleteTextures(GLsizei n, const GLuint *textures); } - void OVR::GLEContext::glDeleteTextures_Hook(GLsizei n, const GLuint *textures) - { - glDeleteTextures(n, textures); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDepthFunc - extern "C" { GLAPI void GLAPIENTRY glDepthFunc(GLenum func); } - void OVR::GLEContext::glDepthFunc_Hook(GLenum func) - { - glDepthFunc(func); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDepthMask - extern "C" { GLAPI void GLAPIENTRY glDepthMask(GLboolean flag); } - void OVR::GLEContext::glDepthMask_Hook(GLboolean flag) - { - glDepthMask(flag); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDepthRange - extern "C" { GLAPI void GLAPIENTRY glDepthRange(GLclampd zNear, GLclampd zFar); } - void OVR::GLEContext::glDepthRange_Hook(GLclampd zNear, GLclampd zFar) - { - glDepthRange(zNear, zFar); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDisable - extern "C" { GLAPI void GLAPIENTRY glDisable(GLenum cap); } - void OVR::GLEContext::glDisable_Hook(GLenum cap) - { - glDisable(cap); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDisableClientState - extern "C" { GLAPI void GLAPIENTRY glDisableClientState(GLenum array); } - void OVR::GLEContext::glDisableClientState_Hook(GLenum array) - { - glDisableClientState(array); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDrawArrays - extern "C" { GLAPI void GLAPIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count); } - void OVR::GLEContext::glDrawArrays_Hook(GLenum mode, GLint first, GLsizei count) - { - glDrawArrays(mode, first, count); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDrawBuffer - extern "C" { GLAPI void GLAPIENTRY glDrawBuffer(GLenum mode); } - void OVR::GLEContext::glDrawBuffer_Hook(GLenum mode) - { - glDrawBuffer(mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDrawElements - extern "C" { GLAPI void GLAPIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); } - void OVR::GLEContext::glDrawElements_Hook(GLenum mode, GLsizei count, GLenum type, const void *indices) - { - glDrawElements(mode, count, type, indices); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glDrawPixels - extern "C" { GLAPI void GLAPIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); } - void OVR::GLEContext::glDrawPixels_Hook(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) - { - glDrawPixels(width, height, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEdgeFlag - extern "C" { GLAPI void GLAPIENTRY glEdgeFlag(GLboolean flag); } - void OVR::GLEContext::glEdgeFlag_Hook(GLboolean flag) - { - glEdgeFlag(flag); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEdgeFlagPointer - extern "C" { GLAPI void GLAPIENTRY glEdgeFlagPointer(GLsizei stride, const void *pointer); } - void OVR::GLEContext::glEdgeFlagPointer_Hook(GLsizei stride, const void *pointer) - { - glEdgeFlagPointer(stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEdgeFlagv - extern "C" { GLAPI void GLAPIENTRY glEdgeFlagv(const GLboolean *flag); } - void OVR::GLEContext::glEdgeFlagv_Hook(const GLboolean *flag) - { - glEdgeFlagv(flag); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEnable - extern "C" { GLAPI void GLAPIENTRY glEnable(GLenum cap); } - namespace OVR { - void GLEContext::glEnable_Hook(GLenum cap) - { - glEnable(cap); - PostHook(GLE_CURRENT_FUNCTION); - } - } - - #undef glEnableClientState - extern "C" { GLAPI void GLAPIENTRY glEnableClientState(GLenum array); } - void OVR::GLEContext::glEnableClientState_Hook(GLenum array) - { - glEnableClientState(array); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEnd - extern "C" { GLAPI void GLAPIENTRY glEnd(); } - void OVR::GLEContext::glEnd_Hook() - { - glEnd(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEndList - extern "C" { GLAPI void GLAPIENTRY glEndList(); } - void OVR::GLEContext::glEndList_Hook() - { - glEndList(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalCoord1d - extern "C" { GLAPI void GLAPIENTRY glEvalCoord1d(GLdouble u); } - void OVR::GLEContext::glEvalCoord1d_Hook(GLdouble u) - { - glEvalCoord1d(u); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalCoord1dv - extern "C" { GLAPI void GLAPIENTRY glEvalCoord1dv(const GLdouble *u); } - void OVR::GLEContext::glEvalCoord1dv_Hook(const GLdouble *u) - { - glEvalCoord1dv(u); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalCoord1f - extern "C" { GLAPI void GLAPIENTRY glEvalCoord1f(GLfloat u); } - void OVR::GLEContext::glEvalCoord1f_Hook(GLfloat u) - { - glEvalCoord1f(u); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalCoord1fv - extern "C" { GLAPI void GLAPIENTRY glEvalCoord1fv(const GLfloat *u); } - void OVR::GLEContext::glEvalCoord1fv_Hook(const GLfloat *u) - { - glEvalCoord1fv(u); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalCoord2d - extern "C" { GLAPI void GLAPIENTRY glEvalCoord2d(GLdouble u, GLdouble v); } - void OVR::GLEContext::glEvalCoord2d_Hook(GLdouble u, GLdouble v) - { - glEvalCoord2d(u, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalCoord2dv - extern "C" { GLAPI void GLAPIENTRY glEvalCoord2dv(const GLdouble *u); } - void OVR::GLEContext::glEvalCoord2dv_Hook(const GLdouble *u) - { - glEvalCoord2dv(u); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalCoord2f - extern "C" { GLAPI void GLAPIENTRY glEvalCoord2f(GLfloat u, GLfloat v); } - void OVR::GLEContext::glEvalCoord2f_Hook(GLfloat u, GLfloat v) - { - glEvalCoord2f(u, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalCoord2fv - extern "C" { GLAPI void GLAPIENTRY glEvalCoord2fv(const GLfloat *u); } - void OVR::GLEContext::glEvalCoord2fv_Hook(const GLfloat *u) - { - glEvalCoord2fv(u); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalMesh1 - extern "C" { GLAPI void GLAPIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2); } - void OVR::GLEContext::glEvalMesh1_Hook(GLenum mode, GLint i1, GLint i2) - { - glEvalMesh1(mode, i1, i2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalMesh2 - extern "C" { GLAPI void GLAPIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); } - void OVR::GLEContext::glEvalMesh2_Hook(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) - { - glEvalMesh2(mode, i1, i2, j1, j2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalPoint1 - extern "C" { GLAPI void GLAPIENTRY glEvalPoint1(GLint i); } - void OVR::GLEContext::glEvalPoint1_Hook(GLint i) - { - glEvalPoint1(i); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glEvalPoint2 - extern "C" { GLAPI void GLAPIENTRY glEvalPoint2(GLint i, GLint j); } - void OVR::GLEContext::glEvalPoint2_Hook(GLint i, GLint j) - { - glEvalPoint2(i, j); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFeedbackBuffer - extern "C" { GLAPI void GLAPIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer); } - void OVR::GLEContext::glFeedbackBuffer_Hook(GLsizei size, GLenum type, GLfloat *buffer) - { - glFeedbackBuffer(size, type, buffer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFinish - extern "C" { GLAPI void GLAPIENTRY glFinish(); } - void OVR::GLEContext::glFinish_Hook() - { - glFinish(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFlush - extern "C" { GLAPI void GLAPIENTRY glFlush(); } - void OVR::GLEContext::glFlush_Hook() - { - glFlush(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFogf - extern "C" { GLAPI void GLAPIENTRY glFogf(GLenum pname, GLfloat param); } - void OVR::GLEContext::glFogf_Hook(GLenum pname, GLfloat param) - { - glFogf(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFogfv - extern "C" { GLAPI void GLAPIENTRY glFogfv(GLenum pname, const GLfloat *params); } - void OVR::GLEContext::glFogfv_Hook(GLenum pname, const GLfloat *params) - { - glFogfv(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFogi - extern "C" { GLAPI void GLAPIENTRY glFogi(GLenum pname, GLint param); } - void OVR::GLEContext::glFogi_Hook(GLenum pname, GLint param) - { - glFogi(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFogiv - extern "C" { GLAPI void GLAPIENTRY glFogiv(GLenum pname, const GLint *params); } - void OVR::GLEContext::glFogiv_Hook(GLenum pname, const GLint *params) - { - glFogiv(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFrontFace - extern "C" { GLAPI void GLAPIENTRY glFrontFace(GLenum mode); } - void OVR::GLEContext::glFrontFace_Hook(GLenum mode) - { - glFrontFace(mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glFrustum - extern "C" { GLAPI void GLAPIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); } - void OVR::GLEContext::glFrustum_Hook(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) - { - glFrustum(left, right, bottom, top, zNear, zFar); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGenLists - extern "C" { GLAPI GLuint GLAPIENTRY glGenLists(GLsizei range); } - GLuint OVR::GLEContext::glGenLists_Hook(GLsizei range) - { - GLuint u = glGenLists(range); - PostHook(GLE_CURRENT_FUNCTION); - return u; - } - - #undef glGenTextures - extern "C" { GLAPI void GLAPIENTRY glGenTextures(GLsizei n, GLuint *textures); } - void OVR::GLEContext::glGenTextures_Hook(GLsizei n, GLuint *textures) - { - glGenTextures(n, textures); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetBooleanv - extern "C" { GLAPI void GLAPIENTRY glGetBooleanv(GLenum pname, GLboolean *params); } - void OVR::GLEContext::glGetBooleanv_Hook(GLenum pname, GLboolean *params) - { - glGetBooleanv(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetClipPlane - extern "C" { GLAPI void GLAPIENTRY glGetClipPlane(GLenum plane, GLdouble *equation); } - void OVR::GLEContext::glGetClipPlane_Hook(GLenum plane, GLdouble *equation) - { - glGetClipPlane(plane, equation); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetDoublev - extern "C" { GLAPI void GLAPIENTRY glGetDoublev(GLenum pname, GLdouble *params); } - void OVR::GLEContext::glGetDoublev_Hook(GLenum pname, GLdouble *params) - { - glGetDoublev(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - //#undef glGetError Not needed because we happen to do this above already. - //extern "C" { GLAPI GLenum GLAPIENTRY glGetError(); } - GLenum OVR::GLEContext::glGetError_Hook() - { - GLenum e = glGetError(); - PostHook(GLE_CURRENT_FUNCTION); - return e; - } - - #undef glGetFloatv - extern "C" { GLAPI void GLAPIENTRY glGetFloatv(GLenum pname, GLfloat *params); } - void OVR::GLEContext::glGetFloatv_Hook(GLenum pname, GLfloat *params) - { - glGetFloatv(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetIntegerv - extern "C" { GLAPI void GLAPIENTRY glGetIntegerv(GLenum pname, GLint *params); } - void OVR::GLEContext::glGetIntegerv_Hook(GLenum pname, GLint *params) - { - glGetIntegerv(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetLightfv - extern "C" { GLAPI void GLAPIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params); } - void OVR::GLEContext::glGetLightfv_Hook(GLenum light, GLenum pname, GLfloat *params) - { - glGetLightfv(light, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetLightiv - extern "C" { GLAPI void GLAPIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params); } - void OVR::GLEContext::glGetLightiv_Hook(GLenum light, GLenum pname, GLint *params) - { - glGetLightiv(light, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetMapdv - extern "C" { GLAPI void GLAPIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v); } - void OVR::GLEContext::glGetMapdv_Hook(GLenum target, GLenum query, GLdouble *v) - { - glGetMapdv(target, query, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetMapfv - extern "C" { GLAPI void GLAPIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v); } - void OVR::GLEContext::glGetMapfv_Hook(GLenum target, GLenum query, GLfloat *v) - { - glGetMapfv(target, query, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetMapiv - extern "C" { GLAPI void GLAPIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v); } - void OVR::GLEContext::glGetMapiv_Hook(GLenum target, GLenum query, GLint *v) - { - glGetMapiv(target, query, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetMaterialfv - extern "C" { GLAPI void GLAPIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params); } - void OVR::GLEContext::glGetMaterialfv_Hook(GLenum face, GLenum pname, GLfloat *params) - { - glGetMaterialfv(face, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetMaterialiv - extern "C" { GLAPI void GLAPIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params); } - void OVR::GLEContext::glGetMaterialiv_Hook(GLenum face, GLenum pname, GLint *params) - { - glGetMaterialiv(face, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetPixelMapfv - extern "C" { GLAPI void GLAPIENTRY glGetPixelMapfv(GLenum map, GLfloat *values); } - void OVR::GLEContext::glGetPixelMapfv_Hook(GLenum map, GLfloat *values) - { - glGetPixelMapfv(map, values); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetPixelMapuiv - extern "C" { GLAPI void GLAPIENTRY glGetPixelMapuiv(GLenum map, GLuint *values); } - void OVR::GLEContext::glGetPixelMapuiv_Hook(GLenum map, GLuint *values) - { - glGetPixelMapuiv(map, values); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetPixelMapusv - extern "C" { GLAPI void GLAPIENTRY glGetPixelMapusv(GLenum map, GLushort *values); } - void OVR::GLEContext::glGetPixelMapusv_Hook(GLenum map, GLushort *values) - { - glGetPixelMapusv(map, values); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetPointerv - extern "C" { GLAPI void GLAPIENTRY glGetPointerv(GLenum pname, void* *params); } - void OVR::GLEContext::glGetPointerv_Hook(GLenum pname, void* *params) - { - glGetPointerv(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetPolygonStipple - extern "C" { GLAPI void GLAPIENTRY glGetPolygonStipple(GLubyte *mask); } - void OVR::GLEContext::glGetPolygonStipple_Hook(GLubyte *mask) - { - glGetPolygonStipple(mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - // #undef glGetString // This was already disabled above. - // extern "C" { GLAPI const GLubyte * GLAPIENTRY glGetString(GLenum name); } - const GLubyte * OVR::GLEContext::glGetString_Hook(GLenum name) - { - const GLubyte * p = glGetString(name); - PostHook(GLE_CURRENT_FUNCTION); - return p; - } - - #undef glGetTexEnvfv - extern "C" { GLAPI void GLAPIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params); } - void OVR::GLEContext::glGetTexEnvfv_Hook(GLenum target, GLenum pname, GLfloat *params) - { - glGetTexEnvfv(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexEnviv - extern "C" { GLAPI void GLAPIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params); } - void OVR::GLEContext::glGetTexEnviv_Hook(GLenum target, GLenum pname, GLint *params) - { - glGetTexEnviv(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexGendv - extern "C" { GLAPI void GLAPIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params); } - void OVR::GLEContext::glGetTexGendv_Hook(GLenum coord, GLenum pname, GLdouble *params) - { - glGetTexGendv(coord, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexGenfv - extern "C" { GLAPI void GLAPIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params); } - void OVR::GLEContext::glGetTexGenfv_Hook(GLenum coord, GLenum pname, GLfloat *params) - { - glGetTexGenfv(coord, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexGeniv - extern "C" { GLAPI void GLAPIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params); } - void OVR::GLEContext::glGetTexGeniv_Hook(GLenum coord, GLenum pname, GLint *params) - { - glGetTexGeniv(coord, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexImage - extern "C" { GLAPI void GLAPIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels); } - void OVR::GLEContext::glGetTexImage_Hook(GLenum target, GLint level, GLenum format, GLenum type, void *pixels) - { - glGetTexImage(target, level, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexLevelParameterfv - extern "C" { GLAPI void GLAPIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params); } - void OVR::GLEContext::glGetTexLevelParameterfv_Hook(GLenum target, GLint level, GLenum pname, GLfloat *params) - { - glGetTexLevelParameterfv(target, level, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexLevelParameteriv - extern "C" { GLAPI void GLAPIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); } - void OVR::GLEContext::glGetTexLevelParameteriv_Hook(GLenum target, GLint level, GLenum pname, GLint *params) - { - glGetTexLevelParameteriv(target, level, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexParameterfv - extern "C" { GLAPI void GLAPIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params); } - void OVR::GLEContext::glGetTexParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) - { - glGetTexParameterfv(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glGetTexParameteriv - extern "C" { GLAPI void GLAPIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint *params); } - void OVR::GLEContext::glGetTexParameteriv_Hook(GLenum target, GLenum pname, GLint *params) - { - glGetTexParameteriv(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glHint - extern "C" { GLAPI void GLAPIENTRY glHint(GLenum target, GLenum mode); } - void OVR::GLEContext::glHint_Hook(GLenum target, GLenum mode) - { - glHint(target, mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexMask - extern "C" { GLAPI void GLAPIENTRY glIndexMask(GLuint mask); } - void OVR::GLEContext::glIndexMask_Hook(GLuint mask) - { - glIndexMask(mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexPointer - extern "C" { GLAPI void GLAPIENTRY glIndexPointer(GLenum type, GLsizei stride, const void *pointer); } - void OVR::GLEContext::glIndexPointer_Hook(GLenum type, GLsizei stride, const void *pointer) - { - glIndexPointer(type, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexd - extern "C" { GLAPI void GLAPIENTRY glIndexd(GLdouble c); } - void OVR::GLEContext::glIndexd_Hook(GLdouble c) - { - glIndexd(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexdv - extern "C" { GLAPI void GLAPIENTRY glIndexdv(const GLdouble *c); } - void OVR::GLEContext::glIndexdv_Hook(const GLdouble *c) - { - glIndexdv(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexf - extern "C" { GLAPI void GLAPIENTRY glIndexf(GLfloat c); } - void OVR::GLEContext::glIndexf_Hook(GLfloat c) - { - glIndexf(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexfv - extern "C" { GLAPI void GLAPIENTRY glIndexfv(const GLfloat *c); } - void OVR::GLEContext::glIndexfv_Hook(const GLfloat *c) - { - glIndexfv(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexi - extern "C" { GLAPI void GLAPIENTRY glIndexi(GLint c); } - void OVR::GLEContext::glIndexi_Hook(GLint c) - { - glIndexi(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexiv - extern "C" { GLAPI void GLAPIENTRY glIndexiv(const GLint *c); } - void OVR::GLEContext::glIndexiv_Hook(const GLint *c) - { - glIndexiv(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexs - extern "C" { GLAPI void GLAPIENTRY glIndexs(GLshort c); } - void OVR::GLEContext::glIndexs_Hook(GLshort c) - { - glIndexs(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexsv - extern "C" { GLAPI void GLAPIENTRY glIndexsv(const GLshort *c); } - void OVR::GLEContext::glIndexsv_Hook(const GLshort *c) - { - glIndexsv(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexub - extern "C" { GLAPI void GLAPIENTRY glIndexub(GLubyte c); } - void OVR::GLEContext::glIndexub_Hook(GLubyte c) - { - glIndexub(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIndexubv - extern "C" { GLAPI void GLAPIENTRY glIndexubv(const GLubyte *c); } - void OVR::GLEContext::glIndexubv_Hook(const GLubyte *c) - { - glIndexubv(c); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glInitNames - extern "C" { GLAPI void GLAPIENTRY glInitNames(); } - void OVR::GLEContext::glInitNames_Hook() - { - glInitNames(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glInterleavedArrays - extern "C" { GLAPI void GLAPIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const void *pointer); } - void OVR::GLEContext::glInterleavedArrays_Hook(GLenum format, GLsizei stride, const void *pointer) - { - glInterleavedArrays(format, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glIsEnabled - extern "C" { GLAPI GLboolean GLAPIENTRY glIsEnabled(GLenum cap); } - GLboolean OVR::GLEContext::glIsEnabled_Hook(GLenum cap) - { - GLboolean b = glIsEnabled(cap); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef glIsList - extern "C" { GLAPI GLboolean GLAPIENTRY glIsList(GLuint list); } - GLboolean OVR::GLEContext::glIsList_Hook(GLuint list) - { - GLboolean b = glIsList(list); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef glIsTexture - extern "C" { GLAPI GLboolean GLAPIENTRY glIsTexture(GLuint texture); } - GLboolean OVR::GLEContext::glIsTexture_Hook(GLuint texture) - { - GLboolean b = glIsTexture(texture); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef glLightModelf - extern "C" { GLAPI void GLAPIENTRY glLightModelf(GLenum pname, GLfloat param); } - void OVR::GLEContext::glLightModelf_Hook(GLenum pname, GLfloat param) - { - glLightModelf(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLightModelfv - extern "C" { GLAPI void GLAPIENTRY glLightModelfv(GLenum pname, const GLfloat *params); } - void OVR::GLEContext::glLightModelfv_Hook(GLenum pname, const GLfloat *params) - { - glLightModelfv(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLightModeli - extern "C" { GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param); } - void OVR::GLEContext::glLightModeli_Hook(GLenum pname, GLint param) - { - glLightModeli(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLightModeliv - extern "C" { GLAPI void GLAPIENTRY glLightModeliv(GLenum pname, const GLint *params); } - void OVR::GLEContext::glLightModeliv_Hook(GLenum pname, const GLint *params) - { - glLightModeliv(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLightf - extern "C" { GLAPI void GLAPIENTRY glLightf(GLenum light, GLenum pname, GLfloat param); } - void OVR::GLEContext::glLightf_Hook(GLenum light, GLenum pname, GLfloat param) - { - glLightf(light, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLightfv - extern "C" { GLAPI void GLAPIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params); } - void OVR::GLEContext::glLightfv_Hook(GLenum light, GLenum pname, const GLfloat *params) - { - glLightfv(light, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLighti - extern "C" { GLAPI void GLAPIENTRY glLighti(GLenum light, GLenum pname, GLint param); } - void OVR::GLEContext::glLighti_Hook(GLenum light, GLenum pname, GLint param) - { - glLighti(light, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLightiv - extern "C" { GLAPI void GLAPIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params); } - void OVR::GLEContext::glLightiv_Hook(GLenum light, GLenum pname, const GLint *params) - { - glLightiv(light, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLineStipple - extern "C" { GLAPI void GLAPIENTRY glLineStipple(GLint factor, GLushort pattern); } - void OVR::GLEContext::glLineStipple_Hook(GLint factor, GLushort pattern) - { - glLineStipple(factor, pattern); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLineWidth - extern "C" { GLAPI void GLAPIENTRY glLineWidth(GLfloat width); } - void OVR::GLEContext::glLineWidth_Hook(GLfloat width) - { - glLineWidth(width); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glListBase - extern "C" { GLAPI void GLAPIENTRY glListBase(GLuint base); } - void OVR::GLEContext::glListBase_Hook(GLuint base) - { - glListBase(base); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLoadIdentity - extern "C" { GLAPI void GLAPIENTRY glLoadIdentity(); } - void OVR::GLEContext::glLoadIdentity_Hook() - { - glLoadIdentity(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLoadMatrixd - extern "C" { GLAPI void GLAPIENTRY glLoadMatrixd(const GLdouble *m); } - void OVR::GLEContext::glLoadMatrixd_Hook(const GLdouble *m) - { - glLoadMatrixd(m); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLoadMatrixf - extern "C" { GLAPI void GLAPIENTRY glLoadMatrixf(const GLfloat *m); } - void OVR::GLEContext::glLoadMatrixf_Hook(const GLfloat *m) - { - glLoadMatrixf(m); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLoadName - extern "C" { GLAPI void GLAPIENTRY glLoadName(GLuint name); } - void OVR::GLEContext::glLoadName_Hook(GLuint name) - { - glLoadName(name); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glLogicOp - extern "C" { GLAPI void GLAPIENTRY glLogicOp(GLenum opcode); } - void OVR::GLEContext::glLogicOp_Hook(GLenum opcode) - { - glLogicOp(opcode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMap1d - extern "C" { GLAPI void GLAPIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); } - void OVR::GLEContext::glMap1d_Hook(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) - { - glMap1d(target, u1, u2, stride, order, points); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMap1f - extern "C" { GLAPI void GLAPIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); } - void OVR::GLEContext::glMap1f_Hook(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) - { - glMap1f(target, u1, u2, stride, order, points); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMap2d - extern "C" { GLAPI void GLAPIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); } - void OVR::GLEContext::glMap2d_Hook(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) - { - glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMap2f - extern "C" { GLAPI void GLAPIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); } - void OVR::GLEContext::glMap2f_Hook(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) - { - glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMapGrid1d - extern "C" { GLAPI void GLAPIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2); } - void OVR::GLEContext::glMapGrid1d_Hook(GLint un, GLdouble u1, GLdouble u2) - { - glMapGrid1d(un, u1, u2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMapGrid1f - extern "C" { GLAPI void GLAPIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2); } - void OVR::GLEContext::glMapGrid1f_Hook(GLint un, GLfloat u1, GLfloat u2) - { - glMapGrid1f(un, u1, u2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMapGrid2d - extern "C" { GLAPI void GLAPIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); } - void OVR::GLEContext::glMapGrid2d_Hook(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) - { - glMapGrid2d(un, u1, u2, vn, v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMapGrid2f - extern "C" { GLAPI void GLAPIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); } - void OVR::GLEContext::glMapGrid2f_Hook(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) - { - glMapGrid2f(un, u1, u2, vn, v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMaterialf - extern "C" { GLAPI void GLAPIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param); } - void OVR::GLEContext::glMaterialf_Hook(GLenum face, GLenum pname, GLfloat param) - { - glMaterialf(face, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMaterialfv - extern "C" { GLAPI void GLAPIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params); } - void OVR::GLEContext::glMaterialfv_Hook(GLenum face, GLenum pname, const GLfloat *params) - { - glMaterialfv(face, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMateriali - extern "C" { GLAPI void GLAPIENTRY glMateriali(GLenum face, GLenum pname, GLint param); } - void OVR::GLEContext::glMateriali_Hook(GLenum face, GLenum pname, GLint param) - { - glMateriali(face, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMaterialiv - extern "C" { GLAPI void GLAPIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params); } - void OVR::GLEContext::glMaterialiv_Hook(GLenum face, GLenum pname, const GLint *params) - { - glMaterialiv(face, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMatrixMode - extern "C" { GLAPI void GLAPIENTRY glMatrixMode(GLenum mode); } - void OVR::GLEContext::glMatrixMode_Hook(GLenum mode) - { - glMatrixMode(mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMultMatrixd - extern "C" { GLAPI void GLAPIENTRY glMultMatrixd(const GLdouble *m); } - void OVR::GLEContext::glMultMatrixd_Hook(const GLdouble *m) - { - glMultMatrixd(m); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glMultMatrixf - extern "C" { GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat *m); } - void OVR::GLEContext::glMultMatrixf_Hook(const GLfloat *m) - { - glMultMatrixf(m); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNewList - extern "C" { GLAPI void GLAPIENTRY glNewList(GLuint list, GLenum mode); } - void OVR::GLEContext::glNewList_Hook(GLuint list, GLenum mode) - { - glNewList(list, mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3b - extern "C" { GLAPI void GLAPIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz); } - void OVR::GLEContext::glNormal3b_Hook(GLbyte nx, GLbyte ny, GLbyte nz) - { - glNormal3b(nx, ny, nz); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3bv - extern "C" { GLAPI void GLAPIENTRY glNormal3bv(const GLbyte *v); } - void OVR::GLEContext::glNormal3bv_Hook(const GLbyte *v) - { - glNormal3bv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3d - extern "C" { GLAPI void GLAPIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz); } - void OVR::GLEContext::glNormal3d_Hook(GLdouble nx, GLdouble ny, GLdouble nz) - { - glNormal3d(nx, ny, nz); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3dv - extern "C" { GLAPI void GLAPIENTRY glNormal3dv(const GLdouble *v); } - void OVR::GLEContext::glNormal3dv_Hook(const GLdouble *v) - { - glNormal3dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3f - extern "C" { GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz); } - void OVR::GLEContext::glNormal3f_Hook(GLfloat nx, GLfloat ny, GLfloat nz) - { - glNormal3f(nx, ny, nz); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3fv - extern "C" { GLAPI void GLAPIENTRY glNormal3fv(const GLfloat *v); } - void OVR::GLEContext::glNormal3fv_Hook(const GLfloat *v) - { - glNormal3fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3i - extern "C" { GLAPI void GLAPIENTRY glNormal3i(GLint nx, GLint ny, GLint nz); } - void OVR::GLEContext::glNormal3i_Hook(GLint nx, GLint ny, GLint nz) - { - glNormal3i(nx, ny, nz); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3iv - extern "C" { GLAPI void GLAPIENTRY glNormal3iv(const GLint *v); } - void OVR::GLEContext::glNormal3iv_Hook(const GLint *v) - { - glNormal3iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3s - extern "C" { GLAPI void GLAPIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz); } - void OVR::GLEContext::glNormal3s_Hook(GLshort nx, GLshort ny, GLshort nz) - { - glNormal3s(nx, ny, nz); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormal3sv - extern "C" { GLAPI void GLAPIENTRY glNormal3sv(const GLshort *v); } - void OVR::GLEContext::glNormal3sv_Hook(const GLshort *v) - { - glNormal3sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glNormalPointer - extern "C" { GLAPI void GLAPIENTRY glNormalPointer(GLenum type, GLsizei stride, const void *pointer); } - void OVR::GLEContext::glNormalPointer_Hook(GLenum type, GLsizei stride, const void *pointer) - { - glNormalPointer(type, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glOrtho - extern "C" { GLAPI void GLAPIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); } - void OVR::GLEContext::glOrtho_Hook(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) - { - glOrtho(left, right, bottom, top, zNear, zFar); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPassThrough - extern "C" { GLAPI void GLAPIENTRY glPassThrough(GLfloat token); } - void OVR::GLEContext::glPassThrough_Hook(GLfloat token) - { - glPassThrough(token); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPixelMapfv - extern "C" { GLAPI void GLAPIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values); } - void OVR::GLEContext::glPixelMapfv_Hook(GLenum map, GLsizei mapsize, const GLfloat *values) - { - glPixelMapfv(map, mapsize, values); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPixelMapuiv - extern "C" { GLAPI void GLAPIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values); } - void OVR::GLEContext::glPixelMapuiv_Hook(GLenum map, GLsizei mapsize, const GLuint *values) - { - glPixelMapuiv(map, mapsize, values); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPixelMapusv - extern "C" { GLAPI void GLAPIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values); } - void OVR::GLEContext::glPixelMapusv_Hook(GLenum map, GLsizei mapsize, const GLushort *values) - { - glPixelMapusv(map, mapsize, values); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPixelStoref - extern "C" { GLAPI void GLAPIENTRY glPixelStoref(GLenum pname, GLfloat param); } - void OVR::GLEContext::glPixelStoref_Hook(GLenum pname, GLfloat param) - { - glPixelStoref(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPixelStorei - extern "C" { GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param); } - void OVR::GLEContext::glPixelStorei_Hook(GLenum pname, GLint param) - { - glPixelStorei(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPixelTransferf - extern "C" { GLAPI void GLAPIENTRY glPixelTransferf(GLenum pname, GLfloat param); } - void OVR::GLEContext::glPixelTransferf_Hook(GLenum pname, GLfloat param) - { - glPixelTransferf(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPixelTransferi - extern "C" { GLAPI void GLAPIENTRY glPixelTransferi(GLenum pname, GLint param); } - void OVR::GLEContext::glPixelTransferi_Hook(GLenum pname, GLint param) - { - glPixelTransferi(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPixelZoom - extern "C" { GLAPI void GLAPIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor); } - void OVR::GLEContext::glPixelZoom_Hook(GLfloat xfactor, GLfloat yfactor) - { - glPixelZoom(xfactor, yfactor); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPointSize - extern "C" { GLAPI void GLAPIENTRY glPointSize(GLfloat size); } - void OVR::GLEContext::glPointSize_Hook(GLfloat size) - { - glPointSize(size); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPolygonMode - extern "C" { GLAPI void GLAPIENTRY glPolygonMode(GLenum face, GLenum mode); } - void OVR::GLEContext::glPolygonMode_Hook(GLenum face, GLenum mode) - { - glPolygonMode(face, mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPolygonOffset - extern "C" { GLAPI void GLAPIENTRY glPolygonOffset(GLfloat factor, GLfloat units); } - void OVR::GLEContext::glPolygonOffset_Hook(GLfloat factor, GLfloat units) - { - glPolygonOffset(factor, units); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPolygonStipple - extern "C" { GLAPI void GLAPIENTRY glPolygonStipple(const GLubyte *mask); } - void OVR::GLEContext::glPolygonStipple_Hook(const GLubyte *mask) - { - glPolygonStipple(mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPopAttrib - extern "C" { GLAPI void GLAPIENTRY glPopAttrib(); } - void OVR::GLEContext::glPopAttrib_Hook() - { - glPopAttrib(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPopClientAttrib - extern "C" { GLAPI void GLAPIENTRY glPopClientAttrib(); } - void OVR::GLEContext::glPopClientAttrib_Hook() - { - glPopClientAttrib(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPopMatrix - extern "C" { GLAPI void GLAPIENTRY glPopMatrix(); } - void OVR::GLEContext::glPopMatrix_Hook() - { - glPopMatrix(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPopName - extern "C" { GLAPI void GLAPIENTRY glPopName(); } - void OVR::GLEContext::glPopName_Hook() - { - glPopName(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPrioritizeTextures - extern "C" { GLAPI void GLAPIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities); } - void OVR::GLEContext::glPrioritizeTextures_Hook(GLsizei n, const GLuint *textures, const GLclampf *priorities) - { - glPrioritizeTextures(n, textures, priorities); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPushAttrib - extern "C" { GLAPI void GLAPIENTRY glPushAttrib(GLbitfield mask); } - void OVR::GLEContext::glPushAttrib_Hook(GLbitfield mask) - { - glPushAttrib(mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPushClientAttrib - extern "C" { GLAPI void GLAPIENTRY glPushClientAttrib(GLbitfield mask); } - void OVR::GLEContext::glPushClientAttrib_Hook(GLbitfield mask) - { - glPushClientAttrib(mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPushMatrix - extern "C" { GLAPI void GLAPIENTRY glPushMatrix(); } - void OVR::GLEContext::glPushMatrix_Hook() - { - glPushMatrix(); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glPushName - extern "C" { GLAPI void GLAPIENTRY glPushName(GLuint name); } - void OVR::GLEContext::glPushName_Hook(GLuint name) - { - glPushName(name); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos2d - extern "C" { GLAPI void GLAPIENTRY glRasterPos2d(GLdouble x, GLdouble y); } - void OVR::GLEContext::glRasterPos2d_Hook(GLdouble x, GLdouble y) - { - glRasterPos2d(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos2dv - extern "C" { GLAPI void GLAPIENTRY glRasterPos2dv(const GLdouble *v); } - void OVR::GLEContext::glRasterPos2dv_Hook(const GLdouble *v) - { - glRasterPos2dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos2f - extern "C" { GLAPI void GLAPIENTRY glRasterPos2f(GLfloat x, GLfloat y); } - void OVR::GLEContext::glRasterPos2f_Hook(GLfloat x, GLfloat y) - { - glRasterPos2f(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos2fv - extern "C" { GLAPI void GLAPIENTRY glRasterPos2fv(const GLfloat *v); } - void OVR::GLEContext::glRasterPos2fv_Hook(const GLfloat *v) - { - glRasterPos2fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos2i - extern "C" { GLAPI void GLAPIENTRY glRasterPos2i(GLint x, GLint y); } - void OVR::GLEContext::glRasterPos2i_Hook(GLint x, GLint y) - { - glRasterPos2i(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos2iv - extern "C" { GLAPI void GLAPIENTRY glRasterPos2iv(const GLint *v); } - void OVR::GLEContext::glRasterPos2iv_Hook(const GLint *v) - { - glRasterPos2iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos2s - extern "C" { GLAPI void GLAPIENTRY glRasterPos2s(GLshort x, GLshort y); } - void OVR::GLEContext::glRasterPos2s_Hook(GLshort x, GLshort y) - { - glRasterPos2s(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos2sv - extern "C" { GLAPI void GLAPIENTRY glRasterPos2sv(const GLshort *v); } - void OVR::GLEContext::glRasterPos2sv_Hook(const GLshort *v) - { - glRasterPos2sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos3d - extern "C" { GLAPI void GLAPIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z); } - void OVR::GLEContext::glRasterPos3d_Hook(GLdouble x, GLdouble y, GLdouble z) - { - glRasterPos3d(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos3dv - extern "C" { GLAPI void GLAPIENTRY glRasterPos3dv(const GLdouble *v); } - void OVR::GLEContext::glRasterPos3dv_Hook(const GLdouble *v) - { - glRasterPos3dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos3f - extern "C" { GLAPI void GLAPIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z); } - void OVR::GLEContext::glRasterPos3f_Hook(GLfloat x, GLfloat y, GLfloat z) - { - glRasterPos3f(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos3fv - extern "C" { GLAPI void GLAPIENTRY glRasterPos3fv(const GLfloat *v); } - void OVR::GLEContext::glRasterPos3fv_Hook(const GLfloat *v) - { - glRasterPos3fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos3i - extern "C" { GLAPI void GLAPIENTRY glRasterPos3i(GLint x, GLint y, GLint z); } - void OVR::GLEContext::glRasterPos3i_Hook(GLint x, GLint y, GLint z) - { - glRasterPos3i(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos3iv - extern "C" { GLAPI void GLAPIENTRY glRasterPos3iv(const GLint *v); } - void OVR::GLEContext::glRasterPos3iv_Hook(const GLint *v) - { - glRasterPos3iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos3s - extern "C" { GLAPI void GLAPIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z); } - void OVR::GLEContext::glRasterPos3s_Hook(GLshort x, GLshort y, GLshort z) - { - glRasterPos3s(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos3sv - extern "C" { GLAPI void GLAPIENTRY glRasterPos3sv(const GLshort *v); } - void OVR::GLEContext::glRasterPos3sv_Hook(const GLshort *v) - { - glRasterPos3sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos4d - extern "C" { GLAPI void GLAPIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); } - void OVR::GLEContext::glRasterPos4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w) - { - glRasterPos4d(x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos4dv - extern "C" { GLAPI void GLAPIENTRY glRasterPos4dv(const GLdouble *v); } - void OVR::GLEContext::glRasterPos4dv_Hook(const GLdouble *v) - { - glRasterPos4dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos4f - extern "C" { GLAPI void GLAPIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); } - void OVR::GLEContext::glRasterPos4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w) - { - glRasterPos4f(x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos4fv - extern "C" { GLAPI void GLAPIENTRY glRasterPos4fv(const GLfloat *v); } - void OVR::GLEContext::glRasterPos4fv_Hook(const GLfloat *v) - { - glRasterPos4fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos4i - extern "C" { GLAPI void GLAPIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w); } - void OVR::GLEContext::glRasterPos4i_Hook(GLint x, GLint y, GLint z, GLint w) - { - glRasterPos4i(x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos4iv - extern "C" { GLAPI void GLAPIENTRY glRasterPos4iv(const GLint *v); } - void OVR::GLEContext::glRasterPos4iv_Hook(const GLint *v) - { - glRasterPos4iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos4s - extern "C" { GLAPI void GLAPIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); } - void OVR::GLEContext::glRasterPos4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w) - { - glRasterPos4s(x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRasterPos4sv - extern "C" { GLAPI void GLAPIENTRY glRasterPos4sv(const GLshort *v); } - void OVR::GLEContext::glRasterPos4sv_Hook(const GLshort *v) - { - glRasterPos4sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glReadBuffer - extern "C" { GLAPI void GLAPIENTRY glReadBuffer(GLenum mode); } - void OVR::GLEContext::glReadBuffer_Hook(GLenum mode) - { - glReadBuffer(mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glReadPixels - extern "C" { GLAPI void GLAPIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); } - void OVR::GLEContext::glReadPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) - { - glReadPixels(x, y, width, height, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRectd - extern "C" { GLAPI void GLAPIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); } - void OVR::GLEContext::glRectd_Hook(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) - { - glRectd(x1, y1, x2, y2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRectdv - extern "C" { GLAPI void GLAPIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2); } - void OVR::GLEContext::glRectdv_Hook(const GLdouble *v1, const GLdouble *v2) - { - glRectdv(v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRectf - extern "C" { GLAPI void GLAPIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); } - void OVR::GLEContext::glRectf_Hook(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) - { - glRectf(x1, y1, x2, y2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRectfv - extern "C" { GLAPI void GLAPIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2); } - void OVR::GLEContext::glRectfv_Hook(const GLfloat *v1, const GLfloat *v2) - { - glRectfv(v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRecti - extern "C" { GLAPI void GLAPIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2); } - void OVR::GLEContext::glRecti_Hook(GLint x1, GLint y1, GLint x2, GLint y2) - { - glRecti(x1, y1, x2, y2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRectiv - extern "C" { GLAPI void GLAPIENTRY glRectiv(const GLint *v1, const GLint *v2); } - void OVR::GLEContext::glRectiv_Hook(const GLint *v1, const GLint *v2) - { - glRectiv(v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRects - extern "C" { GLAPI void GLAPIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2); } - void OVR::GLEContext::glRects_Hook(GLshort x1, GLshort y1, GLshort x2, GLshort y2) - { - glRects(x1, y1, x2, y2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRectsv - extern "C" { GLAPI void GLAPIENTRY glRectsv(const GLshort *v1, const GLshort *v2); } - void OVR::GLEContext::glRectsv_Hook(const GLshort *v1, const GLshort *v2) - { - glRectsv(v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRenderMode - extern "C" { GLAPI GLint GLAPIENTRY glRenderMode(GLenum mode); } - GLint OVR::GLEContext::glRenderMode_Hook(GLenum mode) - { - GLint i = glRenderMode(mode); - PostHook(GLE_CURRENT_FUNCTION); - return i; - } - - #undef glRotated - extern "C" { GLAPI void GLAPIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); } - void OVR::GLEContext::glRotated_Hook(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) - { - glRotated(angle, x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glRotatef - extern "C" { GLAPI void GLAPIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); } - void OVR::GLEContext::glRotatef_Hook(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) - { - glRotatef(angle, x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glScaled - extern "C" { GLAPI void GLAPIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z); } - void OVR::GLEContext::glScaled_Hook(GLdouble x, GLdouble y, GLdouble z) - { - glScaled(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glScalef - extern "C" { GLAPI void GLAPIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z); } - void OVR::GLEContext::glScalef_Hook(GLfloat x, GLfloat y, GLfloat z) - { - glScalef(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glScissor - extern "C" { GLAPI void GLAPIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height); } - void OVR::GLEContext::glScissor_Hook(GLint x, GLint y, GLsizei width, GLsizei height) - { - glScissor(x, y, width, height); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glSelectBuffer - extern "C" { GLAPI void GLAPIENTRY glSelectBuffer(GLsizei size, GLuint *buffer); } - void OVR::GLEContext::glSelectBuffer_Hook(GLsizei size, GLuint *buffer) - { - glSelectBuffer(size, buffer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glShadeModel - extern "C" { GLAPI void GLAPIENTRY glShadeModel(GLenum mode); } - void OVR::GLEContext::glShadeModel_Hook(GLenum mode) - { - glShadeModel(mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glStencilFunc - extern "C" { GLAPI void GLAPIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask); } - void OVR::GLEContext::glStencilFunc_Hook(GLenum func, GLint ref, GLuint mask) - { - glStencilFunc(func, ref, mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glStencilMask - extern "C" { GLAPI void GLAPIENTRY glStencilMask(GLuint mask); } - void OVR::GLEContext::glStencilMask_Hook(GLuint mask) - { - glStencilMask(mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glStencilOp - extern "C" { GLAPI void GLAPIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass); } - void OVR::GLEContext::glStencilOp_Hook(GLenum fail, GLenum zfail, GLenum zpass) - { - glStencilOp(fail, zfail, zpass); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord1d - extern "C" { GLAPI void GLAPIENTRY glTexCoord1d(GLdouble s); } - void OVR::GLEContext::glTexCoord1d_Hook(GLdouble s) - { - glTexCoord1d(s); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord1dv - extern "C" { GLAPI void GLAPIENTRY glTexCoord1dv(const GLdouble *v); } - void OVR::GLEContext::glTexCoord1dv_Hook(const GLdouble *v) - { - glTexCoord1dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord1f - extern "C" { GLAPI void GLAPIENTRY glTexCoord1f(GLfloat s); } - void OVR::GLEContext::glTexCoord1f_Hook(GLfloat s) - { - glTexCoord1f(s); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord1fv - extern "C" { GLAPI void GLAPIENTRY glTexCoord1fv(const GLfloat *v); } - void OVR::GLEContext::glTexCoord1fv_Hook(const GLfloat *v) - { - glTexCoord1fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord1i - extern "C" { GLAPI void GLAPIENTRY glTexCoord1i(GLint s); } - void OVR::GLEContext::glTexCoord1i_Hook(GLint s) - { - glTexCoord1i(s); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord1iv - extern "C" { GLAPI void GLAPIENTRY glTexCoord1iv(const GLint *v); } - void OVR::GLEContext::glTexCoord1iv_Hook(const GLint *v) - { - glTexCoord1iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord1s - extern "C" { GLAPI void GLAPIENTRY glTexCoord1s(GLshort s); } - void OVR::GLEContext::glTexCoord1s_Hook(GLshort s) - { - glTexCoord1s(s); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord1sv - extern "C" { GLAPI void GLAPIENTRY glTexCoord1sv(const GLshort *v); } - void OVR::GLEContext::glTexCoord1sv_Hook(const GLshort *v) - { - glTexCoord1sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord2d - extern "C" { GLAPI void GLAPIENTRY glTexCoord2d(GLdouble s, GLdouble t); } - void OVR::GLEContext::glTexCoord2d_Hook(GLdouble s, GLdouble t) - { - glTexCoord2d(s, t); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord2dv - extern "C" { GLAPI void GLAPIENTRY glTexCoord2dv(const GLdouble *v); } - void OVR::GLEContext::glTexCoord2dv_Hook(const GLdouble *v) - { - glTexCoord2dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord2f - extern "C" { GLAPI void GLAPIENTRY glTexCoord2f(GLfloat s, GLfloat t); } - void OVR::GLEContext::glTexCoord2f_Hook(GLfloat s, GLfloat t) - { - glTexCoord2f(s, t); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord2fv - extern "C" { GLAPI void GLAPIENTRY glTexCoord2fv(const GLfloat *v); } - void OVR::GLEContext::glTexCoord2fv_Hook(const GLfloat *v) - { - glTexCoord2fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord2i - extern "C" { GLAPI void GLAPIENTRY glTexCoord2i(GLint s, GLint t); } - void OVR::GLEContext::glTexCoord2i_Hook(GLint s, GLint t) - { - glTexCoord2i(s, t); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord2iv - extern "C" { GLAPI void GLAPIENTRY glTexCoord2iv(const GLint *v); } - void OVR::GLEContext::glTexCoord2iv_Hook(const GLint *v) - { - glTexCoord2iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord2s - extern "C" { GLAPI void GLAPIENTRY glTexCoord2s(GLshort s, GLshort t); } - void OVR::GLEContext::glTexCoord2s_Hook(GLshort s, GLshort t) - { - glTexCoord2s(s, t); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord2sv - extern "C" { GLAPI void GLAPIENTRY glTexCoord2sv(const GLshort *v); } - void OVR::GLEContext::glTexCoord2sv_Hook(const GLshort *v) - { - glTexCoord2sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord3d - extern "C" { GLAPI void GLAPIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r); } - void OVR::GLEContext::glTexCoord3d_Hook(GLdouble s, GLdouble t, GLdouble r) - { - glTexCoord3d(s, t, r); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord3dv - extern "C" { GLAPI void GLAPIENTRY glTexCoord3dv(const GLdouble *v); } - void OVR::GLEContext::glTexCoord3dv_Hook(const GLdouble *v) - { - glTexCoord3dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord3f - extern "C" { GLAPI void GLAPIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r); } - void OVR::GLEContext::glTexCoord3f_Hook(GLfloat s, GLfloat t, GLfloat r) - { - glTexCoord3f(s, t, r); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord3fv - extern "C" { GLAPI void GLAPIENTRY glTexCoord3fv(const GLfloat *v); } - void OVR::GLEContext::glTexCoord3fv_Hook(const GLfloat *v) - { - glTexCoord3fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord3i - extern "C" { GLAPI void GLAPIENTRY glTexCoord3i(GLint s, GLint t, GLint r); } - void OVR::GLEContext::glTexCoord3i_Hook(GLint s, GLint t, GLint r) - { - glTexCoord3i(s, t, r); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord3iv - extern "C" { GLAPI void GLAPIENTRY glTexCoord3iv(const GLint *v); } - void OVR::GLEContext::glTexCoord3iv_Hook(const GLint *v) - { - glTexCoord3iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord3s - extern "C" { GLAPI void GLAPIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r); } - void OVR::GLEContext::glTexCoord3s_Hook(GLshort s, GLshort t, GLshort r) - { - glTexCoord3s(s, t, r); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord3sv - extern "C" { GLAPI void GLAPIENTRY glTexCoord3sv(const GLshort *v); } - void OVR::GLEContext::glTexCoord3sv_Hook(const GLshort *v) - { - glTexCoord3sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord4d - extern "C" { GLAPI void GLAPIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q); } - void OVR::GLEContext::glTexCoord4d_Hook(GLdouble s, GLdouble t, GLdouble r, GLdouble q) - { - glTexCoord4d(s, t, r, q); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord4dv - extern "C" { GLAPI void GLAPIENTRY glTexCoord4dv(const GLdouble *v); } - void OVR::GLEContext::glTexCoord4dv_Hook(const GLdouble *v) - { - glTexCoord4dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord4f - extern "C" { GLAPI void GLAPIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q); } - void OVR::GLEContext::glTexCoord4f_Hook(GLfloat s, GLfloat t, GLfloat r, GLfloat q) - { - glTexCoord4f(s, t, r, q); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord4fv - extern "C" { GLAPI void GLAPIENTRY glTexCoord4fv(const GLfloat *v); } - void OVR::GLEContext::glTexCoord4fv_Hook(const GLfloat *v) - { - glTexCoord4fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord4i - extern "C" { GLAPI void GLAPIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q); } - void OVR::GLEContext::glTexCoord4i_Hook(GLint s, GLint t, GLint r, GLint q) - { - glTexCoord4i(s, t, r, q); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord4iv - extern "C" { GLAPI void GLAPIENTRY glTexCoord4iv(const GLint *v); } - void OVR::GLEContext::glTexCoord4iv_Hook(const GLint *v) - { - glTexCoord4iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord4s - extern "C" { GLAPI void GLAPIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q); } - void OVR::GLEContext::glTexCoord4s_Hook(GLshort s, GLshort t, GLshort r, GLshort q) - { - glTexCoord4s(s, t, r, q); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoord4sv - extern "C" { GLAPI void GLAPIENTRY glTexCoord4sv(const GLshort *v); } - void OVR::GLEContext::glTexCoord4sv_Hook(const GLshort *v) - { - glTexCoord4sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexCoordPointer - extern "C" { GLAPI void GLAPIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); } - void OVR::GLEContext::glTexCoordPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer) - { - glTexCoordPointer(size, type, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexEnvf - extern "C" { GLAPI void GLAPIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param); } - void OVR::GLEContext::glTexEnvf_Hook(GLenum target, GLenum pname, GLfloat param) - { - glTexEnvf(target, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexEnvfv - extern "C" { GLAPI void GLAPIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params); } - void OVR::GLEContext::glTexEnvfv_Hook(GLenum target, GLenum pname, const GLfloat *params) - { - glTexEnvfv(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexEnvi - extern "C" { GLAPI void GLAPIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param); } - void OVR::GLEContext::glTexEnvi_Hook(GLenum target, GLenum pname, GLint param) - { - glTexEnvi(target, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexEnviv - extern "C" { GLAPI void GLAPIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params); } - void OVR::GLEContext::glTexEnviv_Hook(GLenum target, GLenum pname, const GLint *params) - { - glTexEnviv(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexGend - extern "C" { GLAPI void GLAPIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param); } - void OVR::GLEContext::glTexGend_Hook(GLenum coord, GLenum pname, GLdouble param) - { - glTexGend(coord, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexGendv - extern "C" { GLAPI void GLAPIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params); } - void OVR::GLEContext::glTexGendv_Hook(GLenum coord, GLenum pname, const GLdouble *params) - { - glTexGendv(coord, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexGenf - extern "C" { GLAPI void GLAPIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param); } - void OVR::GLEContext::glTexGenf_Hook(GLenum coord, GLenum pname, GLfloat param) - { - glTexGenf(coord, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexGenfv - extern "C" { GLAPI void GLAPIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params); } - void OVR::GLEContext::glTexGenfv_Hook(GLenum coord, GLenum pname, const GLfloat *params) - { - glTexGenfv(coord, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexGeni - extern "C" { GLAPI void GLAPIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param); } - void OVR::GLEContext::glTexGeni_Hook(GLenum coord, GLenum pname, GLint param) - { - glTexGeni(coord, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexGeniv - extern "C" { GLAPI void GLAPIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params); } - void OVR::GLEContext::glTexGeniv_Hook(GLenum coord, GLenum pname, const GLint *params) - { - glTexGeniv(coord, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexImage1D - extern "C" { GLAPI void GLAPIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); } - void OVR::GLEContext::glTexImage1D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels) - { - glTexImage1D(target, level, internalformat, width, border, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexImage2D - extern "C" { GLAPI void GLAPIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); } - void OVR::GLEContext::glTexImage2D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) - { - glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexParameterf - extern "C" { GLAPI void GLAPIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param); } - void OVR::GLEContext::glTexParameterf_Hook(GLenum target, GLenum pname, GLfloat param) - { - glTexParameterf(target, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexParameterfv - extern "C" { GLAPI void GLAPIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params); } - void OVR::GLEContext::glTexParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params) - { - glTexParameterfv(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexParameteri - extern "C" { GLAPI void GLAPIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param); } - void OVR::GLEContext::glTexParameteri_Hook(GLenum target, GLenum pname, GLint param) - { - glTexParameteri(target, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexParameteriv - extern "C" { GLAPI void GLAPIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint *params); } - void OVR::GLEContext::glTexParameteriv_Hook(GLenum target, GLenum pname, const GLint *params) - { - glTexParameteriv(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexSubImage1D - extern "C" { GLAPI void GLAPIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); } - void OVR::GLEContext::glTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) - { - glTexSubImage1D(target, level, xoffset, width, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTexSubImage2D - extern "C" { GLAPI void GLAPIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); } - void OVR::GLEContext::glTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) - { - glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTranslated - extern "C" { GLAPI void GLAPIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z); } - void OVR::GLEContext::glTranslated_Hook(GLdouble x, GLdouble y, GLdouble z) - { - glTranslated(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glTranslatef - extern "C" { GLAPI void GLAPIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z); } - void OVR::GLEContext::glTranslatef_Hook(GLfloat x, GLfloat y, GLfloat z) - { - glTranslatef(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex2d - extern "C" { GLAPI void GLAPIENTRY glVertex2d(GLdouble x, GLdouble y); } - void OVR::GLEContext::glVertex2d_Hook(GLdouble x, GLdouble y) - { - glVertex2d(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex2dv - extern "C" { GLAPI void GLAPIENTRY glVertex2dv(const GLdouble *v); } - void OVR::GLEContext::glVertex2dv_Hook(const GLdouble *v) - { - glVertex2dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex2f - extern "C" { GLAPI void GLAPIENTRY glVertex2f(GLfloat x, GLfloat y); } - void OVR::GLEContext::glVertex2f_Hook(GLfloat x, GLfloat y) - { - glVertex2f(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex2fv - extern "C" { GLAPI void GLAPIENTRY glVertex2fv(const GLfloat *v); } - void OVR::GLEContext::glVertex2fv_Hook(const GLfloat *v) - { - glVertex2fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex2i - extern "C" { GLAPI void GLAPIENTRY glVertex2i(GLint x, GLint y); } - void OVR::GLEContext::glVertex2i_Hook(GLint x, GLint y) - { - glVertex2i(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex2iv - extern "C" { GLAPI void GLAPIENTRY glVertex2iv(const GLint *v); } - void OVR::GLEContext::glVertex2iv_Hook(const GLint *v) - { - glVertex2iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex2s - extern "C" { GLAPI void GLAPIENTRY glVertex2s(GLshort x, GLshort y); } - void OVR::GLEContext::glVertex2s_Hook(GLshort x, GLshort y) - { - glVertex2s(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex2sv - extern "C" { GLAPI void GLAPIENTRY glVertex2sv(const GLshort *v); } - void OVR::GLEContext::glVertex2sv_Hook(const GLshort *v) - { - glVertex2sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex3d - extern "C" { GLAPI void GLAPIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z); } - void OVR::GLEContext::glVertex3d_Hook(GLdouble x, GLdouble y, GLdouble z) - { - glVertex3d(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex3dv - extern "C" { GLAPI void GLAPIENTRY glVertex3dv(const GLdouble *v); } - void OVR::GLEContext::glVertex3dv_Hook(const GLdouble *v) - { - glVertex3dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex3f - extern "C" { GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z); } - void OVR::GLEContext::glVertex3f_Hook(GLfloat x, GLfloat y, GLfloat z) - { - glVertex3f(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex3fv - extern "C" { GLAPI void GLAPIENTRY glVertex3fv(const GLfloat *v); } - void OVR::GLEContext::glVertex3fv_Hook(const GLfloat *v) - { - glVertex3fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex3i - extern "C" { GLAPI void GLAPIENTRY glVertex3i(GLint x, GLint y, GLint z); } - void OVR::GLEContext::glVertex3i_Hook(GLint x, GLint y, GLint z) - { - glVertex3i(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex3iv - extern "C" { GLAPI void GLAPIENTRY glVertex3iv(const GLint *v); } - void OVR::GLEContext::glVertex3iv_Hook(const GLint *v) - { - glVertex3iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex3s - extern "C" { GLAPI void GLAPIENTRY glVertex3s(GLshort x, GLshort y, GLshort z); } - void OVR::GLEContext::glVertex3s_Hook(GLshort x, GLshort y, GLshort z) - { - glVertex3s(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex3sv - extern "C" { GLAPI void GLAPIENTRY glVertex3sv(const GLshort *v); } - void OVR::GLEContext::glVertex3sv_Hook(const GLshort *v) - { - glVertex3sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex4d - extern "C" { GLAPI void GLAPIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); } - void OVR::GLEContext::glVertex4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w) - { - glVertex4d(x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex4dv - extern "C" { GLAPI void GLAPIENTRY glVertex4dv(const GLdouble *v); } - void OVR::GLEContext::glVertex4dv_Hook(const GLdouble *v) - { - glVertex4dv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex4f - extern "C" { GLAPI void GLAPIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); } - void OVR::GLEContext::glVertex4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w) - { - glVertex4f(x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex4fv - extern "C" { GLAPI void GLAPIENTRY glVertex4fv(const GLfloat *v); } - void OVR::GLEContext::glVertex4fv_Hook(const GLfloat *v) - { - glVertex4fv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex4i - extern "C" { GLAPI void GLAPIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w); } - void OVR::GLEContext::glVertex4i_Hook(GLint x, GLint y, GLint z, GLint w) - { - glVertex4i(x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex4iv - extern "C" { GLAPI void GLAPIENTRY glVertex4iv(const GLint *v); } - void OVR::GLEContext::glVertex4iv_Hook(const GLint *v) - { - glVertex4iv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex4s - extern "C" { GLAPI void GLAPIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w); } - void OVR::GLEContext::glVertex4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w) - { - glVertex4s(x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertex4sv - extern "C" { GLAPI void GLAPIENTRY glVertex4sv(const GLshort *v); } - void OVR::GLEContext::glVertex4sv_Hook(const GLshort *v) - { - glVertex4sv(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glVertexPointer - extern "C" { GLAPI void GLAPIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); } - void OVR::GLEContext::glVertexPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer) - { - glVertexPointer(size, type, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - #undef glViewport - extern "C" { GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height); } - void OVR::GLEContext::glViewport_Hook(GLint x, GLint y, GLsizei width, GLsizei height) - { - glViewport(x, y, width, height); - PostHook(GLE_CURRENT_FUNCTION); - } - - - - // Pointer-based functions - void OVR::GLEContext::glBlendColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) - { - if(glBlendColor_Impl) - glBlendColor_Impl(red, green, blue, alpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBlendEquation_Hook(GLenum mode) - { - if(glBlendEquation_Impl) - glBlendEquation_Impl(mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDrawRangeElements_Hook(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) - { - if(glDrawRangeElements_Impl) - glDrawRangeElements_Impl(mode, start, end, count, type, indices); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glTexImage3D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) - { - if(glTexImage3D_Impl) - glTexImage3D_Impl(target, level, internalformat, width, height, depth, border, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) - { - if(glTexSubImage3D_Impl) - glTexSubImage3D_Impl(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); - PostHook(GLE_CURRENT_FUNCTION); - } - - - void OVR::GLEContext::glCopyTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) - { - if(glCopyTexSubImage3D_Impl) - glCopyTexSubImage3D_Impl(target, level, xoffset, yoffset, zoffset, x, y, width, height); - PostHook(GLE_CURRENT_FUNCTION); - } - - // GL_VERSION_1_2 deprecated functions - /* Not currently supported - void OVR::GLEContext::glColorTable_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) - { - if(glColorTable_Impl) - glColorTable_Impl(target, internalformat, width, format, type, table); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glColorTableParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params) - { - if(glColorTableParameterfv_Impl) - glColorTableParameterfv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glColorTableParameteriv_Hook(GLenum target, GLenum pname, const GLint *params) - { - if(glColorTableParameteriv_Impl) - glColorTableParameteriv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCopyColorTable_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) - { - if(glCopyColorTable_Impl) - glCopyColorTable_Impl(target, internalformat, x, y, width); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetColorTable_Hook(GLenum target, GLenum format, GLenum type, GLvoid *table) - { - if(glGetColorTable_Impl) - glGetColorTable_Impl(target, format, type, table); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetColorTableParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) - { - if(glGetColorTableParameterfv_Impl) - glGetColorTableParameterfv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetColorTableParameteriv_Hook(GLenum target, GLenum pname, GLint *params) - { - if(glGetColorTableParameteriv_Impl) - glGetColorTableParameteriv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glColorSubTable_Hook(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) - { - if(glColorSubTable_Impl) - glColorSubTable_Impl(target, start, count, format, type, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCopyColorSubTable_Hook(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) - { - if(glCopyColorSubTable_Impl) - glCopyColorSubTable_Impl(target, start, x, y, width); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) - { - if(glConvolutionFilter1D_Impl) - glConvolutionFilter1D_Impl(target, internalformat, width, format, type, image); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) - { - if(glConvolutionFilter2D_Impl) - glConvolutionFilter2D_Impl(target, internalformat, width, height, format, type, image); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glConvolutionParameterf_Hook(GLenum target, GLenum pname, GLfloat params) - { - if(glConvolutionParameterf_Impl) - glConvolutionParameterf_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glConvolutionParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params) - { - if(glConvolutionParameterfv_Impl) - glConvolutionParameterfv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glConvolutionParameteri_Hook(GLenum target, GLenum pname, GLint params) - { - if(glConvolutionParameteri_Impl) - glConvolutionParameteri_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glConvolutionParameteriv_Hook(GLenum target, GLenum pname, const GLint *params) - { - if(glConvolutionParameteriv_Impl) - glConvolutionParameteriv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCopyConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) - { - if(glCopyConvolutionFilter1D_Impl) - glCopyConvolutionFilter1D_Impl(target, internalformat, x, y, width); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCopyConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) - { - if(glCopyConvolutionFilter2D_Impl) - glCopyConvolutionFilter2D_Impl(target, internalformat, x, y, width, height); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetConvolutionFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *image) - { - if(glGetConvolutionFilter_Impl) - glGetConvolutionFilter_Impl(target, format, type, image); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetConvolutionParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) - { - if(glGetConvolutionParameterfv_Impl) - glGetConvolutionParameterfv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetConvolutionParameteriv_Hook(GLenum target, GLenum pname, GLint *params) - { - if(glGetConvolutionParameteriv_Impl) - glGetConvolutionParameteriv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetSeparableFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) - { - if(glGetSeparableFilter_Impl) - glGetSeparableFilter_Impl(target, format, type, row, column, span); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSeparableFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) - { - if(glSeparableFilter2D_Impl) - glSeparableFilter2D_Impl(target, internalformat, width, height, format, type, row, column); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetHistogram_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) - { - if(glGetHistogram_Impl) - glGetHistogram_Impl(target, reset, format, type, values); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetHistogramParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) - { - if(glGetHistogramParameterfv_Impl) - glGetHistogramParameterfv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetHistogramParameteriv_Hook(GLenum target, GLenum pname, GLint *params) - { - if(glGetHistogramParameteriv_Impl) - glGetHistogramParameteriv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetMinmax_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) - { - if(glGetMinmax_Impl) - glGetMinmax_Impl(target, reset, format, type, values); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetMinmaxParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) - { - if(glGetMinmaxParameterfv_Impl) - glGetMinmaxParameterfv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetMinmaxParameteriv_Hook(GLenum target, GLenum pname, GLint *params) - { - if(glGetMinmaxParameteriv_Impl) - glGetMinmaxParameteriv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glHistogram_Hook(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) - { - if(glHistogram_Impl) - glHistogram_Impl(target, width, internalformat, sink); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMinmax_Hook(GLenum target, GLenum internalformat, GLboolean sink) - { - if(glMinmax_Impl) - glMinmax_Impl(target, internalformat, sink); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glResetHistogram_Hook(GLenum target) - { - if(glResetHistogram_Impl) - glResetHistogram_Impl(target); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glResetMinmax_Hook(GLenum target) - { - if(glResetMinmax_Impl) - glResetMinmax_Impl(target); - PostHook(GLE_CURRENT_FUNCTION); - } - */ - - // GL_VERSION_1_3 - void OVR::GLEContext::glActiveTexture_Hook(GLenum texture) - { - if(glActiveTexture_Impl) - glActiveTexture_Impl(texture); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSampleCoverage_Hook(GLclampf value, GLboolean invert) - { - if(glSampleCoverage_Impl) - glSampleCoverage_Impl(value, invert); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCompressedTexImage3D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) - { - if(glCompressedTexImage3D_Impl) - glCompressedTexImage3D_Impl(target, level, internalformat, width, height, depth, border, imageSize, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCompressedTexImage2D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) - { - if(glCompressedTexImage2D_Impl) - glCompressedTexImage2D_Impl(target, level, internalformat, width, height, border, imageSize, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCompressedTexImage1D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) - { - if(glCompressedTexImage1D_Impl) - glCompressedTexImage1D_Impl(target, level, internalformat, width, border, imageSize, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCompressedTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) - { - if(glCompressedTexSubImage3D_Impl) - glCompressedTexSubImage3D_Impl(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCompressedTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) - { - if(glCompressedTexSubImage2D_Impl) - glCompressedTexSubImage2D_Impl(target, level, xoffset, yoffset, width, height, format, imageSize, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCompressedTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) - { - if(glCompressedTexSubImage1D_Impl) - glCompressedTexSubImage1D_Impl(target, level, xoffset, width, format, imageSize, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetCompressedTexImage_Hook(GLenum target, GLint level, GLvoid *img) - { - if(glGetCompressedTexImage_Impl) - glGetCompressedTexImage_Impl(target, level, img); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_1_3 deprecated functions - void OVR::GLEContext::glClientActiveTexture_Hook(GLenum texture) - { - if(glClientActiveTexture_Impl) - glClientActiveTexture_Impl(texture); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord1d_Hook(GLenum target, GLdouble s) - { - if(glMultiTexCoord1d_Impl) - glMultiTexCoord1d_Impl(target, s); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord1dv_Hook(GLenum target, const GLdouble *v) - { - if(glMultiTexCoord1dv_Impl) - glMultiTexCoord1dv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord1f_Hook(GLenum target, GLfloat s) - { - if(glMultiTexCoord1f_Impl) - glMultiTexCoord1f_Impl(target, s); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord1fv_Hook(GLenum target, const GLfloat *v) - { - if(glMultiTexCoord1fv_Impl) - glMultiTexCoord1fv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord1i_Hook(GLenum target, GLint s) - { - if(glMultiTexCoord1i_Impl) - glMultiTexCoord1i_Impl(target, s); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord1iv_Hook(GLenum target, const GLint *v) - { - if(glMultiTexCoord1iv_Impl) - glMultiTexCoord1iv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord1s_Hook(GLenum target, GLshort s) - { - if(glMultiTexCoord1s_Impl) - glMultiTexCoord1s_Impl(target, s); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord1sv_Hook(GLenum target, const GLshort *v) - { - if(glMultiTexCoord1sv_Impl) - glMultiTexCoord1sv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord2d_Hook(GLenum target, GLdouble s, GLdouble t) - { - if(glMultiTexCoord2d_Impl) - glMultiTexCoord2d_Impl(target, s, t); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord2dv_Hook(GLenum target, const GLdouble *v) - { - if(glMultiTexCoord2dv_Impl) - glMultiTexCoord2dv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord2f_Hook(GLenum target, GLfloat s, GLfloat t) - { - if(glMultiTexCoord2f_Impl) - glMultiTexCoord2f_Impl(target, s, t); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord2fv_Hook(GLenum target, const GLfloat *v) - { - if(glMultiTexCoord2fv_Impl) - glMultiTexCoord2fv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord2i_Hook(GLenum target, GLint s, GLint t) - { - if(glMultiTexCoord2i_Impl) - glMultiTexCoord2i_Impl(target, s, t); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord2iv_Hook(GLenum target, const GLint *v) - { - if(glMultiTexCoord2iv_Impl) - glMultiTexCoord2iv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord2s_Hook(GLenum target, GLshort s, GLshort t) - { - if(glMultiTexCoord2s_Impl) - glMultiTexCoord2s_Impl(target, s, t); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord2sv_Hook(GLenum target, const GLshort *v) - { - if(glMultiTexCoord2sv_Impl) - glMultiTexCoord2sv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord3d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r) - { - if(glMultiTexCoord3d_Impl) - glMultiTexCoord3d_Impl(target, s, t, r); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord3dv_Hook(GLenum target, const GLdouble *v) - { - if(glMultiTexCoord3dv_Impl) - glMultiTexCoord3dv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord3f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r) - { - if(glMultiTexCoord3f_Impl) - glMultiTexCoord3f_Impl(target, s, t, r); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord3fv_Hook(GLenum target, const GLfloat *v) - { - if(glMultiTexCoord3fv_Impl) - glMultiTexCoord3fv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord3i_Hook(GLenum target, GLint s, GLint t, GLint r) - { - if(glMultiTexCoord3i_Impl) - glMultiTexCoord3i_Impl(target, s, t, r); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord3iv_Hook(GLenum target, const GLint *v) - { - if(glMultiTexCoord3iv_Impl) - glMultiTexCoord3iv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord3s_Hook(GLenum target, GLshort s, GLshort t, GLshort r) - { - if(glMultiTexCoord3s_Impl) - glMultiTexCoord3s_Impl(target, s, t, r); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord3sv_Hook(GLenum target, const GLshort *v) - { - if(glMultiTexCoord3sv_Impl) - glMultiTexCoord3sv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord4d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) - { - if(glMultiTexCoord4d_Impl) - glMultiTexCoord4d_Impl(target, s, t, r, q); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord4dv_Hook(GLenum target, const GLdouble *v) - { - if(glMultiTexCoord4dv_Impl) - glMultiTexCoord4dv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord4f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) - { - if(glMultiTexCoord4f_Impl) - glMultiTexCoord4f_Impl(target, s, t, r, q); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord4fv_Hook(GLenum target, const GLfloat *v) - { - if(glMultiTexCoord4fv_Impl) - glMultiTexCoord4fv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord4i_Hook(GLenum target, GLint s, GLint t, GLint r, GLint q) - { - if(glMultiTexCoord4i_Impl) - glMultiTexCoord4i_Impl(target, s, t, r, q); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord4iv_Hook(GLenum target, const GLint *v) - { - if(glMultiTexCoord4iv_Impl) - glMultiTexCoord4iv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord4s_Hook(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) - { - if(glMultiTexCoord4s_Impl) - glMultiTexCoord4s_Impl(target, s, t, r, q); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiTexCoord4sv_Hook(GLenum target, const GLshort *v) - { - if(glMultiTexCoord4sv_Impl) - glMultiTexCoord4sv_Impl(target, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glLoadTransposeMatrixf_Hook(const GLfloat *m) - { - if(glLoadTransposeMatrixf_Impl) - glLoadTransposeMatrixf_Impl(m); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glLoadTransposeMatrixd_Hook(const GLdouble *m) - { - if(glLoadTransposeMatrixd_Impl) - glLoadTransposeMatrixd_Impl(m); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultTransposeMatrixf_Hook(const GLfloat *m) - { - if(glMultTransposeMatrixf_Impl) - glMultTransposeMatrixf_Impl(m); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultTransposeMatrixd_Hook(const GLdouble *m) - { - if(glMultTransposeMatrixd_Impl) - glMultTransposeMatrixd_Impl(m); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_1_4 - void OVR::GLEContext::glBlendFuncSeparate_Hook(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) - { - if(glBlendFuncSeparate_Impl) - glBlendFuncSeparate_Impl(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiDrawArrays_Hook(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) - { - if(glMultiDrawArrays_Impl) - glMultiDrawArrays_Impl(mode, first, count, primcount); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiDrawElements_Hook(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) - { - if(glMultiDrawElements_Impl) - glMultiDrawElements_Impl(mode, count, type, indices, primcount); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glPointParameterf_Hook(GLenum pname, GLfloat param) - { - if(glPointParameterf_Impl) - glPointParameterf_Impl(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glPointParameterfv_Hook(GLenum pname, const GLfloat *params) - { - if(glPointParameterfv_Impl) - glPointParameterfv_Impl(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glPointParameteri_Hook(GLenum pname, GLint param) - { - if(glPointParameteri_Impl) - glPointParameteri_Impl(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glPointParameteriv_Hook(GLenum pname, const GLint *params) - { - if(glPointParameteriv_Impl) - glPointParameteriv_Impl(pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_1_4 deprecated functions - void OVR::GLEContext::glFogCoordf_Hook(GLfloat coord) - { - if(glFogCoordf_Impl) - glFogCoordf_Impl(coord); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFogCoordfv_Hook(const GLfloat *coord) - { - if(glFogCoordfv_Impl) - glFogCoordfv_Impl(coord); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFogCoordd_Hook(GLdouble coord) - { - if(glFogCoordd_Impl) - glFogCoordd_Impl(coord); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFogCoorddv_Hook(const GLdouble *coord) - { - if(glFogCoorddv_Impl) - glFogCoorddv_Impl(coord); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFogCoordPointer_Hook(GLenum type, GLsizei stride, const GLvoid *pointer) - { - if(glFogCoordPointer_Impl) - glFogCoordPointer_Impl(type, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue) - { - if(glSecondaryColor3b_Impl) - glSecondaryColor3b_Impl(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3bv_Hook(const GLbyte *v) - { - if(glSecondaryColor3bv_Impl) - glSecondaryColor3bv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue) - { - if(glSecondaryColor3d_Impl) - glSecondaryColor3d_Impl(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3dv_Hook(const GLdouble *v) - { - if(glSecondaryColor3dv_Impl) - glSecondaryColor3dv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue) - { - if(glSecondaryColor3f_Impl) - glSecondaryColor3f_Impl(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3fv_Hook(const GLfloat *v) - { - if(glSecondaryColor3fv_Impl) - glSecondaryColor3fv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3i_Hook(GLint red, GLint green, GLint blue) - { - if(glSecondaryColor3i_Impl) - glSecondaryColor3i_Impl(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3iv_Hook(const GLint *v) - { - if(glSecondaryColor3iv_Impl) - glSecondaryColor3iv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3s_Hook(GLshort red, GLshort green, GLshort blue) - { - if(glSecondaryColor3s_Impl) - glSecondaryColor3s_Impl(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3sv_Hook(const GLshort *v) - { - if(glSecondaryColor3sv_Impl) - glSecondaryColor3sv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue) - { - if(glSecondaryColor3ub_Impl) - glSecondaryColor3ub_Impl(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3ubv_Hook(const GLubyte *v) - { - if(glSecondaryColor3ubv_Impl) - glSecondaryColor3ubv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3ui_Hook(GLuint red, GLuint green, GLuint blue) - { - if(glSecondaryColor3ui_Impl) - glSecondaryColor3ui_Impl(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3uiv_Hook(const GLuint *v) - { - if(glSecondaryColor3uiv_Impl) - glSecondaryColor3uiv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3us_Hook(GLushort red, GLushort green, GLushort blue) - { - if(glSecondaryColor3us_Impl) - glSecondaryColor3us_Impl(red, green, blue); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColor3usv_Hook(const GLushort *v) - { - if(glSecondaryColor3usv_Impl) - glSecondaryColor3usv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSecondaryColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) - { - if(glSecondaryColorPointer_Impl) - glSecondaryColorPointer_Impl(size, type, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos2d_Hook(GLdouble x, GLdouble y) - { - if(glWindowPos2d_Impl) - glWindowPos2d_Impl(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos2dv_Hook(const GLdouble *v) - { - if(glWindowPos2dv_Impl) - glWindowPos2dv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos2f_Hook(GLfloat x, GLfloat y) - { - if(glWindowPos2f_Impl) - glWindowPos2f_Impl(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos2fv_Hook(const GLfloat *v) - { - if(glWindowPos2fv_Impl) - glWindowPos2fv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos2i_Hook(GLint x, GLint y) - { - if(glWindowPos2i_Impl) - glWindowPos2i_Impl(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos2iv_Hook(const GLint *v) - { - if(glWindowPos2iv_Impl) - glWindowPos2iv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos2s_Hook(GLshort x, GLshort y) - { - if(glWindowPos2s_Impl) - glWindowPos2s_Impl(x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos2sv_Hook(const GLshort *v) - { - if(glWindowPos2sv_Impl) - glWindowPos2sv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos3d_Hook(GLdouble x, GLdouble y, GLdouble z) - { - if(glWindowPos3d_Impl) - glWindowPos3d_Impl(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos3dv_Hook(const GLdouble *v) - { - if(glWindowPos3dv_Impl) - glWindowPos3dv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos3f_Hook(GLfloat x, GLfloat y, GLfloat z) - { - if(glWindowPos3f_Impl) - glWindowPos3f_Impl(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos3fv_Hook(const GLfloat *v) - { - if(glWindowPos3fv_Impl) - glWindowPos3fv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos3i_Hook(GLint x, GLint y, GLint z) - { - if(glWindowPos3i_Impl) - glWindowPos3i_Impl(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos3iv_Hook(const GLint *v) - { - if(glWindowPos3iv_Impl) - glWindowPos3iv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos3s_Hook(GLshort x, GLshort y, GLshort z) - { - if(glWindowPos3s_Impl) - glWindowPos3s_Impl(x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glWindowPos3sv_Hook(const GLshort *v) - { - if(glWindowPos3sv_Impl) - glWindowPos3sv_Impl(v); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_1_5 - void OVR::GLEContext::glGenQueries_Hook(GLsizei n, GLuint *ids) - { - if(glGenQueries_Impl) - glGenQueries_Impl(n, ids); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDeleteQueries_Hook(GLsizei n, const GLuint *ids) - { - if(glDeleteQueries_Impl) - glDeleteQueries_Impl(n, ids); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsQuery_Hook(GLuint id) - { - GLboolean b = GL_FALSE; - if(glIsQuery_Impl) - b = glIsQuery_Impl(id); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glBeginQuery_Hook(GLenum target, GLuint id) - { - if(glBeginQuery_Impl) - glBeginQuery_Impl(target, id); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glEndQuery_Hook(GLenum target) - { - if(glEndQuery_Impl) - glEndQuery_Impl(target); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetQueryiv_Hook(GLenum target, GLenum pname, GLint *params) - { - if(glGetQueryiv_Impl) - glGetQueryiv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetQueryObjectiv_Hook(GLuint id, GLenum pname, GLint *params) - { - if(glGetQueryObjectiv_Impl) - glGetQueryObjectiv_Impl(id, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetQueryObjectuiv_Hook(GLuint id, GLenum pname, GLuint *params) - { - if(glGetQueryObjectuiv_Impl) - glGetQueryObjectuiv_Impl(id, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBindBuffer_Hook(GLenum target, GLuint buffer) - { - if(glBindBuffer_Impl) - glBindBuffer_Impl(target, buffer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDeleteBuffers_Hook(GLsizei n, const GLuint *buffers) - { - if(glDeleteBuffers_Impl) - glDeleteBuffers_Impl(n, buffers); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGenBuffers_Hook(GLsizei n, GLuint *buffers) - { - if(glGenBuffers_Impl) - glGenBuffers_Impl(n, buffers); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsBuffer_Hook(GLuint buffer) - { - GLboolean b = GL_FALSE; - if(glIsBuffer_Impl) - b = glIsBuffer_Impl(buffer); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glBufferData_Hook(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) - { - if(glBufferData_Impl) - glBufferData_Impl(target, size, data, usage); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) - { - if(glBufferSubData_Impl) - glBufferSubData_Impl(target, offset, size, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) - { - if(glGetBufferSubData_Impl) - glGetBufferSubData_Impl(target, offset, size, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLvoid* OVR::GLEContext::glMapBuffer_Hook(GLenum target, GLenum access) - { - GLvoid* p = NULL; - if(glMapBuffer_Impl) - p = glMapBuffer_Impl(target, access); - PostHook(GLE_CURRENT_FUNCTION); - return p; - } - - GLboolean OVR::GLEContext::glUnmapBuffer_Hook(GLenum target) - { - GLboolean b = GL_FALSE; - if(glUnmapBuffer_Impl) - b = glUnmapBuffer_Impl(target); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glGetBufferParameteriv_Hook(GLenum target, GLenum pname, GLint *params) - { - if(glGetBufferParameteriv_Impl) - glGetBufferParameteriv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetBufferPointerv_Hook(GLenum target, GLenum pname, GLvoid* *params) - { - if(glGetBufferPointerv_Impl) - glGetBufferPointerv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_2_0 - void OVR::GLEContext::glBlendEquationSeparate_Hook(GLenum modeRGB, GLenum modeAlpha) - { - if(glBlendEquationSeparate_Impl) - glBlendEquationSeparate_Impl(modeRGB, modeAlpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDrawBuffers_Hook(GLsizei n, const GLenum *bufs) - { - if(glDrawBuffers_Impl) - glDrawBuffers_Impl(n, bufs); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glStencilOpSeparate_Hook(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) - { - if(glStencilOpSeparate_Impl) - glStencilOpSeparate_Impl(face, sfail, dpfail, dppass); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glStencilFuncSeparate_Hook(GLenum face, GLenum func, GLint ref, GLuint mask) - { - if(glStencilFuncSeparate_Impl) - glStencilFuncSeparate_Impl(face, func, ref, mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glStencilMaskSeparate_Hook(GLenum face, GLuint mask) - { - if(glStencilMaskSeparate_Impl) - glStencilMaskSeparate_Impl(face, mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glAttachShader_Hook(GLuint program, GLuint shader) - { - if(glAttachShader_Impl) - glAttachShader_Impl(program, shader); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBindAttribLocation_Hook(GLuint program, GLuint index, const GLchar *name) - { - if(glBindAttribLocation_Impl) - glBindAttribLocation_Impl(program, index, name); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glCompileShader_Hook(GLuint shader) - { - if(glCompileShader_Impl) - glCompileShader_Impl(shader); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLuint OVR::GLEContext::glCreateProgram_Hook() - { - GLuint u = 0; - if(glCreateProgram_Impl) - u = glCreateProgram_Impl(); - PostHook(GLE_CURRENT_FUNCTION); - return u; - } - - GLuint OVR::GLEContext::glCreateShader_Hook(GLenum type) - { - GLuint u = 0; - if(glCreateShader_Impl) - u = glCreateShader_Impl(type); - PostHook(GLE_CURRENT_FUNCTION); - return u; - } - - void OVR::GLEContext::glDeleteProgram_Hook(GLuint program) - { - if(glDeleteProgram_Impl) - glDeleteProgram_Impl(program); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDeleteShader_Hook(GLuint shader) - { - if(glDeleteShader_Impl) - glDeleteShader_Impl(shader); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDetachShader_Hook(GLuint program, GLuint shader) - { - if(glDetachShader_Impl) - glDetachShader_Impl(program, shader); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDisableVertexAttribArray_Hook(GLuint index) - { - if(glDisableVertexAttribArray_Impl) - glDisableVertexAttribArray_Impl(index); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glEnableVertexAttribArray_Hook(GLuint index) - { - if(glEnableVertexAttribArray_Impl) - glEnableVertexAttribArray_Impl(index); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetActiveAttrib_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) - { - if(glGetActiveAttrib_Impl) - glGetActiveAttrib_Impl(program, index, bufSize, length, size, type, name); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetActiveUniform_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) - { - if(glGetActiveUniform_Impl) - glGetActiveUniform_Impl(program, index, bufSize, length, size, type, name); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetAttachedShaders_Hook(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj) - { - if(glGetAttachedShaders_Impl) - glGetAttachedShaders_Impl(program, maxCount, count, obj); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLint OVR::GLEContext::glGetAttribLocation_Hook(GLuint program, const GLchar *name) - { - GLint i = 0; - if(glGetAttribLocation_Impl) - i = glGetAttribLocation_Impl(program, name); - PostHook(GLE_CURRENT_FUNCTION); - return i; - } - - void OVR::GLEContext::glGetProgramiv_Hook(GLuint program, GLenum pname, GLint *params) - { - if(glGetProgramiv_Impl) - glGetProgramiv_Impl(program, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetProgramInfoLog_Hook(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) - { - if(glGetProgramInfoLog_Impl) - glGetProgramInfoLog_Impl(program, bufSize, length, infoLog); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetShaderiv_Hook(GLuint shader, GLenum pname, GLint *params) - { - if(glGetShaderiv_Impl) - glGetShaderiv_Impl(shader, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetShaderInfoLog_Hook(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) - { - if(glGetShaderInfoLog_Impl) - glGetShaderInfoLog_Impl(shader, bufSize, length, infoLog); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetShaderSource_Hook(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) - { - if(glGetShaderSource_Impl) - glGetShaderSource_Impl(shader, bufSize, length, source); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLint OVR::GLEContext::glGetUniformLocation_Hook(GLuint program, const GLchar *name) - { - GLint i = 0; - if(glGetUniformLocation_Impl) - i = glGetUniformLocation_Impl(program, name); - PostHook(GLE_CURRENT_FUNCTION); - return i; - } - - void OVR::GLEContext::glGetUniformfv_Hook(GLuint program, GLint location, GLfloat *params) - { - if(glGetUniformfv_Impl) - glGetUniformfv_Impl(program, location, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetUniformiv_Hook(GLuint program, GLint location, GLint *params) - { - if(glGetUniformiv_Impl) - glGetUniformiv_Impl(program, location, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetVertexAttribdv_Hook(GLuint index, GLenum pname, GLdouble *params) - { - if(glGetVertexAttribdv_Impl) - glGetVertexAttribdv_Impl(index, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetVertexAttribfv_Hook(GLuint index, GLenum pname, GLfloat *params) - { - if(glGetVertexAttribfv_Impl) - glGetVertexAttribfv_Impl(index, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetVertexAttribiv_Hook(GLuint index, GLenum pname, GLint *params) - { - if(glGetVertexAttribiv_Impl) - glGetVertexAttribiv_Impl(index, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetVertexAttribPointerv_Hook(GLuint index, GLenum pname, GLvoid* *pointer) - { - if(glGetVertexAttribPointerv_Impl) - glGetVertexAttribPointerv_Impl(index, pname, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsProgram_Hook(GLuint program) - { - GLboolean b = GL_FALSE; - if(glIsProgram_Impl) - b = glIsProgram_Impl(program); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - GLboolean OVR::GLEContext::glIsShader_Hook(GLuint shader) - { - GLboolean b = GL_FALSE; - if(glIsShader_Impl) - b = glIsShader_Impl(shader); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glLinkProgram_Hook(GLuint program) - { - if(glLinkProgram_Impl) - glLinkProgram_Impl(program); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glShaderSource_Hook(GLuint shader, GLsizei count, const GLchar* *string, const GLint *length) - { - if(glShaderSource_Impl) - glShaderSource_Impl(shader, count, string, length); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUseProgram_Hook(GLuint program) - { - if(glUseProgram_Impl) - glUseProgram_Impl(program); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform1f_Hook(GLint location, GLfloat v0) - { - if(glUniform1f_Impl) - glUniform1f_Impl(location, v0); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform2f_Hook(GLint location, GLfloat v0, GLfloat v1) - { - if(glUniform2f_Impl) - glUniform2f_Impl(location, v0, v1); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform3f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) - { - if(glUniform3f_Impl) - glUniform3f_Impl(location, v0, v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform4f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) - { - if(glUniform4f_Impl) - glUniform4f_Impl(location, v0, v1, v2, v3); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform1i_Hook(GLint location, GLint v0) - { - if(glUniform1i_Impl) - glUniform1i_Impl(location, v0); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform2i_Hook(GLint location, GLint v0, GLint v1) - { - if(glUniform2i_Impl) - glUniform2i_Impl(location, v0, v1); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform3i_Hook(GLint location, GLint v0, GLint v1, GLint v2) - { - if(glUniform3i_Impl) - glUniform3i_Impl(location, v0, v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform4i_Hook(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) - { - if(glUniform4i_Impl) - glUniform4i_Impl(location, v0, v1, v2, v3); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform1fv_Hook(GLint location, GLsizei count, const GLfloat *value) - { - if(glUniform1fv_Impl) - glUniform1fv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform2fv_Hook(GLint location, GLsizei count, const GLfloat *value) - { - if(glUniform2fv_Impl) - glUniform2fv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform3fv_Hook(GLint location, GLsizei count, const GLfloat *value) - { - if(glUniform3fv_Impl) - glUniform3fv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform4fv_Hook(GLint location, GLsizei count, const GLfloat *value) - { - if(glUniform4fv_Impl) - glUniform4fv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform1iv_Hook(GLint location, GLsizei count, const GLint *value) - { - if(glUniform1iv_Impl) - glUniform1iv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform2iv_Hook(GLint location, GLsizei count, const GLint *value) - { - if(glUniform2iv_Impl) - glUniform2iv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform3iv_Hook(GLint location, GLsizei count, const GLint *value) - { - if(glUniform3iv_Impl) - glUniform3iv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform4iv_Hook(GLint location, GLsizei count, const GLint *value) - { - if(glUniform4iv_Impl) - glUniform4iv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniformMatrix2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix2fv_Impl) - glUniformMatrix2fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniformMatrix3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix3fv_Impl) - glUniformMatrix3fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniformMatrix4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix4fv_Impl) - glUniformMatrix4fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glValidateProgram_Hook(GLuint program) - { - if(glValidateProgram_Impl) - glValidateProgram_Impl(program); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib1d_Hook(GLuint index, GLdouble x) - { - if(glVertexAttrib1d_Impl) - glVertexAttrib1d_Impl(index, x); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib1dv_Hook(GLuint index, const GLdouble *v) - { - if(glVertexAttrib1dv_Impl) - glVertexAttrib1dv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib1f_Hook(GLuint index, GLfloat x) - { - if(glVertexAttrib1f_Impl) - glVertexAttrib1f_Impl(index, x); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib1fv_Hook(GLuint index, const GLfloat *v) - { - if(glVertexAttrib1fv_Impl) - glVertexAttrib1fv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib1s_Hook(GLuint index, GLshort x) - { - if(glVertexAttrib1s_Impl) - glVertexAttrib1s_Impl(index, x); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib1sv_Hook(GLuint index, const GLshort *v) - { - if(glVertexAttrib1sv_Impl) - glVertexAttrib1sv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib2d_Hook(GLuint index, GLdouble x, GLdouble y) - { - if(glVertexAttrib2d_Impl) - glVertexAttrib2d_Impl(index, x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib2dv_Hook(GLuint index, const GLdouble *v) - { - if(glVertexAttrib2dv_Impl) - glVertexAttrib2dv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib2f_Hook(GLuint index, GLfloat x, GLfloat y) - { - if(glVertexAttrib2f_Impl) - glVertexAttrib2f_Impl(index, x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib2fv_Hook(GLuint index, const GLfloat *v) - { - if(glVertexAttrib2fv_Impl) - glVertexAttrib2fv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib2s_Hook(GLuint index, GLshort x, GLshort y) - { - if(glVertexAttrib2s_Impl) - glVertexAttrib2s_Impl(index, x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib2sv_Hook(GLuint index, const GLshort *v) - { - if(glVertexAttrib2sv_Impl) - glVertexAttrib2sv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib3d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z) - { - if(glVertexAttrib3d_Impl) - glVertexAttrib3d_Impl(index, x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib3dv_Hook(GLuint index, const GLdouble *v) - { - if(glVertexAttrib3dv_Impl) - glVertexAttrib3dv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib3f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z) - { - if(glVertexAttrib3f_Impl) - glVertexAttrib3f_Impl(index, x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib3fv_Hook(GLuint index, const GLfloat *v) - { - if(glVertexAttrib3fv_Impl) - glVertexAttrib3fv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib3s_Hook(GLuint index, GLshort x, GLshort y, GLshort z) - { - if(glVertexAttrib3s_Impl) - glVertexAttrib3s_Impl(index, x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib3sv_Hook(GLuint index, const GLshort *v) - { - if(glVertexAttrib3sv_Impl) - glVertexAttrib3sv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4Nbv_Hook(GLuint index, const GLbyte *v) - { - if(glVertexAttrib4Nbv_Impl) - glVertexAttrib4Nbv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4Niv_Hook(GLuint index, const GLint *v) - { - if(glVertexAttrib4Niv_Impl) - glVertexAttrib4Niv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4Nsv_Hook(GLuint index, const GLshort *v) - { - if(glVertexAttrib4Nsv_Impl) - glVertexAttrib4Nsv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4Nub_Hook(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) - { - if(glVertexAttrib4Nub_Impl) - glVertexAttrib4Nub_Impl(index, x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4Nubv_Hook(GLuint index, const GLubyte *v) - { - if(glVertexAttrib4Nubv_Impl) - glVertexAttrib4Nubv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4Nuiv_Hook(GLuint index, const GLuint *v) - { - if(glVertexAttrib4Nuiv_Impl) - glVertexAttrib4Nuiv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4Nusv_Hook(GLuint index, const GLushort *v) - { - if(glVertexAttrib4Nusv_Impl) - glVertexAttrib4Nusv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4bv_Hook(GLuint index, const GLbyte *v) - { - if(glVertexAttrib4bv_Impl) - glVertexAttrib4bv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) - { - if(glVertexAttrib4d_Impl) - glVertexAttrib4d_Impl(index, x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4dv_Hook(GLuint index, const GLdouble *v) - { - if(glVertexAttrib4dv_Impl) - glVertexAttrib4dv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) - { - if(glVertexAttrib4f_Impl) - glVertexAttrib4f_Impl(index, x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4fv_Hook(GLuint index, const GLfloat *v) - { - if(glVertexAttrib4fv_Impl) - glVertexAttrib4fv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4iv_Hook(GLuint index, const GLint *v) - { - if(glVertexAttrib4iv_Impl) - glVertexAttrib4iv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4s_Hook(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) - { - if(glVertexAttrib4s_Impl) - glVertexAttrib4s_Impl(index, x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4sv_Hook(GLuint index, const GLshort *v) - { - if(glVertexAttrib4sv_Impl) - glVertexAttrib4sv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4ubv_Hook(GLuint index, const GLubyte *v) - { - if(glVertexAttrib4ubv_Impl) - glVertexAttrib4ubv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4uiv_Hook(GLuint index, const GLuint *v) - { - if(glVertexAttrib4uiv_Impl) - glVertexAttrib4uiv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttrib4usv_Hook(GLuint index, const GLushort *v) - { - if(glVertexAttrib4usv_Impl) - glVertexAttrib4usv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribPointer_Hook(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) - { - if(glVertexAttribPointer_Impl) - glVertexAttribPointer_Impl(index, size, type, normalized, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_2_1 - void OVR::GLEContext::glUniformMatrix2x3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix2x3fv_Impl) - glUniformMatrix2x3fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniformMatrix3x2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix3x2fv_Impl) - glUniformMatrix3x2fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniformMatrix2x4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix2x4fv_Impl) - glUniformMatrix2x4fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniformMatrix4x2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix4x2fv_Impl) - glUniformMatrix4x2fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniformMatrix3x4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix3x4fv_Impl) - glUniformMatrix3x4fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniformMatrix4x3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) - { - if(glUniformMatrix4x3fv_Impl) - glUniformMatrix4x3fv_Impl(location, count, transpose, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_3_0 - void OVR::GLEContext::glColorMaski_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) - { - if(glColorMaski_Impl) - glColorMaski_Impl(index, r, g, b, a); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetBooleani_v_Hook(GLenum target, GLuint index, GLboolean *data) - { - if(glGetBooleani_v_Impl) - glGetBooleani_v_Impl(target, index, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetIntegeri_v_Hook(GLenum target, GLuint index, GLint *data) - { - if(glGetIntegeri_v_Impl) - glGetIntegeri_v_Impl(target, index, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glEnablei_Hook(GLenum target, GLuint index) - { - if(glEnablei_Impl) - glEnablei_Impl(target, index); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDisablei_Hook(GLenum target, GLuint index) - { - if(glDisablei_Impl) - glDisablei_Impl(target, index); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsEnabledi_Hook(GLenum target, GLuint index) - { - GLboolean b = GL_FALSE; - if(glIsEnabledi_Impl) - b = glIsEnabledi_Impl(target, index); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glBeginTransformFeedback_Hook(GLenum primitiveMode) - { - if(glBeginTransformFeedback_Impl) - glBeginTransformFeedback_Impl(primitiveMode); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glEndTransformFeedback_Hook() - { - if(glEndTransformFeedback_Impl) - glEndTransformFeedback_Impl(); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBindBufferRange_Hook(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) - { - if(glBindBufferRange_Impl) - glBindBufferRange_Impl(target, index, buffer, offset, size); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBindBufferBase_Hook(GLenum target, GLuint index, GLuint buffer) - { - if(glBindBufferBase_Impl) - glBindBufferBase_Impl(target, index, buffer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glTransformFeedbackVaryings_Hook(GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode) - { - if(glTransformFeedbackVaryings_Impl) - glTransformFeedbackVaryings_Impl(program, count, varyings, bufferMode); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetTransformFeedbackVarying_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) - { - if(glGetTransformFeedbackVarying_Impl) - glGetTransformFeedbackVarying_Impl(program, index, bufSize, length, size, type, name); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glClampColor_Hook(GLenum target, GLenum clamp) - { - if(glClampColor_Impl) - glClampColor_Impl(target, clamp); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBeginConditionalRender_Hook(GLuint id, GLenum mode) - { - if(glBeginConditionalRender_Impl) - glBeginConditionalRender_Impl(id, mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glEndConditionalRender_Hook() - { - if(glEndConditionalRender_Impl) - glEndConditionalRender_Impl(); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribIPointer_Hook(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) - { - if(glVertexAttribIPointer_Impl) - glVertexAttribIPointer_Impl(index, size, type, stride, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetVertexAttribIiv_Hook(GLuint index, GLenum pname, GLint *params) - { - if(glGetVertexAttribIiv_Impl) - glGetVertexAttribIiv_Impl(index, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetVertexAttribIuiv_Hook(GLuint index, GLenum pname, GLuint *params) - { - if(glGetVertexAttribIuiv_Impl) - glGetVertexAttribIuiv_Impl(index, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI1i_Hook(GLuint index, GLint x) - { - if(glVertexAttribI1i_Impl) - glVertexAttribI1i_Impl(index, x); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI2i_Hook(GLuint index, GLint x, GLint y) - { - if(glVertexAttribI2i_Impl) - glVertexAttribI2i_Impl(index, x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI3i_Hook(GLuint index, GLint x, GLint y, GLint z) - { - if(glVertexAttribI3i_Impl) - glVertexAttribI3i_Impl(index, x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI4i_Hook(GLuint index, GLint x, GLint y, GLint z, GLint w) - { - if(glVertexAttribI4i_Impl) - glVertexAttribI4i_Impl(index, x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI1ui_Hook(GLuint index, GLuint x) - { - if(glVertexAttribI1ui_Impl) - glVertexAttribI1ui_Impl(index, x); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI2ui_Hook(GLuint index, GLuint x, GLuint y) - { - if(glVertexAttribI2ui_Impl) - glVertexAttribI2ui_Impl(index, x, y); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI3ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z) - { - if(glVertexAttribI3ui_Impl) - glVertexAttribI3ui_Impl(index, x, y, z); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI4ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) - { - if(glVertexAttribI4ui_Impl) - glVertexAttribI4ui_Impl(index, x, y, z, w); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI1iv_Hook(GLuint index, const GLint *v) - { - if(glVertexAttribI1iv_Impl) - glVertexAttribI1iv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI2iv_Hook(GLuint index, const GLint *v) - { - if(glVertexAttribI2iv_Impl) - glVertexAttribI2iv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI3iv_Hook(GLuint index, const GLint *v) - { - if(glVertexAttribI3iv_Impl) - glVertexAttribI3iv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI4iv_Hook(GLuint index, const GLint *v) - { - if(glVertexAttribI4iv_Impl) - glVertexAttribI4iv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI1uiv_Hook(GLuint index, const GLuint *v) - { - if(glVertexAttribI1uiv_Impl) - glVertexAttribI1uiv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI2uiv_Hook(GLuint index, const GLuint *v) - { - if(glVertexAttribI2uiv_Impl) - glVertexAttribI2uiv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI3uiv_Hook(GLuint index, const GLuint *v) - { - if(glVertexAttribI3uiv_Impl) - glVertexAttribI3uiv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI4uiv_Hook(GLuint index, const GLuint *v) - { - if(glVertexAttribI4uiv_Impl) - glVertexAttribI4uiv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI4bv_Hook(GLuint index, const GLbyte *v) - { - if(glVertexAttribI4bv_Impl) - glVertexAttribI4bv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI4sv_Hook(GLuint index, const GLshort *v) - { - if(glVertexAttribI4sv_Impl) - glVertexAttribI4sv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI4ubv_Hook(GLuint index, const GLubyte *v) - { - if(glVertexAttribI4ubv_Impl) - glVertexAttribI4ubv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexAttribI4usv_Hook(GLuint index, const GLushort *v) - { - if(glVertexAttribI4usv_Impl) - glVertexAttribI4usv_Impl(index, v); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetUniformuiv_Hook(GLuint program, GLint location, GLuint *params) - { - if(glGetUniformuiv_Impl) - glGetUniformuiv_Impl(program, location, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBindFragDataLocation_Hook(GLuint program, GLuint color, const GLchar *name) - { - if(glBindFragDataLocation_Impl) - glBindFragDataLocation_Impl(program, color, name); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLint OVR::GLEContext::glGetFragDataLocation_Hook(GLuint program, const GLchar *name) - { - GLint i = 0; - if(glGetFragDataLocation_Impl) - i = glGetFragDataLocation_Impl(program, name); - PostHook(GLE_CURRENT_FUNCTION); - return i; - } - - void OVR::GLEContext::glUniform1ui_Hook(GLint location, GLuint v0) - { - if(glUniform1ui_Impl) - glUniform1ui_Impl(location, v0); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform2ui_Hook(GLint location, GLuint v0, GLuint v1) - { - if(glUniform2ui_Impl) - glUniform2ui_Impl(location, v0, v1); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform3ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2) - { - if(glUniform3ui_Impl) - glUniform3ui_Impl(location, v0, v1, v2); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform4ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) - { - if(glUniform4ui_Impl) - glUniform4ui_Impl(location, v0, v1, v2, v3); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform1uiv_Hook(GLint location, GLsizei count, const GLuint *value) - { - if(glUniform1uiv_Impl) - glUniform1uiv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform2uiv_Hook(GLint location, GLsizei count, const GLuint *value) - { - if(glUniform2uiv_Impl) - glUniform2uiv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform3uiv_Hook(GLint location, GLsizei count, const GLuint *value) - { - if(glUniform3uiv_Impl) - glUniform3uiv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glUniform4uiv_Hook(GLint location, GLsizei count, const GLuint *value) - { - if(glUniform4uiv_Impl) - glUniform4uiv_Impl(location, count, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glTexParameterIiv_Hook(GLenum target, GLenum pname, const GLint *params) - { - if(glTexParameterIiv_Impl) - glTexParameterIiv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glTexParameterIuiv_Hook(GLenum target, GLenum pname, const GLuint *params) - { - if(glTexParameterIuiv_Impl) - glTexParameterIuiv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetTexParameterIiv_Hook(GLenum target, GLenum pname, GLint *params) - { - if(glGetTexParameterIiv_Impl) - glGetTexParameterIiv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetTexParameterIuiv_Hook(GLenum target, GLenum pname, GLuint *params) - { - if(glGetTexParameterIuiv_Impl) - glGetTexParameterIuiv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glClearBufferiv_Hook(GLenum buffer, GLint drawbuffer, const GLint *value) - { - if(glClearBufferiv_Impl) - glClearBufferiv_Impl(buffer, drawbuffer, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glClearBufferuiv_Hook(GLenum buffer, GLint drawbuffer, const GLuint *value) - { - if(glClearBufferuiv_Impl) - glClearBufferuiv_Impl(buffer, drawbuffer, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glClearBufferfv_Hook(GLenum buffer, GLint drawbuffer, const GLfloat *value) - { - if(glClearBufferfv_Impl) - glClearBufferfv_Impl(buffer, drawbuffer, value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glClearBufferfi_Hook(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) - { - if(glClearBufferfi_Impl) - glClearBufferfi_Impl(buffer, drawbuffer, depth, stencil); - PostHook(GLE_CURRENT_FUNCTION); - } - - const GLubyte* OVR::GLEContext::glGetStringi_Hook(GLenum name, GLuint index) - { - const GLubyte* p = NULL; - if(glGetStringi_Impl) - p = glGetStringi_Impl(name, index); - PostHook(GLE_CURRENT_FUNCTION); - return p; - } - - - // GL_VERSION_3_1 - void OVR::GLEContext::glDrawArraysInstanced_Hook(GLenum mode, GLint first, GLsizei count, GLsizei primcount) - { - if(glDrawArraysInstanced_Impl) - glDrawArraysInstanced_Impl(mode, first, count, primcount); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDrawElementsInstanced_Hook(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) - { - if(glDrawElementsInstanced_Impl) - glDrawElementsInstanced_Impl(mode, count, type, indices, primcount); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glTexBuffer_Hook(GLenum target, GLenum internalformat, GLuint buffer) - { - if(glTexBuffer_Impl) - glTexBuffer_Impl(target, internalformat, buffer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glPrimitiveRestartIndex_Hook(GLuint index) - { - if(glPrimitiveRestartIndex_Impl) - glPrimitiveRestartIndex_Impl(index); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_3_2 - void OVR::GLEContext::glGetInteger64i_v_Hook(GLenum target, GLuint index, GLint64 *data) - { - if(glGetInteger64i_v_Impl) - glGetInteger64i_v_Impl(target, index, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetBufferParameteri64v_Hook(GLenum target, GLenum pname, GLint64 *params) - { - if(glGetBufferParameteri64v_Impl) - glGetBufferParameteri64v_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFramebufferTexture_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level) - { - if(glFramebufferTexture_Impl) - glFramebufferTexture_Impl(target, attachment, texture, level); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_3_3 - void OVR::GLEContext::glVertexAttribDivisor_Hook(GLuint index, GLuint divisor) - { - if(glVertexAttribDivisor_Impl) - glVertexAttribDivisor_Impl(index, divisor); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_VERSION_4_0 - void OVR::GLEContext::glMinSampleShading_Hook(GLclampf value) - { - if(glMinSampleShading_Impl) - glMinSampleShading_Impl(value); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBlendEquationi_Hook(GLuint buf, GLenum mode) - { - if(glBlendEquationi_Impl) - glBlendEquationi_Impl(buf, mode); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBlendEquationSeparatei_Hook(GLuint buf, GLenum modeRGB, GLenum modeAlpha) - { - if(glBlendEquationSeparatei_Impl) - glBlendEquationSeparatei_Impl(buf, modeRGB, modeAlpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBlendFunci_Hook(GLuint buf, GLenum src, GLenum dst) - { - if(glBlendFunci_Impl) - glBlendFunci_Impl(buf, src, dst); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBlendFuncSeparatei_Hook(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) - { - if(glBlendFuncSeparatei_Impl) - glBlendFuncSeparatei_Impl(buf, srcRGB, dstRGB, srcAlpha, dstAlpha); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_AMD_debug_output - void OVR::GLEContext::glDebugMessageEnableAMD_Hook(GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled) - { - if(glDebugMessageEnableAMD_Impl) - glDebugMessageEnableAMD_Impl(category, severity, count, ids, enabled); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDebugMessageInsertAMD_Hook(GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf) - { - if(glDebugMessageInsertAMD_Impl) - glDebugMessageInsertAMD_Impl(category, severity, id, length, buf); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDebugMessageCallbackAMD_Hook(GLDEBUGPROCAMD callback, GLvoid *userParam) - { - if(glDebugMessageCallbackAMD_Impl) - glDebugMessageCallbackAMD_Impl(callback, userParam); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLuint OVR::GLEContext::glGetDebugMessageLogAMD_Hook(GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message) - { - GLuint u = 0; - if(glGetDebugMessageLogAMD_Impl) - u = glGetDebugMessageLogAMD_Impl(count, bufsize, categories, severities, ids, lengths, message); - PostHook(GLE_CURRENT_FUNCTION); - return u; - } - - - #if defined(GLE_CGL_ENABLED) - // GL_APPLE_element_array - void OVR::GLEContext::glElementPointerAPPLE_Hook(GLenum type, const GLvoid *pointer) - { - if(glElementPointerAPPLE_Impl) - glElementPointerAPPLE_Impl(type, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDrawElementArrayAPPLE_Hook(GLenum mode, GLint first, GLsizei count) - { - if(glDrawElementArrayAPPLE_Impl) - glDrawElementArrayAPPLE_Impl(mode, first, count); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDrawRangeElementArrayAPPLE_Hook(GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count) - { - if(glDrawRangeElementArrayAPPLE_Impl) - glDrawRangeElementArrayAPPLE_Impl(mode, start, end, first, count); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiDrawElementArrayAPPLE_Hook(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) - { - if(glMultiDrawElementArrayAPPLE_Impl) - glMultiDrawElementArrayAPPLE_Impl(mode, first, count, primcount); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMultiDrawRangeElementArrayAPPLE_Hook(GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount) - { - if(glMultiDrawRangeElementArrayAPPLE_Impl) - glMultiDrawRangeElementArrayAPPLE_Impl(mode, start, end, first, count, primcount); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_APPLE_fence - void OVR::GLEContext::glGenFencesAPPLE_Hook(GLsizei n, GLuint *fences) - { - if(glGenFencesAPPLE_Impl) - glGenFencesAPPLE_Impl(n, fences); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDeleteFencesAPPLE_Hook(GLsizei n, const GLuint *fences) - { - if(glDeleteFencesAPPLE_Impl) - glDeleteFencesAPPLE_Impl(n, fences); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSetFenceAPPLE_Hook(GLuint fence) - { - if(glSetFenceAPPLE_Impl) - glSetFenceAPPLE_Impl(fence); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsFenceAPPLE_Hook(GLuint fence) - { - GLboolean b = GL_FALSE; - if(glIsFenceAPPLE_Impl) - b = glIsFenceAPPLE_Impl(fence); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - GLboolean OVR::GLEContext::glTestFenceAPPLE_Hook(GLuint fence) - { - GLboolean b = GL_FALSE; - if(glTestFenceAPPLE_Impl) - b = glTestFenceAPPLE_Impl(fence); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glFinishFenceAPPLE_Hook(GLuint fence) - { - if(glFinishFenceAPPLE_Impl) - glFinishFenceAPPLE_Impl(fence); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glTestObjectAPPLE_Hook(GLenum object, GLuint name) - { - GLboolean b = GL_FALSE; - if(glTestObjectAPPLE_Impl) - b = glTestObjectAPPLE_Impl(object, name); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glFinishObjectAPPLE_Hook(GLenum object, GLint name) - { - if(glFinishObjectAPPLE_Impl) - glFinishObjectAPPLE_Impl(object, name); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_APPLE_flush_buffer_range - void OVR::GLEContext::glBufferParameteriAPPLE_Hook(GLenum target, GLenum pname, GLint param) - { - if(glBufferParameteriAPPLE_Impl) - glBufferParameteriAPPLE_Impl(target, pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFlushMappedBufferRangeAPPLE_Hook(GLenum target, GLintptr offset, GLsizeiptr size) - { - if(glFlushMappedBufferRangeAPPLE_Impl) - glFlushMappedBufferRangeAPPLE_Impl(target, offset, size); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_APPLE_object_purgeable - GLenum OVR::GLEContext::glObjectPurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option) - { - GLenum e = 0; - if(glObjectPurgeableAPPLE_Impl) - e = glObjectPurgeableAPPLE_Impl(objectType, name, option); - PostHook(GLE_CURRENT_FUNCTION); - return e; - } - - GLenum OVR::GLEContext::glObjectUnpurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option) - { - GLenum e = 0; - if(glObjectUnpurgeableAPPLE_Impl) - e =glObjectUnpurgeableAPPLE_Impl(objectType, name, option); - PostHook(GLE_CURRENT_FUNCTION); - return e; - } - - void OVR::GLEContext::glGetObjectParameterivAPPLE_Hook(GLenum objectType, GLuint name, GLenum pname, GLint *params) - { - if(glGetObjectParameterivAPPLE_Impl) - glGetObjectParameterivAPPLE_Impl(objectType, name, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_APPLE_texture_range - void OVR::GLEContext::glTextureRangeAPPLE_Hook(GLenum target, GLsizei length, const GLvoid *pointer) - { - if(glTextureRangeAPPLE_Impl) - glTextureRangeAPPLE_Impl(target, length, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetTexParameterPointervAPPLE_Hook(GLenum target, GLenum pname, GLvoid **params) - { - if(glGetTexParameterPointervAPPLE_Impl) - glGetTexParameterPointervAPPLE_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_APPLE_vertex_array_object - void OVR::GLEContext::glBindVertexArrayAPPLE_Hook(GLuint array) - { - if(glBindVertexArrayAPPLE_Impl) - glBindVertexArrayAPPLE_Impl(array); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDeleteVertexArraysAPPLE_Hook(GLsizei n, const GLuint *arrays) - { - if(glDeleteVertexArraysAPPLE_Impl) - glDeleteVertexArraysAPPLE_Impl(n, arrays); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGenVertexArraysAPPLE_Hook(GLsizei n, GLuint *arrays) - { - if(glGenVertexArraysAPPLE_Impl) - glGenVertexArraysAPPLE_Impl(n, arrays); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsVertexArrayAPPLE_Hook(GLuint array) - { - GLboolean b = GL_FALSE; - if(glIsVertexArrayAPPLE_Impl) - b = glIsVertexArrayAPPLE_Impl(array); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - - // GL_APPLE_vertex_array_range - void OVR::GLEContext::glVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid *pointer) - { - if(glVertexArrayRangeAPPLE_Impl) - glVertexArrayRangeAPPLE_Impl(length, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFlushVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid *pointer) - { - if(glFlushVertexArrayRangeAPPLE_Impl) - glFlushVertexArrayRangeAPPLE_Impl(length, pointer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glVertexArrayParameteriAPPLE_Hook(GLenum pname, GLint param) - { - if(glVertexArrayParameteriAPPLE_Impl) - glVertexArrayParameteriAPPLE_Impl(pname, param); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_APPLE_vertex_program_evaluators - void OVR::GLEContext::glEnableVertexAttribAPPLE_Hook(GLuint index, GLenum pname) - { - if(glEnableVertexAttribAPPLE_Impl) - glEnableVertexAttribAPPLE_Impl(index, pname); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDisableVertexAttribAPPLE_Hook(GLuint index, GLenum pname) - { - if(glDisableVertexAttribAPPLE_Impl) - glDisableVertexAttribAPPLE_Impl(index, pname); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsVertexAttribEnabledAPPLE_Hook(GLuint index, GLenum pname) - { - GLboolean b = GL_FALSE; - if(glIsVertexAttribEnabledAPPLE_Impl) - b = glIsVertexAttribEnabledAPPLE_Impl(index, pname); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glMapVertexAttrib1dAPPLE_Hook(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) - { - if(glMapVertexAttrib1dAPPLE_Impl) - glMapVertexAttrib1dAPPLE_Impl(index, size, u1, u2, stride, order, points); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMapVertexAttrib1fAPPLE_Hook(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) - { - if(glMapVertexAttrib1fAPPLE_Impl) - glMapVertexAttrib1fAPPLE_Impl(index, size, u1, u2, stride, order, points); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMapVertexAttrib2dAPPLE_Hook(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) - { - if(glMapVertexAttrib2dAPPLE_Impl) - glMapVertexAttrib2dAPPLE_Impl(index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glMapVertexAttrib2fAPPLE_Hook(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) - { - if(glMapVertexAttrib2fAPPLE_Impl) - glMapVertexAttrib2fAPPLE_Impl(index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); - PostHook(GLE_CURRENT_FUNCTION); - } - #endif // GLE_CGL_ENABLED - - - // GL_ARB_debug_output - void OVR::GLEContext::glDebugMessageControlARB_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled) - { - if(glDebugMessageControlARB_Impl) - glDebugMessageControlARB_Impl(source, type, severity, count, ids, enabled); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDebugMessageInsertARB_Hook(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf) - { - if(glDebugMessageInsertARB_Impl) - glDebugMessageInsertARB_Impl(source, type, id, severity, length, buf); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDebugMessageCallbackARB_Hook(GLDEBUGPROCARB callback, const GLvoid *userParam) - { - if(glDebugMessageCallbackARB_Impl) - glDebugMessageCallbackARB_Impl(callback, userParam); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLuint OVR::GLEContext::glGetDebugMessageLogARB_Hook(GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog) - { - GLuint u = 0; - if(glGetDebugMessageLogARB_Impl) - u = glGetDebugMessageLogARB_Impl(count, bufsize, sources, types, ids, severities, lengths, messageLog); - PostHook(GLE_CURRENT_FUNCTION); - return u; - } - - - // GL_ARB_ES2_compatibility - void OVR::GLEContext::glReleaseShaderCompiler_Hook() - { - if(glReleaseShaderCompiler_Impl) - glReleaseShaderCompiler_Impl(); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glShaderBinary_Hook(GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length) - { - if(glShaderBinary_Impl) - glShaderBinary_Impl(count, shaders, binaryformat, binary, length); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetShaderPrecisionFormat_Hook(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) - { - if(glGetShaderPrecisionFormat_Impl) - glGetShaderPrecisionFormat_Impl(shadertype, precisiontype, range, precision); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDepthRangef_Hook(GLclampf n, GLclampf f) - { - if(glDepthRangef_Impl) - glDepthRangef_Impl(n, f); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glClearDepthf_Hook(GLclampf d) - { - if(glClearDepthf_Impl) - glClearDepthf_Impl(d); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_ARB_framebuffer_object - GLboolean OVR::GLEContext::glIsRenderbuffer_Hook(GLuint renderbuffer) - { - GLboolean b = GL_FALSE; - if(glIsRenderbuffer_Impl) - b = glIsRenderbuffer_Impl(renderbuffer); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glBindRenderbuffer_Hook(GLenum target, GLuint renderbuffer) - { - if(glBindRenderbuffer_Impl) - glBindRenderbuffer_Impl(target, renderbuffer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDeleteRenderbuffers_Hook(GLsizei n, const GLuint *renderbuffers) - { - if(glDeleteRenderbuffers_Impl) - glDeleteRenderbuffers_Impl(n, renderbuffers); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGenRenderbuffers_Hook(GLsizei n, GLuint *renderbuffers) - { - if(glGenRenderbuffers_Impl) - glGenRenderbuffers_Impl(n, renderbuffers); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glRenderbufferStorage_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) - { - if(glRenderbufferStorage_Impl) - glRenderbufferStorage_Impl(target, internalformat, width, height); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetRenderbufferParameteriv_Hook(GLenum target, GLenum pname, GLint *params) - { - if(glGetRenderbufferParameteriv_Impl) - glGetRenderbufferParameteriv_Impl(target, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsFramebuffer_Hook(GLuint framebuffer) - { - GLboolean b = GL_FALSE; - if(glIsFramebuffer_Impl) - b = glIsFramebuffer_Impl(framebuffer); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - void OVR::GLEContext::glBindFramebuffer_Hook(GLenum target, GLuint framebuffer) - { - if(glBindFramebuffer_Impl) - glBindFramebuffer_Impl(target, framebuffer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDeleteFramebuffers_Hook(GLsizei n, const GLuint *framebuffers) - { - if(glDeleteFramebuffers_Impl) - glDeleteFramebuffers_Impl(n, framebuffers); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGenFramebuffers_Hook(GLsizei n, GLuint *framebuffers) - { - if(glGenFramebuffers_Impl) - glGenFramebuffers_Impl(n, framebuffers); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLenum OVR::GLEContext::glCheckFramebufferStatus_Hook(GLenum target) - { - GLenum e = 0; - if(glCheckFramebufferStatus_Impl) - e = glCheckFramebufferStatus_Impl(target); - PostHook(GLE_CURRENT_FUNCTION); - return e; - } - - void OVR::GLEContext::glFramebufferTexture1D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) - { - if(glFramebufferTexture1D_Impl) - glFramebufferTexture1D_Impl(target, attachment, textarget, texture, level); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFramebufferTexture2D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) - { - if(glFramebufferTexture2D_Impl) - glFramebufferTexture2D_Impl(target, attachment, textarget, texture, level); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFramebufferTexture3D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) - { - if(glFramebufferTexture3D_Impl) - glFramebufferTexture3D_Impl(target, attachment, textarget, texture, level, zoffset); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFramebufferRenderbuffer_Hook(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) - { - if(glFramebufferRenderbuffer_Impl) - glFramebufferRenderbuffer_Impl(target, attachment, renderbuffertarget, renderbuffer); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetFramebufferAttachmentParameteriv_Hook(GLenum target, GLenum attachment, GLenum pname, GLint *params) - { - if(glGetFramebufferAttachmentParameteriv_Impl) - glGetFramebufferAttachmentParameteriv_Impl(target, attachment, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGenerateMipmap_Hook(GLenum target) - { - if(glGenerateMipmap_Impl) - glGenerateMipmap_Impl(target); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glBlitFramebuffer_Hook(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) - { - if(glBlitFramebuffer_Impl) - glBlitFramebuffer_Impl(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glRenderbufferStorageMultisample_Hook(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) - { - if(glRenderbufferStorageMultisample_Impl) - glRenderbufferStorageMultisample_Impl(target, samples, internalformat, width, height); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glFramebufferTextureLayer_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) - { - if(glFramebufferTextureLayer_Impl) - glFramebufferTextureLayer_Impl(target, attachment, texture, level, layer); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_ARB_texture_multisample - void OVR::GLEContext::glTexImage2DMultisample_Hook(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) - { - if(glTexImage2DMultisample_Impl) - glTexImage2DMultisample_Impl(target, samples, internalformat, width, height, fixedsamplelocations); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glTexImage3DMultisample_Hook(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) - { - if(glTexImage3DMultisample_Impl) - glTexImage3DMultisample_Impl(target, samples, internalformat, width, height, depth, fixedsamplelocations); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetMultisamplefv_Hook(GLenum pname, GLuint index, GLfloat *val) - { - if(glGetMultisamplefv_Impl) - glGetMultisamplefv_Impl(pname, index, val); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glSampleMaski_Hook(GLuint index, GLbitfield mask) - { - if(glSampleMaski_Impl) - glSampleMaski_Impl(index, mask); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_ARB_timer_query - void OVR::GLEContext::glQueryCounter_Hook(GLuint id, GLenum target) - { - if(glQueryCounter_Impl) - glQueryCounter_Impl(id, target); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetQueryObjecti64v_Hook(GLuint id, GLenum pname, GLint64 *params) - { - if(glGetQueryObjecti64v_Impl) - glGetQueryObjecti64v_Impl(id, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetQueryObjectui64v_Hook(GLuint id, GLenum pname, GLuint64 *params) - { - if(glGetQueryObjectui64v_Impl) - glGetQueryObjectui64v_Impl(id, pname, params); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_ARB_vertex_array_object - void OVR::GLEContext::glBindVertexArray_Hook(GLuint array) - { - if(glBindVertexArray_Impl) - glBindVertexArray_Impl(array); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDeleteVertexArrays_Hook(GLsizei n, const GLuint *arrays) - { - if(glDeleteVertexArrays_Impl) - glDeleteVertexArrays_Impl(n, arrays); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGenVertexArrays_Hook(GLsizei n, GLuint *arrays) - { - if(glGenVertexArrays_Impl) - glGenVertexArrays_Impl(n, arrays); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsVertexArray_Hook(GLuint array) - { - GLboolean b = GL_FALSE; - if(glIsVertexArray_Impl) - b = glIsVertexArray_Impl(array); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - - // GL_EXT_draw_buffers2 - void OVR::GLEContext::glColorMaskIndexedEXT_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) - { - if(glColorMaskIndexedEXT_Impl) - glColorMaskIndexedEXT_Impl(index, r, g, b, a); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetBooleanIndexedvEXT_Hook(GLenum target, GLuint index, GLboolean *data) - { - if(glGetBooleanIndexedvEXT_Impl) - glGetBooleanIndexedvEXT_Impl(target, index, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetIntegerIndexedvEXT_Hook(GLenum target, GLuint index, GLint *data) - { - if(glGetIntegerIndexedvEXT_Impl) - glGetIntegerIndexedvEXT_Impl(target, index, data); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glEnableIndexedEXT_Hook(GLenum target, GLuint index) - { - if(glEnableIndexedEXT_Impl) - glEnableIndexedEXT_Impl(target, index); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDisableIndexedEXT_Hook(GLenum target, GLuint index) - { - if(glDisableIndexedEXT_Impl) - glDisableIndexedEXT_Impl(target, index); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLboolean OVR::GLEContext::glIsEnabledIndexedEXT_Hook(GLenum target, GLuint index) - { - GLboolean b = GL_FALSE; - if(glIsEnabledIndexedEXT_Impl) - b = glIsEnabledIndexedEXT_Impl(target, index); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - - // GL_KHR_debug - void OVR::GLEContext::glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled) - { - if(glDebugMessageControl_Impl) - glDebugMessageControl_Impl(source, type, severity, count, ids, enabled); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDebugMessageInsert_Hook(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* buf) - { - if(glDebugMessageInsert_Impl) - glDebugMessageInsert_Impl(source, type, id, severity, length, buf); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glDebugMessageCallback_Hook(GLDEBUGPROC callback, const void* userParam) - { - if(glDebugMessageCallback_Impl) - glDebugMessageCallback_Impl(callback, userParam); - PostHook(GLE_CURRENT_FUNCTION); - } - - GLuint OVR::GLEContext::glGetDebugMessageLog_Hook(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, char* messageLog) - { - GLuint u = 0; - if(glGetDebugMessageLog_Impl) - u = glGetDebugMessageLog_Impl(count, bufSize, sources, types, ids, severities, lengths, messageLog); - PostHook(GLE_CURRENT_FUNCTION); - return u; - } - - void OVR::GLEContext::glPushDebugGroup_Hook(GLenum source, GLuint id, GLsizei length, const char * message) - { - if(glPushDebugGroup_Impl) - glPushDebugGroup_Impl(source, id, length, message); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glPopDebugGroup_Hook() - { - if(glPopDebugGroup_Impl) - glPopDebugGroup_Impl(); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei length, const char *label) - { - if(glObjectLabel_Impl) - glObjectLabel_Impl(identifier, name, length, label); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, char *label) - { - if(glGetObjectLabel_Impl) - glGetObjectLabel_Impl(identifier, name, bufSize, length, label); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glObjectPtrLabel_Hook(void* ptr, GLsizei length, const char *label) - { - if(glObjectPtrLabel_Impl) - glObjectPtrLabel_Impl(ptr, length, label); - PostHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glGetObjectPtrLabel_Hook(void* ptr, GLsizei bufSize, GLsizei *length, char *label) - { - if(glGetObjectPtrLabel_Impl) - glGetObjectPtrLabel_Impl(ptr, bufSize, length, label); - PostHook(GLE_CURRENT_FUNCTION); - } - - - // GL_WIN_swap_hint - void OVR::GLEContext::glAddSwapHintRectWIN_Hook(GLint x, GLint y, GLsizei width, GLsizei height) - { - if(glAddSwapHintRectWIN_Impl) - glAddSwapHintRectWIN_Impl(x, y, width, height); - PostHook(GLE_CURRENT_FUNCTION); - } - - - #if defined(GLE_WGL_ENABLED) - // WGL - void OVR::GLEContext::PostWGLHook(const char* /*function*/) - { - // Empty for now. WGL functions don't have a function like glGetError(). - } - - /* We currently don't hook these - #undef wglCopyContext - extern "C" { GLAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask); } - BOOL OVR::GLEContext::wglCopyContext_Hook(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) - { - BOOL b = wglCopyContext(hglrcSrc, hglrcDst, mask); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglCreateContext - extern "C" { GLAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc); } - HGLRC OVR::GLEContext::wglCreateContext_Hook(HDC hdc) - { - HGLRC h = wglCreateContext(hdc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - #undef wglCreateLayerContext - extern "C" { GLAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, int iLayerPlane); } - HGLRC OVR::GLEContext::wglCreateLayerContext_Hook(HDC hdc, int iLayerPlane) - { - HGLRC h = wglCreateLayerContext(hdc, iLayerPlane); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - #undef wglDeleteContext - extern "C" { GLAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc); } - BOOL OVR::GLEContext::wglDeleteContext_Hook(HGLRC hglrc) - { - BOOL b = wglDeleteContext(hglrc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglGetCurrentContext - extern "C" { GLAPI HGLRC GLAPIENTRY wglGetCurrentContext(); } - HGLRC OVR::GLEContext::wglGetCurrentContext_Hook() - { - HGLRC h = wglGetCurrentContext(); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - #undef wglGetCurrentDC - extern "C" { GLAPI HDC GLAPIENTRY wglGetCurrentDC(); } - HDC OVR::GLEContext::wglGetCurrentDC_Hook() - { - HDC h = wglGetCurrentDC(); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - //#undef wglGetProcAddress Not needed because we happen to do it above already. - //extern "C" { GLAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc); } - PROC OVR::GLEContext::wglGetProcAddress_Hook(LPCSTR lpszProc) - { - PROC p = wglGetProcAddress(lpszProc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return p; - } - - #undef wglMakeCurrent - extern "C" { GLAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc); } - BOOL OVR::GLEContext::wglMakeCurrent_Hook(HDC hdc, HGLRC hglrc) - { - BOOL b = wglMakeCurrent(hdc, hglrc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglShareLists - extern "C" { GLAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, HGLRC hglrc2); } - BOOL OVR::GLEContext::wglShareLists_Hook(HGLRC hglrc1, HGLRC hglrc2) - { - BOOL b = wglShareLists(hglrc1, hglrc2); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglUseFontBitmapsA - extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD listBase); } - BOOL OVR::GLEContext::wglUseFontBitmapsA_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase) - { - BOOL b = wglUseFontBitmapsA(hdc, first, count, listBase); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglUseFontBitmapsW - extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD listBase); } - BOOL OVR::GLEContext::wglUseFontBitmapsW_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase) - { - BOOL b = wglUseFontBitmapsW(hdc, first, count, listBase); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglUseFontOutlinesA - extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf); } - BOOL OVR::GLEContext::wglUseFontOutlinesA_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) - { - BOOL b = wglUseFontOutlinesA(hdc, first, count, listBase, deviation, extrusion, format, lpgmf); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglUseFontOutlinesW - extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf); } - BOOL OVR::GLEContext::wglUseFontOutlinesW_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) - { - BOOL b = wglUseFontOutlinesW(hdc, first, count, listBase, deviation, extrusion, format, lpgmf); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglDescribeLayerPlane - extern "C" { GLAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd); } - BOOL OVR::GLEContext::wglDescribeLayerPlane_Hook(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd) - { - BOOL b = wglDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglSetLayerPaletteEntries - extern "C" { GLAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr); } - int OVR::GLEContext::wglSetLayerPaletteEntries_Hook(HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr) - { - int i = wglSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); - PostWGLHook(GLE_CURRENT_FUNCTION); - return i; - } - - #undef wglGetLayerPaletteEntries - extern "C" { GLAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, int cEntries, COLORREF *pcr); } - int OVR::GLEContext::wglGetLayerPaletteEntries_Hook(HDC hdc, int iLayerPlane, int iStart, int cEntries, COLORREF *pcr) - { - int i = wglGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); - PostWGLHook(GLE_CURRENT_FUNCTION); - return i; - } - - #undef wglRealizeLayerPalette - extern "C" { GLAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc, int iLayerPlane, BOOL bRealize); } - BOOL OVR::GLEContext::wglRealizeLayerPalette_Hook(HDC hdc, int iLayerPlane, BOOL bRealize) - { - BOOL b = wglRealizeLayerPalette(hdc, iLayerPlane, bRealize); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglSwapLayerBuffers - extern "C" { GLAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc, UINT fuPlanes); } - BOOL OVR::GLEContext::wglSwapLayerBuffers_Hook(HDC hdc, UINT fuPlanes) - { - BOOL b = wglSwapLayerBuffers(hdc, fuPlanes); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #undef wglSwapMultipleBuffers - extern "C" { GLAPI DWORD GLAPIENTRY wglSwapMultipleBuffers(UINT i, CONST WGLSWAP* p); } - DWORD OVR::GLEContext::wglSwapMultipleBuffers_Hook(UINT i, CONST WGLSWAP* p) - { - DWORD dw = wglSwapMultipleBuffers(i, p); - PostWGLHook(GLE_CURRENT_FUNCTION); - return dw; - } - */ - - // The rest of the functions are pointer-based. - - // WGL_ARB_buffer_region - HANDLE OVR::GLEContext::wglCreateBufferRegionARB_Hook(HDC hDC, int iLayerPlane, UINT uType) - { - HANDLE h = NULL; - if(wglCreateBufferRegionARB_Impl) - h = wglCreateBufferRegionARB_Impl(hDC, iLayerPlane, uType); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - VOID OVR::GLEContext::wglDeleteBufferRegionARB_Hook(HANDLE hRegion) - { - if(wglDeleteBufferRegionARB_Impl) - wglDeleteBufferRegionARB_Impl(hRegion); - PostWGLHook(GLE_CURRENT_FUNCTION); - } - - BOOL OVR::GLEContext::wglSaveBufferRegionARB_Hook(HANDLE hRegion, int x, int y, int width, int height) - { - BOOL b = FALSE; - if(wglSaveBufferRegionARB_Impl) - b = wglSaveBufferRegionARB_Impl(hRegion, x, y, width, height); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglRestoreBufferRegionARB_Hook(HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc) - { - BOOL b = FALSE; - if(wglRestoreBufferRegionARB_Impl) - b = wglRestoreBufferRegionARB_Impl(hRegion, x, y, width, height, xSrc, ySrc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_ARB_extensions_string - const char * OVR::GLEContext::wglGetExtensionsStringARB_Hook(HDC hdc) - { - const char * p = NULL; - if(wglGetExtensionsStringARB_Impl) - p = wglGetExtensionsStringARB_Impl(hdc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return p; - } - - // WGL_ARB_pixel_format - BOOL OVR::GLEContext::wglGetPixelFormatAttribivARB_Hook(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues) - { - BOOL b = FALSE; - if(wglGetPixelFormatAttribivARB_Impl) - b = wglGetPixelFormatAttribivARB_Impl(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglGetPixelFormatAttribfvARB_Hook(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues) - { - BOOL b = FALSE; - if(wglGetPixelFormatAttribfvARB_Impl) - b = wglGetPixelFormatAttribfvARB_Impl(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglChoosePixelFormatARB_Hook(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats) - { - BOOL b = FALSE; - if(wglChoosePixelFormatARB_Impl) - b = wglChoosePixelFormatARB_Impl(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_ARB_make_current_read - BOOL OVR::GLEContext::wglMakeContextCurrentARB_Hook(HDC hDrawDC, HDC hReadDC, HGLRC hglrc) - { - BOOL b = FALSE; - if(wglMakeContextCurrentARB_Impl) - b = wglMakeContextCurrentARB_Impl(hDrawDC, hReadDC, hglrc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - HDC OVR::GLEContext::wglGetCurrentReadDCARB_Hook() - { - HDC h = NULL; - if(wglGetCurrentReadDCARB_Impl) - h = wglGetCurrentReadDCARB_Impl(); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - // WGL_ARB_pbuffer - HPBUFFERARB OVR::GLEContext::wglCreatePbufferARB_Hook(HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList) - { - HPBUFFERARB h = NULL; - if(wglCreatePbufferARB_Impl) - h = wglCreatePbufferARB_Impl(hDC, iPixelFormat, iWidth, iHeight, piAttribList); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - HDC OVR::GLEContext::wglGetPbufferDCARB_Hook(HPBUFFERARB hPbuffer) - { - HDC h = NULL; - if(wglGetPbufferDCARB_Impl) - h = wglGetPbufferDCARB_Impl(hPbuffer); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - int OVR::GLEContext::wglReleasePbufferDCARB_Hook(HPBUFFERARB hPbuffer, HDC hDC) - { - int i = 0; - if(wglReleasePbufferDCARB_Impl) - i = wglReleasePbufferDCARB_Impl(hPbuffer, hDC); - PostWGLHook(GLE_CURRENT_FUNCTION); - return i; - } - - BOOL OVR::GLEContext::wglDestroyPbufferARB_Hook(HPBUFFERARB hPbuffer) - { - BOOL b = FALSE; - if(wglDestroyPbufferARB_Impl) - b = wglDestroyPbufferARB_Impl(hPbuffer); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglQueryPbufferARB_Hook(HPBUFFERARB hPbuffer, int iAttribute, int *piValue) - { - BOOL b = FALSE; - if(wglQueryPbufferARB_Impl) - b = wglQueryPbufferARB_Impl(hPbuffer, iAttribute, piValue); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_ARB_render_texture - BOOL OVR::GLEContext::wglBindTexImageARB_Hook(HPBUFFERARB hPbuffer, int iBuffer) - { - BOOL b = FALSE; - if(wglBindTexImageARB_Impl) - b = wglBindTexImageARB_Impl(hPbuffer, iBuffer); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglReleaseTexImageARB_Hook(HPBUFFERARB hPbuffer, int iBuffer) - { - BOOL b = FALSE; - if(wglReleaseTexImageARB_Impl) - b = wglReleaseTexImageARB_Impl(hPbuffer, iBuffer); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglSetPbufferAttribARB_Hook(HPBUFFERARB hPbuffer, const int *piAttribList) - { - BOOL b = FALSE; - if(wglSetPbufferAttribARB_Impl) - b = wglSetPbufferAttribARB_Impl(hPbuffer, piAttribList); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_NV_present_video - int OVR::GLEContext::wglEnumerateVideoDevicesNV_Hook(HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList) - { - int i = 0; - if(wglEnumerateVideoDevicesNV_Impl) - i = wglEnumerateVideoDevicesNV_Impl(hDC, phDeviceList); - PostWGLHook(GLE_CURRENT_FUNCTION); - return i; - } - - BOOL OVR::GLEContext::wglBindVideoDeviceNV_Hook(HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList) - { - BOOL b = FALSE; - if(wglBindVideoDeviceNV_Impl) - b = wglBindVideoDeviceNV_Impl(hDC, uVideoSlot, hVideoDevice, piAttribList); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglQueryCurrentContextNV_Hook(int iAttribute, int *piValue) - { - BOOL b = FALSE; - if(wglQueryCurrentContextNV_Impl) - b = wglQueryCurrentContextNV_Impl(iAttribute, piValue); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_ARB_create_context - HGLRC OVR::GLEContext::wglCreateContextAttribsARB_Hook(HDC hDC, HGLRC hShareContext, const int *attribList) - { - HGLRC h = NULL; - if(wglCreateContextAttribsARB_Impl) - h = wglCreateContextAttribsARB_Impl(hDC, hShareContext, attribList); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - // WGL_EXT_extensions_string - const char * OVR::GLEContext::wglGetExtensionsStringEXT_Hook() - { - const char * p = NULL; - if(wglGetExtensionsStringEXT_Impl) - p = wglGetExtensionsStringEXT_Impl(); - PostWGLHook(GLE_CURRENT_FUNCTION); - return p; - } - - // WGL_EXT_swap_control - BOOL OVR::GLEContext::wglSwapIntervalEXT_Hook(int interval) - { - BOOL b = FALSE; - if(wglSwapIntervalEXT_Impl) - b = wglSwapIntervalEXT_Impl(interval); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - int OVR::GLEContext::wglGetSwapIntervalEXT_Hook() - { - int i = 0; - if(wglGetSwapIntervalEXT_Impl) - i = wglGetSwapIntervalEXT_Impl(); - PostWGLHook(GLE_CURRENT_FUNCTION); - return i; - } - - // WGL_OML_sync_control - BOOL OVR::GLEContext::wglGetSyncValuesOML_Hook(HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc) - { - BOOL b = FALSE; - if(wglGetSyncValuesOML_Impl) - b = wglGetSyncValuesOML_Impl(hdc, ust, msc, sbc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglGetMscRateOML_Hook(HDC hdc, INT32 *numerator, INT32 *denominator) - { - BOOL b = FALSE; - if(wglGetMscRateOML_Impl) - b = wglGetMscRateOML_Impl(hdc, numerator, denominator); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - INT64 OVR::GLEContext::wglSwapBuffersMscOML_Hook(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder) - { - INT64 i = 0; - if(wglSwapBuffersMscOML_Impl) - i = wglSwapBuffersMscOML_Impl(hdc, target_msc, divisor, remainder); - PostWGLHook(GLE_CURRENT_FUNCTION); - return i; - } - - INT64 OVR::GLEContext::wglSwapLayerBuffersMscOML_Hook(HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder) - { - INT64 i = 0; - if(wglSwapLayerBuffersMscOML_Impl) - i = wglSwapLayerBuffersMscOML_Impl(hdc, fuPlanes, target_msc, divisor, remainder); - PostWGLHook(GLE_CURRENT_FUNCTION); - return i; - } - - BOOL OVR::GLEContext::wglWaitForMscOML_Hook(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc) - { - BOOL b = FALSE; - if(wglWaitForMscOML_Impl) - b = wglWaitForMscOML_Impl(hdc, target_msc, divisor, remainder, ust, msc, sbc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglWaitForSbcOML_Hook(HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc) - { - BOOL b = FALSE; - if(wglWaitForSbcOML_Impl) - b = wglWaitForSbcOML_Impl(hdc, target_sbc, ust, msc, sbc); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_NV_video_output - BOOL OVR::GLEContext::wglGetVideoDeviceNV_Hook(HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice) - { - BOOL b = FALSE; - if(wglGetVideoDeviceNV_Impl) - b = wglGetVideoDeviceNV_Impl(hDC, numDevices, hVideoDevice); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglReleaseVideoDeviceNV_Hook(HPVIDEODEV hVideoDevice) - { - BOOL b = FALSE; - if(wglReleaseVideoDeviceNV_Impl) - b = wglReleaseVideoDeviceNV_Impl(hVideoDevice); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglBindVideoImageNV_Hook(HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer) - { - BOOL b = FALSE; - if(wglBindVideoImageNV_Impl) - b = wglBindVideoImageNV_Impl(hVideoDevice, hPbuffer, iVideoBuffer); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglReleaseVideoImageNV_Hook(HPBUFFERARB hPbuffer, int iVideoBuffer) - { - BOOL b = FALSE; - if(wglReleaseVideoImageNV_Impl) - b = wglReleaseVideoImageNV_Impl(hPbuffer, iVideoBuffer); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglSendPbufferToVideoNV_Hook(HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock) - { - BOOL b = FALSE; - if(wglSendPbufferToVideoNV_Impl) - b = wglSendPbufferToVideoNV_Impl(hPbuffer, iBufferType, pulCounterPbuffer, bBlock); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglGetVideoInfoNV_Hook(HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo) - { - BOOL b = FALSE; - if(wglGetVideoInfoNV_Impl) - b = wglGetVideoInfoNV_Impl(hpVideoDevice, pulCounterOutputPbuffer, pulCounterOutputVideo); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_NV_swap_group - BOOL OVR::GLEContext::wglJoinSwapGroupNV_Hook(HDC hDC, GLuint group) - { - BOOL b = FALSE; - if(wglJoinSwapGroupNV_Impl) - b = wglJoinSwapGroupNV_Impl(hDC, group); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglBindSwapBarrierNV_Hook(GLuint group, GLuint barrier) - { - BOOL b = FALSE; - if(wglBindSwapBarrierNV_Impl) - b = wglBindSwapBarrierNV_Impl(group, barrier); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglQuerySwapGroupNV_Hook(HDC hDC, GLuint *group, GLuint *barrier) - { - BOOL b = FALSE; - if(wglQuerySwapGroupNV_Impl) - b = wglQuerySwapGroupNV_Impl(hDC, group, barrier); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglQueryMaxSwapGroupsNV_Hook(HDC hDC, GLuint *maxGroups, GLuint *maxBarriers) - { - BOOL b = FALSE; - if(wglQueryMaxSwapGroupsNV_Impl) - b = wglQueryMaxSwapGroupsNV_Impl(hDC, maxGroups, maxBarriers); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglQueryFrameCountNV_Hook(HDC hDC, GLuint *count) - { - BOOL b = FALSE; - if(wglQueryFrameCountNV_Impl) - b = wglQueryFrameCountNV_Impl(hDC, count); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglResetFrameCountNV_Hook(HDC hDC) - { - BOOL b = FALSE; - if(wglResetFrameCountNV_Impl) - b = wglResetFrameCountNV_Impl(hDC); - PostHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_NV_video_capture - BOOL OVR::GLEContext::wglBindVideoCaptureDeviceNV_Hook(UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice) - { - BOOL b = FALSE; - if(wglBindVideoCaptureDeviceNV_Impl) - b = wglBindVideoCaptureDeviceNV_Impl(uVideoSlot, hDevice); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - UINT OVR::GLEContext::wglEnumerateVideoCaptureDevicesNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList) - { - UINT u = 0; - if(wglEnumerateVideoCaptureDevicesNV_Impl) - u = wglEnumerateVideoCaptureDevicesNV_Impl(hDc, phDeviceList); - PostWGLHook(GLE_CURRENT_FUNCTION); - return u; - } - - BOOL OVR::GLEContext::wglLockVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice) - { - BOOL b = FALSE; - if(wglLockVideoCaptureDeviceNV_Impl) - b = wglLockVideoCaptureDeviceNV_Impl(hDc, hDevice); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglQueryVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue) - { - BOOL b = FALSE; - if(wglQueryVideoCaptureDeviceNV_Impl) - b = wglQueryVideoCaptureDeviceNV_Impl(hDc, hDevice, iAttribute, piValue); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglReleaseVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice) - { - BOOL b = FALSE; - if(wglReleaseVideoCaptureDeviceNV_Impl) - b = wglReleaseVideoCaptureDeviceNV_Impl(hDc, hDevice); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_NV_copy_image - BOOL OVR::GLEContext::wglCopyImageSubDataNV_Hook(HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, - GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth) - { - BOOL b = FALSE; - if(wglCopyImageSubDataNV_Impl) - b = wglCopyImageSubDataNV_Impl(hSrcRC, srcName, srcTarget, srcLevel, srcX, srcY, srcZ, hDstRC, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, width, height, depth); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - // WGL_NV_DX_interop - BOOL OVR::GLEContext::wglDXSetResourceShareHandleNV_Hook(void *dxObject, HANDLE shareHandle) - { - BOOL b = FALSE; - if(wglDXSetResourceShareHandleNV_Impl) - b = wglDXSetResourceShareHandleNV_Impl(dxObject, shareHandle); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - HANDLE OVR::GLEContext::wglDXOpenDeviceNV_Hook(void *dxDevice) - { - HANDLE h = NULL; - if(wglDXOpenDeviceNV_Impl) - h = wglDXOpenDeviceNV_Impl(dxDevice); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - BOOL OVR::GLEContext::wglDXCloseDeviceNV_Hook(HANDLE hDevice) - { - BOOL b = FALSE; - if(wglDXCloseDeviceNV_Impl) - b = wglDXCloseDeviceNV_Impl(hDevice); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - HANDLE OVR::GLEContext::wglDXRegisterObjectNV_Hook(HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access) - { - HANDLE h = NULL; - if(wglDXRegisterObjectNV_Impl) - h = wglDXRegisterObjectNV_Impl(hDevice, dxObject, name, type, access); - PostWGLHook(GLE_CURRENT_FUNCTION); - return h; - } - - BOOL OVR::GLEContext::wglDXUnregisterObjectNV_Hook(HANDLE hDevice, HANDLE hObject) - { - BOOL b = FALSE; - if(wglDXUnregisterObjectNV_Impl) - b = wglDXUnregisterObjectNV_Impl(hDevice, hObject); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglDXObjectAccessNV_Hook(HANDLE hObject, GLenum access) - { - BOOL b = FALSE; - if(wglDXObjectAccessNV_Impl) - b = wglDXObjectAccessNV_Impl(hObject, access); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglDXLockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE *hObjects) - { - BOOL b = FALSE; - if(wglDXLockObjectsNV_Impl) - b = wglDXLockObjectsNV_Impl(hDevice, count, hObjects); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - BOOL OVR::GLEContext::wglDXUnlockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE *hObjects) - { - BOOL b = FALSE; - if(wglDXUnlockObjectsNV_Impl) - b = wglDXUnlockObjectsNV_Impl(hDevice, count, hObjects); - PostWGLHook(GLE_CURRENT_FUNCTION); - return b; - } - - #endif // defined(GLE_WGL_ENABLED) - - #if defined(GLE_GLX_ENABLED) - void OVR::GLEContext::PostGLXHook(const char* /*function*/) - { - // Empty for now. GLX functions don't have a function like glGetError(). - } - - // GLX_VERSION_1_0 - // GLX_VERSION_1_1 - // We don't currently implement hooking of these. - - // GLX_VERSION_1_2 - ::Display* OVR::GLEContext::glXGetCurrentDisplay_Hook(void) - { - ::Display* p = NULL; - if(glXGetCurrentDisplay_Impl) - p = glXGetCurrentDisplay_Impl(); - PostGLXHook(GLE_CURRENT_FUNCTION); - return p; - } - - // GLX_VERSION_1_3 - GLXFBConfig* OVR::GLEContext::glXChooseFBConfig_Hook(Display *dpy, int screen, const int *attrib_list, int *nelements) - { - GLXFBConfig* p = NULL; - if(glXChooseFBConfig_Impl) - p = glXChooseFBConfig_Impl(dpy, screen, attrib_list, nelements); - PostGLXHook(GLE_CURRENT_FUNCTION); - return p; - } - - GLXContext OVR::GLEContext::glXCreateNewContext_Hook(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct) - { - GLXContext c = 0; - if(glXCreateNewContext_Impl) - c = glXCreateNewContext_Impl(dpy, config, render_type, share_list, direct); - PostGLXHook(GLE_CURRENT_FUNCTION); - return c; - } - - GLXPbuffer OVR::GLEContext::glXCreatePbuffer_Hook(Display *dpy, GLXFBConfig config, const int *attrib_list) - { - GLXPbuffer b = 0; - if(glXCreatePbuffer_Impl) - b = glXCreatePbuffer_Impl(dpy, config, attrib_list); - PostGLXHook(GLE_CURRENT_FUNCTION); - return b; - } - - GLXPixmap OVR::GLEContext::glXCreatePixmap_Hook(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list) - { - GLXPixmap m = 0; - if(glXCreatePixmap_Impl) - m = glXCreatePixmap_Impl(dpy, config, pixmap, attrib_list); - PostGLXHook(GLE_CURRENT_FUNCTION); - return m; - } - - GLXWindow OVR::GLEContext::glXCreateWindow_Hook(Display *dpy, GLXFBConfig config, Window win, const int *attrib_list) - { - GLXWindow w = 0; - if(glXCreateWindow_Impl) - w = glXCreateWindow_Impl(dpy, config, win, attrib_list); - PostGLXHook(GLE_CURRENT_FUNCTION); - return w; - } - - void OVR::GLEContext::glXDestroyPbuffer_Hook(Display *dpy, GLXPbuffer pbuf) - { - if(glXDestroyPbuffer_Impl) - glXDestroyPbuffer_Impl(dpy, pbuf); - PostGLXHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glXDestroyPixmap_Hook(Display *dpy, GLXPixmap pixmap) - { - if(glXDestroyPixmap_Impl) - glXDestroyPixmap_Impl(dpy, pixmap); - PostGLXHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glXDestroyWindow_Hook(Display *dpy, GLXWindow win) - { - if(glXDestroyWindow_Impl) - glXDestroyWindow_Impl(dpy, win); - PostGLXHook(GLE_CURRENT_FUNCTION); - } - - GLXDrawable OVR::GLEContext::glXGetCurrentReadDrawable_Hook(void) - { - GLXDrawable d; - if(glXGetCurrentReadDrawable_Impl) - d = glXGetCurrentReadDrawable_Impl(); - PostGLXHook(GLE_CURRENT_FUNCTION); - return d; - } - - int OVR::GLEContext::glXGetFBConfigAttrib_Hook(Display *dpy, GLXFBConfig config, int attribute, int *value) - { - int i = -1; - if(glXGetFBConfigAttrib_Impl) - i = glXGetFBConfigAttrib_Impl(dpy, config, attribute, value); - PostGLXHook(GLE_CURRENT_FUNCTION); - return i; - } - - GLXFBConfig* OVR::GLEContext::glXGetFBConfigs_Hook(Display *dpy, int screen, int *nelements) - { - GLXFBConfig* p = NULL; - if(glXGetFBConfigs_Impl) - p = glXGetFBConfigs_Impl(dpy, screen, nelements); - PostGLXHook(GLE_CURRENT_FUNCTION); - return p; - } - - void OVR::GLEContext::glXGetSelectedEvent_Hook(Display *dpy, GLXDrawable draw, unsigned long *event_mask) - { - if(glXGetSelectedEvent_Impl) - glXGetSelectedEvent_Impl(dpy, draw, event_mask); - PostGLXHook(GLE_CURRENT_FUNCTION); - } - - XVisualInfo* OVR::GLEContext::glXGetVisualFromFBConfig_Hook(Display *dpy, GLXFBConfig config) - { - XVisualInfo* p = NULL; - if(glXGetVisualFromFBConfig_Impl) - p = glXGetVisualFromFBConfig_Impl(dpy, config); - PostGLXHook(GLE_CURRENT_FUNCTION); - return p; - } - - Bool OVR::GLEContext::glXMakeContextCurrent_Hook(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) - { - Bool b = False; - if(glXMakeContextCurrent_Impl) - b = glXMakeContextCurrent_Impl(dpy, draw, read, ctx); - PostGLXHook(GLE_CURRENT_FUNCTION); - return b; - } - - int OVR::GLEContext::glXQueryContext_Hook(Display *dpy, GLXContext ctx, int attribute, int *value) - { - int i = GLX_BAD_ATTRIBUTE; - if(glXQueryContext_Impl) - i = glXQueryContext_Impl(dpy, ctx, attribute, value); - PostGLXHook(GLE_CURRENT_FUNCTION); - return i; - } - - void OVR::GLEContext::glXQueryDrawable_Hook(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) - { - if(glXQueryDrawable_Impl) - glXQueryDrawable_Impl(dpy, draw, attribute, value); - PostGLXHook(GLE_CURRENT_FUNCTION); - } - - void OVR::GLEContext::glXSelectEvent_Hook(Display *dpy, GLXDrawable draw, unsigned long event_mask) - { - if(glXSelectEvent_Impl) - glXSelectEvent_Impl(dpy, draw, event_mask); - PostGLXHook(GLE_CURRENT_FUNCTION); - } - - // GLX_VERSION_1_4 - // We don't do hooking of this. - - // GLX_ARB_create_context - GLXContext OVR::GLEContext::glXCreateContextAttribsARB_Hook(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list) - { - GLXContext c = 0; - if(glXCreateContextAttribsARB_Impl) - c = glXCreateContextAttribsARB_Impl(dpy, config, share_context, direct, attrib_list); - PostGLXHook(GLE_CURRENT_FUNCTION); - return c; - } - - // GLX_EXT_swap_control - void OVR::GLEContext::glXSwapIntervalEXT_Hook(Display* dpy, GLXDrawable drawable, int interval) - { - if(glXSwapIntervalEXT_Impl) - glXSwapIntervalEXT_Impl(dpy, drawable, interval); - PostGLXHook(GLE_CURRENT_FUNCTION); - } - - // GLX_OML_sync_control - Bool OVR::GLEContext::glXGetMscRateOML_Hook(Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator) - { - Bool b = False; - if(glXGetMscRateOML_Impl) - b = glXGetMscRateOML_Impl(dpy, drawable, numerator, denominator); - PostGLXHook(GLE_CURRENT_FUNCTION); - return b; - } - - Bool OVR::GLEContext::glXGetSyncValuesOML_Hook(Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc) - { - Bool b = False; - if(glXGetSyncValuesOML_Impl) - b = glXGetSyncValuesOML_Impl(dpy, drawable, ust, msc, sbc); - PostGLXHook(GLE_CURRENT_FUNCTION); - return b; - } - - int64_t OVR::GLEContext::glXSwapBuffersMscOML_Hook(Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) - { - int64_t i = 0; - if(glXSwapBuffersMscOML_Impl) - i = glXSwapBuffersMscOML_Impl(dpy, drawable, target_msc, divisor, remainder); - PostGLXHook(GLE_CURRENT_FUNCTION); - return i; - } - - Bool OVR::GLEContext::glXWaitForMscOML_Hook(Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc) - { - Bool b = False; - if(glXWaitForMscOML_Impl) - b = glXWaitForMscOML_Impl(dpy, drawable, target_msc, divisor, remainder, ust, msc, sbc); - PostGLXHook(GLE_CURRENT_FUNCTION); - return b; - } - - Bool OVR::GLEContext::glXWaitForSbcOML_Hook(Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc) - { - Bool b = False; - if(glXWaitForSbcOML_Impl) - b = glXWaitForSbcOML_Impl(dpy, drawable, target_sbc, ust, msc, sbc); - PostGLXHook(GLE_CURRENT_FUNCTION); - return b; - } - - // GLX_MESA_swap_control - int OVR::GLEContext::glXGetSwapIntervalMESA_Hook() - { - int i = 0; - if(glXGetSwapIntervalMESA_Impl) - i = glXGetSwapIntervalMESA_Impl(); - PostGLXHook(GLE_CURRENT_FUNCTION); - return i; - } - - - int OVR::GLEContext::glXSwapIntervalMESA_Hook(unsigned int interval) - { - int i = 0; - if(glXSwapIntervalMESA_Impl) - i = glXSwapIntervalMESA_Impl(interval); - PostGLXHook(GLE_CURRENT_FUNCTION); - return i; - } - - #endif // defined(GLE_GLX_ENABLED) - - #endif // GLE_HOOKING_ENABLED - -//} // namespace OVR - - - diff --git a/LibOVR/Src/CAPI/GL/CAPI_GLE.h b/LibOVR/Src/CAPI/GL/CAPI_GLE.h deleted file mode 100644 index d2e8080..0000000 --- a/LibOVR/Src/CAPI/GL/CAPI_GLE.h +++ /dev/null @@ -1,2003 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_GLE.h -Content : OpenGL extensions support. Implements a stripped down glew-like - interface with some additional functionality. -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -// This file provides functionality similar to a reduced version of GLEW, plus some -// additional functionality that's useful to us, such as function hooking. - -#ifndef INC_OVR_CAPI_GLE_h -#define INC_OVR_CAPI_GLE_h - - -#include "../../Kernel/OVR_Types.h" -#include "CAPI_GLE_GL.h" - - -/////////////////////////////////////////////////////////////////////////////// -// How to use this functionality -// -// - You #include this header instead of gl.h, glext.h, wglext.h (Windows), gl3.h (Apple), gl3ext.h (Apple), glx.h (Unix), and glxext.h (Unix). -// Currently you still would #include for the base wgl functions on Windows and OpenGL.h or NSOpenGL for the -// base Apple cgl functions. -// -// - You call OpenGL functions just like you would if you were directly using OpenGL -// headers and declarations. The difference is that this module automatically loads -// extensions on init and so you should never need to use GetProcAddress, wglGetProcAddress, etc. -// -// - OpenGL 1.1 functions can be called unilaterally without checking if they are present, -// as it's assumed they are always present. -// -// - In order to use an OpenGL 1.2 or later function you can check the GLEContext::WholeVersion -// variable to tell what version of OpenGL is present and active. Example usage: -// if(GLEContext::GetCurrentContext()->WholeVersion >= 302) // If OpenGL 3.2 or later... -// -// - In order to use an OpenGL extension, you can check the GLE_ helper macro that exists for each -// extension. For example, in order to check of the KHR_debug is present you could do this: -// if(GLE_KHR_debug) ... -// You cannot check for the presence of extensions by testing the function pointer, because -// when hooking is enabled then we aren't using function pointers and thus all functions will -// look like they are present. -// -// - You can test if the OpenGL implementation is OpenGL ES by checking the GLEContext IsGLES -// member variable. For example: if(GLEContext::GetCurrentContext()->IsGLES) ... -// -// - You can test if the OpenGL implementation is a core profile ES by checking the GLEContext IsCoreProfile -// member variable. For example: if(GLEContext::GetCurrentContext()->IsCoreProfile) ... -// -/////////////////////////////////////////////////////////////////////////////// - - -/////////////////////////////////////////////////////////////////////////////// -// How to add support for additional functions to this module. -// -// For an example of how to do this, search the source files for all cases of KHR_Debug and just copy -// the things that it does but for your new extension. -// -// 1) Add the appropriate extension declaration to CAPI_GLE_GL.h, preferably by -// copying it from the standard header file it normally comes from. If it's -// platform-specific (e.g. a Windows wgl function) then make sure it's declared -// within the given platform section. Note that there are potentially #defines, typedefs, -// function typedefs, and function #defines. There is always a GLE_ macro declared which -// lets the user know at runtime whether the extension is present. -// e.g. #ifndef GL_KHR_debug -// #define GL_KHR_debug 1 -// #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 etc. -// typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (); -// #define glPopDebugGroup GLEGetCurrentFunction(glPopDebugGroup) -// #define GLE_KHR_debug GLEGetCurrentVariable(gl_KHR_debug) -// #endif etc. -// -// 2) Add a hook function for in the hook section of the GLEContext class in this header, -// ideally in the same order it's declared in the CAPI_GLE_GL.h so it's easily readable. -// e.g. void glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); etc. -// -// 3) Add a declaration for each interface function to the GLEContext class in this header. -// e.g. PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback_Impl; etc. -// -// 4) Add code to GLEContext::InitExtensionLoad to load the function pointer. -// e.g. GLELoadProc(glDebugMessageCallback_Impl, glDebugMessageCallback); etc. -// -// 5) Add code to GLEContext::InitExtensionSupport to detect the extension support. -// e.g. { gl_KHR_debug, "GL_KHR_debug" }, etc. -// -// 6) Implement the GLEContext hook function(s) you declared. -// e.g. void OVR::GLEContext::glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled) -// { -// if(glDebugMessageControl_Impl) -// glDebugMessageControl_Impl(source, type, severity, count, ids, enabled); -// PostHook(); -// } -// -// Note that if the extension is a WGL-, GLX-, or CGL-specific extension, they are handled like above -// but are in their own section below the section for regular OpenGL extensions. -// -// In some cases the given interface may already be present by currently commented out, -// in which case you can simply un-comment it to enable it. -/////////////////////////////////////////////////////////////////////////////// - - -namespace OVR -{ - // Generic OpenGL GetProcAddress function interface. Maps to platform-specific functionality - // internally. On Windows this is equivalent to wglGetProcAddress as opposed to global GetProcAddress. - void* GLEGetProcAddress(const char* name); - - - // GLEContext - // - // Manages a collection of OpenGL extension interfaces. - // If the application has multiple OpenGL unrelated contexts then you will want to create a - // different instance of this class for each one you intend to use it with. - // - // Example usage: - // GLEContext gGLEContext; - // - // GLEContext::SetCurrentContext(&gGLEContext); - // gGLEContext.PlatformInit(); // Initializes WGL/GLX/etc. platform-specific OpenGL functionality - // - // if(GLE_WGL_ARB_create_context) // If wglCreateContextAttribsARB is available... - // { - // int attribList[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 2, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, None }; - // HGLRC h = wglCreateContextAttribsARB(hDC, 0, attribList); - // [...] - // } - // - // gGLEContext.Init(); // Must be called after an OpenGL context has been created. - // - // if(GLE_WHOLE_VERSION() >= 302) // If OpenGL 3.2 or later - // { - // glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, someTexture, 0); // This is an OpenGL 3.2 function. - // [...] - // } - // - // if(GLE_GL_ARB_texture_multisample) // If the GL_ARB_texture_multisample extension is available... - // { - // glEnable(GL_SAMPLE_MASK); - // glSampleMaski(0, 0x1); - // [...] - // } - // - // [...] - // - // gGLEContext.Shutdown(); - // - GLE_CLASS_EXPORT class GLEContext - { - public: - GLEContext(); - ~GLEContext(); - - // Initializes platform-specific functionality (e.g. Windows WGL, Unix GLX, Android EGL, Apple CGL). - // You would typically call this before creating an OpenGL context and using platform-specific functions. - void PlatformInit(); - bool IsPlatformInitialized() const; - - // Loads all the extensions from the current OpenGL context. This must be called after an OpenGL context - // has been created and made current. - void Init(); - bool IsInitialized() const; - - // Clears all the extensions initialized by PlatformInit and Init. - void Shutdown(); - - void SetEnableHookGetError(bool enabled) - { EnableHookGetError = enabled; } - - // Returns the default instance of this class. - static GLEContext* GetCurrentContext(); - - // Sets the default instance of this class. This should be called after enabling a new OpenGL context. - // This sets the current GLEContext; it does not set the underlying OpenGL context itself. - static void SetCurrentContext(GLEContext*); - - public: - // OpenGL version information - int MajorVersion; // Best guess at major version - int MinorVersion; // Best guess at minor version - int WholeVersion; // Equals ((MajorVersion * 100) + MinorVersion). Example usage: if(glv.WholeVersion >= 302) // If OpenGL v3.02+ ... - bool IsGLES; // Open GL ES? - bool IsCoreProfile; // Is the current OpenGL context a core profile context? Its trueness may be a false positive but will never be a false negative. - bool EnableHookGetError; // If enabled then hook functions call glGetError after making the call. - - int PlatformMajorVersion; // GLX/WGL/EGL/CGL version. Not the same as OpenGL version. - int PlatformMinorVersion; - int PlatformWholeVersion; - - void InitVersion(); // Initializes the version information (e.g. MajorVersion). Called by the public Init function. - void InitExtensionLoad(); // Loads the function addresses into the function pointers. - void InitExtensionSupport(); // Loads the boolean extension support booleans. - - void InitPlatformVersion(); - void InitPlatformExtensionLoad(); - void InitPlatformExtensionSupport(); - - public: - // GL_VERSION_1_1 - // Not normally included because all OpenGL 1.1 functionality is always present. But if we have - // hooking enabled then we implement our own version of each function. - #if defined(GLE_HOOKING_ENABLED) - //void PreHook(const char* functionName); // Called at the beginning of a hook function. - void PostHook(const char* functionName); // Called at the end of a hook function. - - void glAccum_Hook(GLenum op, GLfloat value); - void glAlphaFunc_Hook(GLenum func, GLclampf ref); - GLboolean glAreTexturesResident_Hook(GLsizei n, const GLuint *textures, GLboolean *residences); - void glArrayElement_Hook(GLint i); - void glBegin_Hook(GLenum mode); - void glBindTexture_Hook(GLenum target, GLuint texture); - void glBitmap_Hook(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); - void glBlendFunc_Hook(GLenum sfactor, GLenum dfactor); - void glCallList_Hook(GLuint list); - void glCallLists_Hook(GLsizei n, GLenum type, const void *lists); - void glClear_Hook(GLbitfield mask); - void glClearAccum_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - void glClearColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - void glClearDepth_Hook(GLclampd depth); - void glClearIndex_Hook(GLfloat c); - void glClearStencil_Hook(GLint s); - void glClipPlane_Hook(GLenum plane, const GLdouble *equation); - void glColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue); - void glColor3bv_Hook(const GLbyte *v); - void glColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue); - void glColor3dv_Hook(const GLdouble *v); - void glColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue); - void glColor3fv_Hook(const GLfloat *v); - void glColor3i_Hook(GLint red, GLint green, GLint blue); - void glColor3iv_Hook(const GLint *v); - void glColor3s_Hook(GLshort red, GLshort green, GLshort blue); - void glColor3sv_Hook(const GLshort *v); - void glColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue); - void glColor3ubv_Hook(const GLubyte *v); - void glColor3ui_Hook(GLuint red, GLuint green, GLuint blue); - void glColor3uiv_Hook(const GLuint *v); - void glColor3us_Hook(GLushort red, GLushort green, GLushort blue); - void glColor3usv_Hook(const GLushort *v); - void glColor4b_Hook(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); - void glColor4bv_Hook(const GLbyte *v); - void glColor4d_Hook(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); - void glColor4dv_Hook(const GLdouble *v); - void glColor4f_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - void glColor4fv_Hook(const GLfloat *v); - void glColor4i_Hook(GLint red, GLint green, GLint blue, GLint alpha); - void glColor4iv_Hook(const GLint *v); - void glColor4s_Hook(GLshort red, GLshort green, GLshort blue, GLshort alpha); - void glColor4sv_Hook(const GLshort *v); - void glColor4ub_Hook(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); - void glColor4ubv_Hook(const GLubyte *v); - void glColor4ui_Hook(GLuint red, GLuint green, GLuint blue, GLuint alpha); - void glColor4uiv_Hook(const GLuint *v); - void glColor4us_Hook(GLushort red, GLushort green, GLushort blue, GLushort alpha); - void glColor4usv_Hook(const GLushort *v); - void glColorMask_Hook(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); - void glColorMaterial_Hook(GLenum face, GLenum mode); - void glColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer); - void glCopyPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); - void glCopyTexImage1D_Hook(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); - void glCopyTexImage2D_Hook(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); - void glCopyTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); - void glCopyTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); - void glCullFace_Hook(GLenum mode); - void glDeleteLists_Hook(GLuint list, GLsizei range); - void glDeleteTextures_Hook(GLsizei n, const GLuint *textures); - void glDepthFunc_Hook(GLenum func); - void glDepthMask_Hook(GLboolean flag); - void glDepthRange_Hook(GLclampd zNear, GLclampd zFar); - void glDisable_Hook(GLenum cap); - void glDisableClientState_Hook(GLenum array); - void glDrawArrays_Hook(GLenum mode, GLint first, GLsizei count); - void glDrawBuffer_Hook(GLenum mode); - void glDrawElements_Hook(GLenum mode, GLsizei count, GLenum type, const void *indices); - void glDrawPixels_Hook(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); - void glEdgeFlag_Hook(GLboolean flag); - void glEdgeFlagPointer_Hook(GLsizei stride, const void *pointer); - void glEdgeFlagv_Hook(const GLboolean *flag); - void glEnable_Hook(GLenum cap); - void glEnableClientState_Hook(GLenum array); - void glEnd_Hook(void); - void glEndList_Hook(void); - void glEvalCoord1d_Hook(GLdouble u); - void glEvalCoord1dv_Hook(const GLdouble *u); - void glEvalCoord1f_Hook(GLfloat u); - void glEvalCoord1fv_Hook(const GLfloat *u); - void glEvalCoord2d_Hook(GLdouble u, GLdouble v); - void glEvalCoord2dv_Hook(const GLdouble *u); - void glEvalCoord2f_Hook(GLfloat u, GLfloat v); - void glEvalCoord2fv_Hook(const GLfloat *u); - void glEvalMesh1_Hook(GLenum mode, GLint i1, GLint i2); - void glEvalMesh2_Hook(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); - void glEvalPoint1_Hook(GLint i); - void glEvalPoint2_Hook(GLint i, GLint j); - void glFeedbackBuffer_Hook(GLsizei size, GLenum type, GLfloat *buffer); - void glFinish_Hook(void); - void glFlush_Hook(void); - void glFogf_Hook(GLenum pname, GLfloat param); - void glFogfv_Hook(GLenum pname, const GLfloat *params); - void glFogi_Hook(GLenum pname, GLint param); - void glFogiv_Hook(GLenum pname, const GLint *params); - void glFrontFace_Hook(GLenum mode); - void glFrustum_Hook(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); - GLuint glGenLists_Hook(GLsizei range); - void glGenTextures_Hook(GLsizei n, GLuint *textures); - void glGetBooleanv_Hook(GLenum pname, GLboolean *params); - void glGetClipPlane_Hook(GLenum plane, GLdouble *equation); - void glGetDoublev_Hook(GLenum pname, GLdouble *params); - GLenum glGetError_Hook(void); - void glGetFloatv_Hook(GLenum pname, GLfloat *params); - void glGetIntegerv_Hook(GLenum pname, GLint *params); - void glGetLightfv_Hook(GLenum light, GLenum pname, GLfloat *params); - void glGetLightiv_Hook(GLenum light, GLenum pname, GLint *params); - void glGetMapdv_Hook(GLenum target, GLenum query, GLdouble *v); - void glGetMapfv_Hook(GLenum target, GLenum query, GLfloat *v); - void glGetMapiv_Hook(GLenum target, GLenum query, GLint *v); - void glGetMaterialfv_Hook(GLenum face, GLenum pname, GLfloat *params); - void glGetMaterialiv_Hook(GLenum face, GLenum pname, GLint *params); - void glGetPixelMapfv_Hook(GLenum map, GLfloat *values); - void glGetPixelMapuiv_Hook(GLenum map, GLuint *values); - void glGetPixelMapusv_Hook(GLenum map, GLushort *values); - void glGetPointerv_Hook(GLenum pname, void* *params); - void glGetPolygonStipple_Hook(GLubyte *mask); - const GLubyte * glGetString_Hook(GLenum name); - void glGetTexEnvfv_Hook(GLenum target, GLenum pname, GLfloat *params); - void glGetTexEnviv_Hook(GLenum target, GLenum pname, GLint *params); - void glGetTexGendv_Hook(GLenum coord, GLenum pname, GLdouble *params); - void glGetTexGenfv_Hook(GLenum coord, GLenum pname, GLfloat *params); - void glGetTexGeniv_Hook(GLenum coord, GLenum pname, GLint *params); - void glGetTexImage_Hook(GLenum target, GLint level, GLenum format, GLenum type, void *pixels); - void glGetTexLevelParameterfv_Hook(GLenum target, GLint level, GLenum pname, GLfloat *params); - void glGetTexLevelParameteriv_Hook(GLenum target, GLint level, GLenum pname, GLint *params); - void glGetTexParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); - void glGetTexParameteriv_Hook(GLenum target, GLenum pname, GLint *params); - void glHint_Hook(GLenum target, GLenum mode); - void glIndexMask_Hook(GLuint mask); - void glIndexPointer_Hook(GLenum type, GLsizei stride, const void *pointer); - void glIndexd_Hook(GLdouble c); - void glIndexdv_Hook(const GLdouble *c); - void glIndexf_Hook(GLfloat c); - void glIndexfv_Hook(const GLfloat *c); - void glIndexi_Hook(GLint c); - void glIndexiv_Hook(const GLint *c); - void glIndexs_Hook(GLshort c); - void glIndexsv_Hook(const GLshort *c); - void glIndexub_Hook(GLubyte c); - void glIndexubv_Hook(const GLubyte *c); - void glInitNames_Hook(void); - void glInterleavedArrays_Hook(GLenum format, GLsizei stride, const void *pointer); - GLboolean glIsEnabled_Hook(GLenum cap); - GLboolean glIsList_Hook(GLuint list); - GLboolean glIsTexture_Hook(GLuint texture); - void glLightModelf_Hook(GLenum pname, GLfloat param); - void glLightModelfv_Hook(GLenum pname, const GLfloat *params); - void glLightModeli_Hook(GLenum pname, GLint param); - void glLightModeliv_Hook(GLenum pname, const GLint *params); - void glLightf_Hook(GLenum light, GLenum pname, GLfloat param); - void glLightfv_Hook(GLenum light, GLenum pname, const GLfloat *params); - void glLighti_Hook(GLenum light, GLenum pname, GLint param); - void glLightiv_Hook(GLenum light, GLenum pname, const GLint *params); - void glLineStipple_Hook(GLint factor, GLushort pattern); - void glLineWidth_Hook(GLfloat width); - void glListBase_Hook(GLuint base); - void glLoadIdentity_Hook(void); - void glLoadMatrixd_Hook(const GLdouble *m); - void glLoadMatrixf_Hook(const GLfloat *m); - void glLoadName_Hook(GLuint name); - void glLogicOp_Hook(GLenum opcode); - void glMap1d_Hook(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); - void glMap1f_Hook(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); - void glMap2d_Hook(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); - void glMap2f_Hook(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); - void glMapGrid1d_Hook(GLint un, GLdouble u1, GLdouble u2); - void glMapGrid1f_Hook(GLint un, GLfloat u1, GLfloat u2); - void glMapGrid2d_Hook(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); - void glMapGrid2f_Hook(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); - void glMaterialf_Hook(GLenum face, GLenum pname, GLfloat param); - void glMaterialfv_Hook(GLenum face, GLenum pname, const GLfloat *params); - void glMateriali_Hook(GLenum face, GLenum pname, GLint param); - void glMaterialiv_Hook(GLenum face, GLenum pname, const GLint *params); - void glMatrixMode_Hook(GLenum mode); - void glMultMatrixd_Hook(const GLdouble *m); - void glMultMatrixf_Hook(const GLfloat *m); - void glNewList_Hook(GLuint list, GLenum mode); - void glNormal3b_Hook(GLbyte nx, GLbyte ny, GLbyte nz); - void glNormal3bv_Hook(const GLbyte *v); - void glNormal3d_Hook(GLdouble nx, GLdouble ny, GLdouble nz); - void glNormal3dv_Hook(const GLdouble *v); - void glNormal3f_Hook(GLfloat nx, GLfloat ny, GLfloat nz); - void glNormal3fv_Hook(const GLfloat *v); - void glNormal3i_Hook(GLint nx, GLint ny, GLint nz); - void glNormal3iv_Hook(const GLint *v); - void glNormal3s_Hook(GLshort nx, GLshort ny, GLshort nz); - void glNormal3sv_Hook(const GLshort *v); - void glNormalPointer_Hook(GLenum type, GLsizei stride, const void *pointer); - void glOrtho_Hook(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); - void glPassThrough_Hook(GLfloat token); - void glPixelMapfv_Hook(GLenum map, GLsizei mapsize, const GLfloat *values); - void glPixelMapuiv_Hook(GLenum map, GLsizei mapsize, const GLuint *values); - void glPixelMapusv_Hook(GLenum map, GLsizei mapsize, const GLushort *values); - void glPixelStoref_Hook(GLenum pname, GLfloat param); - void glPixelStorei_Hook(GLenum pname, GLint param); - void glPixelTransferf_Hook(GLenum pname, GLfloat param); - void glPixelTransferi_Hook(GLenum pname, GLint param); - void glPixelZoom_Hook(GLfloat xfactor, GLfloat yfactor); - void glPointSize_Hook(GLfloat size); - void glPolygonMode_Hook(GLenum face, GLenum mode); - void glPolygonOffset_Hook(GLfloat factor, GLfloat units); - void glPolygonStipple_Hook(const GLubyte *mask); - void glPopAttrib_Hook(void); - void glPopClientAttrib_Hook(void); - void glPopMatrix_Hook(void); - void glPopName_Hook(void); - void glPrioritizeTextures_Hook(GLsizei n, const GLuint *textures, const GLclampf *priorities); - void glPushAttrib_Hook(GLbitfield mask); - void glPushClientAttrib_Hook(GLbitfield mask); - void glPushMatrix_Hook(void); - void glPushName_Hook(GLuint name); - void glRasterPos2d_Hook(GLdouble x, GLdouble y); - void glRasterPos2dv_Hook(const GLdouble *v); - void glRasterPos2f_Hook(GLfloat x, GLfloat y); - void glRasterPos2fv_Hook(const GLfloat *v); - void glRasterPos2i_Hook(GLint x, GLint y); - void glRasterPos2iv_Hook(const GLint *v); - void glRasterPos2s_Hook(GLshort x, GLshort y); - void glRasterPos2sv_Hook(const GLshort *v); - void glRasterPos3d_Hook(GLdouble x, GLdouble y, GLdouble z); - void glRasterPos3dv_Hook(const GLdouble *v); - void glRasterPos3f_Hook(GLfloat x, GLfloat y, GLfloat z); - void glRasterPos3fv_Hook(const GLfloat *v); - void glRasterPos3i_Hook(GLint x, GLint y, GLint z); - void glRasterPos3iv_Hook(const GLint *v); - void glRasterPos3s_Hook(GLshort x, GLshort y, GLshort z); - void glRasterPos3sv_Hook(const GLshort *v); - void glRasterPos4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w); - void glRasterPos4dv_Hook(const GLdouble *v); - void glRasterPos4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void glRasterPos4fv_Hook(const GLfloat *v); - void glRasterPos4i_Hook(GLint x, GLint y, GLint z, GLint w); - void glRasterPos4iv_Hook(const GLint *v); - void glRasterPos4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w); - void glRasterPos4sv_Hook(const GLshort *v); - void glReadBuffer_Hook(GLenum mode); - void glReadPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); - void glRectd_Hook(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); - void glRectdv_Hook(const GLdouble *v1, const GLdouble *v2); - void glRectf_Hook(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); - void glRectfv_Hook(const GLfloat *v1, const GLfloat *v2); - void glRecti_Hook(GLint x1, GLint y1, GLint x2, GLint y2); - void glRectiv_Hook(const GLint *v1, const GLint *v2); - void glRects_Hook(GLshort x1, GLshort y1, GLshort x2, GLshort y2); - void glRectsv_Hook(const GLshort *v1, const GLshort *v2); - GLint glRenderMode_Hook(GLenum mode); - void glRotated_Hook(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); - void glRotatef_Hook(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); - void glScaled_Hook(GLdouble x, GLdouble y, GLdouble z); - void glScalef_Hook(GLfloat x, GLfloat y, GLfloat z); - void glScissor_Hook(GLint x, GLint y, GLsizei width, GLsizei height); - void glSelectBuffer_Hook(GLsizei size, GLuint *buffer); - void glShadeModel_Hook(GLenum mode); - void glStencilFunc_Hook(GLenum func, GLint ref, GLuint mask); - void glStencilMask_Hook(GLuint mask); - void glStencilOp_Hook(GLenum fail, GLenum zfail, GLenum zpass); - void glTexCoord1d_Hook(GLdouble s); - void glTexCoord1dv_Hook(const GLdouble *v); - void glTexCoord1f_Hook(GLfloat s); - void glTexCoord1fv_Hook(const GLfloat *v); - void glTexCoord1i_Hook(GLint s); - void glTexCoord1iv_Hook(const GLint *v); - void glTexCoord1s_Hook(GLshort s); - void glTexCoord1sv_Hook(const GLshort *v); - void glTexCoord2d_Hook(GLdouble s, GLdouble t); - void glTexCoord2dv_Hook(const GLdouble *v); - void glTexCoord2f_Hook(GLfloat s, GLfloat t); - void glTexCoord2fv_Hook(const GLfloat *v); - void glTexCoord2i_Hook(GLint s, GLint t); - void glTexCoord2iv_Hook(const GLint *v); - void glTexCoord2s_Hook(GLshort s, GLshort t); - void glTexCoord2sv_Hook(const GLshort *v); - void glTexCoord3d_Hook(GLdouble s, GLdouble t, GLdouble r); - void glTexCoord3dv_Hook(const GLdouble *v); - void glTexCoord3f_Hook(GLfloat s, GLfloat t, GLfloat r); - void glTexCoord3fv_Hook(const GLfloat *v); - void glTexCoord3i_Hook(GLint s, GLint t, GLint r); - void glTexCoord3iv_Hook(const GLint *v); - void glTexCoord3s_Hook(GLshort s, GLshort t, GLshort r); - void glTexCoord3sv_Hook(const GLshort *v); - void glTexCoord4d_Hook(GLdouble s, GLdouble t, GLdouble r, GLdouble q); - void glTexCoord4dv_Hook(const GLdouble *v); - void glTexCoord4f_Hook(GLfloat s, GLfloat t, GLfloat r, GLfloat q); - void glTexCoord4fv_Hook(const GLfloat *v); - void glTexCoord4i_Hook(GLint s, GLint t, GLint r, GLint q); - void glTexCoord4iv_Hook(const GLint *v); - void glTexCoord4s_Hook(GLshort s, GLshort t, GLshort r, GLshort q); - void glTexCoord4sv_Hook(const GLshort *v); - void glTexCoordPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer); - void glTexEnvf_Hook(GLenum target, GLenum pname, GLfloat param); - void glTexEnvfv_Hook(GLenum target, GLenum pname, const GLfloat *params); - void glTexEnvi_Hook(GLenum target, GLenum pname, GLint param); - void glTexEnviv_Hook(GLenum target, GLenum pname, const GLint *params); - void glTexGend_Hook(GLenum coord, GLenum pname, GLdouble param); - void glTexGendv_Hook(GLenum coord, GLenum pname, const GLdouble *params); - void glTexGenf_Hook(GLenum coord, GLenum pname, GLfloat param); - void glTexGenfv_Hook(GLenum coord, GLenum pname, const GLfloat *params); - void glTexGeni_Hook(GLenum coord, GLenum pname, GLint param); - void glTexGeniv_Hook(GLenum coord, GLenum pname, const GLint *params); - void glTexImage1D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); - void glTexImage2D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); - void glTexParameterf_Hook(GLenum target, GLenum pname, GLfloat param); - void glTexParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params); - void glTexParameteri_Hook(GLenum target, GLenum pname, GLint param); - void glTexParameteriv_Hook(GLenum target, GLenum pname, const GLint *params); - void glTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); - void glTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); - void glTranslated_Hook(GLdouble x, GLdouble y, GLdouble z); - void glTranslatef_Hook(GLfloat x, GLfloat y, GLfloat z); - void glVertex2d_Hook(GLdouble x, GLdouble y); - void glVertex2dv_Hook(const GLdouble *v); - void glVertex2f_Hook(GLfloat x, GLfloat y); - void glVertex2fv_Hook(const GLfloat *v); - void glVertex2i_Hook(GLint x, GLint y); - void glVertex2iv_Hook(const GLint *v); - void glVertex2s_Hook(GLshort x, GLshort y); - void glVertex2sv_Hook(const GLshort *v); - void glVertex3d_Hook(GLdouble x, GLdouble y, GLdouble z); - void glVertex3dv_Hook(const GLdouble *v); - void glVertex3f_Hook(GLfloat x, GLfloat y, GLfloat z); - void glVertex3fv_Hook(const GLfloat *v); - void glVertex3i_Hook(GLint x, GLint y, GLint z); - void glVertex3iv_Hook(const GLint *v); - void glVertex3s_Hook(GLshort x, GLshort y, GLshort z); - void glVertex3sv_Hook(const GLshort *v); - void glVertex4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w); - void glVertex4dv_Hook(const GLdouble *v); - void glVertex4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void glVertex4fv_Hook(const GLfloat *v); - void glVertex4i_Hook(GLint x, GLint y, GLint z, GLint w); - void glVertex4iv_Hook(const GLint *v); - void glVertex4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w); - void glVertex4sv_Hook(const GLshort *v); - void glVertexPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer); - void glViewport_Hook(GLint x, GLint y, GLsizei width, GLsizei height); - - // GL_VERSION_1_2 - void glBlendColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - void glBlendEquation_Hook(GLenum mode); - void glDrawRangeElements_Hook(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); - void glTexImage3D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); - void glTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); - void glCopyTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - - // GL_VERSION_1_2 deprecated functions - /* Not currently supported - void glColorTable_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); - void glColorTableParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params); - void glColorTableParameteriv_Hook(GLenum target, GLenum pname, const GLint *params); - void glCopyColorTable_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); - void glGetColorTable_Hook(GLenum target, GLenum format, GLenum type, GLvoid *table); - void glGetColorTableParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); - void glGetColorTableParameteriv_Hook(GLenum target, GLenum pname, GLint *params); - void glColorSubTable_Hook(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); - void glCopyColorSubTable_Hook(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); - void glConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); - void glConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); - void glConvolutionParameterf_Hook(GLenum target, GLenum pname, GLfloat params); - void glConvolutionParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params); - void glConvolutionParameteri_Hook(GLenum target, GLenum pname, GLint params); - void glConvolutionParameteriv_Hook(GLenum target, GLenum pname, const GLint *params); - void glCopyConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); - void glCopyConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); - void glGetConvolutionFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *image); - void glGetConvolutionParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); - void glGetConvolutionParameteriv_Hook(GLenum target, GLenum pname, GLint *params); - void glGetSeparableFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); - void glSeparableFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); - void glGetHistogram_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); - void glGetHistogramParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); - void glGetHistogramParameteriv_Hook(GLenum target, GLenum pname, GLint *params); - void glGetMinmax_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); - void glGetMinmaxParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); - void glGetMinmaxParameteriv_Hook(GLenum target, GLenum pname, GLint *params); - void glHistogram_Hook(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); - void glMinmax_Hook(GLenum target, GLenum internalformat, GLboolean sink); - void glResetHistogram_Hook(GLenum target); - void glResetMinmax_Hook(GLenum target); - */ - - // GL_VERSION_1_3 - void glActiveTexture_Hook(GLenum texture); - void glSampleCoverage_Hook(GLclampf value, GLboolean invert); - void glCompressedTexImage3D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); - void glCompressedTexImage2D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); - void glCompressedTexImage1D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); - void glCompressedTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); - void glCompressedTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); - void glCompressedTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); - void glGetCompressedTexImage_Hook(GLenum target, GLint level, GLvoid *img); - - // GL_VERSION_1_3 deprecated functions - void glClientActiveTexture_Hook(GLenum texture); - void glMultiTexCoord1d_Hook(GLenum target, GLdouble s); - void glMultiTexCoord1dv_Hook(GLenum target, const GLdouble *v); - void glMultiTexCoord1f_Hook(GLenum target, GLfloat s); - void glMultiTexCoord1fv_Hook(GLenum target, const GLfloat *v); - void glMultiTexCoord1i_Hook(GLenum target, GLint s); - void glMultiTexCoord1iv_Hook(GLenum target, const GLint *v); - void glMultiTexCoord1s_Hook(GLenum target, GLshort s); - void glMultiTexCoord1sv_Hook(GLenum target, const GLshort *v); - void glMultiTexCoord2d_Hook(GLenum target, GLdouble s, GLdouble t); - void glMultiTexCoord2dv_Hook(GLenum target, const GLdouble *v); - void glMultiTexCoord2f_Hook(GLenum target, GLfloat s, GLfloat t); - void glMultiTexCoord2fv_Hook(GLenum target, const GLfloat *v); - void glMultiTexCoord2i_Hook(GLenum target, GLint s, GLint t); - void glMultiTexCoord2iv_Hook(GLenum target, const GLint *v); - void glMultiTexCoord2s_Hook(GLenum target, GLshort s, GLshort t); - void glMultiTexCoord2sv_Hook(GLenum target, const GLshort *v); - void glMultiTexCoord3d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r); - void glMultiTexCoord3dv_Hook(GLenum target, const GLdouble *v); - void glMultiTexCoord3f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r); - void glMultiTexCoord3fv_Hook(GLenum target, const GLfloat *v); - void glMultiTexCoord3i_Hook(GLenum target, GLint s, GLint t, GLint r); - void glMultiTexCoord3iv_Hook(GLenum target, const GLint *v); - void glMultiTexCoord3s_Hook(GLenum target, GLshort s, GLshort t, GLshort r); - void glMultiTexCoord3sv_Hook(GLenum target, const GLshort *v); - void glMultiTexCoord4d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); - void glMultiTexCoord4dv_Hook(GLenum target, const GLdouble *v); - void glMultiTexCoord4f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); - void glMultiTexCoord4fv_Hook(GLenum target, const GLfloat *v); - void glMultiTexCoord4i_Hook(GLenum target, GLint s, GLint t, GLint r, GLint q); - void glMultiTexCoord4iv_Hook(GLenum target, const GLint *v); - void glMultiTexCoord4s_Hook(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); - void glMultiTexCoord4sv_Hook(GLenum target, const GLshort *v); - void glLoadTransposeMatrixf_Hook(const GLfloat *m); - void glLoadTransposeMatrixd_Hook(const GLdouble *m); - void glMultTransposeMatrixf_Hook(const GLfloat *m); - void glMultTransposeMatrixd_Hook(const GLdouble *m); - - // GL_VERSION_1_4 - void glBlendFuncSeparate_Hook(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); - void glMultiDrawArrays_Hook(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); - void glMultiDrawElements_Hook(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); - void glPointParameterf_Hook(GLenum pname, GLfloat param); - void glPointParameterfv_Hook(GLenum pname, const GLfloat *params); - void glPointParameteri_Hook(GLenum pname, GLint param); - void glPointParameteriv_Hook(GLenum pname, const GLint *params); - - // GL_VERSION_1_4 deprecated functions - void glFogCoordf_Hook(GLfloat coord); - void glFogCoordfv_Hook(const GLfloat *coord); - void glFogCoordd_Hook(GLdouble coord); - void glFogCoorddv_Hook(const GLdouble *coord); - void glFogCoordPointer_Hook(GLenum type, GLsizei stride, const GLvoid *pointer); - void glSecondaryColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue); - void glSecondaryColor3bv_Hook(const GLbyte *v); - void glSecondaryColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue); - void glSecondaryColor3dv_Hook(const GLdouble *v); - void glSecondaryColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue); - void glSecondaryColor3fv_Hook(const GLfloat *v); - void glSecondaryColor3i_Hook(GLint red, GLint green, GLint blue); - void glSecondaryColor3iv_Hook(const GLint *v); - void glSecondaryColor3s_Hook(GLshort red, GLshort green, GLshort blue); - void glSecondaryColor3sv_Hook(const GLshort *v); - void glSecondaryColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue); - void glSecondaryColor3ubv_Hook(const GLubyte *v); - void glSecondaryColor3ui_Hook(GLuint red, GLuint green, GLuint blue); - void glSecondaryColor3uiv_Hook(const GLuint *v); - void glSecondaryColor3us_Hook(GLushort red, GLushort green, GLushort blue); - void glSecondaryColor3usv_Hook(const GLushort *v); - void glSecondaryColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - void glWindowPos2d_Hook(GLdouble x, GLdouble y); - void glWindowPos2dv_Hook(const GLdouble *v); - void glWindowPos2f_Hook(GLfloat x, GLfloat y); - void glWindowPos2fv_Hook(const GLfloat *v); - void glWindowPos2i_Hook(GLint x, GLint y); - void glWindowPos2iv_Hook(const GLint *v); - void glWindowPos2s_Hook(GLshort x, GLshort y); - void glWindowPos2sv_Hook(const GLshort *v); - void glWindowPos3d_Hook(GLdouble x, GLdouble y, GLdouble z); - void glWindowPos3dv_Hook(const GLdouble *v); - void glWindowPos3f_Hook(GLfloat x, GLfloat y, GLfloat z); - void glWindowPos3fv_Hook(const GLfloat *v); - void glWindowPos3i_Hook(GLint x, GLint y, GLint z); - void glWindowPos3iv_Hook(const GLint *v); - void glWindowPos3s_Hook(GLshort x, GLshort y, GLshort z); - void glWindowPos3sv_Hook(const GLshort *v); - - // GL_VERSION_1_5 - void glGenQueries_Hook(GLsizei n, GLuint *ids); - void glDeleteQueries_Hook(GLsizei n, const GLuint *ids); - GLboolean glIsQuery_Hook(GLuint id); - void glBeginQuery_Hook(GLenum target, GLuint id); - void glEndQuery_Hook(GLenum target); - void glGetQueryiv_Hook(GLenum target, GLenum pname, GLint *params); - void glGetQueryObjectiv_Hook(GLuint id, GLenum pname, GLint *params); - void glGetQueryObjectuiv_Hook(GLuint id, GLenum pname, GLuint *params); - void glBindBuffer_Hook(GLenum target, GLuint buffer); - void glDeleteBuffers_Hook(GLsizei n, const GLuint *buffers); - void glGenBuffers_Hook(GLsizei n, GLuint *buffers); - GLboolean glIsBuffer_Hook(GLuint buffer); - void glBufferData_Hook(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); - void glBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); - void glGetBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); - GLvoid* glMapBuffer_Hook(GLenum target, GLenum access); - GLboolean glUnmapBuffer_Hook(GLenum target); - void glGetBufferParameteriv_Hook(GLenum target, GLenum pname, GLint *params); - void glGetBufferPointerv_Hook(GLenum target, GLenum pname, GLvoid* *params); - - // GL_VERSION_2_0 - void glBlendEquationSeparate_Hook(GLenum modeRGB, GLenum modeAlpha); - void glDrawBuffers_Hook(GLsizei n, const GLenum *bufs); - void glStencilOpSeparate_Hook(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); - void glStencilFuncSeparate_Hook(GLenum face, GLenum func, GLint ref, GLuint mask); - void glStencilMaskSeparate_Hook(GLenum face, GLuint mask); - void glAttachShader_Hook(GLuint program, GLuint shader); - void glBindAttribLocation_Hook(GLuint program, GLuint index, const GLchar *name); - void glCompileShader_Hook(GLuint shader); - GLuint glCreateProgram_Hook(void); - GLuint glCreateShader_Hook(GLenum type); - void glDeleteProgram_Hook(GLuint program); - void glDeleteShader_Hook(GLuint shader); - void glDetachShader_Hook(GLuint program, GLuint shader); - void glDisableVertexAttribArray_Hook(GLuint index); - void glEnableVertexAttribArray_Hook(GLuint index); - void glGetActiveAttrib_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); - void glGetActiveUniform_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); - void glGetAttachedShaders_Hook(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); - GLint glGetAttribLocation_Hook(GLuint program, const GLchar *name); - void glGetProgramiv_Hook(GLuint program, GLenum pname, GLint *params); - void glGetProgramInfoLog_Hook(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - void glGetShaderiv_Hook(GLuint shader, GLenum pname, GLint *params); - void glGetShaderInfoLog_Hook(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); - void glGetShaderSource_Hook(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); - GLint glGetUniformLocation_Hook(GLuint program, const GLchar *name); - void glGetUniformfv_Hook(GLuint program, GLint location, GLfloat *params); - void glGetUniformiv_Hook(GLuint program, GLint location, GLint *params); - void glGetVertexAttribdv_Hook(GLuint index, GLenum pname, GLdouble *params); - void glGetVertexAttribfv_Hook(GLuint index, GLenum pname, GLfloat *params); - void glGetVertexAttribiv_Hook(GLuint index, GLenum pname, GLint *params); - void glGetVertexAttribPointerv_Hook(GLuint index, GLenum pname, GLvoid* *pointer); - GLboolean glIsProgram_Hook(GLuint program); - GLboolean glIsShader_Hook(GLuint shader); - void glLinkProgram_Hook(GLuint program); - void glShaderSource_Hook(GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); - void glUseProgram_Hook(GLuint program); - void glUniform1f_Hook(GLint location, GLfloat v0); - void glUniform2f_Hook(GLint location, GLfloat v0, GLfloat v1); - void glUniform3f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); - void glUniform4f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); - void glUniform1i_Hook(GLint location, GLint v0); - void glUniform2i_Hook(GLint location, GLint v0, GLint v1); - void glUniform3i_Hook(GLint location, GLint v0, GLint v1, GLint v2); - void glUniform4i_Hook(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); - void glUniform1fv_Hook(GLint location, GLsizei count, const GLfloat *value); - void glUniform2fv_Hook(GLint location, GLsizei count, const GLfloat *value); - void glUniform3fv_Hook(GLint location, GLsizei count, const GLfloat *value); - void glUniform4fv_Hook(GLint location, GLsizei count, const GLfloat *value); - void glUniform1iv_Hook(GLint location, GLsizei count, const GLint *value); - void glUniform2iv_Hook(GLint location, GLsizei count, const GLint *value); - void glUniform3iv_Hook(GLint location, GLsizei count, const GLint *value); - void glUniform4iv_Hook(GLint location, GLsizei count, const GLint *value); - void glUniformMatrix2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void glUniformMatrix3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void glUniformMatrix4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void glValidateProgram_Hook(GLuint program); - void glVertexAttrib1d_Hook(GLuint index, GLdouble x); - void glVertexAttrib1dv_Hook(GLuint index, const GLdouble *v); - void glVertexAttrib1f_Hook(GLuint index, GLfloat x); - void glVertexAttrib1fv_Hook(GLuint index, const GLfloat *v); - void glVertexAttrib1s_Hook(GLuint index, GLshort x); - void glVertexAttrib1sv_Hook(GLuint index, const GLshort *v); - void glVertexAttrib2d_Hook(GLuint index, GLdouble x, GLdouble y); - void glVertexAttrib2dv_Hook(GLuint index, const GLdouble *v); - void glVertexAttrib2f_Hook(GLuint index, GLfloat x, GLfloat y); - void glVertexAttrib2fv_Hook(GLuint index, const GLfloat *v); - void glVertexAttrib2s_Hook(GLuint index, GLshort x, GLshort y); - void glVertexAttrib2sv_Hook(GLuint index, const GLshort *v); - void glVertexAttrib3d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z); - void glVertexAttrib3dv_Hook(GLuint index, const GLdouble *v); - void glVertexAttrib3f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z); - void glVertexAttrib3fv_Hook(GLuint index, const GLfloat *v); - void glVertexAttrib3s_Hook(GLuint index, GLshort x, GLshort y, GLshort z); - void glVertexAttrib3sv_Hook(GLuint index, const GLshort *v); - void glVertexAttrib4Nbv_Hook(GLuint index, const GLbyte *v); - void glVertexAttrib4Niv_Hook(GLuint index, const GLint *v); - void glVertexAttrib4Nsv_Hook(GLuint index, const GLshort *v); - void glVertexAttrib4Nub_Hook(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); - void glVertexAttrib4Nubv_Hook(GLuint index, const GLubyte *v); - void glVertexAttrib4Nuiv_Hook(GLuint index, const GLuint *v); - void glVertexAttrib4Nusv_Hook(GLuint index, const GLushort *v); - void glVertexAttrib4bv_Hook(GLuint index, const GLbyte *v); - void glVertexAttrib4d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); - void glVertexAttrib4dv_Hook(GLuint index, const GLdouble *v); - void glVertexAttrib4f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - void glVertexAttrib4fv_Hook(GLuint index, const GLfloat *v); - void glVertexAttrib4iv_Hook(GLuint index, const GLint *v); - void glVertexAttrib4s_Hook(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); - void glVertexAttrib4sv_Hook(GLuint index, const GLshort *v); - void glVertexAttrib4ubv_Hook(GLuint index, const GLubyte *v); - void glVertexAttrib4uiv_Hook(GLuint index, const GLuint *v); - void glVertexAttrib4usv_Hook(GLuint index, const GLushort *v); - void glVertexAttribPointer_Hook(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); - - // GL_VERSION_2_1 - void glUniformMatrix2x3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void glUniformMatrix3x2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void glUniformMatrix2x4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void glUniformMatrix4x2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void glUniformMatrix3x4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - void glUniformMatrix4x3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - - // GL_VERSION_3_0 - void glColorMaski_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); - void glGetBooleani_v_Hook(GLenum target, GLuint index, GLboolean *data); - void glGetIntegeri_v_Hook(GLenum target, GLuint index, GLint *data); - void glEnablei_Hook(GLenum target, GLuint index); - void glDisablei_Hook(GLenum target, GLuint index); - GLboolean glIsEnabledi_Hook(GLenum target, GLuint index); - void glBeginTransformFeedback_Hook(GLenum primitiveMode); - void glEndTransformFeedback_Hook(void); - void glBindBufferRange_Hook(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); - void glBindBufferBase_Hook(GLenum target, GLuint index, GLuint buffer); - void glTransformFeedbackVaryings_Hook(GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); - void glGetTransformFeedbackVarying_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); - void glClampColor_Hook(GLenum target, GLenum clamp); - void glBeginConditionalRender_Hook(GLuint id, GLenum mode); - void glEndConditionalRender_Hook(void); - void glVertexAttribIPointer_Hook(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); - void glGetVertexAttribIiv_Hook(GLuint index, GLenum pname, GLint *params); - void glGetVertexAttribIuiv_Hook(GLuint index, GLenum pname, GLuint *params); - void glVertexAttribI1i_Hook(GLuint index, GLint x); - void glVertexAttribI2i_Hook(GLuint index, GLint x, GLint y); - void glVertexAttribI3i_Hook(GLuint index, GLint x, GLint y, GLint z); - void glVertexAttribI4i_Hook(GLuint index, GLint x, GLint y, GLint z, GLint w); - void glVertexAttribI1ui_Hook(GLuint index, GLuint x); - void glVertexAttribI2ui_Hook(GLuint index, GLuint x, GLuint y); - void glVertexAttribI3ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z); - void glVertexAttribI4ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); - void glVertexAttribI1iv_Hook(GLuint index, const GLint *v); - void glVertexAttribI2iv_Hook(GLuint index, const GLint *v); - void glVertexAttribI3iv_Hook(GLuint index, const GLint *v); - void glVertexAttribI4iv_Hook(GLuint index, const GLint *v); - void glVertexAttribI1uiv_Hook(GLuint index, const GLuint *v); - void glVertexAttribI2uiv_Hook(GLuint index, const GLuint *v); - void glVertexAttribI3uiv_Hook(GLuint index, const GLuint *v); - void glVertexAttribI4uiv_Hook(GLuint index, const GLuint *v); - void glVertexAttribI4bv_Hook(GLuint index, const GLbyte *v); - void glVertexAttribI4sv_Hook(GLuint index, const GLshort *v); - void glVertexAttribI4ubv_Hook(GLuint index, const GLubyte *v); - void glVertexAttribI4usv_Hook(GLuint index, const GLushort *v); - void glGetUniformuiv_Hook(GLuint program, GLint location, GLuint *params); - void glBindFragDataLocation_Hook(GLuint program, GLuint color, const GLchar *name); - GLint glGetFragDataLocation_Hook(GLuint program, const GLchar *name); - void glUniform1ui_Hook(GLint location, GLuint v0); - void glUniform2ui_Hook(GLint location, GLuint v0, GLuint v1); - void glUniform3ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2); - void glUniform4ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); - void glUniform1uiv_Hook(GLint location, GLsizei count, const GLuint *value); - void glUniform2uiv_Hook(GLint location, GLsizei count, const GLuint *value); - void glUniform3uiv_Hook(GLint location, GLsizei count, const GLuint *value); - void glUniform4uiv_Hook(GLint location, GLsizei count, const GLuint *value); - void glTexParameterIiv_Hook(GLenum target, GLenum pname, const GLint *params); - void glTexParameterIuiv_Hook(GLenum target, GLenum pname, const GLuint *params); - void glGetTexParameterIiv_Hook(GLenum target, GLenum pname, GLint *params); - void glGetTexParameterIuiv_Hook(GLenum target, GLenum pname, GLuint *params); - void glClearBufferiv_Hook(GLenum buffer, GLint drawbuffer, const GLint *value); - void glClearBufferuiv_Hook(GLenum buffer, GLint drawbuffer, const GLuint *value); - void glClearBufferfv_Hook(GLenum buffer, GLint drawbuffer, const GLfloat *value); - void glClearBufferfi_Hook(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); - const GLubyte* glGetStringi_Hook(GLenum name, GLuint index); - - // GL_VERSION_3_1 - void glDrawArraysInstanced_Hook(GLenum mode, GLint first, GLsizei count, GLsizei primcount); - void glDrawElementsInstanced_Hook(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); - void glTexBuffer_Hook(GLenum target, GLenum internalformat, GLuint buffer); - void glPrimitiveRestartIndex_Hook(GLuint index); - - // GL_VERSION_3_2 - void glGetInteger64i_v_Hook(GLenum target, GLuint index, GLint64 *data); - void glGetBufferParameteri64v_Hook(GLenum target, GLenum pname, GLint64 *params); - void glFramebufferTexture_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level); - - // GL_VERSION_3_3 - void glVertexAttribDivisor_Hook(GLuint index, GLuint divisor); - - // GL_VERSION_4_0 - void glMinSampleShading_Hook(GLclampf value); - void glBlendEquationi_Hook(GLuint buf, GLenum mode); - void glBlendEquationSeparatei_Hook(GLuint buf, GLenum modeRGB, GLenum modeAlpha); - void glBlendFunci_Hook(GLuint buf, GLenum src, GLenum dst); - void glBlendFuncSeparatei_Hook(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); - - // GL_AMD_debug_output - void glDebugMessageEnableAMD_Hook(GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); - void glDebugMessageInsertAMD_Hook(GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); - void glDebugMessageCallbackAMD_Hook(GLDEBUGPROCAMD callback, GLvoid *userParam); - GLuint glGetDebugMessageLogAMD_Hook(GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); - - #if defined(GLE_CGL_ENABLED) - // GL_APPLE_element_array - void glElementPointerAPPLE_Hook(GLenum type, const GLvoid *pointer); - void glDrawElementArrayAPPLE_Hook(GLenum mode, GLint first, GLsizei count); - void glDrawRangeElementArrayAPPLE_Hook(GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); - void glMultiDrawElementArrayAPPLE_Hook(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); - void glMultiDrawRangeElementArrayAPPLE_Hook(GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); - - // GL_APPLE_fence - void glGenFencesAPPLE_Hook(GLsizei n, GLuint *fences); - void glDeleteFencesAPPLE_Hook(GLsizei n, const GLuint *fences); - void glSetFenceAPPLE_Hook(GLuint fence); - GLboolean glIsFenceAPPLE_Hook(GLuint fence); - GLboolean glTestFenceAPPLE_Hook(GLuint fence); - void glFinishFenceAPPLE_Hook(GLuint fence); - GLboolean glTestObjectAPPLE_Hook(GLenum object, GLuint name); - void glFinishObjectAPPLE_Hook(GLenum object, GLint name); - - // GL_APPLE_flush_buffer_range - void glBufferParameteriAPPLE_Hook(GLenum target, GLenum pname, GLint param); - void glFlushMappedBufferRangeAPPLE_Hook(GLenum target, GLintptr offset, GLsizeiptr size); - - // GL_APPLE_object_purgeable - GLenum glObjectPurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option); - GLenum glObjectUnpurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option); - void glGetObjectParameterivAPPLE_Hook(GLenum objectType, GLuint name, GLenum pname, GLint *params); - - // GL_APPLE_texture_range - void glTextureRangeAPPLE_Hook(GLenum target, GLsizei length, const GLvoid *pointer); - void glGetTexParameterPointervAPPLE_Hook(GLenum target, GLenum pname, GLvoid **params); - - // GL_APPLE_vertex_array_object - void glBindVertexArrayAPPLE_Hook(GLuint array); - void glDeleteVertexArraysAPPLE_Hook(GLsizei n, const GLuint *arrays); - void glGenVertexArraysAPPLE_Hook(GLsizei n, GLuint *arrays); - GLboolean glIsVertexArrayAPPLE_Hook(GLuint array); - - // GL_APPLE_vertex_array_range - void glVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid *pointer); - void glFlushVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid *pointer); - void glVertexArrayParameteriAPPLE_Hook(GLenum pname, GLint param); - - // GL_APPLE_vertex_program_evaluators - void glEnableVertexAttribAPPLE_Hook(GLuint index, GLenum pname); - void glDisableVertexAttribAPPLE_Hook(GLuint index, GLenum pname); - GLboolean glIsVertexAttribEnabledAPPLE_Hook(GLuint index, GLenum pname); - void glMapVertexAttrib1dAPPLE_Hook(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); - void glMapVertexAttrib1fAPPLE_Hook(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); - void glMapVertexAttrib2dAPPLE_Hook(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); - void glMapVertexAttrib2fAPPLE_Hook(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); - #endif // GLE_CGL_ENABLED - - // GL_ARB_debug_output - void glDebugMessageControlARB_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); - void glDebugMessageInsertARB_Hook(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); - void glDebugMessageCallbackARB_Hook(GLDEBUGPROCARB callback, const GLvoid *userParam); - GLuint glGetDebugMessageLogARB_Hook(GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); - - // GL_ARB_ES2_compatibility - void glReleaseShaderCompiler_Hook(); - void glShaderBinary_Hook(GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); - void glGetShaderPrecisionFormat_Hook(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); - void glDepthRangef_Hook(GLclampf n, GLclampf f); - void glClearDepthf_Hook(GLclampf d); - - // GL_ARB_framebuffer_object - GLboolean glIsRenderbuffer_Hook(GLuint renderbuffer); - void glBindRenderbuffer_Hook(GLenum target, GLuint renderbuffer); - void glDeleteRenderbuffers_Hook(GLsizei n, const GLuint *renderbuffers); - void glGenRenderbuffers_Hook(GLsizei n, GLuint *renderbuffers); - void glRenderbufferStorage_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - void glGetRenderbufferParameteriv_Hook(GLenum target, GLenum pname, GLint *params); - GLboolean glIsFramebuffer_Hook(GLuint framebuffer); - void glBindFramebuffer_Hook(GLenum target, GLuint framebuffer); - void glDeleteFramebuffers_Hook(GLsizei n, const GLuint *framebuffers); - void glGenFramebuffers_Hook(GLsizei n, GLuint *framebuffers); - GLenum glCheckFramebufferStatus_Hook(GLenum target); - void glFramebufferTexture1D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); - void glFramebufferTexture2D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); - void glFramebufferTexture3D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); - void glFramebufferRenderbuffer_Hook(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); - void glGetFramebufferAttachmentParameteriv_Hook(GLenum target, GLenum attachment, GLenum pname, GLint *params); - void glGenerateMipmap_Hook(GLenum target); - void glBlitFramebuffer_Hook(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - void glRenderbufferStorageMultisample_Hook(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - void glFramebufferTextureLayer_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); - - // GL_ARB_texture_multisample - void glTexImage2DMultisample_Hook(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); - void glTexImage3DMultisample_Hook(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - void glGetMultisamplefv_Hook(GLenum pname, GLuint index, GLfloat *val); - void glSampleMaski_Hook(GLuint index, GLbitfield mask); - - // GL_ARB_timer_query - void glQueryCounter_Hook(GLuint id, GLenum target); - void glGetQueryObjecti64v_Hook(GLuint id, GLenum pname, GLint64 *params); - void glGetQueryObjectui64v_Hook(GLuint id, GLenum pname, GLuint64 *params); - - // GL_ARB_vertex_array_object - void glBindVertexArray_Hook(GLuint array); - void glDeleteVertexArrays_Hook(GLsizei n, const GLuint *arrays); - void glGenVertexArrays_Hook(GLsizei n, GLuint *arrays); - GLboolean glIsVertexArray_Hook(GLuint array); - - // GL_EXT_draw_buffers2 - void glColorMaskIndexedEXT_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); - void glGetBooleanIndexedvEXT_Hook(GLenum target, GLuint index, GLboolean *data); - void glGetIntegerIndexedvEXT_Hook(GLenum target, GLuint index, GLint *data); - void glEnableIndexedEXT_Hook(GLenum target, GLuint index); - void glDisableIndexedEXT_Hook(GLenum target, GLuint index); - GLboolean glIsEnabledIndexedEXT_Hook(GLenum target, GLuint index); - - // GL_KHR_debug - void glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); - void glDebugMessageInsert_Hook(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* buf); - void glDebugMessageCallback_Hook(GLDEBUGPROC callback, const void* userParam); - GLuint glGetDebugMessageLog_Hook(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, char* messageLog); - void glPushDebugGroup_Hook(GLenum source, GLuint id, GLsizei length, const char * message); - void glPopDebugGroup_Hook(void); - void glObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei length, const char *label); - void glGetObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, char *label); - void glObjectPtrLabel_Hook(void* ptr, GLsizei length, const char *label); - void glGetObjectPtrLabel_Hook(void* ptr, GLsizei bufSize, GLsizei *length, char *label); - - // GL_WIN_swap_hint - void glAddSwapHintRectWIN_Hook(GLint x, GLint y, GLsizei width, GLsizei height); - - #if defined(GLE_WGL_ENABLED) - void PostWGLHook(const char* functionName); - - // WGL - /* Hooking of these is currently disabled. - BOOL wglCopyContext_Hook(HGLRC, HGLRC, UINT); - HGLRC wglCreateContext_Hook(HDC); - HGLRC wglCreateLayerContext_Hook(HDC, int); - BOOL wglDeleteContext_Hook(HGLRC); - HGLRC wglGetCurrentContext_Hook(VOID); - HDC wglGetCurrentDC_Hook(VOID); - PROC wglGetProcAddress_Hook(LPCSTR); - BOOL wglMakeCurrent_Hook(HDC, HGLRC); - BOOL wglShareLists_Hook(HGLRC, HGLRC); - BOOL wglUseFontBitmapsA_Hook(HDC, DWORD, DWORD, DWORD); - BOOL wglUseFontBitmapsW_Hook(HDC, DWORD, DWORD, DWORD); - BOOL wglUseFontOutlinesA_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); - BOOL wglUseFontOutlinesW_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); - BOOL wglDescribeLayerPlane_Hook(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); - int wglSetLayerPaletteEntries_Hook(HDC, int, int, int, CONST COLORREF *); - int wglGetLayerPaletteEntries_Hook(HDC, int, int, int, COLORREF *); - BOOL wglRealizeLayerPalette_Hook(HDC, int, BOOL); - BOOL wglSwapLayerBuffers_Hook(HDC, UINT); - DWORD wglSwapMultipleBuffers_Hook(UINT, CONST WGLSWAP *); - */ - - // WGL_ARB_buffer_region - HANDLE wglCreateBufferRegionARB_Hook (HDC hDC, int iLayerPlane, UINT uType); - VOID wglDeleteBufferRegionARB_Hook (HANDLE hRegion); - BOOL wglSaveBufferRegionARB_Hook (HANDLE hRegion, int x, int y, int width, int height); - BOOL wglRestoreBufferRegionARB_Hook (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); - - // WGL_ARB_extensions_string - const char * wglGetExtensionsStringARB_Hook (HDC hdc); - - // WGL_ARB_pixel_format - BOOL wglGetPixelFormatAttribivARB_Hook (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); - BOOL wglGetPixelFormatAttribfvARB_Hook (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); - BOOL wglChoosePixelFormatARB_Hook (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); - - // WGL_ARB_make_current_read - BOOL wglMakeContextCurrentARB_Hook (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); - HDC wglGetCurrentReadDCARB_Hook (void); - - // WGL_ARB_pbuffer - HPBUFFERARB wglCreatePbufferARB_Hook (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); - HDC wglGetPbufferDCARB_Hook (HPBUFFERARB hPbuffer); - int wglReleasePbufferDCARB_Hook (HPBUFFERARB hPbuffer, HDC hDC); - BOOL wglDestroyPbufferARB_Hook (HPBUFFERARB hPbuffer); - BOOL wglQueryPbufferARB_Hook (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); - - // WGL_ARB_render_texture - BOOL wglBindTexImageARB_Hook (HPBUFFERARB hPbuffer, int iBuffer); - BOOL wglReleaseTexImageARB_Hook (HPBUFFERARB hPbuffer, int iBuffer); - BOOL wglSetPbufferAttribARB_Hook (HPBUFFERARB hPbuffer, const int *piAttribList); - - // WGL_NV_present_video - int wglEnumerateVideoDevicesNV_Hook (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); - BOOL wglBindVideoDeviceNV_Hook (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); - BOOL wglQueryCurrentContextNV_Hook (int iAttribute, int *piValue); - - // WGL_ARB_create_context - HGLRC wglCreateContextAttribsARB_Hook (HDC hDC, HGLRC hShareContext, const int *attribList); - - // WGL_EXT_extensions_string - const char * wglGetExtensionsStringEXT_Hook (); - - // WGL_EXT_swap_control - BOOL wglSwapIntervalEXT_Hook(int interval); - int wglGetSwapIntervalEXT_Hook(); - - // WGL_OML_sync_control - BOOL wglGetSyncValuesOML_Hook (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); - BOOL wglGetMscRateOML_Hook (HDC hdc, INT32 *numerator, INT32 *denominator); - INT64 wglSwapBuffersMscOML_Hook (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); - INT64 wglSwapLayerBuffersMscOML_Hook (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); - BOOL wglWaitForMscOML_Hook (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); - BOOL wglWaitForSbcOML_Hook (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); - - // WGL_NV_video_output - BOOL wglGetVideoDeviceNV_Hook (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); - BOOL wglReleaseVideoDeviceNV_Hook (HPVIDEODEV hVideoDevice); - BOOL wglBindVideoImageNV_Hook (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); - BOOL wglReleaseVideoImageNV_Hook (HPBUFFERARB hPbuffer, int iVideoBuffer); - BOOL wglSendPbufferToVideoNV_Hook (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); - BOOL wglGetVideoInfoNV_Hook (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); - - // WGL_NV_swap_group - BOOL wglJoinSwapGroupNV_Hook (HDC hDC, GLuint group); - BOOL wglBindSwapBarrierNV_Hook (GLuint group, GLuint barrier); - BOOL wglQuerySwapGroupNV_Hook (HDC hDC, GLuint *group, GLuint *barrier); - BOOL wglQueryMaxSwapGroupsNV_Hook (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); - BOOL wglQueryFrameCountNV_Hook (HDC hDC, GLuint *count); - BOOL wglResetFrameCountNV_Hook (HDC hDC); - - // WGL_NV_video_capture - BOOL wglBindVideoCaptureDeviceNV_Hook (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); - UINT wglEnumerateVideoCaptureDevicesNV_Hook (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); - BOOL wglLockVideoCaptureDeviceNV_Hook (HDC hDc, HVIDEOINPUTDEVICENV hDevice); - BOOL wglQueryVideoCaptureDeviceNV_Hook (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); - BOOL wglReleaseVideoCaptureDeviceNV_Hook (HDC hDc, HVIDEOINPUTDEVICENV hDevice); - - // WGL_NV_copy_image - BOOL wglCopyImageSubDataNV_Hook (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); - - // WGL_NV_DX_interop - BOOL wglDXSetResourceShareHandleNV_Hook(void *dxObject, HANDLE shareHandle); - HANDLE wglDXOpenDeviceNV_Hook(void *dxDevice); - BOOL wglDXCloseDeviceNV_Hook(HANDLE hDevice); - HANDLE wglDXRegisterObjectNV_Hook(HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); - BOOL wglDXUnregisterObjectNV_Hook(HANDLE hDevice, HANDLE hObject); - BOOL wglDXObjectAccessNV_Hook(HANDLE hObject, GLenum access); - BOOL wglDXLockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE *hObjects); - BOOL wglDXUnlockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE *hObjects); - #endif // GLE_WGL_ENABLED - - #if defined(GLE_GLX_ENABLED) - void PostGLXHook(const char* functionName); - - // GLX_VERSION_1_0 - // GLX_VERSION_1_1 - // We don't currently do hooking of these. - - // GLX_VERSION_1_2 - ::Display* glXGetCurrentDisplay_Hook(void); - - // GLX_VERSION_1_3 - GLXFBConfig* glXChooseFBConfig_Hook(::Display *dpy, int screen, const int *attrib_list, int *nelements); - GLXContext glXCreateNewContext_Hook(::Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); - GLXPbuffer glXCreatePbuffer_Hook(::Display *dpy, GLXFBConfig config, const int *attrib_list); - GLXPixmap glXCreatePixmap_Hook(::Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); - GLXWindow glXCreateWindow_Hook(::Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); - void glXDestroyPbuffer_Hook(::Display *dpy, GLXPbuffer pbuf); - void glXDestroyPixmap_Hook(::Display *dpy, GLXPixmap pixmap); - void glXDestroyWindow_Hook(::Display *dpy, GLXWindow win); - GLXDrawable glXGetCurrentReadDrawable_Hook(void); - int glXGetFBConfigAttrib_Hook(::Display *dpy, GLXFBConfig config, int attribute, int *value); - GLXFBConfig* glXGetFBConfigs_Hook(::Display *dpy, int screen, int *nelements); - void glXGetSelectedEvent_Hook(::Display *dpy, GLXDrawable draw, unsigned long *event_mask); - XVisualInfo* glXGetVisualFromFBConfig_Hook(::Display *dpy, GLXFBConfig config); - Bool glXMakeContextCurrent_Hook(::Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); - int glXQueryContext_Hook(::Display *dpy, GLXContext ctx, int attribute, int *value); - void glXQueryDrawable_Hook(::Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); - void glXSelectEvent_Hook(::Display *dpy, GLXDrawable draw, unsigned long event_mask); - - // GLX_VERSION_1_4 - // We don't do hooking of this. - - // GLX_ARB_create_context - GLXContext glXCreateContextAttribsARB_Hook(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); - - // GLX_EXT_swap_control - void glXSwapIntervalEXT_Hook(::Display* dpy, GLXDrawable drawable, int interval); - - // GLX_OML_sync_control - Bool glXGetMscRateOML_Hook(::Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); - Bool glXGetSyncValuesOML_Hook(::Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); - int64_t glXSwapBuffersMscOML_Hook(::Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); - Bool glXWaitForMscOML_Hook(::Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); - Bool glXWaitForSbcOML_Hook(::Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); - - // GLX_MESA_swap_control - int glXGetSwapIntervalMESA_Hook(); - int glXSwapIntervalMESA_Hook(unsigned int interval); - - #endif // GLE_GLX_ENABLED - - #endif // #if defined(GLE_HOOKING_ENABLED) - - // GL_VERSION_1_1 - // These are not represented by function pointers. - - // GL_VERSION_1_2 - PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D_Impl; - PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements_Impl; - PFNGLTEXIMAGE3DPROC glTexImage3D_Impl; - PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D_Impl; - - // GL_VERSION_1_2 deprecated functions - /* Not currently supported - PFNGLCOLORTABLEPROC glColorTable_Impl; - PFNGLCOLORTABLEPARAMETERFVPROC glColorTableParameterfv_Impl; - PFNGLCOLORTABLEPARAMETERIVPROC glColorTableParameteriv_Impl; - PFNGLCOPYCOLORTABLEPROC glCopyColorTable_Impl; - PFNGLGETCOLORTABLEPROC glGetColorTable_Impl; - PFNGLGETCOLORTABLEPARAMETERFVPROC glGetColorTableParameterfv_Impl; - PFNGLGETCOLORTABLEPARAMETERIVPROC glGetColorTableParameteriv_Impl; - PFNGLCOLORSUBTABLEPROC glColorSubTable_Impl; - PFNGLCOPYCOLORSUBTABLEPROC glCopyColorSubTable_Impl; - PFNGLCONVOLUTIONFILTER1DPROC glConvolutionFilter1D_Impl; - PFNGLCONVOLUTIONFILTER2DPROC glConvolutionFilter2D_Impl; - PFNGLCONVOLUTIONPARAMETERFPROC glConvolutionParameterf_Impl; - PFNGLCONVOLUTIONPARAMETERFVPROC glConvolutionParameterfv_Impl; - PFNGLCONVOLUTIONPARAMETERIPROC glConvolutionParameteri_Impl; - PFNGLCONVOLUTIONPARAMETERIVPROC glConvolutionParameteriv_Impl; - PFNGLCOPYCONVOLUTIONFILTER1DPROC glCopyConvolutionFilter1D_Impl; - PFNGLCOPYCONVOLUTIONFILTER2DPROC glCopyConvolutionFilter2D_Impl; - PFNGLGETCONVOLUTIONFILTERPROC glGetConvolutionFilter_Impl; - PFNGLGETCONVOLUTIONPARAMETERFVPROC glGetConvolutionParameterfv_Impl; - PFNGLGETCONVOLUTIONPARAMETERIVPROC glGetConvolutionParameteriv_Impl; - PFNGLGETSEPARABLEFILTERPROC glGetSeparableFilter_Impl; - PFNGLSEPARABLEFILTER2DPROC glSeparableFilter2D_Impl; - PFNGLGETHISTOGRAMPROC glGetHistogram_Impl; - PFNGLGETHISTOGRAMPARAMETERFVPROC glGetHistogramParameterfv_Impl; - PFNGLGETHISTOGRAMPARAMETERIVPROC glGetHistogramParameteriv_Impl; - PFNGLGETMINMAXPROC glGetMinmax_Impl; - PFNGLGETMINMAXPARAMETERFVPROC glGetMinmaxParameterfv_Impl; - PFNGLGETMINMAXPARAMETERIVPROC glGetMinmaxParameteriv_Impl; - PFNGLHISTOGRAMPROC glHistogram_Impl; - PFNGLMINMAXPROC glMinmax_Impl; - PFNGLRESETHISTOGRAMPROC glResetHistogram_Impl; - PFNGLRESETMINMAXPROC glResetMinmax_Impl; - */ - - // GL_VERSION_1_3 - PFNGLACTIVETEXTUREPROC glActiveTexture_Impl; - PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture_Impl; - PFNGLCOMPRESSEDTEXIMAGE1DPROC glCompressedTexImage1D_Impl; - PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D_Impl; - PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D_Impl; - PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D_Impl; - PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D_Impl; - PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D_Impl; - PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage_Impl; - PFNGLLOADTRANSPOSEMATRIXDPROC glLoadTransposeMatrixd_Impl; - PFNGLLOADTRANSPOSEMATRIXFPROC glLoadTransposeMatrixf_Impl; - PFNGLMULTTRANSPOSEMATRIXDPROC glMultTransposeMatrixd_Impl; - PFNGLMULTTRANSPOSEMATRIXFPROC glMultTransposeMatrixf_Impl; - PFNGLMULTITEXCOORD1DPROC glMultiTexCoord1d_Impl; - PFNGLMULTITEXCOORD1DVPROC glMultiTexCoord1dv_Impl; - PFNGLMULTITEXCOORD1FPROC glMultiTexCoord1f_Impl; - PFNGLMULTITEXCOORD1FVPROC glMultiTexCoord1fv_Impl; - PFNGLMULTITEXCOORD1IPROC glMultiTexCoord1i_Impl; - PFNGLMULTITEXCOORD1IVPROC glMultiTexCoord1iv_Impl; - PFNGLMULTITEXCOORD1SPROC glMultiTexCoord1s_Impl; - PFNGLMULTITEXCOORD1SVPROC glMultiTexCoord1sv_Impl; - PFNGLMULTITEXCOORD2DPROC glMultiTexCoord2d_Impl; - PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv_Impl; - PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f_Impl; - PFNGLMULTITEXCOORD2FVPROC glMultiTexCoord2fv_Impl; - PFNGLMULTITEXCOORD2IPROC glMultiTexCoord2i_Impl; - PFNGLMULTITEXCOORD2IVPROC glMultiTexCoord2iv_Impl; - PFNGLMULTITEXCOORD2SPROC glMultiTexCoord2s_Impl; - PFNGLMULTITEXCOORD2SVPROC glMultiTexCoord2sv_Impl; - PFNGLMULTITEXCOORD3DPROC glMultiTexCoord3d_Impl; - PFNGLMULTITEXCOORD3DVPROC glMultiTexCoord3dv_Impl; - PFNGLMULTITEXCOORD3FPROC glMultiTexCoord3f_Impl; - PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv_Impl; - PFNGLMULTITEXCOORD3IPROC glMultiTexCoord3i_Impl; - PFNGLMULTITEXCOORD3IVPROC glMultiTexCoord3iv_Impl; - PFNGLMULTITEXCOORD3SPROC glMultiTexCoord3s_Impl; - PFNGLMULTITEXCOORD3SVPROC glMultiTexCoord3sv_Impl; - PFNGLMULTITEXCOORD4DPROC glMultiTexCoord4d_Impl; - PFNGLMULTITEXCOORD4DVPROC glMultiTexCoord4dv_Impl; - PFNGLMULTITEXCOORD4FPROC glMultiTexCoord4f_Impl; - PFNGLMULTITEXCOORD4FVPROC glMultiTexCoord4fv_Impl; - PFNGLMULTITEXCOORD4IPROC glMultiTexCoord4i_Impl; - PFNGLMULTITEXCOORD4IVPROC glMultiTexCoord4iv_Impl; - PFNGLMULTITEXCOORD4SPROC glMultiTexCoord4s_Impl; - PFNGLMULTITEXCOORD4SVPROC glMultiTexCoord4sv_Impl; - PFNGLSAMPLECOVERAGEPROC glSampleCoverage_Impl; - - // GL_VERSION_1_4 - PFNGLBLENDCOLORPROC glBlendColor_Impl; - PFNGLBLENDEQUATIONPROC glBlendEquation_Impl; - PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate_Impl; - PFNGLFOGCOORDPOINTERPROC glFogCoordPointer_Impl; - PFNGLFOGCOORDDPROC glFogCoordd_Impl; - PFNGLFOGCOORDDVPROC glFogCoorddv_Impl; - PFNGLFOGCOORDFPROC glFogCoordf_Impl; - PFNGLFOGCOORDFVPROC glFogCoordfv_Impl; - PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays_Impl; - PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements_Impl; - PFNGLPOINTPARAMETERFPROC glPointParameterf_Impl; - PFNGLPOINTPARAMETERFVPROC glPointParameterfv_Impl; - PFNGLPOINTPARAMETERIPROC glPointParameteri_Impl; - PFNGLPOINTPARAMETERIVPROC glPointParameteriv_Impl; - PFNGLSECONDARYCOLOR3BPROC glSecondaryColor3b_Impl; - PFNGLSECONDARYCOLOR3BVPROC glSecondaryColor3bv_Impl; - PFNGLSECONDARYCOLOR3DPROC glSecondaryColor3d_Impl; - PFNGLSECONDARYCOLOR3DVPROC glSecondaryColor3dv_Impl; - PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f_Impl; - PFNGLSECONDARYCOLOR3FVPROC glSecondaryColor3fv_Impl; - PFNGLSECONDARYCOLOR3IPROC glSecondaryColor3i_Impl; - PFNGLSECONDARYCOLOR3IVPROC glSecondaryColor3iv_Impl; - PFNGLSECONDARYCOLOR3SPROC glSecondaryColor3s_Impl; - PFNGLSECONDARYCOLOR3SVPROC glSecondaryColor3sv_Impl; - PFNGLSECONDARYCOLOR3UBPROC glSecondaryColor3ub_Impl; - PFNGLSECONDARYCOLOR3UBVPROC glSecondaryColor3ubv_Impl; - PFNGLSECONDARYCOLOR3UIPROC glSecondaryColor3ui_Impl; - PFNGLSECONDARYCOLOR3UIVPROC glSecondaryColor3uiv_Impl; - PFNGLSECONDARYCOLOR3USPROC glSecondaryColor3us_Impl; - PFNGLSECONDARYCOLOR3USVPROC glSecondaryColor3usv_Impl; - PFNGLSECONDARYCOLORPOINTERPROC glSecondaryColorPointer_Impl; - PFNGLWINDOWPOS2DPROC glWindowPos2d_Impl; - PFNGLWINDOWPOS2DVPROC glWindowPos2dv_Impl; - PFNGLWINDOWPOS2FPROC glWindowPos2f_Impl; - PFNGLWINDOWPOS2FVPROC glWindowPos2fv_Impl; - PFNGLWINDOWPOS2IPROC glWindowPos2i_Impl; - PFNGLWINDOWPOS2IVPROC glWindowPos2iv_Impl; - PFNGLWINDOWPOS2SPROC glWindowPos2s_Impl; - PFNGLWINDOWPOS2SVPROC glWindowPos2sv_Impl; - PFNGLWINDOWPOS3DPROC glWindowPos3d_Impl; - PFNGLWINDOWPOS3DVPROC glWindowPos3dv_Impl; - PFNGLWINDOWPOS3FPROC glWindowPos3f_Impl; - PFNGLWINDOWPOS3FVPROC glWindowPos3fv_Impl; - PFNGLWINDOWPOS3IPROC glWindowPos3i_Impl; - PFNGLWINDOWPOS3IVPROC glWindowPos3iv_Impl; - PFNGLWINDOWPOS3SPROC glWindowPos3s_Impl; - PFNGLWINDOWPOS3SVPROC glWindowPos3sv_Impl; - - // GL_VERSION_1_5 - PFNGLBEGINQUERYPROC glBeginQuery_Impl; - PFNGLBINDBUFFERPROC glBindBuffer_Impl; - PFNGLBUFFERDATAPROC glBufferData_Impl; - PFNGLBUFFERSUBDATAPROC glBufferSubData_Impl; - PFNGLDELETEBUFFERSPROC glDeleteBuffers_Impl; - PFNGLDELETEQUERIESPROC glDeleteQueries_Impl; - PFNGLENDQUERYPROC glEndQuery_Impl; - PFNGLGENBUFFERSPROC glGenBuffers_Impl; - PFNGLGENQUERIESPROC glGenQueries_Impl; - PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv_Impl; - PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv_Impl; - PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData_Impl; - PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv_Impl; - PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv_Impl; - PFNGLGETQUERYIVPROC glGetQueryiv_Impl; - PFNGLISBUFFERPROC glIsBuffer_Impl; - PFNGLISQUERYPROC glIsQuery_Impl; - PFNGLMAPBUFFERPROC glMapBuffer_Impl; - PFNGLUNMAPBUFFERPROC glUnmapBuffer_Impl; - - // GL_VERSION_2_0 - PFNGLATTACHSHADERPROC glAttachShader_Impl; - PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation_Impl; - PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate_Impl; - PFNGLCOMPILESHADERPROC glCompileShader_Impl; - PFNGLCREATEPROGRAMPROC glCreateProgram_Impl; - PFNGLCREATESHADERPROC glCreateShader_Impl; - PFNGLDELETEPROGRAMPROC glDeleteProgram_Impl; - PFNGLDELETESHADERPROC glDeleteShader_Impl; - PFNGLDETACHSHADERPROC glDetachShader_Impl; - PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray_Impl; - PFNGLDRAWBUFFERSPROC glDrawBuffers_Impl; - PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray_Impl; - PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib_Impl; - PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform_Impl; - PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders_Impl; - PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation_Impl; - PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_Impl; - PFNGLGETPROGRAMIVPROC glGetProgramiv_Impl; - PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog_Impl; - PFNGLGETSHADERSOURCEPROC glGetShaderSource_Impl; - PFNGLGETSHADERIVPROC glGetShaderiv_Impl; - PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_Impl; - PFNGLGETUNIFORMFVPROC glGetUniformfv_Impl; - PFNGLGETUNIFORMIVPROC glGetUniformiv_Impl; - PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv_Impl; - PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv_Impl; - PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv_Impl; - PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv_Impl; - PFNGLISPROGRAMPROC glIsProgram_Impl; - PFNGLISSHADERPROC glIsShader_Impl; - PFNGLLINKPROGRAMPROC glLinkProgram_Impl; - PFNGLSHADERSOURCEPROC glShaderSource_Impl; - PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate_Impl; - PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate_Impl; - PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate_Impl; - PFNGLUNIFORM1FPROC glUniform1f_Impl; - PFNGLUNIFORM1FVPROC glUniform1fv_Impl; - PFNGLUNIFORM1IPROC glUniform1i_Impl; - PFNGLUNIFORM1IVPROC glUniform1iv_Impl; - PFNGLUNIFORM2FPROC glUniform2f_Impl; - PFNGLUNIFORM2FVPROC glUniform2fv_Impl; - PFNGLUNIFORM2IPROC glUniform2i_Impl; - PFNGLUNIFORM2IVPROC glUniform2iv_Impl; - PFNGLUNIFORM3FPROC glUniform3f_Impl; - PFNGLUNIFORM3FVPROC glUniform3fv_Impl; - PFNGLUNIFORM3IPROC glUniform3i_Impl; - PFNGLUNIFORM3IVPROC glUniform3iv_Impl; - PFNGLUNIFORM4FPROC glUniform4f_Impl; - PFNGLUNIFORM4FVPROC glUniform4fv_Impl; - PFNGLUNIFORM4IPROC glUniform4i_Impl; - PFNGLUNIFORM4IVPROC glUniform4iv_Impl; - PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv_Impl; - PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv_Impl; - PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv_Impl; - PFNGLUSEPROGRAMPROC glUseProgram_Impl; - PFNGLVALIDATEPROGRAMPROC glValidateProgram_Impl; - PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d_Impl; - PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv_Impl; - PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_Impl; - PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv_Impl; - PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s_Impl; - PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv_Impl; - PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d_Impl; - PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv_Impl; - PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_Impl; - PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv_Impl; - PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s_Impl; - PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv_Impl; - PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d_Impl; - PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv_Impl; - PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_Impl; - PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv_Impl; - PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s_Impl; - PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv_Impl; - PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv_Impl; - PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv_Impl; - PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv_Impl; - PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub_Impl; - PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv_Impl; - PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv_Impl; - PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv_Impl; - PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv_Impl; - PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d_Impl; - PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv_Impl; - PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_Impl; - PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv_Impl; - PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv_Impl; - PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s_Impl; - PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv_Impl; - PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv_Impl; - PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv_Impl; - PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv_Impl; - PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer_Impl; - - // GL_VERSION_2_1 - PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv_Impl; - PFNGLUNIFORMMATRIX2X4FVPROC glUniformMatrix2x4fv_Impl; - PFNGLUNIFORMMATRIX3X2FVPROC glUniformMatrix3x2fv_Impl; - PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv_Impl; - PFNGLUNIFORMMATRIX4X2FVPROC glUniformMatrix4x2fv_Impl; - PFNGLUNIFORMMATRIX4X3FVPROC glUniformMatrix4x3fv_Impl; - - // GL_VERSION_3_0 - PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender_Impl; - PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback_Impl; - PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation_Impl; - PFNGLCLAMPCOLORPROC glClampColor_Impl; - PFNGLCLEARBUFFERFIPROC glClearBufferfi_Impl; - PFNGLCLEARBUFFERFVPROC glClearBufferfv_Impl; - PFNGLCLEARBUFFERIVPROC glClearBufferiv_Impl; - PFNGLCLEARBUFFERUIVPROC glClearBufferuiv_Impl; - PFNGLCOLORMASKIPROC glColorMaski_Impl; - PFNGLDISABLEIPROC glDisablei_Impl; - PFNGLENABLEIPROC glEnablei_Impl; - PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender_Impl; - PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback_Impl; - PFNGLBINDBUFFERRANGEPROC glBindBufferRange_Impl; - PFNGLBINDBUFFERBASEPROC glBindBufferBase_Impl; - PFNGLGETBOOLEANI_VPROC glGetBooleani_v_Impl; - PFNGLGETINTEGERI_VPROC glGetIntegeri_v_Impl; - PFNGLGETFRAGDATALOCATIONPROC glGetFragDataLocation_Impl; - PFNGLGETSTRINGIPROC glGetStringi_Impl; - PFNGLGETTEXPARAMETERIIVPROC glGetTexParameterIiv_Impl; - PFNGLGETTEXPARAMETERIUIVPROC glGetTexParameterIuiv_Impl; - PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glGetTransformFeedbackVarying_Impl; - PFNGLGETUNIFORMUIVPROC glGetUniformuiv_Impl; - PFNGLGETVERTEXATTRIBIIVPROC glGetVertexAttribIiv_Impl; - PFNGLGETVERTEXATTRIBIUIVPROC glGetVertexAttribIuiv_Impl; - PFNGLISENABLEDIPROC glIsEnabledi_Impl; - PFNGLTEXPARAMETERIIVPROC glTexParameterIiv_Impl; - PFNGLTEXPARAMETERIUIVPROC glTexParameterIuiv_Impl; - PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings_Impl; - PFNGLUNIFORM1UIPROC glUniform1ui_Impl; - PFNGLUNIFORM1UIVPROC glUniform1uiv_Impl; - PFNGLUNIFORM2UIPROC glUniform2ui_Impl; - PFNGLUNIFORM2UIVPROC glUniform2uiv_Impl; - PFNGLUNIFORM3UIPROC glUniform3ui_Impl; - PFNGLUNIFORM3UIVPROC glUniform3uiv_Impl; - PFNGLUNIFORM4UIPROC glUniform4ui_Impl; - PFNGLUNIFORM4UIVPROC glUniform4uiv_Impl; - PFNGLVERTEXATTRIBI1IPROC glVertexAttribI1i_Impl; - PFNGLVERTEXATTRIBI1IVPROC glVertexAttribI1iv_Impl; - PFNGLVERTEXATTRIBI1UIPROC glVertexAttribI1ui_Impl; - PFNGLVERTEXATTRIBI1UIVPROC glVertexAttribI1uiv_Impl; - PFNGLVERTEXATTRIBI2IPROC glVertexAttribI2i_Impl; - PFNGLVERTEXATTRIBI2IVPROC glVertexAttribI2iv_Impl; - PFNGLVERTEXATTRIBI2UIPROC glVertexAttribI2ui_Impl; - PFNGLVERTEXATTRIBI2UIVPROC glVertexAttribI2uiv_Impl; - PFNGLVERTEXATTRIBI3IPROC glVertexAttribI3i_Impl; - PFNGLVERTEXATTRIBI3IVPROC glVertexAttribI3iv_Impl; - PFNGLVERTEXATTRIBI3UIPROC glVertexAttribI3ui_Impl; - PFNGLVERTEXATTRIBI3UIVPROC glVertexAttribI3uiv_Impl; - PFNGLVERTEXATTRIBI4BVPROC glVertexAttribI4bv_Impl; - PFNGLVERTEXATTRIBI4IPROC glVertexAttribI4i_Impl; - PFNGLVERTEXATTRIBI4IVPROC glVertexAttribI4iv_Impl; - PFNGLVERTEXATTRIBI4SVPROC glVertexAttribI4sv_Impl; - PFNGLVERTEXATTRIBI4UBVPROC glVertexAttribI4ubv_Impl; - PFNGLVERTEXATTRIBI4UIPROC glVertexAttribI4ui_Impl; - PFNGLVERTEXATTRIBI4UIVPROC glVertexAttribI4uiv_Impl; - PFNGLVERTEXATTRIBI4USVPROC glVertexAttribI4usv_Impl; - PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer_Impl; - - // GL_VERSION_3_1 - PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced_Impl; - PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced_Impl; - PFNGLPRIMITIVERESTARTINDEXPROC glPrimitiveRestartIndex_Impl; - PFNGLTEXBUFFERPROC glTexBuffer_Impl; - - // GL_VERSION_3_2 - PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture_Impl; - PFNGLGETBUFFERPARAMETERI64VPROC glGetBufferParameteri64v_Impl; - PFNGLGETINTEGER64I_VPROC glGetInteger64i_v_Impl; - - // GL_VERSION_3_3 - PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor_Impl; - - // GL_VERSION_4_0 - PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei_Impl; - PFNGLBLENDEQUATIONIPROC glBlendEquationi_Impl; - PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei_Impl; - PFNGLBLENDFUNCIPROC glBlendFunci_Impl; - PFNGLMINSAMPLESHADINGPROC glMinSampleShading_Impl; - - // GL_AMD_debug_output - PFNGLDEBUGMESSAGECALLBACKAMDPROC glDebugMessageCallbackAMD_Impl; - PFNGLDEBUGMESSAGEENABLEAMDPROC glDebugMessageEnableAMD_Impl; - PFNGLDEBUGMESSAGEINSERTAMDPROC glDebugMessageInsertAMD_Impl; - PFNGLGETDEBUGMESSAGELOGAMDPROC glGetDebugMessageLogAMD_Impl; - - #if defined(GLE_CGL_ENABLED) - // GL_APPLE_aux_depth_stencil - // (no functions) - - // GL_APPLE_client_storage - // (no functions) - - // GL_APPLE_element_array - PFNGLDRAWELEMENTARRAYAPPLEPROC glDrawElementArrayAPPLE_Impl; - PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glDrawRangeElementArrayAPPLE_Impl; - PFNGLELEMENTPOINTERAPPLEPROC glElementPointerAPPLE_Impl; - PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glMultiDrawElementArrayAPPLE_Impl; - PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glMultiDrawRangeElementArrayAPPLE_Impl; - - // GL_APPLE_fence - PFNGLDELETEFENCESAPPLEPROC glDeleteFencesAPPLE_Impl; - PFNGLFINISHFENCEAPPLEPROC glFinishFenceAPPLE_Impl; - PFNGLFINISHOBJECTAPPLEPROC glFinishObjectAPPLE_Impl; - PFNGLGENFENCESAPPLEPROC glGenFencesAPPLE_Impl; - PFNGLISFENCEAPPLEPROC glIsFenceAPPLE_Impl; - PFNGLSETFENCEAPPLEPROC glSetFenceAPPLE_Impl; - PFNGLTESTFENCEAPPLEPROC glTestFenceAPPLE_Impl; - PFNGLTESTOBJECTAPPLEPROC glTestObjectAPPLE_Impl; - - // GL_APPLE_float_pixels - // (no functions) - - // GL_APPLE_flush_buffer_range - PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE_Impl; - PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE_Impl; - - // GL_APPLE_object_purgeable - PFNGLGETOBJECTPARAMETERIVAPPLEPROC glGetObjectParameterivAPPLE_Impl; - PFNGLOBJECTPURGEABLEAPPLEPROC glObjectPurgeableAPPLE_Impl; - PFNGLOBJECTUNPURGEABLEAPPLEPROC glObjectUnpurgeableAPPLE_Impl; - - // GL_APPLE_pixel_buffer - // (no functions) - - // GL_APPLE_rgb_422 - // (no functions) - - // GL_APPLE_row_bytes - // (no functions) - - // GL_APPLE_specular_vector - // (no functions) - - // GL_APPLE_texture_range - PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glGetTexParameterPointervAPPLE_Impl; - PFNGLTEXTURERANGEAPPLEPROC glTextureRangeAPPLE_Impl; - - // GL_APPLE_transform_hint - // (no functions) - - // GL_APPLE_vertex_array_object - PFNGLBINDVERTEXARRAYAPPLEPROC glBindVertexArrayAPPLE_Impl; - PFNGLDELETEVERTEXARRAYSAPPLEPROC glDeleteVertexArraysAPPLE_Impl; - PFNGLGENVERTEXARRAYSAPPLEPROC glGenVertexArraysAPPLE_Impl; - PFNGLISVERTEXARRAYAPPLEPROC glIsVertexArrayAPPLE_Impl; - - // GL_APPLE_vertex_array_range - PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glFlushVertexArrayRangeAPPLE_Impl; - PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glVertexArrayParameteriAPPLE_Impl; - PFNGLVERTEXARRAYRANGEAPPLEPROC glVertexArrayRangeAPPLE_Impl; - - // GL_APPLE_vertex_program_evaluators - PFNGLDISABLEVERTEXATTRIBAPPLEPROC glDisableVertexAttribAPPLE_Impl; - PFNGLENABLEVERTEXATTRIBAPPLEPROC glEnableVertexAttribAPPLE_Impl; - PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glIsVertexAttribEnabledAPPLE_Impl; - PFNGLMAPVERTEXATTRIB1DAPPLEPROC glMapVertexAttrib1dAPPLE_Impl; - PFNGLMAPVERTEXATTRIB1FAPPLEPROC glMapVertexAttrib1fAPPLE_Impl; - PFNGLMAPVERTEXATTRIB2DAPPLEPROC glMapVertexAttrib2dAPPLE_Impl; - PFNGLMAPVERTEXATTRIB2FAPPLEPROC glMapVertexAttrib2fAPPLE_Impl; - #endif // GLE_CGL_ENABLED - - // GL_ARB_debug_output - PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB_Impl; - PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB_Impl; - PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB_Impl; - PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB_Impl; - - // GL_ARB_ES2_compatibility - PFNGLCLEARDEPTHFPROC glClearDepthf_Impl; - PFNGLDEPTHRANGEFPROC glDepthRangef_Impl; - PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat_Impl; - PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler_Impl; - PFNGLSHADERBINARYPROC glShaderBinary_Impl; - - // GL_ARB_framebuffer_object - PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer_Impl; - PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer_Impl; - PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer_Impl; - PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus_Impl; - PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers_Impl; - PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers_Impl; - PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer_Impl; - PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D_Impl; - PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D_Impl; - PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D_Impl; - PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer_Impl; - PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers_Impl; - PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers_Impl; - PFNGLGENERATEMIPMAPPROC glGenerateMipmap_Impl; - PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv_Impl; - PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv_Impl; - PFNGLISFRAMEBUFFERPROC glIsFramebuffer_Impl; - PFNGLISRENDERBUFFERPROC glIsRenderbuffer_Impl; - PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage_Impl; - PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample_Impl; - - // GL_ARB_framebuffer_sRGB - // (no functions) - - // GL_ARB_texture_multisample - PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv_Impl; - PFNGLSAMPLEMASKIPROC glSampleMaski_Impl; - PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample_Impl; - PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample_Impl; - - // GL_ARB_texture_non_power_of_two - // (no functions) - - // GL_ARB_texture_rectangle - // (no functions) - - // GL_ARB_timer_query - PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v_Impl; - PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v_Impl; - PFNGLQUERYCOUNTERPROC glQueryCounter_Impl; - - // GL_ARB_vertex_array_object - PFNGLBINDVERTEXARRAYPROC glBindVertexArray_Impl; - PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays_Impl; - PFNGLGENVERTEXARRAYSPROC glGenVertexArrays_Impl; - PFNGLISVERTEXARRAYPROC glIsVertexArray_Impl; - - // GL_EXT_draw_buffers2 - PFNGLCOLORMASKINDEXEDEXTPROC glColorMaskIndexedEXT_Impl; - PFNGLDISABLEINDEXEDEXTPROC glDisableIndexedEXT_Impl; - PFNGLENABLEINDEXEDEXTPROC glEnableIndexedEXT_Impl; - PFNGLGETBOOLEANINDEXEDVEXTPROC glGetBooleanIndexedvEXT_Impl; - PFNGLGETINTEGERINDEXEDVEXTPROC glGetIntegerIndexedvEXT_Impl; - PFNGLISENABLEDINDEXEDEXTPROC glIsEnabledIndexedEXT_Impl; - - // GL_EXT_texture_filter_anisotropic - // (no functions) - - // GL_KHR_debug - PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback_Impl; - PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl_Impl; - PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert_Impl; - PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog_Impl; - PFNGLGETOBJECTLABELPROC glGetObjectLabel_Impl; - PFNGLGETOBJECTPTRLABELPROC glGetObjectPtrLabel_Impl; - PFNGLOBJECTLABELPROC glObjectLabel_Impl; - PFNGLOBJECTPTRLABELPROC glObjectPtrLabel_Impl; - PFNGLPOPDEBUGGROUPPROC glPopDebugGroup_Impl; - PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup_Impl; - - // GL_KHR_robust_buffer_access_behavior - - // GL_WIN_swap_hint - PFNGLADDSWAPHINTRECTWINPROC glAddSwapHintRectWIN_Impl; - - #if defined(GLE_WGL_ENABLED) - // WGL - // We don't declare pointers for these because we statically link to the implementations, same as with the OpenGL 1.1 functions. - // BOOL wglCopyContext_Hook(HGLRC, HGLRC, UINT); - // HGLRC wglCreateContext_Hook(HDC); - // HGLRC wglCreateLayerContext_Hook(HDC, int); - // BOOL wglDeleteContext_Hook(HGLRC); - // HGLRC wglGetCurrentContext_Hook(VOID); - // HDC wglGetCurrentDC_Hook(VOID); - // PROC wglGetProcAddress_Hook(LPCSTR); - // BOOL wglMakeCurrent_Hook(HDC, HGLRC); - // BOOL wglShareLists_Hook(HGLRC, HGLRC); - // BOOL wglUseFontBitmapsA_Hook(HDC, DWORD, DWORD, DWORD); - // BOOL wglUseFontBitmapsW_Hook(HDC, DWORD, DWORD, DWORD); - // BOOL wglUseFontOutlinesA_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); - // BOOL wglUseFontOutlinesW_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); - // BOOL wglDescribeLayerPlane_Hook(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); - // int wglSetLayerPaletteEntries_Hook(HDC, int, int, int, CONST COLORREF *); - // int wglGetLayerPaletteEntries_Hook(HDC, int, int, int, COLORREF *); - // BOOL wglRealizeLayerPalette_Hook(HDC, int, BOOL); - // BOOL wglSwapLayerBuffers_Hook(HDC, UINT); - // DWORD wglSwapMultipleBuffers_Hook(UINT, CONST WGLSWAP *); - - #if 0 - PFNWGLCOPYCONTEXTPROC wglCopyContext_Impl; - PFNWGLCREATECONTEXTPROC wglCreateContext_Impl; - PFNWGLCREATELAYERCONTEXTPROC wglCreateLayerContext_Impl; - PFNWGLDELETECONTEXTPROC wglDeleteContext_Impl; - PFNWGLGETCURRENTCONTEXTPROC wglGetCurrentContext_Impl; - PFNWGLGETCURRENTDCPROC wglGetCurrentDC_Impl; - PFNWGLGETPROCADDRESSPROC wglGetProcAddress_Impl; - PFNWGLMAKECURRENTPROC wglMakeCurrent_Impl; - PFNWGLSHARELISTSPROC wglShareLists_Impl; - PFNWGLUSEFONTBITMAPSAPROC wglUseFontBitmapsA_Impl; - PFNWGLUSEFONTBITMAPSWPROC wglUseFontBitmapsW_Impl; - PFNWGLUSEFONTOUTLINESAPROC wglUseFontOutlinesA_Impl; - PFNWGLUSEFONTOUTLINESWPROC wglUseFontOutlinesW_Impl; - PFNWGLDESCRIBELAYERPLANEPROC wglDescribeLayerPlane_Impl; - PFNWGLSETLAYERPALETTEENTRIESPROC wglSetLayerPaletteEntries_Impl; - PFNWGLGETLAYERPALETTEENTRIESPROC wglGetLayerPaletteEntries_Impl; - PFNWGLREALIZELAYERPALETTEPROC wglRealizeLayerPalette_Impl; - PFNWGLSWAPLAYERBUFFERSPROC wglSwapLayerBuffers_Impl; - PFNWGLSWAPMULTIPLEBUFFERSPROC wglSwapMultipleBuffers_Impl; - #endif - - // WGL_ARB_buffer_region - PFNWGLCREATEBUFFERREGIONARBPROC wglCreateBufferRegionARB_Impl; - PFNWGLDELETEBUFFERREGIONARBPROC wglDeleteBufferRegionARB_Impl; - PFNWGLSAVEBUFFERREGIONARBPROC wglSaveBufferRegionARB_Impl; - PFNWGLRESTOREBUFFERREGIONARBPROC wglRestoreBufferRegionARB_Impl; - - // WGL_ARB_extensions_string - PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_Impl; - - // WGL_ARB_pixel_format - PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB_Impl; - PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB_Impl; - PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB_Impl; - - // WGL_ARB_make_current_read - PFNWGLMAKECONTEXTCURRENTARBPROC wglMakeContextCurrentARB_Impl; - PFNWGLGETCURRENTREADDCARBPROC wglGetCurrentReadDCARB_Impl; - - // WGL_ARB_pbuffer - PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB_Impl; - PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB_Impl; - PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB_Impl; - PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB_Impl; - PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB_Impl; - - // WGL_ARB_render_texture - PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB_Impl; - PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB_Impl; - PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB_Impl; - - // WGL_ARB_pixel_format_float - // (no functions) - - // WGL_ARB_framebuffer_sRGB - // (no functions) - - // WGL_NV_present_video - PFNWGLENUMERATEVIDEODEVICESNVPROC wglEnumerateVideoDevicesNV_Impl; - PFNWGLBINDVIDEODEVICENVPROC wglBindVideoDeviceNV_Impl; - PFNWGLQUERYCURRENTCONTEXTNVPROC wglQueryCurrentContextNV_Impl; - - // WGL_ARB_create_context - PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB_Impl; - - // WGL_ARB_create_context_profile - // (no functions) - - // WGL_ARB_create_context_robustness - // (no functions) - - // WGL_EXT_extensions_string - PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT_Impl; - - // WGL_EXT_swap_control - PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT_Impl; - PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT_Impl; - - // WGL_OML_sync_control - PFNWGLGETSYNCVALUESOMLPROC wglGetSyncValuesOML_Impl; - PFNWGLGETMSCRATEOMLPROC wglGetMscRateOML_Impl; - PFNWGLSWAPBUFFERSMSCOMLPROC wglSwapBuffersMscOML_Impl; - PFNWGLSWAPLAYERBUFFERSMSCOMLPROC wglSwapLayerBuffersMscOML_Impl; - PFNWGLWAITFORMSCOMLPROC wglWaitForMscOML_Impl; - PFNWGLWAITFORSBCOMLPROC wglWaitForSbcOML_Impl; - - // WGL_NV_video_output - PFNWGLGETVIDEODEVICENVPROC wglGetVideoDeviceNV_Impl; - PFNWGLRELEASEVIDEODEVICENVPROC wglReleaseVideoDeviceNV_Impl; - PFNWGLBINDVIDEOIMAGENVPROC wglBindVideoImageNV_Impl; - PFNWGLRELEASEVIDEOIMAGENVPROC wglReleaseVideoImageNV_Impl; - PFNWGLSENDPBUFFERTOVIDEONVPROC wglSendPbufferToVideoNV_Impl; - PFNWGLGETVIDEOINFONVPROC wglGetVideoInfoNV_Impl; - - // WGL_NV_swap_group - PFNWGLJOINSWAPGROUPNVPROC wglJoinSwapGroupNV_Impl; - PFNWGLBINDSWAPBARRIERNVPROC wglBindSwapBarrierNV_Impl; - PFNWGLQUERYSWAPGROUPNVPROC wglQuerySwapGroupNV_Impl; - PFNWGLQUERYMAXSWAPGROUPSNVPROC wglQueryMaxSwapGroupsNV_Impl; - PFNWGLQUERYFRAMECOUNTNVPROC wglQueryFrameCountNV_Impl; - PFNWGLRESETFRAMECOUNTNVPROC wglResetFrameCountNV_Impl; - - // WGL_NV_video_capture - PFNWGLBINDVIDEOCAPTUREDEVICENVPROC wglBindVideoCaptureDeviceNV_Impl; - PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC wglEnumerateVideoCaptureDevicesNV_Impl; - PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC wglLockVideoCaptureDeviceNV_Impl; - PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC wglQueryVideoCaptureDeviceNV_Impl; - PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC wglReleaseVideoCaptureDeviceNV_Impl; - - // WGL_NV_copy_image - PFNWGLCOPYIMAGESUBDATANVPROC wglCopyImageSubDataNV_Impl; - - // WGL_NV_DX_interop - PFNWGLDXCLOSEDEVICENVPROC wglDXCloseDeviceNV_Impl; - PFNWGLDXLOCKOBJECTSNVPROC wglDXLockObjectsNV_Impl; - PFNWGLDXOBJECTACCESSNVPROC wglDXObjectAccessNV_Impl; - PFNWGLDXOPENDEVICENVPROC wglDXOpenDeviceNV_Impl; - PFNWGLDXREGISTEROBJECTNVPROC wglDXRegisterObjectNV_Impl; - PFNWGLDXSETRESOURCESHAREHANDLENVPROC wglDXSetResourceShareHandleNV_Impl; - PFNWGLDXUNLOCKOBJECTSNVPROC wglDXUnlockObjectsNV_Impl; - PFNWGLDXUNREGISTEROBJECTNVPROC wglDXUnregisterObjectNV_Impl; - - #endif // GLE_WGL_ENABLED - - #if defined(GLE_GLX_ENABLED) - // GLX_VERSION_1_1 - // We don't create any pointers, because we assume these functions are always present. - - // GLX_VERSION_1_2 - PFNGLXGETCURRENTDISPLAYPROC glXGetCurrentDisplay_Impl; - - // GLX_VERSION_1_3 - PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig_Impl; - PFNGLXCREATENEWCONTEXTPROC glXCreateNewContext_Impl; - PFNGLXCREATEPBUFFERPROC glXCreatePbuffer_Impl; - PFNGLXCREATEPIXMAPPROC glXCreatePixmap_Impl; - PFNGLXCREATEWINDOWPROC glXCreateWindow_Impl; - PFNGLXDESTROYPBUFFERPROC glXDestroyPbuffer_Impl; - PFNGLXDESTROYPIXMAPPROC glXDestroyPixmap_Impl; - PFNGLXDESTROYWINDOWPROC glXDestroyWindow_Impl; - PFNGLXGETCURRENTREADDRAWABLEPROC glXGetCurrentReadDrawable_Impl; - PFNGLXGETFBCONFIGATTRIBPROC glXGetFBConfigAttrib_Impl; - PFNGLXGETFBCONFIGSPROC glXGetFBConfigs_Impl; - PFNGLXGETSELECTEDEVENTPROC glXGetSelectedEvent_Impl; - PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfig_Impl; - PFNGLXMAKECONTEXTCURRENTPROC glXMakeContextCurrent_Impl; - PFNGLXQUERYCONTEXTPROC glXQueryContext_Impl; - PFNGLXQUERYDRAWABLEPROC glXQueryDrawable_Impl; - PFNGLXSELECTEVENTPROC glXSelectEvent_Impl; - - // GLX_VERSION_1_4 - // Nothing to declare - - // GLX_ARB_create_context - PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB_Impl; - - // GLX_EXT_swap_control - PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT_Impl; - - // GLX_OML_sync_control - PFNGLXGETMSCRATEOMLPROC glXGetMscRateOML_Impl; - PFNGLXGETSYNCVALUESOMLPROC glXGetSyncValuesOML_Impl; - PFNGLXSWAPBUFFERSMSCOMLPROC glXSwapBuffersMscOML_Impl; - PFNGLXWAITFORMSCOMLPROC glXWaitForMscOML_Impl; - PFNGLXWAITFORSBCOMLPROC glXWaitForSbcOML_Impl; - - // GLX_MESA_swap_control - PFNGLXGETSWAPINTERVALMESAPROC glXGetSwapIntervalMESA_Impl; - PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA_Impl; - - #endif // GLE_GLX_ENABLED - - - // Boolean extension support indicators. Each of these identifies the - // presence or absence of the given extension. A better solution here - // might be to use an STL map. - bool gle_AMD_debug_output; - //bool gle_AMD_performance_monitor; - bool gle_APPLE_aux_depth_stencil; - bool gle_APPLE_client_storage; - bool gle_APPLE_element_array; - bool gle_APPLE_fence; - bool gle_APPLE_float_pixels; - bool gle_APPLE_flush_buffer_range; - bool gle_APPLE_object_purgeable; - bool gle_APPLE_pixel_buffer; - bool gle_APPLE_rgb_422; - bool gle_APPLE_row_bytes; - bool gle_APPLE_specular_vector; - bool gle_APPLE_texture_range; - bool gle_APPLE_transform_hint; - bool gle_APPLE_vertex_array_object; - bool gle_APPLE_vertex_array_range; - bool gle_APPLE_vertex_program_evaluators; - bool gle_APPLE_ycbcr_422; - bool gle_ARB_debug_output; - bool gle_ARB_depth_buffer_float; - //bool gle_ARB_direct_state_access; - bool gle_ARB_ES2_compatibility; - bool gle_ARB_framebuffer_object; - bool gle_ARB_framebuffer_sRGB; - bool gle_ARB_texture_multisample; - bool gle_ARB_texture_non_power_of_two; - bool gle_ARB_texture_rectangle; - bool gle_ARB_timer_query; - bool gle_ARB_vertex_array_object; - //bool gle_ARB_vertex_attrib_binding; - bool gle_EXT_draw_buffers2; - bool gle_EXT_texture_compression_s3tc; - bool gle_EXT_texture_filter_anisotropic; - //bool gle_KHR_context_flush_control; - bool gle_KHR_debug; - //bool gle_KHR_robust_buffer_access_behavior; - //bool gle_KHR_robustness; - bool gle_WIN_swap_hint; - - #if defined(GLE_WGL_ENABLED) - bool gle_WGL_ARB_buffer_region; - bool gle_WGL_ARB_create_context; - bool gle_WGL_ARB_create_context_profile; - bool gle_WGL_ARB_create_context_robustness; - bool gle_WGL_ARB_extensions_string; - bool gle_WGL_ARB_framebuffer_sRGB; - bool gle_WGL_ARB_make_current_read; - bool gle_WGL_ARB_pbuffer; - bool gle_WGL_ARB_pixel_format; - bool gle_WGL_ARB_pixel_format_float; - bool gle_WGL_ARB_render_texture; - bool gle_WGL_ATI_render_texture_rectangle; - bool gle_WGL_EXT_extensions_string; - bool gle_WGL_EXT_swap_control; - bool gle_WGL_NV_copy_image; - bool gle_WGL_NV_DX_interop; - bool gle_WGL_NV_DX_interop2; - bool gle_WGL_NV_present_video; - bool gle_WGL_NV_render_texture_rectangle; - bool gle_WGL_NV_swap_group; - bool gle_WGL_NV_video_capture; - bool gle_WGL_NV_video_output; - bool gle_WGL_OML_sync_control; - #elif defined(GLE_GLX_ENABLED) - bool gle_GLX_ARB_create_context; - bool gle_GLX_ARB_create_context_profile; - bool gle_GLX_ARB_create_context_robustness; - bool gle_GLX_EXT_swap_control; - bool gle_GLX_OML_sync_control; - bool gle_MESA_swap_control; - #endif - - }; // class GLEContext - - -} // namespace OVR - - -#endif // Header include guard diff --git a/LibOVR/Src/CAPI/GL/CAPI_GLE_GL.h b/LibOVR/Src/CAPI/GL/CAPI_GLE_GL.h deleted file mode 100644 index 2c3256d..0000000 --- a/LibOVR/Src/CAPI/GL/CAPI_GLE_GL.h +++ /dev/null @@ -1,4761 +0,0 @@ -/************************************************************************************ - -Filename : CAPI_GLE_GL.h -Content : GL extensions declarations. -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - - -#ifndef INC_OVR_CAPI_GLE_GL_h -#define INC_OVR_CAPI_GLE_GL_h - - -#include - - -// Windows headers -// Windows-specific OpenGL 1.1 interfaces. Long ago this was . -// OpenGL 1.1 interface. -// OpenGL 1.2+ compatibility profile and extension interfaces. Not provided by Microsoft. -// Windows-specific extension interfaces. Not provided by Microsoft. -// OpenGL core profile and ARB extension interfaces. Doesn't include interfaces found only in the compatibility profile. Overlaps with gl.h and glext.h. -// -// Mac headers -// OpenGL 1.1 interface. -// OpenGL 1.2+ compatibility profile and extension interfaces. -// Includes only interfaces supported in a core OpenGL 3.1 implementations plus a few related extensions. -// Includes extensions supported in a core OpenGL 3.1 implementation. -// Apple-specific OpenGL interfaces. -// Apple-specific OpenGL interfaces. -// -// Linux headers -// OpenGL 1.1 interface. -// OpenGL 1.2+ compatibility profile and extension interfaces. -// X Windows-specific OpenGL interfaces. -// X Windows 1.3+ API and GLX extension interfaces. -// OpenGL core profile and ARB extension interfaces. Doesn't include interfaces found only in the compatibility profile. Overlaps with gl.h and glext.h. - -#if defined(__gl_h_) || defined(__GL_H__) || defined(__X_GL_H) - #error gl.h should be included after this, not before. -#endif -#if defined(__gl2_h_) - #error gl2.h should be included after this, not before. -#endif -#if defined(__gltypes_h_) - #error gltypes.h should be included after this, not before. -#endif -#if defined(__glext_h_) || defined(__GLEXT_H_) - #error glext.h should be included after this, not before. -#endif - -// Prevent other GL versions from being included in the future. -// We do not disable Microsoft's wingdi.h and redeclare its functions. That's a big header that includes many other things. -// We do not currently disable Apple's OpenGL/OpenGL.h, though we could if we replicated its declarations in this header file. -#define __gl_h_ // Disable future #includes of Apple's -#define __GL_H__ // Disable future #includes of Microsoft's -#define __X_GL_H // etc. -#define __gl2_h_ -#define __gltypes_h_ -#define __glext_h_ -#define __GLEXT_H_ - - -// GLE platform identification -#if defined(_WIN32) - #define GLE_WGL_ENABLED 1 // WGL interface -#elif defined(__ANDROID__) - #define GLE_EGL_ENABLED 1 // EGL interface -#elif defined(__IPHONE__) - #define GLE_EAGL_ENABLED 1 // EAGL interface -#elif defined(__APPLE__) - #define GLE_CGL_ENABLED 1 // CGL interface -#else - #define GLE_GLX_ENABLED 1 // GLX interface -#endif - - -// GLAPI / GLAPIENTRY -// -// GLAPI is a wrapper for Microsoft __declspec(dllimport). -// GLAPIENTRY is the calling convention (__stdcall under Microsoft). -// -#if defined(GLE_WGL_ENABLED) - #if !defined(WINAPI) - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN 1 - #endif - #include - #undef WIN32_LEAN_AND_MEAN - #endif - - #ifndef WINGDIAPI // Normally defined via windows.h - #define WINGDIAPI __declspec(dllimport) - #define GLE_WINGDIAPI_DEFINED // We define this so that we can know to undefine WINGDIAPI at the end of this file. - #endif - - #if !defined(GLAPI) - #if defined(__MINGW32__) || defined(__CYGWIN__) - #define GLAPI extern - #else - #define GLAPI WINGDIAPI - #endif - #endif - #if !defined(GLAPIENTRY) - #define GLAPIENTRY __stdcall - #endif -#else - #include - - #define GLAPI extern - #define GLAPIENTRY /* empty */ -#endif - - -// GLE_CLASS_EXPORT -// Possibly maps to Microsoft __declspec(dllexport) or nothing on other platforms. -#define GLE_CLASS_EXPORT // Currently defined to nothing. Could be defined to a dll export type. - - - -// GLE_HOOKING_ENABLED -// When enabled, we intercept all OpenGL calls and do any useful internal processing before or after the call. -// An example use case for this is to intercept OpenGL errors on platforms that don't support the OpenGL -// debug functionality (e.g. KHR_Debug). -#if !defined(GLE_WGL_ENABLED) && !defined(GLE_GLX_ENABLED) && defined(OVR_BUILD_DEBUG) // Windows and Unix don't need it because they have OpenGL debug extension support (e.g. KHR_Debug). - #define GLE_HOOKING_ENABLED 1 -#endif - -// When using hooking, we map all OpenGL function usage to our member functions that end with _Hook. -// These member hook functions will internally call the actual OpenGL functions after doing some internal processing. -#if defined(GLE_HOOKING_ENABLED) - #define GLEGetCurrentFunction(x) GLEContext::GetCurrentContext()->x##_Hook - #define GLEGetCurrentVariable(x) GLEContext::GetCurrentContext()->x -#else - #define GLEGetCurrentFunction(x) GLEContext::GetCurrentContext()->x##_Impl - #define GLEGetCurrentVariable(x) GLEContext::GetCurrentContext()->x -#endif - -// GLE_CURRENT_FUNCTION -// Used by hooking in debug builds. -#if defined(OVR_BUILD_DEBUG) - #define GLE_CURRENT_FUNCTION __FUNCTION__ -#else - #define GLE_CURRENT_FUNCTION NULL -#endif - - -// GLE_WHOLE_VERSION -// Returns the major+minor version of the current GLEContext. -// Example usage: -// if(GLE_WHOLE_VERSION() >= 302) // If OpenGL 3.2 or later... -// ... -#define GLE_WHOLE_VERSION() GLEContext::GetCurrentContext()->WholeVersion() - - - -#ifdef __cplusplus -extern "C" { -#endif - - -// OpenGL 1.1 declarations are present in all versions of gl.h, including Microsoft's. -// You don't need to dynamically link to these functions on any platform and can just assume -// they are present. A number of these functions have been deprecated by OpenGL v3+, and -// if an OpenGL v3+ core profile is enabled then usage of the deprecated functions is an error. - -#ifndef GL_VERSION_1_1 - #define GL_VERSION_1_1 1 - - typedef unsigned int GLenum; - typedef unsigned int GLbitfield; - typedef unsigned int GLuint; - typedef int GLint; - typedef int GLsizei; - typedef unsigned char GLboolean; - typedef signed char GLbyte; - typedef short GLshort; - typedef unsigned char GLubyte; - typedef unsigned short GLushort; - typedef unsigned long GLulong; - typedef float GLfloat; - typedef float GLclampf; - typedef double GLdouble; - typedef double GLclampd; - typedef void GLvoid; - typedef int64_t GLint64EXT; - typedef uint64_t GLuint64EXT; - typedef GLint64EXT GLint64; - typedef GLuint64EXT GLuint64; - typedef struct __GLsync *GLsync; - typedef char GLchar; - - #define GL_ZERO 0 - #define GL_FALSE 0 - #define GL_LOGIC_OP 0x0BF1 - #define GL_NONE 0 - #define GL_TEXTURE_COMPONENTS 0x1003 - #define GL_NO_ERROR 0 - #define GL_POINTS 0x0000 - #define GL_CURRENT_BIT 0x00000001 - #define GL_TRUE 1 - #define GL_ONE 1 - #define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 - #define GL_LINES 0x0001 - #define GL_LINE_LOOP 0x0002 - #define GL_POINT_BIT 0x00000002 - #define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 - #define GL_LINE_STRIP 0x0003 - #define GL_LINE_BIT 0x00000004 - #define GL_TRIANGLES 0x0004 - #define GL_TRIANGLE_STRIP 0x0005 - #define GL_TRIANGLE_FAN 0x0006 - #define GL_QUADS 0x0007 - #define GL_QUAD_STRIP 0x0008 - #define GL_POLYGON_BIT 0x00000008 - #define GL_POLYGON 0x0009 - #define GL_POLYGON_STIPPLE_BIT 0x00000010 - #define GL_PIXEL_MODE_BIT 0x00000020 - #define GL_LIGHTING_BIT 0x00000040 - #define GL_FOG_BIT 0x00000080 - #define GL_DEPTH_BUFFER_BIT 0x00000100 - #define GL_ACCUM 0x0100 - #define GL_LOAD 0x0101 - #define GL_RETURN 0x0102 - #define GL_MULT 0x0103 - #define GL_ADD 0x0104 - #define GL_NEVER 0x0200 - #define GL_ACCUM_BUFFER_BIT 0x00000200 - #define GL_LESS 0x0201 - #define GL_EQUAL 0x0202 - #define GL_LEQUAL 0x0203 - #define GL_GREATER 0x0204 - #define GL_NOTEQUAL 0x0205 - #define GL_GEQUAL 0x0206 - #define GL_ALWAYS 0x0207 - #define GL_SRC_COLOR 0x0300 - #define GL_ONE_MINUS_SRC_COLOR 0x0301 - #define GL_SRC_ALPHA 0x0302 - #define GL_ONE_MINUS_SRC_ALPHA 0x0303 - #define GL_DST_ALPHA 0x0304 - #define GL_ONE_MINUS_DST_ALPHA 0x0305 - #define GL_DST_COLOR 0x0306 - #define GL_ONE_MINUS_DST_COLOR 0x0307 - #define GL_SRC_ALPHA_SATURATE 0x0308 - #define GL_STENCIL_BUFFER_BIT 0x00000400 - #define GL_FRONT_LEFT 0x0400 - #define GL_FRONT_RIGHT 0x0401 - #define GL_BACK_LEFT 0x0402 - #define GL_BACK_RIGHT 0x0403 - #define GL_FRONT 0x0404 - #define GL_BACK 0x0405 - #define GL_LEFT 0x0406 - #define GL_RIGHT 0x0407 - #define GL_FRONT_AND_BACK 0x0408 - #define GL_AUX0 0x0409 - #define GL_AUX1 0x040A - #define GL_AUX2 0x040B - #define GL_AUX3 0x040C - #define GL_INVALID_ENUM 0x0500 - #define GL_INVALID_VALUE 0x0501 - #define GL_INVALID_OPERATION 0x0502 - #define GL_STACK_OVERFLOW 0x0503 - #define GL_STACK_UNDERFLOW 0x0504 - #define GL_OUT_OF_MEMORY 0x0505 - #define GL_2D 0x0600 - #define GL_3D 0x0601 - #define GL_3D_COLOR 0x0602 - #define GL_3D_COLOR_TEXTURE 0x0603 - #define GL_4D_COLOR_TEXTURE 0x0604 - #define GL_PASS_THROUGH_TOKEN 0x0700 - #define GL_POINT_TOKEN 0x0701 - #define GL_LINE_TOKEN 0x0702 - #define GL_POLYGON_TOKEN 0x0703 - #define GL_BITMAP_TOKEN 0x0704 - #define GL_DRAW_PIXEL_TOKEN 0x0705 - #define GL_COPY_PIXEL_TOKEN 0x0706 - #define GL_LINE_RESET_TOKEN 0x0707 - #define GL_EXP 0x0800 - #define GL_VIEWPORT_BIT 0x00000800 - #define GL_EXP2 0x0801 - #define GL_CW 0x0900 - #define GL_CCW 0x0901 - #define GL_COEFF 0x0A00 - #define GL_ORDER 0x0A01 - #define GL_DOMAIN 0x0A02 - #define GL_CURRENT_COLOR 0x0B00 - #define GL_CURRENT_INDEX 0x0B01 - #define GL_CURRENT_NORMAL 0x0B02 - #define GL_CURRENT_TEXTURE_COORDS 0x0B03 - #define GL_CURRENT_RASTER_COLOR 0x0B04 - #define GL_CURRENT_RASTER_INDEX 0x0B05 - #define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 - #define GL_CURRENT_RASTER_POSITION 0x0B07 - #define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 - #define GL_CURRENT_RASTER_DISTANCE 0x0B09 - #define GL_POINT_SMOOTH 0x0B10 - #define GL_POINT_SIZE 0x0B11 - #define GL_POINT_SIZE_RANGE 0x0B12 - #define GL_POINT_SIZE_GRANULARITY 0x0B13 - #define GL_LINE_SMOOTH 0x0B20 - #define GL_LINE_WIDTH 0x0B21 - #define GL_LINE_WIDTH_RANGE 0x0B22 - #define GL_LINE_WIDTH_GRANULARITY 0x0B23 - #define GL_LINE_STIPPLE 0x0B24 - #define GL_LINE_STIPPLE_PATTERN 0x0B25 - #define GL_LINE_STIPPLE_REPEAT 0x0B26 - #define GL_LIST_MODE 0x0B30 - #define GL_MAX_LIST_NESTING 0x0B31 - #define GL_LIST_BASE 0x0B32 - #define GL_LIST_INDEX 0x0B33 - #define GL_POLYGON_MODE 0x0B40 - #define GL_POLYGON_SMOOTH 0x0B41 - #define GL_POLYGON_STIPPLE 0x0B42 - #define GL_EDGE_FLAG 0x0B43 - #define GL_CULL_FACE 0x0B44 - #define GL_CULL_FACE_MODE 0x0B45 - #define GL_FRONT_FACE 0x0B46 - #define GL_LIGHTING 0x0B50 - #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 - #define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 - #define GL_LIGHT_MODEL_AMBIENT 0x0B53 - #define GL_SHADE_MODEL 0x0B54 - #define GL_COLOR_MATERIAL_FACE 0x0B55 - #define GL_COLOR_MATERIAL_PARAMETER 0x0B56 - #define GL_COLOR_MATERIAL 0x0B57 - #define GL_FOG 0x0B60 - #define GL_FOG_INDEX 0x0B61 - #define GL_FOG_DENSITY 0x0B62 - #define GL_FOG_START 0x0B63 - #define GL_FOG_END 0x0B64 - #define GL_FOG_MODE 0x0B65 - #define GL_FOG_COLOR 0x0B66 - #define GL_DEPTH_RANGE 0x0B70 - #define GL_DEPTH_TEST 0x0B71 - #define GL_DEPTH_WRITEMASK 0x0B72 - #define GL_DEPTH_CLEAR_VALUE 0x0B73 - #define GL_DEPTH_FUNC 0x0B74 - #define GL_ACCUM_CLEAR_VALUE 0x0B80 - #define GL_STENCIL_TEST 0x0B90 - #define GL_STENCIL_CLEAR_VALUE 0x0B91 - #define GL_STENCIL_FUNC 0x0B92 - #define GL_STENCIL_VALUE_MASK 0x0B93 - #define GL_STENCIL_FAIL 0x0B94 - #define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 - #define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 - #define GL_STENCIL_REF 0x0B97 - #define GL_STENCIL_WRITEMASK 0x0B98 - #define GL_MATRIX_MODE 0x0BA0 - #define GL_NORMALIZE 0x0BA1 - #define GL_VIEWPORT 0x0BA2 - #define GL_MODELVIEW_STACK_DEPTH 0x0BA3 - #define GL_PROJECTION_STACK_DEPTH 0x0BA4 - #define GL_TEXTURE_STACK_DEPTH 0x0BA5 - #define GL_MODELVIEW_MATRIX 0x0BA6 - #define GL_PROJECTION_MATRIX 0x0BA7 - #define GL_TEXTURE_MATRIX 0x0BA8 - #define GL_ATTRIB_STACK_DEPTH 0x0BB0 - #define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 - #define GL_ALPHA_TEST 0x0BC0 - #define GL_ALPHA_TEST_FUNC 0x0BC1 - #define GL_ALPHA_TEST_REF 0x0BC2 - #define GL_DITHER 0x0BD0 - #define GL_BLEND_DST 0x0BE0 - #define GL_BLEND_SRC 0x0BE1 - #define GL_BLEND 0x0BE2 - #define GL_LOGIC_OP_MODE 0x0BF0 - #define GL_INDEX_LOGIC_OP 0x0BF1 - #define GL_COLOR_LOGIC_OP 0x0BF2 - #define GL_AUX_BUFFERS 0x0C00 - #define GL_DRAW_BUFFER 0x0C01 - #define GL_READ_BUFFER 0x0C02 - #define GL_SCISSOR_BOX 0x0C10 - #define GL_SCISSOR_TEST 0x0C11 - #define GL_INDEX_CLEAR_VALUE 0x0C20 - #define GL_INDEX_WRITEMASK 0x0C21 - #define GL_COLOR_CLEAR_VALUE 0x0C22 - #define GL_COLOR_WRITEMASK 0x0C23 - #define GL_INDEX_MODE 0x0C30 - #define GL_RGBA_MODE 0x0C31 - #define GL_DOUBLEBUFFER 0x0C32 - #define GL_STEREO 0x0C33 - #define GL_RENDER_MODE 0x0C40 - #define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 - #define GL_POINT_SMOOTH_HINT 0x0C51 - #define GL_LINE_SMOOTH_HINT 0x0C52 - #define GL_POLYGON_SMOOTH_HINT 0x0C53 - #define GL_FOG_HINT 0x0C54 - #define GL_TEXTURE_GEN_S 0x0C60 - #define GL_TEXTURE_GEN_T 0x0C61 - #define GL_TEXTURE_GEN_R 0x0C62 - #define GL_TEXTURE_GEN_Q 0x0C63 - #define GL_PIXEL_MAP_I_TO_I 0x0C70 - #define GL_PIXEL_MAP_S_TO_S 0x0C71 - #define GL_PIXEL_MAP_I_TO_R 0x0C72 - #define GL_PIXEL_MAP_I_TO_G 0x0C73 - #define GL_PIXEL_MAP_I_TO_B 0x0C74 - #define GL_PIXEL_MAP_I_TO_A 0x0C75 - #define GL_PIXEL_MAP_R_TO_R 0x0C76 - #define GL_PIXEL_MAP_G_TO_G 0x0C77 - #define GL_PIXEL_MAP_B_TO_B 0x0C78 - #define GL_PIXEL_MAP_A_TO_A 0x0C79 - #define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 - #define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 - #define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 - #define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 - #define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 - #define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 - #define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 - #define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 - #define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 - #define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 - #define GL_UNPACK_SWAP_BYTES 0x0CF0 - #define GL_UNPACK_LSB_FIRST 0x0CF1 - #define GL_UNPACK_ROW_LENGTH 0x0CF2 - #define GL_UNPACK_SKIP_ROWS 0x0CF3 - #define GL_UNPACK_SKIP_PIXELS 0x0CF4 - #define GL_UNPACK_ALIGNMENT 0x0CF5 - #define GL_PACK_SWAP_BYTES 0x0D00 - #define GL_PACK_LSB_FIRST 0x0D01 - #define GL_PACK_ROW_LENGTH 0x0D02 - #define GL_PACK_SKIP_ROWS 0x0D03 - #define GL_PACK_SKIP_PIXELS 0x0D04 - #define GL_PACK_ALIGNMENT 0x0D05 - #define GL_MAP_COLOR 0x0D10 - #define GL_MAP_STENCIL 0x0D11 - #define GL_INDEX_SHIFT 0x0D12 - #define GL_INDEX_OFFSET 0x0D13 - #define GL_RED_SCALE 0x0D14 - #define GL_RED_BIAS 0x0D15 - #define GL_ZOOM_X 0x0D16 - #define GL_ZOOM_Y 0x0D17 - #define GL_GREEN_SCALE 0x0D18 - #define GL_GREEN_BIAS 0x0D19 - #define GL_BLUE_SCALE 0x0D1A - #define GL_BLUE_BIAS 0x0D1B - #define GL_ALPHA_SCALE 0x0D1C - #define GL_ALPHA_BIAS 0x0D1D - #define GL_DEPTH_SCALE 0x0D1E - #define GL_DEPTH_BIAS 0x0D1F - #define GL_MAX_EVAL_ORDER 0x0D30 - #define GL_MAX_LIGHTS 0x0D31 - #define GL_MAX_CLIP_PLANES 0x0D32 - #define GL_MAX_TEXTURE_SIZE 0x0D33 - #define GL_MAX_PIXEL_MAP_TABLE 0x0D34 - #define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 - #define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 - #define GL_MAX_NAME_STACK_DEPTH 0x0D37 - #define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 - #define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 - #define GL_MAX_VIEWPORT_DIMS 0x0D3A - #define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B - #define GL_SUBPIXEL_BITS 0x0D50 - #define GL_INDEX_BITS 0x0D51 - #define GL_RED_BITS 0x0D52 - #define GL_GREEN_BITS 0x0D53 - #define GL_BLUE_BITS 0x0D54 - #define GL_ALPHA_BITS 0x0D55 - #define GL_DEPTH_BITS 0x0D56 - #define GL_STENCIL_BITS 0x0D57 - #define GL_ACCUM_RED_BITS 0x0D58 - #define GL_ACCUM_GREEN_BITS 0x0D59 - #define GL_ACCUM_BLUE_BITS 0x0D5A - #define GL_ACCUM_ALPHA_BITS 0x0D5B - #define GL_NAME_STACK_DEPTH 0x0D70 - #define GL_AUTO_NORMAL 0x0D80 - #define GL_MAP1_COLOR_4 0x0D90 - #define GL_MAP1_INDEX 0x0D91 - #define GL_MAP1_NORMAL 0x0D92 - #define GL_MAP1_TEXTURE_COORD_1 0x0D93 - #define GL_MAP1_TEXTURE_COORD_2 0x0D94 - #define GL_MAP1_TEXTURE_COORD_3 0x0D95 - #define GL_MAP1_TEXTURE_COORD_4 0x0D96 - #define GL_MAP1_VERTEX_3 0x0D97 - #define GL_MAP1_VERTEX_4 0x0D98 - #define GL_MAP2_COLOR_4 0x0DB0 - #define GL_MAP2_INDEX 0x0DB1 - #define GL_MAP2_NORMAL 0x0DB2 - #define GL_MAP2_TEXTURE_COORD_1 0x0DB3 - #define GL_MAP2_TEXTURE_COORD_2 0x0DB4 - #define GL_MAP2_TEXTURE_COORD_3 0x0DB5 - #define GL_MAP2_TEXTURE_COORD_4 0x0DB6 - #define GL_MAP2_VERTEX_3 0x0DB7 - #define GL_MAP2_VERTEX_4 0x0DB8 - #define GL_MAP1_GRID_DOMAIN 0x0DD0 - #define GL_MAP1_GRID_SEGMENTS 0x0DD1 - #define GL_MAP2_GRID_DOMAIN 0x0DD2 - #define GL_MAP2_GRID_SEGMENTS 0x0DD3 - #define GL_TEXTURE_1D 0x0DE0 - #define GL_TEXTURE_2D 0x0DE1 - #define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 - #define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 - #define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 - #define GL_SELECTION_BUFFER_POINTER 0x0DF3 - #define GL_SELECTION_BUFFER_SIZE 0x0DF4 - #define GL_TEXTURE_WIDTH 0x1000 - #define GL_TRANSFORM_BIT 0x00001000 - #define GL_TEXTURE_HEIGHT 0x1001 - #define GL_TEXTURE_INTERNAL_FORMAT 0x1003 - #define GL_TEXTURE_BORDER_COLOR 0x1004 - #define GL_TEXTURE_BORDER 0x1005 - #define GL_DONT_CARE 0x1100 - #define GL_FASTEST 0x1101 - #define GL_NICEST 0x1102 - #define GL_AMBIENT 0x1200 - #define GL_DIFFUSE 0x1201 - #define GL_SPECULAR 0x1202 - #define GL_POSITION 0x1203 - #define GL_SPOT_DIRECTION 0x1204 - #define GL_SPOT_EXPONENT 0x1205 - #define GL_SPOT_CUTOFF 0x1206 - #define GL_CONSTANT_ATTENUATION 0x1207 - #define GL_LINEAR_ATTENUATION 0x1208 - #define GL_QUADRATIC_ATTENUATION 0x1209 - #define GL_COMPILE 0x1300 - #define GL_COMPILE_AND_EXECUTE 0x1301 - #define GL_BYTE 0x1400 - #define GL_UNSIGNED_BYTE 0x1401 - #define GL_SHORT 0x1402 - #define GL_UNSIGNED_SHORT 0x1403 - #define GL_INT 0x1404 - #define GL_UNSIGNED_INT 0x1405 - #define GL_FLOAT 0x1406 - #define GL_2_BYTES 0x1407 - #define GL_3_BYTES 0x1408 - #define GL_4_BYTES 0x1409 - #define GL_DOUBLE 0x140A - #define GL_CLEAR 0x1500 - #define GL_AND 0x1501 - #define GL_AND_REVERSE 0x1502 - #define GL_COPY 0x1503 - #define GL_AND_INVERTED 0x1504 - #define GL_NOOP 0x1505 - #define GL_XOR 0x1506 - #define GL_OR 0x1507 - #define GL_NOR 0x1508 - #define GL_EQUIV 0x1509 - #define GL_INVERT 0x150A - #define GL_OR_REVERSE 0x150B - #define GL_COPY_INVERTED 0x150C - #define GL_OR_INVERTED 0x150D - #define GL_NAND 0x150E - #define GL_SET 0x150F - #define GL_EMISSION 0x1600 - #define GL_SHININESS 0x1601 - #define GL_AMBIENT_AND_DIFFUSE 0x1602 - #define GL_COLOR_INDEXES 0x1603 - #define GL_MODELVIEW 0x1700 - #define GL_PROJECTION 0x1701 - #define GL_TEXTURE 0x1702 - #define GL_COLOR 0x1800 - #define GL_DEPTH 0x1801 - #define GL_STENCIL 0x1802 - #define GL_COLOR_INDEX 0x1900 - #define GL_STENCIL_INDEX 0x1901 - #define GL_DEPTH_COMPONENT 0x1902 - #define GL_RED 0x1903 - #define GL_GREEN 0x1904 - #define GL_BLUE 0x1905 - #define GL_ALPHA 0x1906 - #define GL_RGB 0x1907 - #define GL_RGBA 0x1908 - #define GL_LUMINANCE 0x1909 - #define GL_LUMINANCE_ALPHA 0x190A - #define GL_BITMAP 0x1A00 - #define GL_POINT 0x1B00 - #define GL_LINE 0x1B01 - #define GL_FILL 0x1B02 - #define GL_RENDER 0x1C00 - #define GL_FEEDBACK 0x1C01 - #define GL_SELECT 0x1C02 - #define GL_FLAT 0x1D00 - #define GL_SMOOTH 0x1D01 - #define GL_KEEP 0x1E00 - #define GL_REPLACE 0x1E01 - #define GL_INCR 0x1E02 - #define GL_DECR 0x1E03 - #define GL_VENDOR 0x1F00 - #define GL_RENDERER 0x1F01 - #define GL_VERSION 0x1F02 - #define GL_EXTENSIONS 0x1F03 - #define GL_S 0x2000 - #define GL_ENABLE_BIT 0x00002000 - #define GL_T 0x2001 - #define GL_R 0x2002 - #define GL_Q 0x2003 - #define GL_MODULATE 0x2100 - #define GL_DECAL 0x2101 - #define GL_TEXTURE_ENV_MODE 0x2200 - #define GL_TEXTURE_ENV_COLOR 0x2201 - #define GL_TEXTURE_ENV 0x2300 - #define GL_EYE_LINEAR 0x2400 - #define GL_OBJECT_LINEAR 0x2401 - #define GL_SPHERE_MAP 0x2402 - #define GL_TEXTURE_GEN_MODE 0x2500 - #define GL_OBJECT_PLANE 0x2501 - #define GL_EYE_PLANE 0x2502 - #define GL_NEAREST 0x2600 - #define GL_LINEAR 0x2601 - #define GL_NEAREST_MIPMAP_NEAREST 0x2700 - #define GL_LINEAR_MIPMAP_NEAREST 0x2701 - #define GL_NEAREST_MIPMAP_LINEAR 0x2702 - #define GL_LINEAR_MIPMAP_LINEAR 0x2703 - #define GL_TEXTURE_MAG_FILTER 0x2800 - #define GL_TEXTURE_MIN_FILTER 0x2801 - #define GL_TEXTURE_WRAP_S 0x2802 - #define GL_TEXTURE_WRAP_T 0x2803 - #define GL_CLAMP 0x2900 - #define GL_REPEAT 0x2901 - #define GL_POLYGON_OFFSET_UNITS 0x2A00 - #define GL_POLYGON_OFFSET_POINT 0x2A01 - #define GL_POLYGON_OFFSET_LINE 0x2A02 - #define GL_R3_G3_B2 0x2A10 - #define GL_V2F 0x2A20 - #define GL_V3F 0x2A21 - #define GL_C4UB_V2F 0x2A22 - #define GL_C4UB_V3F 0x2A23 - #define GL_C3F_V3F 0x2A24 - #define GL_N3F_V3F 0x2A25 - #define GL_C4F_N3F_V3F 0x2A26 - #define GL_T2F_V3F 0x2A27 - #define GL_T4F_V4F 0x2A28 - #define GL_T2F_C4UB_V3F 0x2A29 - #define GL_T2F_C3F_V3F 0x2A2A - #define GL_T2F_N3F_V3F 0x2A2B - #define GL_T2F_C4F_N3F_V3F 0x2A2C - #define GL_T4F_C4F_N3F_V4F 0x2A2D - #define GL_CLIP_PLANE0 0x3000 - #define GL_CLIP_PLANE1 0x3001 - #define GL_CLIP_PLANE2 0x3002 - #define GL_CLIP_PLANE3 0x3003 - #define GL_CLIP_PLANE4 0x3004 - #define GL_CLIP_PLANE5 0x3005 - #define GL_LIGHT0 0x4000 - #define GL_COLOR_BUFFER_BIT 0x00004000 - #define GL_LIGHT1 0x4001 - #define GL_LIGHT2 0x4002 - #define GL_LIGHT3 0x4003 - #define GL_LIGHT4 0x4004 - #define GL_LIGHT5 0x4005 - #define GL_LIGHT6 0x4006 - #define GL_LIGHT7 0x4007 - #define GL_HINT_BIT 0x00008000 - #define GL_POLYGON_OFFSET_FILL 0x8037 - #define GL_POLYGON_OFFSET_FACTOR 0x8038 - #define GL_ALPHA4 0x803B - #define GL_ALPHA8 0x803C - #define GL_ALPHA12 0x803D - #define GL_ALPHA16 0x803E - #define GL_LUMINANCE4 0x803F - #define GL_LUMINANCE8 0x8040 - #define GL_LUMINANCE12 0x8041 - #define GL_LUMINANCE16 0x8042 - #define GL_LUMINANCE4_ALPHA4 0x8043 - #define GL_LUMINANCE6_ALPHA2 0x8044 - #define GL_LUMINANCE8_ALPHA8 0x8045 - #define GL_LUMINANCE12_ALPHA4 0x8046 - #define GL_LUMINANCE12_ALPHA12 0x8047 - #define GL_LUMINANCE16_ALPHA16 0x8048 - #define GL_INTENSITY 0x8049 - #define GL_INTENSITY4 0x804A - #define GL_INTENSITY8 0x804B - #define GL_INTENSITY12 0x804C - #define GL_INTENSITY16 0x804D - #define GL_RGB4 0x804F - #define GL_RGB5 0x8050 - #define GL_RGB8 0x8051 - #define GL_RGB10 0x8052 - #define GL_RGB12 0x8053 - #define GL_RGB16 0x8054 - #define GL_RGBA2 0x8055 - #define GL_RGBA4 0x8056 - #define GL_RGB5_A1 0x8057 - #define GL_RGBA8 0x8058 - #define GL_RGB10_A2 0x8059 - #define GL_RGBA12 0x805A - #define GL_RGBA16 0x805B - #define GL_TEXTURE_RED_SIZE 0x805C - #define GL_TEXTURE_GREEN_SIZE 0x805D - #define GL_TEXTURE_BLUE_SIZE 0x805E - #define GL_TEXTURE_ALPHA_SIZE 0x805F - #define GL_TEXTURE_LUMINANCE_SIZE 0x8060 - #define GL_TEXTURE_INTENSITY_SIZE 0x8061 - #define GL_PROXY_TEXTURE_1D 0x8063 - #define GL_PROXY_TEXTURE_2D 0x8064 - #define GL_TEXTURE_PRIORITY 0x8066 - #define GL_TEXTURE_RESIDENT 0x8067 - #define GL_TEXTURE_BINDING_1D 0x8068 - #define GL_TEXTURE_BINDING_2D 0x8069 - #define GL_VERTEX_ARRAY 0x8074 - #define GL_NORMAL_ARRAY 0x8075 - #define GL_COLOR_ARRAY 0x8076 - #define GL_INDEX_ARRAY 0x8077 - #define GL_TEXTURE_COORD_ARRAY 0x8078 - #define GL_EDGE_FLAG_ARRAY 0x8079 - #define GL_VERTEX_ARRAY_SIZE 0x807A - #define GL_VERTEX_ARRAY_TYPE 0x807B - #define GL_VERTEX_ARRAY_STRIDE 0x807C - #define GL_NORMAL_ARRAY_TYPE 0x807E - #define GL_NORMAL_ARRAY_STRIDE 0x807F - #define GL_COLOR_ARRAY_SIZE 0x8081 - #define GL_COLOR_ARRAY_TYPE 0x8082 - #define GL_COLOR_ARRAY_STRIDE 0x8083 - #define GL_INDEX_ARRAY_TYPE 0x8085 - #define GL_INDEX_ARRAY_STRIDE 0x8086 - #define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 - #define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 - #define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A - #define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C - #define GL_VERTEX_ARRAY_POINTER 0x808E - #define GL_NORMAL_ARRAY_POINTER 0x808F - #define GL_COLOR_ARRAY_POINTER 0x8090 - #define GL_INDEX_ARRAY_POINTER 0x8091 - #define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 - #define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 - #define GL_COLOR_INDEX1_EXT 0x80E2 - #define GL_COLOR_INDEX2_EXT 0x80E3 - #define GL_COLOR_INDEX4_EXT 0x80E4 - #define GL_COLOR_INDEX8_EXT 0x80E5 - #define GL_COLOR_INDEX12_EXT 0x80E6 - #define GL_COLOR_INDEX16_EXT 0x80E7 - #define GL_EVAL_BIT 0x00010000 - #define GL_LIST_BIT 0x00020000 - #define GL_TEXTURE_BIT 0x00040000 - #define GL_SCISSOR_BIT 0x00080000 - #define GL_ALL_ATTRIB_BITS 0x000fffff - #define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff - - #if defined(GLE_HOOKING_ENABLED) - // In this case we map these functions to internal versions instead of the standard versions. - #define glAccum(...) GLEGetCurrentFunction(glAccum)(__VA_ARGS__) - #define glAlphaFunc(...) GLEGetCurrentFunction(glAlphaFunc)(__VA_ARGS__) - #define glAreTexturesResident(...) GLEGetCurrentFunction(glAreTexturesResident)(__VA_ARGS__) - #define glArrayElement(...) GLEGetCurrentFunction(glArrayElement)(__VA_ARGS__) - #define glBegin(...) GLEGetCurrentFunction(glBegin)(__VA_ARGS__) - #define glBindTexture(...) GLEGetCurrentFunction(glBindTexture)(__VA_ARGS__) - #define glBitmap(...) GLEGetCurrentFunction(glBitmap)(__VA_ARGS__) - #define glBlendFunc(...) GLEGetCurrentFunction(glBlendFunc)(__VA_ARGS__) - #define glCallList(...) GLEGetCurrentFunction(glCallList)(__VA_ARGS__) - #define glCallLists(...) GLEGetCurrentFunction(glCallLists)(__VA_ARGS__) - #define glClear(...) GLEGetCurrentFunction(glClear)(__VA_ARGS__) - #define glClearAccum(...) GLEGetCurrentFunction(glClearAccum)(__VA_ARGS__) - #define glClearColor(...) GLEGetCurrentFunction(glClearColor)(__VA_ARGS__) - #define glClearDepth(...) GLEGetCurrentFunction(glClearDepth)(__VA_ARGS__) - #define glClearIndex(...) GLEGetCurrentFunction(glClearIndex)(__VA_ARGS__) - #define glClearStencil(...) GLEGetCurrentFunction(glClearStencil)(__VA_ARGS__) - #define glClipPlane(...) GLEGetCurrentFunction(glClipPlane)(__VA_ARGS__) - #define glColor3b(...) GLEGetCurrentFunction(glColor3b)(__VA_ARGS__) - #define glColor3bv(...) GLEGetCurrentFunction(glColor3bv)(__VA_ARGS__) - #define glColor3d(...) GLEGetCurrentFunction(glColor3d)(__VA_ARGS__) - #define glColor3dv(...) GLEGetCurrentFunction(glColor3dv)(__VA_ARGS__) - #define glColor3f(...) GLEGetCurrentFunction(glColor3f)(__VA_ARGS__) - #define glColor3fv(...) GLEGetCurrentFunction(glColor3fv)(__VA_ARGS__) - #define glColor3i(...) GLEGetCurrentFunction(glColor3i)(__VA_ARGS__) - #define glColor3iv(...) GLEGetCurrentFunction(glColor3iv)(__VA_ARGS__) - #define glColor3s(...) GLEGetCurrentFunction(glColor3s)(__VA_ARGS__) - #define glColor3sv(...) GLEGetCurrentFunction(glColor3sv)(__VA_ARGS__) - #define glColor3ub(...) GLEGetCurrentFunction(glColor3ub)(__VA_ARGS__) - #define glColor3ubv(...) GLEGetCurrentFunction(glColor3ubv)(__VA_ARGS__) - #define glColor3ui(...) GLEGetCurrentFunction(glColor3ui)(__VA_ARGS__) - #define glColor3uiv(...) GLEGetCurrentFunction(glColor3uiv)(__VA_ARGS__) - #define glColor3us(...) GLEGetCurrentFunction(glColor3us)(__VA_ARGS__) - #define glColor3usv(...) GLEGetCurrentFunction(glColor3usv)(__VA_ARGS__) - #define glColor4b(...) GLEGetCurrentFunction(glColor4b)(__VA_ARGS__) - #define glColor4bv(...) GLEGetCurrentFunction(glColor4bv)(__VA_ARGS__) - #define glColor4d(...) GLEGetCurrentFunction(glColor4d)(__VA_ARGS__) - #define glColor4dv(...) GLEGetCurrentFunction(glColor4dv)(__VA_ARGS__) - #define glColor4f(...) GLEGetCurrentFunction(glColor4f)(__VA_ARGS__) - #define glColor4fv(...) GLEGetCurrentFunction(glColor4fv)(__VA_ARGS__) - #define glColor4i(...) GLEGetCurrentFunction(glColor4i)(__VA_ARGS__) - #define glColor4iv(...) GLEGetCurrentFunction(glColor4iv)(__VA_ARGS__) - #define glColor4s(...) GLEGetCurrentFunction(glColor4s)(__VA_ARGS__) - #define glColor4sv(...) GLEGetCurrentFunction(glColor4sv)(__VA_ARGS__) - #define glColor4ub(...) GLEGetCurrentFunction(glColor4ub)(__VA_ARGS__) - #define glColor4ubv(...) GLEGetCurrentFunction(glColor4ubv)(__VA_ARGS__) - #define glColor4ui(...) GLEGetCurrentFunction(glColor4ui)(__VA_ARGS__) - #define glColor4uiv(...) GLEGetCurrentFunction(glColor4uiv)(__VA_ARGS__) - #define glColor4us(...) GLEGetCurrentFunction(glColor4us)(__VA_ARGS__) - #define glColor4usv(...) GLEGetCurrentFunction(glColor4usv)(__VA_ARGS__) - #define glColorMask(...) GLEGetCurrentFunction(glColorMask)(__VA_ARGS__) - #define glColorMaterial(...) GLEGetCurrentFunction(glColorMaterial)(__VA_ARGS__) - #define glColorPointer(...) GLEGetCurrentFunction(glColorPointer)(__VA_ARGS__) - #define glCopyPixels(...) GLEGetCurrentFunction(glCopyPixels)(__VA_ARGS__) - #define glCopyTexImage1D(...) GLEGetCurrentFunction(glCopyTexImage1D)(__VA_ARGS__) - #define glCopyTexImage2D(...) GLEGetCurrentFunction(glCopyTexImage2D)(__VA_ARGS__) - #define glCopyTexSubImage1D(...) GLEGetCurrentFunction(glCopyTexSubImage1D)(__VA_ARGS__) - #define glCopyTexSubImage2D(...) GLEGetCurrentFunction(glCopyTexSubImage2D)(__VA_ARGS__) - #define glCullFace(...) GLEGetCurrentFunction(glCullFace)(__VA_ARGS__) - #define glDeleteLists(...) GLEGetCurrentFunction(glDeleteLists)(__VA_ARGS__) - #define glDeleteTextures(...) GLEGetCurrentFunction(glDeleteTextures)(__VA_ARGS__) - #define glDepthFunc(...) GLEGetCurrentFunction(glDepthFunc)(__VA_ARGS__) - #define glDepthMask(...) GLEGetCurrentFunction(glDepthMask)(__VA_ARGS__) - #define glDepthRange(...) GLEGetCurrentFunction(glDepthRange)(__VA_ARGS__) - #define glDisable(...) GLEGetCurrentFunction(glDisable)(__VA_ARGS__) - #define glDisableClientState(...) GLEGetCurrentFunction(glDisableClientState)(__VA_ARGS__) - #define glDrawArrays(...) GLEGetCurrentFunction(glDrawArrays)(__VA_ARGS__) - #define glDrawBuffer(...) GLEGetCurrentFunction(glDrawBuffer)(__VA_ARGS__) - #define glDrawElements(...) GLEGetCurrentFunction(glDrawElements)(__VA_ARGS__) - #define glDrawPixels(...) GLEGetCurrentFunction(glDrawPixels)(__VA_ARGS__) - #define glEdgeFlag(...) GLEGetCurrentFunction(glEdgeFlag)(__VA_ARGS__) - #define glEdgeFlagPointer(...) GLEGetCurrentFunction(glEdgeFlagPointer)(__VA_ARGS__) - #define glEdgeFlagv(...) GLEGetCurrentFunction(glEdgeFlagv)(__VA_ARGS__) - #define glEnable(...) GLEGetCurrentFunction(glEnable)(__VA_ARGS__) - #define glEnableClientState(...) GLEGetCurrentFunction(glEnableClientState)(__VA_ARGS__) - #define glEnd() GLEGetCurrentFunction(glEnd)() - #define glEndList() GLEGetCurrentFunction(glEndList)(_) - #define glEvalCoord1d(...) GLEGetCurrentFunction(glEvalCoord1d)(__VA_ARGS__) - #define glEvalCoord1dv(...) GLEGetCurrentFunction(glEvalCoord1dv)(__VA_ARGS__) - #define glEvalCoord1f(...) GLEGetCurrentFunction(glEvalCoord1f)(__VA_ARGS__) - #define glEvalCoord1fv(...) GLEGetCurrentFunction(glEvalCoord1fv)(__VA_ARGS__) - #define glEvalCoord2d(...) GLEGetCurrentFunction(glEvalCoord2d)(__VA_ARGS__) - #define glEvalCoord2dv(...) GLEGetCurrentFunction(glEvalCoord2dv)(__VA_ARGS__) - #define glEvalCoord2f(...) GLEGetCurrentFunction(glEvalCoord2f)(__VA_ARGS__) - #define glEvalCoord2fv(...) GLEGetCurrentFunction(glEvalCoord2fv)(__VA_ARGS__) - #define glEvalMesh1(...) GLEGetCurrentFunction(glEvalMesh1)(__VA_ARGS__) - #define glEvalMesh2(...) GLEGetCurrentFunction(glEvalMesh2)(__VA_ARGS__) - #define glEvalPoint1(...) GLEGetCurrentFunction(glEvalPoint1)(__VA_ARGS__) - #define glEvalPoint2(...) GLEGetCurrentFunction(glEvalPoint2)(__VA_ARGS__) - #define glFeedbackBuffer(...) GLEGetCurrentFunction(glFeedbackBuffer)(__VA_ARGS__) - #define glFinish() GLEGetCurrentFunction(glFinish)() - #define glFlush() GLEGetCurrentFunction(glFlush)() - #define glFogf(...) GLEGetCurrentFunction(glFogf)(__VA_ARGS__) - #define glFogfv(...) GLEGetCurrentFunction(glFogfv)(__VA_ARGS__) - #define glFogi(...) GLEGetCurrentFunction(glFogi)(__VA_ARGS__) - #define glFogiv(...) GLEGetCurrentFunction(glFogiv)(__VA_ARGS__) - #define glFrontFace(...) GLEGetCurrentFunction(glFrontFace)(__VA_ARGS__) - #define glFrustum(...) GLEGetCurrentFunction(glFrustum)(__VA_ARGS__) - #define glGenLists(...) GLEGetCurrentFunction(glGenLists)(__VA_ARGS__) - #define glGenTextures(...) GLEGetCurrentFunction(glGenTextures)(__VA_ARGS__) - #define glGetBooleanv(...) GLEGetCurrentFunction(glGetBooleanv)(__VA_ARGS__) - #define glGetClipPlane(...) GLEGetCurrentFunction(glGetClipPlane)(__VA_ARGS__) - #define glGetDoublev(...) GLEGetCurrentFunction(glGetDoublev)(__VA_ARGS__) - #define glGetError() GLEGetCurrentFunction(glGetError)() - #define glGetFloatv(...) GLEGetCurrentFunction(glGetFloatv)(__VA_ARGS__) - #define glGetIntegerv(...) GLEGetCurrentFunction(glGetIntegerv)(__VA_ARGS__) - #define glGetLightfv(...) GLEGetCurrentFunction(glGetLightfv)(__VA_ARGS__) - #define glGetLightiv(...) GLEGetCurrentFunction(glGetLightiv)(__VA_ARGS__) - #define glGetMapdv(...) GLEGetCurrentFunction(glGetMapdv)(__VA_ARGS__) - #define glGetMapfv(...) GLEGetCurrentFunction(glGetMapfv)(__VA_ARGS__) - #define glGetMapiv(...) GLEGetCurrentFunction(glGetMapiv)(__VA_ARGS__) - #define glGetMaterialfv(...) GLEGetCurrentFunction(glGetMaterialfv)(__VA_ARGS__) - #define glGetMaterialiv(...) GLEGetCurrentFunction(glGetMaterialiv)(__VA_ARGS__) - #define glGetPixelMapfv(...) GLEGetCurrentFunction(glGetPixelMapfv)(__VA_ARGS__) - #define glGetPixelMapuiv(...) GLEGetCurrentFunction(glGetPixelMapuiv)(__VA_ARGS__) - #define glGetPixelMapusv(...) GLEGetCurrentFunction(glGetPixelMapusv)(__VA_ARGS__) - #define glGetPointerv(...) GLEGetCurrentFunction(glGetPointerv)(__VA_ARGS__) - #define glGetPolygonStipple(...) GLEGetCurrentFunction(glGetPolygonStipple)(__VA_ARGS__) - #define glGetString(...) GLEGetCurrentFunction(glGetString)(__VA_ARGS__) - #define glGetTexEnvfv(...) GLEGetCurrentFunction(glGetTexEnvfv)(__VA_ARGS__) - #define glGetTexEnviv(...) GLEGetCurrentFunction(glGetTexEnviv)(__VA_ARGS__) - #define glGetTexGendv(...) GLEGetCurrentFunction(glGetTexGendv)(__VA_ARGS__) - #define glGetTexGenfv(...) GLEGetCurrentFunction(glGetTexGenfv)(__VA_ARGS__) - #define glGetTexGeniv(...) GLEGetCurrentFunction(glGetTexGeniv)(__VA_ARGS__) - #define glGetTexImage(...) GLEGetCurrentFunction(glGetTexImage)(__VA_ARGS__) - #define glGetTexLevelParameterfv(...) GLEGetCurrentFunction(glGetTexLevelParameterfv)(__VA_ARGS__) - #define glGetTexLevelParameteriv(...) GLEGetCurrentFunction(glGetTexLevelParameteriv)(__VA_ARGS__) - #define glGetTexParameterfv(...) GLEGetCurrentFunction(glGetTexParameterfv)(__VA_ARGS__) - #define glGetTexParameteriv(...) GLEGetCurrentFunction(glGetTexParameteriv)(__VA_ARGS__) - #define glHint(...) GLEGetCurrentFunction(glHint)(__VA_ARGS__) - #define glIndexMask(...) GLEGetCurrentFunction(glIndexMask)(__VA_ARGS__) - #define glIndexPointer(...) GLEGetCurrentFunction(glIndexPointer)(__VA_ARGS__) - #define glIndexd(...) GLEGetCurrentFunction(glIndexd)(__VA_ARGS__) - #define glIndexdv(...) GLEGetCurrentFunction(glIndexdv)(__VA_ARGS__) - #define glIndexf(...) GLEGetCurrentFunction(glIndexf)(__VA_ARGS__) - #define glIndexfv(...) GLEGetCurrentFunction(glIndexfv)(__VA_ARGS__) - #define glIndexi(...) GLEGetCurrentFunction(glIndexi)(__VA_ARGS__) - #define glIndexiv(...) GLEGetCurrentFunction(glIndexiv)(__VA_ARGS__) - #define glIndexs(...) GLEGetCurrentFunction(glIndexs)(__VA_ARGS__) - #define glIndexsv(...) GLEGetCurrentFunction(glIndexsv)(__VA_ARGS__) - #define glIndexub(...) GLEGetCurrentFunction(glIndexub)(__VA_ARGS__) - #define glIndexubv(...) GLEGetCurrentFunction(glIndexubv)(__VA_ARGS__) - #define glInitNames() GLEGetCurrentFunction(glInitNames)() - #define glInterleavedArrays(...) GLEGetCurrentFunction(glInterleavedArrays)(__VA_ARGS__) - #define glIsEnabled(...) GLEGetCurrentFunction(glIsEnabled)(__VA_ARGS__) - #define glIsList(...) GLEGetCurrentFunction(glIsList)(__VA_ARGS__) - #define glIsTexture(...) GLEGetCurrentFunction(glIsTexture)(__VA_ARGS__) - #define glLightModelf(...) GLEGetCurrentFunction(glLightModelf)(__VA_ARGS__) - #define glLightModelfv(...) GLEGetCurrentFunction(glLightModelfv)(__VA_ARGS__) - #define glLightModeli(...) GLEGetCurrentFunction(glLightModeli)(__VA_ARGS__) - #define glLightModeliv(...) GLEGetCurrentFunction(glLightModeliv)(__VA_ARGS__) - #define glLightf(...) GLEGetCurrentFunction(glLightf)(__VA_ARGS__) - #define glLightfv(...) GLEGetCurrentFunction(glLightfv)(__VA_ARGS__) - #define glLighti(...) GLEGetCurrentFunction(glLighti)(__VA_ARGS__) - #define glLightiv(...) GLEGetCurrentFunction(glLightiv)(__VA_ARGS__) - #define glLineStipple(...) GLEGetCurrentFunction(glLineStipple)(__VA_ARGS__) - #define glLineWidth(...) GLEGetCurrentFunction(glLineWidth)(__VA_ARGS__) - #define glListBase(...) GLEGetCurrentFunction(glListBase)(__VA_ARGS__) - #define glLoadIdentity() GLEGetCurrentFunction(glLoadIdentity)() - #define glLoadMatrixd(...) GLEGetCurrentFunction(glLoadMatrixd)(__VA_ARGS__) - #define glLoadMatrixf(...) GLEGetCurrentFunction(glLoadMatrixf)(__VA_ARGS__) - #define glLoadName(...) GLEGetCurrentFunction(glLoadName)(__VA_ARGS__) - #define glLogicOp(...) GLEGetCurrentFunction(glLogicOp)(__VA_ARGS__) - #define glMap1d(...) GLEGetCurrentFunction(glMap1d)(__VA_ARGS__) - #define glMap1f(...) GLEGetCurrentFunction(glMap1f)(__VA_ARGS__) - #define glMap2d(...) GLEGetCurrentFunction(glMap2d)(__VA_ARGS__) - #define glMap2f(...) GLEGetCurrentFunction(glMap2f)(__VA_ARGS__) - #define glMapGrid1d(...) GLEGetCurrentFunction(glMapGrid1d)(__VA_ARGS__) - #define glMapGrid1f(...) GLEGetCurrentFunction(glMapGrid1f)(__VA_ARGS__) - #define glMapGrid2d(...) GLEGetCurrentFunction(glMapGrid2d)(__VA_ARGS__) - #define glMapGrid2f(...) GLEGetCurrentFunction(glMapGrid2f)(__VA_ARGS__) - #define glMaterialf(...) GLEGetCurrentFunction(glMaterialf)(__VA_ARGS__) - #define glMaterialfv(...) GLEGetCurrentFunction(glMaterialfv)(__VA_ARGS__) - #define glMateriali(...) GLEGetCurrentFunction(glMateriali)(__VA_ARGS__) - #define glMaterialiv(...) GLEGetCurrentFunction(glMaterialiv)(__VA_ARGS__) - #define glMatrixMode(...) GLEGetCurrentFunction(glMatrixMode)(__VA_ARGS__) - #define glMultMatrixd(...) GLEGetCurrentFunction(glMultMatrixd)(__VA_ARGS__) - #define glMultMatrixf(...) GLEGetCurrentFunction(glMultMatrixf)(__VA_ARGS__) - #define glNewList(...) GLEGetCurrentFunction(glNewList)(__VA_ARGS__) - #define glNormal3b(...) GLEGetCurrentFunction(glNormal3b)(__VA_ARGS__) - #define glNormal3bv(...) GLEGetCurrentFunction(glNormal3bv)(__VA_ARGS__) - #define glNormal3d(...) GLEGetCurrentFunction(glNormal3d)(__VA_ARGS__) - #define glNormal3dv(...) GLEGetCurrentFunction(glNormal3dv)(__VA_ARGS__) - #define glNormal3f(...) GLEGetCurrentFunction(glNormal3f)(__VA_ARGS__) - #define glNormal3fv(...) GLEGetCurrentFunction(glNormal3fv)(__VA_ARGS__) - #define glNormal3i(...) GLEGetCurrentFunction(glNormal3i)(__VA_ARGS__) - #define glNormal3iv(...) GLEGetCurrentFunction(glNormal3iv)(__VA_ARGS__) - #define glNormal3s(...) GLEGetCurrentFunction(glNormal3s)(__VA_ARGS__) - #define glNormal3sv(...) GLEGetCurrentFunction(glNormal3sv)(__VA_ARGS__) - #define glNormalPointer(...) GLEGetCurrentFunction(glNormalPointer)(__VA_ARGS__) - #define glOrtho(...) GLEGetCurrentFunction(glOrtho)(__VA_ARGS__) - #define glPassThrough(...) GLEGetCurrentFunction(glPassThrough)(__VA_ARGS__) - #define glPixelMapfv(...) GLEGetCurrentFunction(glPixelMapfv)(__VA_ARGS__) - #define glPixelMapuiv(...) GLEGetCurrentFunction(glPixelMapuiv)(__VA_ARGS__) - #define glPixelMapusv(...) GLEGetCurrentFunction(glPixelMapusv)(__VA_ARGS__) - #define glPixelStoref(...) GLEGetCurrentFunction(glPixelStoref)(__VA_ARGS__) - #define glPixelStorei(...) GLEGetCurrentFunction(glPixelStorei)(__VA_ARGS__) - #define glPixelTransferf(...) GLEGetCurrentFunction(glPixelTransferf)(__VA_ARGS__) - #define glPixelTransferi(...) GLEGetCurrentFunction(glPixelTransferi)(__VA_ARGS__) - #define glPixelZoom(...) GLEGetCurrentFunction(glPixelZoom)(__VA_ARGS__) - #define glPointSize(...) GLEGetCurrentFunction(glPointSize)(__VA_ARGS__) - #define glPolygonMode(...) GLEGetCurrentFunction(glPolygonMode)(__VA_ARGS__) - #define glPolygonOffset(...) GLEGetCurrentFunction(glPolygonOffset)(__VA_ARGS__) - #define glPolygonStipple(...) GLEGetCurrentFunction(glPolygonStipple)(__VA_ARGS__) - #define glPopAttrib() GLEGetCurrentFunction(glPopAttrib)() - #define glPopClientAttrib() GLEGetCurrentFunction(glPopClientAttrib)() - #define glPopMatrix() GLEGetCurrentFunction(glPopMatrix)() - #define glPopName() GLEGetCurrentFunction(glPopName)() - #define glPrioritizeTextures(...) GLEGetCurrentFunction(glPrioritizeTextures)(__VA_ARGS__) - #define glPushAttrib(...) GLEGetCurrentFunction(glPushAttrib)(__VA_ARGS__) - #define glPushClientAttrib(...) GLEGetCurrentFunction(glPushClientAttrib)(__VA_ARGS__) - #define glPushMatrix() GLEGetCurrentFunction(glPushMatrix)() - #define glPushName(...) GLEGetCurrentFunction(glPushName)(__VA_ARGS__) - #define glRasterPos2d(...) GLEGetCurrentFunction(glRasterPos2d)(__VA_ARGS__) - #define glRasterPos2dv(...) GLEGetCurrentFunction(glRasterPos2dv)(__VA_ARGS__) - #define glRasterPos2f(...) GLEGetCurrentFunction(glRasterPos2f)(__VA_ARGS__) - #define glRasterPos2fv(...) GLEGetCurrentFunction(glRasterPos2fv)(__VA_ARGS__) - #define glRasterPos2i(...) GLEGetCurrentFunction(glRasterPos2i)(__VA_ARGS__) - #define glRasterPos2iv(...) GLEGetCurrentFunction(glRasterPos2iv)(__VA_ARGS__) - #define glRasterPos2s(...) GLEGetCurrentFunction(glRasterPos2s)(__VA_ARGS__) - #define glRasterPos2sv(...) GLEGetCurrentFunction(glRasterPos2sv)(__VA_ARGS__) - #define glRasterPos3d(...) GLEGetCurrentFunction(glRasterPos3d)(__VA_ARGS__) - #define glRasterPos3dv(...) GLEGetCurrentFunction(glRasterPos3dv)(__VA_ARGS__) - #define glRasterPos3f(...) GLEGetCurrentFunction(glRasterPos3f)(__VA_ARGS__) - #define glRasterPos3fv(...) GLEGetCurrentFunction(glRasterPos3fv)(__VA_ARGS__) - #define glRasterPos3i(...) GLEGetCurrentFunction(glRasterPos3i)(__VA_ARGS__) - #define glRasterPos3iv(...) GLEGetCurrentFunction(glRasterPos3iv)(__VA_ARGS__) - #define glRasterPos3s(...) GLEGetCurrentFunction(glRasterPos3s)(__VA_ARGS__) - #define glRasterPos3sv(...) GLEGetCurrentFunction(glRasterPos3sv)(__VA_ARGS__) - #define glRasterPos4d(...) GLEGetCurrentFunction(glRasterPos4d)(__VA_ARGS__) - #define glRasterPos4dv(...) GLEGetCurrentFunction(glRasterPos4dv)(__VA_ARGS__) - #define glRasterPos4f(...) GLEGetCurrentFunction(glRasterPos4f)(__VA_ARGS__) - #define glRasterPos4fv(...) GLEGetCurrentFunction(glRasterPos4fv)(__VA_ARGS__) - #define glRasterPos4i(...) GLEGetCurrentFunction(glRasterPos4i)(__VA_ARGS__) - #define glRasterPos4iv(...) GLEGetCurrentFunction(glRasterPos4iv)(__VA_ARGS__) - #define glRasterPos4s(...) GLEGetCurrentFunction(glRasterPos4s)(__VA_ARGS__) - #define glRasterPos4sv(...) GLEGetCurrentFunction(glRasterPos4sv)(__VA_ARGS__) - #define glReadBuffer(...) GLEGetCurrentFunction(glReadBuffer)(__VA_ARGS__) - #define glReadPixels(...) GLEGetCurrentFunction(glReadPixels)(__VA_ARGS__) - #define glRectd(...) GLEGetCurrentFunction(glRectd)(__VA_ARGS__) - #define glRectdv(...) GLEGetCurrentFunction(glRectdv)(__VA_ARGS__) - #define glRectf(...) GLEGetCurrentFunction(glRectf)(__VA_ARGS__) - #define glRectfv(...) GLEGetCurrentFunction(glRectfv)(__VA_ARGS__) - #define glRecti(...) GLEGetCurrentFunction(glRecti)(__VA_ARGS__) - #define glRectiv(...) GLEGetCurrentFunction(glRectiv)(__VA_ARGS__) - #define glRects(...) GLEGetCurrentFunction(glRects)(__VA_ARGS__) - #define glRectsv(...) GLEGetCurrentFunction(glRectsv)(__VA_ARGS__) - #define glRenderMode(...) GLEGetCurrentFunction(glRenderMode)(__VA_ARGS__) - #define glRotated(...) GLEGetCurrentFunction(glRotated)(__VA_ARGS__) - #define glRotatef(...) GLEGetCurrentFunction(glRotatef)(__VA_ARGS__) - #define glScaled(...) GLEGetCurrentFunction(glScaled)(__VA_ARGS__) - #define glScalef(...) GLEGetCurrentFunction(glScalef)(__VA_ARGS__) - #define glScissor(...) GLEGetCurrentFunction(glScissor)(__VA_ARGS__) - #define glSelectBuffer(...) GLEGetCurrentFunction(glSelectBuffer)(__VA_ARGS__) - #define glShadeModel(...) GLEGetCurrentFunction(glShadeModel)(__VA_ARGS__) - #define glStencilFunc(...) GLEGetCurrentFunction(glStencilFunc)(__VA_ARGS__) - #define glStencilMask(...) GLEGetCurrentFunction(glStencilMask)(__VA_ARGS__) - #define glStencilOp(...) GLEGetCurrentFunction(glStencilOp)(__VA_ARGS__) - #define glTexCoord1d(...) GLEGetCurrentFunction(glTexCoord1d)(__VA_ARGS__) - #define glTexCoord1dv(...) GLEGetCurrentFunction(glTexCoord1dv)(__VA_ARGS__) - #define glTexCoord1f(...) GLEGetCurrentFunction(glTexCoord1f)(__VA_ARGS__) - #define glTexCoord1fv(...) GLEGetCurrentFunction(glTexCoord1fv)(__VA_ARGS__) - #define glTexCoord1i(...) GLEGetCurrentFunction(glTexCoord1i)(__VA_ARGS__) - #define glTexCoord1iv(...) GLEGetCurrentFunction(glTexCoord1iv)(__VA_ARGS__) - #define glTexCoord1s(...) GLEGetCurrentFunction(glTexCoord1s)(__VA_ARGS__) - #define glTexCoord1sv(...) GLEGetCurrentFunction(glTexCoord1sv)(__VA_ARGS__) - #define glTexCoord2d(...) GLEGetCurrentFunction(glTexCoord2d)(__VA_ARGS__) - #define glTexCoord2dv(...) GLEGetCurrentFunction(glTexCoord2dv)(__VA_ARGS__) - #define glTexCoord2f(...) GLEGetCurrentFunction(glTexCoord2f)(__VA_ARGS__) - #define glTexCoord2fv(...) GLEGetCurrentFunction(glTexCoord2fv)(__VA_ARGS__) - #define glTexCoord2i(...) GLEGetCurrentFunction(glTexCoord2i)(__VA_ARGS__) - #define glTexCoord2iv(...) GLEGetCurrentFunction(glTexCoord2iv)(__VA_ARGS__) - #define glTexCoord2s(...) GLEGetCurrentFunction(glTexCoord2s)(__VA_ARGS__) - #define glTexCoord2sv(...) GLEGetCurrentFunction(glTexCoord2sv)(__VA_ARGS__) - #define glTexCoord3d(...) GLEGetCurrentFunction(glTexCoord3d)(__VA_ARGS__) - #define glTexCoord3dv(...) GLEGetCurrentFunction(glTexCoord3dv)(__VA_ARGS__) - #define glTexCoord3f(...) GLEGetCurrentFunction(glTexCoord3f)(__VA_ARGS__) - #define glTexCoord3fv(...) GLEGetCurrentFunction(glTexCoord3fv)(__VA_ARGS__) - #define glTexCoord3i(...) GLEGetCurrentFunction(glTexCoord3i)(__VA_ARGS__) - #define glTexCoord3iv(...) GLEGetCurrentFunction(glTexCoord3iv)(__VA_ARGS__) - #define glTexCoord3s(...) GLEGetCurrentFunction(glTexCoord3s)(__VA_ARGS__) - #define glTexCoord3sv(...) GLEGetCurrentFunction(glTexCoord3sv)(__VA_ARGS__) - #define glTexCoord4d(...) GLEGetCurrentFunction(glTexCoord4d)(__VA_ARGS__) - #define glTexCoord4dv(...) GLEGetCurrentFunction(glTexCoord4dv)(__VA_ARGS__) - #define glTexCoord4f(...) GLEGetCurrentFunction(glTexCoord4f)(__VA_ARGS__) - #define glTexCoord4fv(...) GLEGetCurrentFunction(glTexCoord4fv)(__VA_ARGS__) - #define glTexCoord4i(...) GLEGetCurrentFunction(glTexCoord4i)(__VA_ARGS__) - #define glTexCoord4iv(...) GLEGetCurrentFunction(glTexCoord4iv)(__VA_ARGS__) - #define glTexCoord4s(...) GLEGetCurrentFunction(glTexCoord4s)(__VA_ARGS__) - #define glTexCoord4sv(...) GLEGetCurrentFunction(glTexCoord4sv)(__VA_ARGS__) - #define glTexCoordPointer(...) GLEGetCurrentFunction(glTexCoordPointer)(__VA_ARGS__) - #define glTexEnvf(...) GLEGetCurrentFunction(glTexEnvf)(__VA_ARGS__) - #define glTexEnvfv(...) GLEGetCurrentFunction(glTexEnvfv)(__VA_ARGS__) - #define glTexEnvi(...) GLEGetCurrentFunction(glTexEnvi)(__VA_ARGS__) - #define glTexEnviv(...) GLEGetCurrentFunction(glTexEnviv)(__VA_ARGS__) - #define glTexGend(...) GLEGetCurrentFunction(glTexGend)(__VA_ARGS__) - #define glTexGendv(...) GLEGetCurrentFunction(glTexGendv)(__VA_ARGS__) - #define glTexGenf(...) GLEGetCurrentFunction(glTexGenf)(__VA_ARGS__) - #define glTexGenfv(...) GLEGetCurrentFunction(glTexGenfv)(__VA_ARGS__) - #define glTexGeni(...) GLEGetCurrentFunction(glTexGeni)(__VA_ARGS__) - #define glTexGeniv(...) GLEGetCurrentFunction(glTexGeniv)(__VA_ARGS__) - #define glTexImage1D(...) GLEGetCurrentFunction(glTexImage1D)(__VA_ARGS__) - #define glTexImage2D(...) GLEGetCurrentFunction(glTexImage2D)(__VA_ARGS__) - #define glTexParameterf(...) GLEGetCurrentFunction(glTexParameterf)(__VA_ARGS__) - #define glTexParameterfv(...) GLEGetCurrentFunction(glTexParameterfv)(__VA_ARGS__) - #define glTexParameteri(...) GLEGetCurrentFunction(glTexParameteri)(__VA_ARGS__) - #define glTexParameteriv(...) GLEGetCurrentFunction(glTexParameteriv)(__VA_ARGS__) - #define glTexSubImage1D(...) GLEGetCurrentFunction(glTexSubImage1D)(__VA_ARGS__) - #define glTexSubImage2D(...) GLEGetCurrentFunction(glTexSubImage2D)(__VA_ARGS__) - #define glTranslated(...) GLEGetCurrentFunction(glTranslated)(__VA_ARGS__) - #define glTranslatef(...) GLEGetCurrentFunction(glTranslatef)(__VA_ARGS__) - #define glVertex2d(...) GLEGetCurrentFunction(glVertex2d)(__VA_ARGS__) - #define glVertex2dv(...) GLEGetCurrentFunction(glVertex2dv)(__VA_ARGS__) - #define glVertex2f(...) GLEGetCurrentFunction(glVertex2f)(__VA_ARGS__) - #define glVertex2fv(...) GLEGetCurrentFunction(glVertex2fv)(__VA_ARGS__) - #define glVertex2i(...) GLEGetCurrentFunction(glVertex2i)(__VA_ARGS__) - #define glVertex2iv(...) GLEGetCurrentFunction(glVertex2iv)(__VA_ARGS__) - #define glVertex2s(...) GLEGetCurrentFunction(glVertex2s)(__VA_ARGS__) - #define glVertex2sv(...) GLEGetCurrentFunction(glVertex2sv)(__VA_ARGS__) - #define glVertex3d(...) GLEGetCurrentFunction(glVertex3d)(__VA_ARGS__) - #define glVertex3dv(...) GLEGetCurrentFunction(glVertex3dv)(__VA_ARGS__) - #define glVertex3f(...) GLEGetCurrentFunction(glVertex3f)(__VA_ARGS__) - #define glVertex3fv(...) GLEGetCurrentFunction(glVertex3fv)(__VA_ARGS__) - #define glVertex3i(...) GLEGetCurrentFunction(glVertex3i)(__VA_ARGS__) - #define glVertex3iv(...) GLEGetCurrentFunction(glVertex3iv)(__VA_ARGS__) - #define glVertex3s(...) GLEGetCurrentFunction(glVertex3s)(__VA_ARGS__) - #define glVertex3sv(...) GLEGetCurrentFunction(glVertex3sv)(__VA_ARGS__) - #define glVertex4d(...) GLEGetCurrentFunction(glVertex4d)(__VA_ARGS__) - #define glVertex4dv(...) GLEGetCurrentFunction(glVertex4dv)(__VA_ARGS__) - #define glVertex4f(...) GLEGetCurrentFunction(glVertex4f)(__VA_ARGS__) - #define glVertex4fv(...) GLEGetCurrentFunction(glVertex4fv)(__VA_ARGS__) - #define glVertex4i(...) GLEGetCurrentFunction(glVertex4i)(__VA_ARGS__) - #define glVertex4iv(...) GLEGetCurrentFunction(glVertex4iv)(__VA_ARGS__) - #define glVertex4s(...) GLEGetCurrentFunction(glVertex4s)(__VA_ARGS__) - #define glVertex4sv(...) GLEGetCurrentFunction(glVertex4sv)(__VA_ARGS__) - #define glVertexPointer(...) GLEGetCurrentFunction(glVertexPointer)(__VA_ARGS__) - #define glViewport(...) GLEGetCurrentFunction(glViewport)(__VA_ARGS__) - #else - // There is no need to typedef OpenGL 1.1 function types because they are present in all - // OpenGL implementations and don't need to be treated dynamically like extensions. - GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); - GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); - GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); - GLAPI void GLAPIENTRY glArrayElement (GLint i); - GLAPI void GLAPIENTRY glBegin (GLenum mode); - GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); - GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); - GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); - GLAPI void GLAPIENTRY glCallList (GLuint list); - GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const void *lists); - GLAPI void GLAPIENTRY glClear (GLbitfield mask); - GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); - GLAPI void GLAPIENTRY glClearIndex (GLfloat c); - GLAPI void GLAPIENTRY glClearStencil (GLint s); - GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); - GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); - GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); - GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); - GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); - GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); - GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); - GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); - GLAPI void GLAPIENTRY glColor3iv (const GLint *v); - GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); - GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); - GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); - GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); - GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); - GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); - GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); - GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); - GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); - GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); - GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); - GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); - GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); - GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); - GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); - GLAPI void GLAPIENTRY glColor4iv (const GLint *v); - GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); - GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); - GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); - GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); - GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); - GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); - GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); - GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); - GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); - GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); - GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); - GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); - GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); - GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); - GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); - GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); - GLAPI void GLAPIENTRY glCullFace (GLenum mode); - GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); - GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); - GLAPI void GLAPIENTRY glDepthFunc (GLenum func); - GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); - GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); - GLAPI void GLAPIENTRY glDisable (GLenum cap); - GLAPI void GLAPIENTRY glDisableClientState (GLenum array); - GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); - GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); - GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); - GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); - GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); - GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const void *pointer); - GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); - GLAPI void GLAPIENTRY glEnable (GLenum cap); - GLAPI void GLAPIENTRY glEnableClientState (GLenum array); - GLAPI void GLAPIENTRY glEnd (void); - GLAPI void GLAPIENTRY glEndList (void); - GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); - GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); - GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); - GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); - GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); - GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); - GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); - GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); - GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); - GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); - GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); - GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); - GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); - GLAPI void GLAPIENTRY glFinish (void); - GLAPI void GLAPIENTRY glFlush (void); - GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); - GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); - GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); - GLAPI void GLAPIENTRY glFrontFace (GLenum mode); - GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); - GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); - GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); - GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); - GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); - GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); - GLAPI GLenum GLAPIENTRY glGetError (void); - GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); - GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); - GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); - GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); - GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); - GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); - GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); - GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); - GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); - GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); - GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); - GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); - GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, void* *params); - GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); - GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); - GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); - GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); - GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); - GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); - GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); - GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, void *pixels); - GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); - GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); - GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); - GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); - GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); - GLAPI void GLAPIENTRY glIndexMask (GLuint mask); - GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const void *pointer); - GLAPI void GLAPIENTRY glIndexd (GLdouble c); - GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); - GLAPI void GLAPIENTRY glIndexf (GLfloat c); - GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); - GLAPI void GLAPIENTRY glIndexi (GLint c); - GLAPI void GLAPIENTRY glIndexiv (const GLint *c); - GLAPI void GLAPIENTRY glIndexs (GLshort c); - GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); - GLAPI void GLAPIENTRY glIndexub (GLubyte c); - GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); - GLAPI void GLAPIENTRY glInitNames (void); - GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const void *pointer); - GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); - GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); - GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); - GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); - GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); - GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); - GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); - GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); - GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); - GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); - GLAPI void GLAPIENTRY glLineWidth (GLfloat width); - GLAPI void GLAPIENTRY glListBase (GLuint base); - GLAPI void GLAPIENTRY glLoadIdentity (void); - GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); - GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); - GLAPI void GLAPIENTRY glLoadName (GLuint name); - GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); - GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); - GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); - GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); - GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); - GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); - GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); - GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); - GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); - GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); - GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); - GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); - GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); - GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); - GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); - GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); - GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); - GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); - GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); - GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); - GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); - GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); - GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); - GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); - GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); - GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); - GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const void *pointer); - GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); - GLAPI void GLAPIENTRY glPassThrough (GLfloat token); - GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); - GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); - GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); - GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); - GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); - GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); - GLAPI void GLAPIENTRY glPointSize (GLfloat size); - GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); - GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); - GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); - GLAPI void GLAPIENTRY glPopAttrib (void); - GLAPI void GLAPIENTRY glPopClientAttrib (void); - GLAPI void GLAPIENTRY glPopMatrix (void); - GLAPI void GLAPIENTRY glPopName (void); - GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); - GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); - GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); - GLAPI void GLAPIENTRY glPushMatrix (void); - GLAPI void GLAPIENTRY glPushName (GLuint name); - GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); - GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); - GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); - GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); - GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); - GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); - GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); - GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); - GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); - GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); - GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); - GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); - GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); - GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); - GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); - GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); - GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); - GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); - GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); - GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); - GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); - GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); - GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); - GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); - GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); - GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); - GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); - GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); - GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); - GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); - GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); - GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); - GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); - GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); - GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); - GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); - GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); - GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); - GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); - GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); - GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); - GLAPI void GLAPIENTRY glShadeModel (GLenum mode); - GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); - GLAPI void GLAPIENTRY glStencilMask (GLuint mask); - GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); - GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); - GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); - GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); - GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); - GLAPI void GLAPIENTRY glTexCoord1i (GLint s); - GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); - GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); - GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); - GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); - GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); - GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); - GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); - GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); - GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); - GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); - GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); - GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); - GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); - GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); - GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); - GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); - GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); - GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); - GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); - GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); - GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); - GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); - GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); - GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); - GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); - GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); - GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); - GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); - GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); - GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); - GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); - GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); - GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); - GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); - GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); - GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); - GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); - GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); - GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); - GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); - GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); - GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); - GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); - GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); - GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); - GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); - GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); - GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); - GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); - GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); - GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); - GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); - GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); - GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); - GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); - GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); - GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); - GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); - GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); - GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); - GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); - GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); - GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); - GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); - GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); - GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); - GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); - GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); - GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); - GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); - GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); - GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); - - #endif // GLE_HOOKING_ENABLED - -#endif // GL_VERSION_1_1 - - - - -// OpenGL 1.2+ functions are not declared in Microsoft's gl.h - -#ifndef GL_VERSION_1_2 - #define GL_VERSION_1_2 1 - - #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 - #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 - #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 - #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 - #define GL_UNSIGNED_BYTE_3_3_2 0x8032 - #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 - #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 - #define GL_UNSIGNED_INT_8_8_8_8 0x8035 - #define GL_UNSIGNED_INT_10_10_10_2 0x8036 - #define GL_RESCALE_NORMAL 0x803A - #define GL_TEXTURE_BINDING_3D 0x806A - #define GL_PACK_SKIP_IMAGES 0x806B - #define GL_PACK_IMAGE_HEIGHT 0x806C - #define GL_UNPACK_SKIP_IMAGES 0x806D - #define GL_UNPACK_IMAGE_HEIGHT 0x806E - #define GL_TEXTURE_3D 0x806F - #define GL_PROXY_TEXTURE_3D 0x8070 - #define GL_TEXTURE_DEPTH 0x8071 - #define GL_TEXTURE_WRAP_R 0x8072 - #define GL_MAX_3D_TEXTURE_SIZE 0x8073 - #define GL_BGR 0x80E0 - #define GL_BGRA 0x80E1 - #define GL_MAX_ELEMENTS_VERTICES 0x80E8 - #define GL_MAX_ELEMENTS_INDICES 0x80E9 - #define GL_CLAMP_TO_EDGE 0x812F - #define GL_TEXTURE_MIN_LOD 0x813A - #define GL_TEXTURE_MAX_LOD 0x813B - #define GL_TEXTURE_BASE_LEVEL 0x813C - #define GL_TEXTURE_MAX_LEVEL 0x813D - #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 - #define GL_SINGLE_COLOR 0x81F9 - #define GL_SEPARATE_SPECULAR_COLOR 0x81FA - #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 - #define GL_UNSIGNED_SHORT_5_6_5 0x8363 - #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 - #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 - #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 - #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 - #define GL_ALIASED_POINT_SIZE_RANGE 0x846D - #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E - - typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); - typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); - typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); - - #define glCopyTexSubImage3D GLEGetCurrentFunction(glCopyTexSubImage3D) - #define glDrawRangeElements GLEGetCurrentFunction(glDrawRangeElements) - #define glTexImage3D GLEGetCurrentFunction(glTexImage3D) - #define glTexSubImage3D GLEGetCurrentFunction(glTexSubImage3D) - - // OpenGL 2.1 deprecated functions - /* - typedef void (GLAPIENTRY PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - typedef void (GLAPIENTRY PFNGLBLENDEQUATIONPROC) (GLenum mode); - typedef void (GLAPIENTRY PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); - typedef void (GLAPIENTRY PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); - typedef void (GLAPIENTRY PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); - typedef void (GLAPIENTRY PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); - typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); - typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); - typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); - typedef void (GLAPIENTRY PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); - typedef void (GLAPIENTRY PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); - typedef void (GLAPIENTRY PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); - typedef void (GLAPIENTRY PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); - typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); - typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); - typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); - typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); - typedef void (GLAPIENTRY PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); - typedef void (GLAPIENTRY PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); - typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); - typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); - typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); - typedef void (GLAPIENTRY PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); - typedef void (GLAPIENTRY PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); - typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); - typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); - typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); - typedef void (GLAPIENTRY PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); - typedef void (GLAPIENTRY PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); - typedef void (GLAPIENTRY PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); - typedef void (GLAPIENTRY PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); - typedef void (GLAPIENTRY PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); - typedef void (GLAPIENTRY PFNGLRESETHISTOGRAMPROC) (GLenum target); - typedef void (GLAPIENTRY PFNGLRESETMINMAXPROC) (GLenum target); - */ -#endif // GL_VERSION_1_2 - - - -#ifndef GL_VERSION_1_3 - #define GL_VERSION_1_3 1 - - #define GL_MULTISAMPLE 0x809D - #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E - #define GL_SAMPLE_ALPHA_TO_ONE 0x809F - #define GL_SAMPLE_COVERAGE 0x80A0 - #define GL_SAMPLE_BUFFERS 0x80A8 - #define GL_SAMPLES 0x80A9 - #define GL_SAMPLE_COVERAGE_VALUE 0x80AA - #define GL_SAMPLE_COVERAGE_INVERT 0x80AB - #define GL_CLAMP_TO_BORDER 0x812D - #define GL_TEXTURE0 0x84C0 - #define GL_TEXTURE1 0x84C1 - #define GL_TEXTURE2 0x84C2 - #define GL_TEXTURE3 0x84C3 - #define GL_TEXTURE4 0x84C4 - #define GL_TEXTURE5 0x84C5 - #define GL_TEXTURE6 0x84C6 - #define GL_TEXTURE7 0x84C7 - #define GL_TEXTURE8 0x84C8 - #define GL_TEXTURE9 0x84C9 - #define GL_TEXTURE10 0x84CA - #define GL_TEXTURE11 0x84CB - #define GL_TEXTURE12 0x84CC - #define GL_TEXTURE13 0x84CD - #define GL_TEXTURE14 0x84CE - #define GL_TEXTURE15 0x84CF - #define GL_TEXTURE16 0x84D0 - #define GL_TEXTURE17 0x84D1 - #define GL_TEXTURE18 0x84D2 - #define GL_TEXTURE19 0x84D3 - #define GL_TEXTURE20 0x84D4 - #define GL_TEXTURE21 0x84D5 - #define GL_TEXTURE22 0x84D6 - #define GL_TEXTURE23 0x84D7 - #define GL_TEXTURE24 0x84D8 - #define GL_TEXTURE25 0x84D9 - #define GL_TEXTURE26 0x84DA - #define GL_TEXTURE27 0x84DB - #define GL_TEXTURE28 0x84DC - #define GL_TEXTURE29 0x84DD - #define GL_TEXTURE30 0x84DE - #define GL_TEXTURE31 0x84DF - #define GL_ACTIVE_TEXTURE 0x84E0 - #define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 - #define GL_MAX_TEXTURE_UNITS 0x84E2 - #define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 - #define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 - #define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 - #define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 - #define GL_SUBTRACT 0x84E7 - #define GL_COMPRESSED_ALPHA 0x84E9 - #define GL_COMPRESSED_LUMINANCE 0x84EA - #define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB - #define GL_COMPRESSED_INTENSITY 0x84EC - #define GL_COMPRESSED_RGB 0x84ED - #define GL_COMPRESSED_RGBA 0x84EE - #define GL_TEXTURE_COMPRESSION_HINT 0x84EF - #define GL_NORMAL_MAP 0x8511 - #define GL_REFLECTION_MAP 0x8512 - #define GL_TEXTURE_CUBE_MAP 0x8513 - #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 - #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 - #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 - #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 - #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 - #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 - #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A - #define GL_PROXY_TEXTURE_CUBE_MAP 0x851B - #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C - #define GL_COMBINE 0x8570 - #define GL_COMBINE_RGB 0x8571 - #define GL_COMBINE_ALPHA 0x8572 - #define GL_RGB_SCALE 0x8573 - #define GL_ADD_SIGNED 0x8574 - #define GL_INTERPOLATE 0x8575 - #define GL_CONSTANT 0x8576 - #define GL_PRIMARY_COLOR 0x8577 - #define GL_PREVIOUS 0x8578 - #define GL_SOURCE0_RGB 0x8580 - #define GL_SOURCE1_RGB 0x8581 - #define GL_SOURCE2_RGB 0x8582 - #define GL_SOURCE0_ALPHA 0x8588 - #define GL_SOURCE1_ALPHA 0x8589 - #define GL_SOURCE2_ALPHA 0x858A - #define GL_OPERAND0_RGB 0x8590 - #define GL_OPERAND1_RGB 0x8591 - #define GL_OPERAND2_RGB 0x8592 - #define GL_OPERAND0_ALPHA 0x8598 - #define GL_OPERAND1_ALPHA 0x8599 - #define GL_OPERAND2_ALPHA 0x859A - #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 - #define GL_TEXTURE_COMPRESSED 0x86A1 - #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 - #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 - #define GL_DOT3_RGB 0x86AE - #define GL_DOT3_RGBA 0x86AF - #define GL_MULTISAMPLE_BIT 0x20000000 - - typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); - typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, void *img); - typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); - typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); - typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); - typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); - typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); - typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); - - #define glActiveTexture GLEGetCurrentFunction(glActiveTexture) - #define glClientActiveTexture GLEGetCurrentFunction(glClientActiveTexture) - #define glCompressedTexImage1D GLEGetCurrentFunction(glCompressedTexImage1D) - #define glCompressedTexImage2D GLEGetCurrentFunction(glCompressedTexImage2D) - #define glCompressedTexImage3D GLEGetCurrentFunction(glCompressedTexImage3D) - #define glCompressedTexSubImage1D GLEGetCurrentFunction(glCompressedTexSubImage1D) - #define glCompressedTexSubImage2D GLEGetCurrentFunction(glCompressedTexSubImage2D) - #define glCompressedTexSubImage3D GLEGetCurrentFunction(glCompressedTexSubImage3D) - #define glGetCompressedTexImage GLEGetCurrentFunction(glGetCompressedTexImage) - #define glLoadTransposeMatrixd GLEGetCurrentFunction(glLoadTransposeMatrixd) - #define glLoadTransposeMatrixf GLEGetCurrentFunction(glLoadTransposeMatrixf) - #define glMultTransposeMatrixd GLEGetCurrentFunction(glMultTransposeMatrixd) - #define glMultTransposeMatrixf GLEGetCurrentFunction(glMultTransposeMatrixf) - #define glMultiTexCoord1d GLEGetCurrentFunction(glMultiTexCoord1d) - #define glMultiTexCoord1dv GLEGetCurrentFunction(glMultiTexCoord1dv) - #define glMultiTexCoord1f GLEGetCurrentFunction(glMultiTexCoord1f) - #define glMultiTexCoord1fv GLEGetCurrentFunction(glMultiTexCoord1fv) - #define glMultiTexCoord1i GLEGetCurrentFunction(glMultiTexCoord1i) - #define glMultiTexCoord1iv GLEGetCurrentFunction(glMultiTexCoord1iv) - #define glMultiTexCoord1s GLEGetCurrentFunction(glMultiTexCoord1s) - #define glMultiTexCoord1sv GLEGetCurrentFunction(glMultiTexCoord1sv) - #define glMultiTexCoord2d GLEGetCurrentFunction(glMultiTexCoord2d) - #define glMultiTexCoord2dv GLEGetCurrentFunction(glMultiTexCoord2dv) - #define glMultiTexCoord2f GLEGetCurrentFunction(glMultiTexCoord2f) - #define glMultiTexCoord2fv GLEGetCurrentFunction(glMultiTexCoord2fv) - #define glMultiTexCoord2i GLEGetCurrentFunction(glMultiTexCoord2i) - #define glMultiTexCoord2iv GLEGetCurrentFunction(glMultiTexCoord2iv) - #define glMultiTexCoord2s GLEGetCurrentFunction(glMultiTexCoord2s) - #define glMultiTexCoord2sv GLEGetCurrentFunction(glMultiTexCoord2sv) - #define glMultiTexCoord3d GLEGetCurrentFunction(glMultiTexCoord3d) - #define glMultiTexCoord3dv GLEGetCurrentFunction(glMultiTexCoord3dv) - #define glMultiTexCoord3f GLEGetCurrentFunction(glMultiTexCoord3f) - #define glMultiTexCoord3fv GLEGetCurrentFunction(glMultiTexCoord3fv) - #define glMultiTexCoord3i GLEGetCurrentFunction(glMultiTexCoord3i) - #define glMultiTexCoord3iv GLEGetCurrentFunction(glMultiTexCoord3iv) - #define glMultiTexCoord3s GLEGetCurrentFunction(glMultiTexCoord3s) - #define glMultiTexCoord3sv GLEGetCurrentFunction(glMultiTexCoord3sv) - #define glMultiTexCoord4d GLEGetCurrentFunction(glMultiTexCoord4d) - #define glMultiTexCoord4dv GLEGetCurrentFunction(glMultiTexCoord4dv) - #define glMultiTexCoord4f GLEGetCurrentFunction(glMultiTexCoord4f) - #define glMultiTexCoord4fv GLEGetCurrentFunction(glMultiTexCoord4fv) - #define glMultiTexCoord4i GLEGetCurrentFunction(glMultiTexCoord4i) - #define glMultiTexCoord4iv GLEGetCurrentFunction(glMultiTexCoord4iv) - #define glMultiTexCoord4s GLEGetCurrentFunction(glMultiTexCoord4s) - #define glMultiTexCoord4sv GLEGetCurrentFunction(glMultiTexCoord4sv) - #define glSampleCoverage GLEGetCurrentFunction(glSampleCoverage) - -#endif // GL_VERSION_1_3 - - - -#ifndef GL_VERSION_1_4 - #define GL_VERSION_1_4 1 - - #define GL_BLEND_DST_RGB 0x80C8 - #define GL_BLEND_SRC_RGB 0x80C9 - #define GL_BLEND_DST_ALPHA 0x80CA - #define GL_BLEND_SRC_ALPHA 0x80CB - #define GL_POINT_SIZE_MIN 0x8126 - #define GL_POINT_SIZE_MAX 0x8127 - #define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 - #define GL_POINT_DISTANCE_ATTENUATION 0x8129 - #define GL_GENERATE_MIPMAP 0x8191 - #define GL_GENERATE_MIPMAP_HINT 0x8192 - #define GL_DEPTH_COMPONENT16 0x81A5 - #define GL_DEPTH_COMPONENT24 0x81A6 - #define GL_DEPTH_COMPONENT32 0x81A7 - #define GL_MIRRORED_REPEAT 0x8370 - #define GL_FOG_COORDINATE_SOURCE 0x8450 - #define GL_FOG_COORDINATE 0x8451 - #define GL_FRAGMENT_DEPTH 0x8452 - #define GL_CURRENT_FOG_COORDINATE 0x8453 - #define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 - #define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 - #define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 - #define GL_FOG_COORDINATE_ARRAY 0x8457 - #define GL_COLOR_SUM 0x8458 - #define GL_CURRENT_SECONDARY_COLOR 0x8459 - #define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A - #define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B - #define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C - #define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D - #define GL_SECONDARY_COLOR_ARRAY 0x845E - #define GL_MAX_TEXTURE_LOD_BIAS 0x84FD - #define GL_TEXTURE_FILTER_CONTROL 0x8500 - #define GL_TEXTURE_LOD_BIAS 0x8501 - #define GL_INCR_WRAP 0x8507 - #define GL_DECR_WRAP 0x8508 - #define GL_TEXTURE_DEPTH_SIZE 0x884A - #define GL_DEPTH_TEXTURE_MODE 0x884B - #define GL_TEXTURE_COMPARE_MODE 0x884C - #define GL_TEXTURE_COMPARE_FUNC 0x884D - #define GL_COMPARE_R_TO_TEXTURE 0x884E - - typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); - typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); - typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); - typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); - typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); - typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); - typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); - typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); - typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const* indices, GLsizei drawcount); - typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); - typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); - typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); - typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); - typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); - typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); - - #define glBlendColor GLEGetCurrentFunction(glBlendColor) - #define glBlendEquation GLEGetCurrentFunction(glBlendEquation) - #define glBlendFuncSeparate GLEGetCurrentFunction(glBlendFuncSeparate) - #define glFogCoordPointer GLEGetCurrentFunction(glFogCoordPointer) - #define glFogCoordd GLEGetCurrentFunction(glFogCoordd) - #define glFogCoorddv GLEGetCurrentFunction(glFogCoorddv) - #define glFogCoordf GLEGetCurrentFunction(glFogCoordf) - #define glFogCoordfv GLEGetCurrentFunction(glFogCoordfv) - #define glMultiDrawArrays GLEGetCurrentFunction(glMultiDrawArrays) - #define glMultiDrawElements GLEGetCurrentFunction(glMultiDrawElements) - #define glPointParameterf GLEGetCurrentFunction(glPointParameterf) - #define glPointParameterfv GLEGetCurrentFunction(glPointParameterfv) - #define glPointParameteri GLEGetCurrentFunction(glPointParameteri) - #define glPointParameteriv GLEGetCurrentFunction(glPointParameteriv) - #define glSecondaryColor3b GLEGetCurrentFunction(glSecondaryColor3b) - #define glSecondaryColor3bv GLEGetCurrentFunction(glSecondaryColor3bv) - #define glSecondaryColor3d GLEGetCurrentFunction(glSecondaryColor3d) - #define glSecondaryColor3dv GLEGetCurrentFunction(glSecondaryColor3dv) - #define glSecondaryColor3f GLEGetCurrentFunction(glSecondaryColor3f) - #define glSecondaryColor3fv GLEGetCurrentFunction(glSecondaryColor3fv) - #define glSecondaryColor3i GLEGetCurrentFunction(glSecondaryColor3i) - #define glSecondaryColor3iv GLEGetCurrentFunction(glSecondaryColor3iv) - #define glSecondaryColor3s GLEGetCurrentFunction(glSecondaryColor3s) - #define glSecondaryColor3sv GLEGetCurrentFunction(glSecondaryColor3sv) - #define glSecondaryColor3ub GLEGetCurrentFunction(glSecondaryColor3ub) - #define glSecondaryColor3ubv GLEGetCurrentFunction(glSecondaryColor3ubv) - #define glSecondaryColor3ui GLEGetCurrentFunction(glSecondaryColor3ui) - #define glSecondaryColor3uiv GLEGetCurrentFunction(glSecondaryColor3uiv) - #define glSecondaryColor3us GLEGetCurrentFunction(glSecondaryColor3us) - #define glSecondaryColor3usv GLEGetCurrentFunction(glSecondaryColor3usv) - #define glSecondaryColorPointer GLEGetCurrentFunction(glSecondaryColorPointer) - #define glWindowPos2d GLEGetCurrentFunction(glWindowPos2d) - #define glWindowPos2dv GLEGetCurrentFunction(glWindowPos2dv) - #define glWindowPos2f GLEGetCurrentFunction(glWindowPos2f) - #define glWindowPos2fv GLEGetCurrentFunction(glWindowPos2fv) - #define glWindowPos2i GLEGetCurrentFunction(glWindowPos2i) - #define glWindowPos2iv GLEGetCurrentFunction(glWindowPos2iv) - #define glWindowPos2s GLEGetCurrentFunction(glWindowPos2s) - #define glWindowPos2sv GLEGetCurrentFunction(glWindowPos2sv) - #define glWindowPos3d GLEGetCurrentFunction(glWindowPos3d) - #define glWindowPos3dv GLEGetCurrentFunction(glWindowPos3dv) - #define glWindowPos3f GLEGetCurrentFunction(glWindowPos3f) - #define glWindowPos3fv GLEGetCurrentFunction(glWindowPos3fv) - #define glWindowPos3i GLEGetCurrentFunction(glWindowPos3i) - #define glWindowPos3iv GLEGetCurrentFunction(glWindowPos3iv) - #define glWindowPos3s GLEGetCurrentFunction(glWindowPos3s) - #define glWindowPos3sv GLEGetCurrentFunction(glWindowPos3sv) - -#endif // GL_VERSION_1_4 - - - -#ifndef GL_VERSION_1_5 - #define GL_VERSION_1_5 1 - - #define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE - #define GL_FOG_COORD GL_FOG_COORDINATE - #define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY - #define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING - #define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER - #define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE - #define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE - #define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE - #define GL_SRC0_ALPHA GL_SOURCE0_ALPHA - #define GL_SRC0_RGB GL_SOURCE0_RGB - #define GL_SRC1_ALPHA GL_SOURCE1_ALPHA - #define GL_SRC1_RGB GL_SOURCE1_RGB - #define GL_SRC2_ALPHA GL_SOURCE2_ALPHA - #define GL_SRC2_RGB GL_SOURCE2_RGB - #define GL_BUFFER_SIZE 0x8764 - #define GL_BUFFER_USAGE 0x8765 - #define GL_QUERY_COUNTER_BITS 0x8864 - #define GL_CURRENT_QUERY 0x8865 - #define GL_QUERY_RESULT 0x8866 - #define GL_QUERY_RESULT_AVAILABLE 0x8867 - #define GL_ARRAY_BUFFER 0x8892 - #define GL_ELEMENT_ARRAY_BUFFER 0x8893 - #define GL_ARRAY_BUFFER_BINDING 0x8894 - #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 - #define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 - #define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 - #define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 - #define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 - #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A - #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B - #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C - #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D - #define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E - #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F - #define GL_READ_ONLY 0x88B8 - #define GL_WRITE_ONLY 0x88B9 - #define GL_READ_WRITE 0x88BA - #define GL_BUFFER_ACCESS 0x88BB - #define GL_BUFFER_MAPPED 0x88BC - #define GL_BUFFER_MAP_POINTER 0x88BD - #define GL_STREAM_DRAW 0x88E0 - #define GL_STREAM_READ 0x88E1 - #define GL_STREAM_COPY 0x88E2 - #define GL_STATIC_DRAW 0x88E4 - #define GL_STATIC_READ 0x88E5 - #define GL_STATIC_COPY 0x88E6 - #define GL_DYNAMIC_DRAW 0x88E8 - #define GL_DYNAMIC_READ 0x88E9 - #define GL_DYNAMIC_COPY 0x88EA - #define GL_SAMPLES_PASSED 0x8914 - - typedef ptrdiff_t GLintptr; - typedef ptrdiff_t GLsizeiptr; - - typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); - typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); - typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void* data, GLenum usage); - typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); - typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); - typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); - typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); - typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); - typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); - typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void** params); - typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void* data); - typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); - typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); - typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); - typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); - typedef void* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); - typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); - - #define glBeginQuery GLEGetCurrentFunction(glBeginQuery) - #define glBindBuffer GLEGetCurrentFunction(glBindBuffer) - #define glBufferData GLEGetCurrentFunction(glBufferData) - #define glBufferSubData GLEGetCurrentFunction(glBufferSubData) - #define glDeleteBuffers GLEGetCurrentFunction(glDeleteBuffers) - #define glDeleteQueries GLEGetCurrentFunction(glDeleteQueries) - #define glEndQuery GLEGetCurrentFunction(glEndQuery) - #define glGenBuffers GLEGetCurrentFunction(glGenBuffers) - #define glGenQueries GLEGetCurrentFunction(glGenQueries) - #define glGetBufferParameteriv GLEGetCurrentFunction(glGetBufferParameteriv) - #define glGetBufferPointerv GLEGetCurrentFunction(glGetBufferPointerv) - #define glGetBufferSubData GLEGetCurrentFunction(glGetBufferSubData) - #define glGetQueryObjectiv GLEGetCurrentFunction(glGetQueryObjectiv) - #define glGetQueryObjectuiv GLEGetCurrentFunction(glGetQueryObjectuiv) - #define glGetQueryiv GLEGetCurrentFunction(glGetQueryiv) - #define glIsBuffer GLEGetCurrentFunction(glIsBuffer) - #define glIsQuery GLEGetCurrentFunction(glIsQuery) - #define glMapBuffer GLEGetCurrentFunction(glMapBuffer) - #define glUnmapBuffer GLEGetCurrentFunction(glUnmapBuffer) - -#endif // GL_VERSION_1_5 - - - - -#ifndef GL_VERSION_2_0 - #define GL_VERSION_2_0 1 - - #define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION - #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 - #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 - #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 - #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 - #define GL_CURRENT_VERTEX_ATTRIB 0x8626 - #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 - #define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 - #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 - #define GL_STENCIL_BACK_FUNC 0x8800 - #define GL_STENCIL_BACK_FAIL 0x8801 - #define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 - #define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 - #define GL_MAX_DRAW_BUFFERS 0x8824 - #define GL_DRAW_BUFFER0 0x8825 - #define GL_DRAW_BUFFER1 0x8826 - #define GL_DRAW_BUFFER2 0x8827 - #define GL_DRAW_BUFFER3 0x8828 - #define GL_DRAW_BUFFER4 0x8829 - #define GL_DRAW_BUFFER5 0x882A - #define GL_DRAW_BUFFER6 0x882B - #define GL_DRAW_BUFFER7 0x882C - #define GL_DRAW_BUFFER8 0x882D - #define GL_DRAW_BUFFER9 0x882E - #define GL_DRAW_BUFFER10 0x882F - #define GL_DRAW_BUFFER11 0x8830 - #define GL_DRAW_BUFFER12 0x8831 - #define GL_DRAW_BUFFER13 0x8832 - #define GL_DRAW_BUFFER14 0x8833 - #define GL_DRAW_BUFFER15 0x8834 - #define GL_BLEND_EQUATION_ALPHA 0x883D - #define GL_POINT_SPRITE 0x8861 - #define GL_COORD_REPLACE 0x8862 - #define GL_MAX_VERTEX_ATTRIBS 0x8869 - #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A - #define GL_MAX_TEXTURE_COORDS 0x8871 - #define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 - #define GL_FRAGMENT_SHADER 0x8B30 - #define GL_VERTEX_SHADER 0x8B31 - #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 - #define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A - #define GL_MAX_VARYING_FLOATS 0x8B4B - #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C - #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D - #define GL_SHADER_TYPE 0x8B4F - #define GL_FLOAT_VEC2 0x8B50 - #define GL_FLOAT_VEC3 0x8B51 - #define GL_FLOAT_VEC4 0x8B52 - #define GL_INT_VEC2 0x8B53 - #define GL_INT_VEC3 0x8B54 - #define GL_INT_VEC4 0x8B55 - #define GL_BOOL 0x8B56 - #define GL_BOOL_VEC2 0x8B57 - #define GL_BOOL_VEC3 0x8B58 - #define GL_BOOL_VEC4 0x8B59 - #define GL_FLOAT_MAT2 0x8B5A - #define GL_FLOAT_MAT3 0x8B5B - #define GL_FLOAT_MAT4 0x8B5C - #define GL_SAMPLER_1D 0x8B5D - #define GL_SAMPLER_2D 0x8B5E - #define GL_SAMPLER_3D 0x8B5F - #define GL_SAMPLER_CUBE 0x8B60 - #define GL_SAMPLER_1D_SHADOW 0x8B61 - #define GL_SAMPLER_2D_SHADOW 0x8B62 - #define GL_DELETE_STATUS 0x8B80 - #define GL_COMPILE_STATUS 0x8B81 - #define GL_LINK_STATUS 0x8B82 - #define GL_VALIDATE_STATUS 0x8B83 - #define GL_INFO_LOG_LENGTH 0x8B84 - #define GL_ATTACHED_SHADERS 0x8B85 - #define GL_ACTIVE_UNIFORMS 0x8B86 - #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 - #define GL_SHADER_SOURCE_LENGTH 0x8B88 - #define GL_ACTIVE_ATTRIBUTES 0x8B89 - #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A - #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B - #define GL_SHADING_LANGUAGE_VERSION 0x8B8C - #define GL_CURRENT_PROGRAM 0x8B8D - #define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 - #define GL_LOWER_LEFT 0x8CA1 - #define GL_UPPER_LEFT 0x8CA2 - #define GL_STENCIL_BACK_REF 0x8CA3 - #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 - #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 - - typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); - typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); - typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); - typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); - typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); - typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); - typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); - typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); - typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); - typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); - typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); - typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); - typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); - typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); - typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); - typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); - typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); - typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); - typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); - typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source); - typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); - typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); - typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); - typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void** pointer); - typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble* params); - typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat* params); - typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint* params); - typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); - typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); - typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); - typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const* string, const GLint* length); - typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); - typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); - typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); - typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); - typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); - typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); - typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); - typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); - typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); - typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); - typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); - typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); - typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); - - #define glAttachShader GLEGetCurrentFunction(glAttachShader) - #define glBindAttribLocation GLEGetCurrentFunction(glBindAttribLocation) - #define glBlendEquationSeparate GLEGetCurrentFunction(glBlendEquationSeparate) - #define glCompileShader GLEGetCurrentFunction(glCompileShader) - #define glCreateProgram GLEGetCurrentFunction(glCreateProgram) - #define glCreateShader GLEGetCurrentFunction(glCreateShader) - #define glDeleteProgram GLEGetCurrentFunction(glDeleteProgram) - #define glDeleteShader GLEGetCurrentFunction(glDeleteShader) - #define glDetachShader GLEGetCurrentFunction(glDetachShader) - #define glDisableVertexAttribArray GLEGetCurrentFunction(glDisableVertexAttribArray) - #define glDrawBuffers GLEGetCurrentFunction(glDrawBuffers) - #define glEnableVertexAttribArray GLEGetCurrentFunction(glEnableVertexAttribArray) - #define glGetActiveAttrib GLEGetCurrentFunction(glGetActiveAttrib) - #define glGetActiveUniform GLEGetCurrentFunction(glGetActiveUniform) - #define glGetAttachedShaders GLEGetCurrentFunction(glGetAttachedShaders) - #define glGetAttribLocation GLEGetCurrentFunction(glGetAttribLocation) - #define glGetProgramInfoLog GLEGetCurrentFunction(glGetProgramInfoLog) - #define glGetProgramiv GLEGetCurrentFunction(glGetProgramiv) - #define glGetShaderInfoLog GLEGetCurrentFunction(glGetShaderInfoLog) - #define glGetShaderSource GLEGetCurrentFunction(glGetShaderSource) - #define glGetShaderiv GLEGetCurrentFunction(glGetShaderiv) - #define glGetUniformLocation GLEGetCurrentFunction(glGetUniformLocation) - #define glGetUniformfv GLEGetCurrentFunction(glGetUniformfv) - #define glGetUniformiv GLEGetCurrentFunction(glGetUniformiv) - #define glGetVertexAttribPointerv GLEGetCurrentFunction(glGetVertexAttribPointerv) - #define glGetVertexAttribdv GLEGetCurrentFunction(glGetVertexAttribdv) - #define glGetVertexAttribfv GLEGetCurrentFunction(glGetVertexAttribfv) - #define glGetVertexAttribiv GLEGetCurrentFunction(glGetVertexAttribiv) - #define glIsProgram GLEGetCurrentFunction(glIsProgram) - #define glIsShader GLEGetCurrentFunction(glIsShader) - #define glLinkProgram GLEGetCurrentFunction(glLinkProgram) - #define glShaderSource GLEGetCurrentFunction(glShaderSource) - #define glStencilFuncSeparate GLEGetCurrentFunction(glStencilFuncSeparate) - #define glStencilMaskSeparate GLEGetCurrentFunction(glStencilMaskSeparate) - #define glStencilOpSeparate GLEGetCurrentFunction(glStencilOpSeparate) - #define glUniform1f GLEGetCurrentFunction(glUniform1f) - #define glUniform1fv GLEGetCurrentFunction(glUniform1fv) - #define glUniform1i GLEGetCurrentFunction(glUniform1i) - #define glUniform1iv GLEGetCurrentFunction(glUniform1iv) - #define glUniform2f GLEGetCurrentFunction(glUniform2f) - #define glUniform2fv GLEGetCurrentFunction(glUniform2fv) - #define glUniform2i GLEGetCurrentFunction(glUniform2i) - #define glUniform2iv GLEGetCurrentFunction(glUniform2iv) - #define glUniform3f GLEGetCurrentFunction(glUniform3f) - #define glUniform3fv GLEGetCurrentFunction(glUniform3fv) - #define glUniform3i GLEGetCurrentFunction(glUniform3i) - #define glUniform3iv GLEGetCurrentFunction(glUniform3iv) - #define glUniform4f GLEGetCurrentFunction(glUniform4f) - #define glUniform4fv GLEGetCurrentFunction(glUniform4fv) - #define glUniform4i GLEGetCurrentFunction(glUniform4i) - #define glUniform4iv GLEGetCurrentFunction(glUniform4iv) - #define glUniformMatrix2fv GLEGetCurrentFunction(glUniformMatrix2fv) - #define glUniformMatrix3fv GLEGetCurrentFunction(glUniformMatrix3fv) - #define glUniformMatrix4fv GLEGetCurrentFunction(glUniformMatrix4fv) - #define glUseProgram GLEGetCurrentFunction(glUseProgram) - #define glValidateProgram GLEGetCurrentFunction(glValidateProgram) - #define glVertexAttrib1d GLEGetCurrentFunction(glVertexAttrib1d) - #define glVertexAttrib1dv GLEGetCurrentFunction(glVertexAttrib1dv) - #define glVertexAttrib1f GLEGetCurrentFunction(glVertexAttrib1f) - #define glVertexAttrib1fv GLEGetCurrentFunction(glVertexAttrib1fv) - #define glVertexAttrib1s GLEGetCurrentFunction(glVertexAttrib1s) - #define glVertexAttrib1sv GLEGetCurrentFunction(glVertexAttrib1sv) - #define glVertexAttrib2d GLEGetCurrentFunction(glVertexAttrib2d) - #define glVertexAttrib2dv GLEGetCurrentFunction(glVertexAttrib2dv) - #define glVertexAttrib2f GLEGetCurrentFunction(glVertexAttrib2f) - #define glVertexAttrib2fv GLEGetCurrentFunction(glVertexAttrib2fv) - #define glVertexAttrib2s GLEGetCurrentFunction(glVertexAttrib2s) - #define glVertexAttrib2sv GLEGetCurrentFunction(glVertexAttrib2sv) - #define glVertexAttrib3d GLEGetCurrentFunction(glVertexAttrib3d) - #define glVertexAttrib3dv GLEGetCurrentFunction(glVertexAttrib3dv) - #define glVertexAttrib3f GLEGetCurrentFunction(glVertexAttrib3f) - #define glVertexAttrib3fv GLEGetCurrentFunction(glVertexAttrib3fv) - #define glVertexAttrib3s GLEGetCurrentFunction(glVertexAttrib3s) - #define glVertexAttrib3sv GLEGetCurrentFunction(glVertexAttrib3sv) - #define glVertexAttrib4Nbv GLEGetCurrentFunction(glVertexAttrib4Nbv) - #define glVertexAttrib4Niv GLEGetCurrentFunction(glVertexAttrib4Niv) - #define glVertexAttrib4Nsv GLEGetCurrentFunction(glVertexAttrib4Nsv) - #define glVertexAttrib4Nub GLEGetCurrentFunction(glVertexAttrib4Nub) - #define glVertexAttrib4Nubv GLEGetCurrentFunction(glVertexAttrib4Nubv) - #define glVertexAttrib4Nuiv GLEGetCurrentFunction(glVertexAttrib4Nuiv) - #define glVertexAttrib4Nusv GLEGetCurrentFunction(glVertexAttrib4Nusv) - #define glVertexAttrib4bv GLEGetCurrentFunction(glVertexAttrib4bv) - #define glVertexAttrib4d GLEGetCurrentFunction(glVertexAttrib4d) - #define glVertexAttrib4dv GLEGetCurrentFunction(glVertexAttrib4dv) - #define glVertexAttrib4f GLEGetCurrentFunction(glVertexAttrib4f) - #define glVertexAttrib4fv GLEGetCurrentFunction(glVertexAttrib4fv) - #define glVertexAttrib4iv GLEGetCurrentFunction(glVertexAttrib4iv) - #define glVertexAttrib4s GLEGetCurrentFunction(glVertexAttrib4s) - #define glVertexAttrib4sv GLEGetCurrentFunction(glVertexAttrib4sv) - #define glVertexAttrib4ubv GLEGetCurrentFunction(glVertexAttrib4ubv) - #define glVertexAttrib4uiv GLEGetCurrentFunction(glVertexAttrib4uiv) - #define glVertexAttrib4usv GLEGetCurrentFunction(glVertexAttrib4usv) - #define glVertexAttribPointer GLEGetCurrentFunction(glVertexAttribPointer) - -#endif // GL_VERSION_2_0 - - - -#ifndef GL_VERSION_2_1 - #define GL_VERSION_2_1 1 - - #define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F - #define GL_PIXEL_PACK_BUFFER 0x88EB - #define GL_PIXEL_UNPACK_BUFFER 0x88EC - #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED - #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF - #define GL_FLOAT_MAT2x3 0x8B65 - #define GL_FLOAT_MAT2x4 0x8B66 - #define GL_FLOAT_MAT3x2 0x8B67 - #define GL_FLOAT_MAT3x4 0x8B68 - #define GL_FLOAT_MAT4x2 0x8B69 - #define GL_FLOAT_MAT4x3 0x8B6A - #define GL_SRGB 0x8C40 - #define GL_SRGB8 0x8C41 - #define GL_SRGB_ALPHA 0x8C42 - #define GL_SRGB8_ALPHA8 0x8C43 - #define GL_SLUMINANCE_ALPHA 0x8C44 - #define GL_SLUMINANCE8_ALPHA8 0x8C45 - #define GL_SLUMINANCE 0x8C46 - #define GL_SLUMINANCE8 0x8C47 - #define GL_COMPRESSED_SRGB 0x8C48 - #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 - #define GL_COMPRESSED_SLUMINANCE 0x8C4A - #define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B - - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); - - #define glUniformMatrix2x3fv GLEGetCurrentFunction(glUniformMatrix2x3fv) - #define glUniformMatrix2x4fv GLEGetCurrentFunction(glUniformMatrix2x4fv) - #define glUniformMatrix3x2fv GLEGetCurrentFunction(glUniformMatrix3x2fv) - #define glUniformMatrix3x4fv GLEGetCurrentFunction(glUniformMatrix3x4fv) - #define glUniformMatrix4x2fv GLEGetCurrentFunction(glUniformMatrix4x2fv) - #define glUniformMatrix4x3fv GLEGetCurrentFunction(glUniformMatrix4x3fv) - -#endif // GL_VERSION_2_1 - - - - -#ifndef GL_VERSION_3_0 - #define GL_VERSION_3_0 1 - - #define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 - #define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 - #define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 - #define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 - #define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 - #define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 - #define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB - #define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES - #define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS - #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 - #define GL_MAJOR_VERSION 0x821B - #define GL_MINOR_VERSION 0x821C - #define GL_NUM_EXTENSIONS 0x821D - #define GL_CONTEXT_FLAGS 0x821E - #define GL_DEPTH_BUFFER 0x8223 - #define GL_STENCIL_BUFFER 0x8224 - #define GL_RGBA32F 0x8814 - #define GL_RGB32F 0x8815 - #define GL_RGBA16F 0x881A - #define GL_RGB16F 0x881B - #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD - #define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF - #define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 - #define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 - #define GL_CLAMP_VERTEX_COLOR 0x891A - #define GL_CLAMP_FRAGMENT_COLOR 0x891B - #define GL_CLAMP_READ_COLOR 0x891C - #define GL_FIXED_ONLY 0x891D - #define GL_TEXTURE_RED_TYPE 0x8C10 - #define GL_TEXTURE_GREEN_TYPE 0x8C11 - #define GL_TEXTURE_BLUE_TYPE 0x8C12 - #define GL_TEXTURE_ALPHA_TYPE 0x8C13 - #define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 - #define GL_TEXTURE_INTENSITY_TYPE 0x8C15 - #define GL_TEXTURE_DEPTH_TYPE 0x8C16 - #define GL_TEXTURE_1D_ARRAY 0x8C18 - #define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 - #define GL_TEXTURE_2D_ARRAY 0x8C1A - #define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B - #define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C - #define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D - #define GL_R11F_G11F_B10F 0x8C3A - #define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B - #define GL_RGB9_E5 0x8C3D - #define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E - #define GL_TEXTURE_SHARED_SIZE 0x8C3F - #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 - #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F - #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 - #define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 - #define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 - #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 - #define GL_PRIMITIVES_GENERATED 0x8C87 - #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 - #define GL_RASTERIZER_DISCARD 0x8C89 - #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A - #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B - #define GL_INTERLEAVED_ATTRIBS 0x8C8C - #define GL_SEPARATE_ATTRIBS 0x8C8D - #define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E - #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F - #define GL_RGBA32UI 0x8D70 - #define GL_RGB32UI 0x8D71 - #define GL_RGBA16UI 0x8D76 - #define GL_RGB16UI 0x8D77 - #define GL_RGBA8UI 0x8D7C - #define GL_RGB8UI 0x8D7D - #define GL_RGBA32I 0x8D82 - #define GL_RGB32I 0x8D83 - #define GL_RGBA16I 0x8D88 - #define GL_RGB16I 0x8D89 - #define GL_RGBA8I 0x8D8E - #define GL_RGB8I 0x8D8F - #define GL_RED_INTEGER 0x8D94 - #define GL_GREEN_INTEGER 0x8D95 - #define GL_BLUE_INTEGER 0x8D96 - #define GL_ALPHA_INTEGER 0x8D97 - #define GL_RGB_INTEGER 0x8D98 - #define GL_RGBA_INTEGER 0x8D99 - #define GL_BGR_INTEGER 0x8D9A - #define GL_BGRA_INTEGER 0x8D9B - #define GL_SAMPLER_1D_ARRAY 0x8DC0 - #define GL_SAMPLER_2D_ARRAY 0x8DC1 - #define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 - #define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 - #define GL_SAMPLER_CUBE_SHADOW 0x8DC5 - #define GL_UNSIGNED_INT_VEC2 0x8DC6 - #define GL_UNSIGNED_INT_VEC3 0x8DC7 - #define GL_UNSIGNED_INT_VEC4 0x8DC8 - #define GL_INT_SAMPLER_1D 0x8DC9 - #define GL_INT_SAMPLER_2D 0x8DCA - #define GL_INT_SAMPLER_3D 0x8DCB - #define GL_INT_SAMPLER_CUBE 0x8DCC - #define GL_INT_SAMPLER_1D_ARRAY 0x8DCE - #define GL_INT_SAMPLER_2D_ARRAY 0x8DCF - #define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 - #define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 - #define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 - #define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 - #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 - #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 - #define GL_QUERY_WAIT 0x8E13 - #define GL_QUERY_NO_WAIT 0x8E14 - #define GL_QUERY_BY_REGION_WAIT 0x8E15 - #define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 - - typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); - typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); - typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint colorNumber, const GLchar* name); - typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); - typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil); - typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawBuffer, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawBuffer, const GLint* value); - typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawBuffer, const GLuint* value); - typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); - typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum cap, GLuint index); - typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum cap, GLuint index); - typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); - typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); - typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); - typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); - typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum pname, GLuint index, GLboolean* data); - typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data); - typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar* name); - typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); - typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint* params); - typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); - typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint* params); - typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint* params); - typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum cap, GLuint index); - typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint* params); - typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint* params); - typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); - typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); - typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); - typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); - typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint* value); - typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); - typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint* value); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint v0, GLint v1); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint v0, GLuint v1); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint v0, GLint v1, GLint v2); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint v0, GLint v1, GLint v2, GLint v3); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort* v0); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void*pointer); - - #define glBeginConditionalRender GLEGetCurrentFunction(glBeginConditionalRender) - #define glBeginTransformFeedback GLEGetCurrentFunction(glBeginTransformFeedback) - #define glBindFragDataLocation GLEGetCurrentFunction(glBindFragDataLocation) - #define glClampColor GLEGetCurrentFunction(glClampColor) - #define glClearBufferfi GLEGetCurrentFunction(glClearBufferfi) - #define glClearBufferfv GLEGetCurrentFunction(glClearBufferfv) - #define glClearBufferiv GLEGetCurrentFunction(glClearBufferiv) - #define glClearBufferuiv GLEGetCurrentFunction(glClearBufferuiv) - #define glColorMaski GLEGetCurrentFunction(glColorMaski) - #define glDisablei GLEGetCurrentFunction(glDisablei) - #define glEnablei GLEGetCurrentFunction(glEnablei) - #define glEndConditionalRender GLEGetCurrentFunction(glEndConditionalRender) - #define glEndTransformFeedback GLEGetCurrentFunction(glEndTransformFeedback) - #define glGetBooleani_v GLEGetCurrentFunction(glGetBooleani_v) - #define glGetIntegeri_v GLEGetCurrentFunction(glGetIntegeri_v) - #define glGetFragDataLocation GLEGetCurrentFunction(glGetFragDataLocation) - #define glGetStringi GLEGetCurrentFunction(glGetStringi) - #define glGetTexParameterIiv GLEGetCurrentFunction(glGetTexParameterIiv) - #define glGetTexParameterIuiv GLEGetCurrentFunction(glGetTexParameterIuiv) - #define glGetTransformFeedbackVarying GLEGetCurrentFunction(glGetTransformFeedbackVarying) - #define glGetUniformuiv GLEGetCurrentFunction(glGetUniformuiv) - #define glGetVertexAttribIiv GLEGetCurrentFunction(glGetVertexAttribIiv) - #define glGetVertexAttribIuiv GLEGetCurrentFunction(glGetVertexAttribIuiv) - #define glIsEnabledi GLEGetCurrentFunction(glIsEnabledi) - #define glTexParameterIiv GLEGetCurrentFunction(glTexParameterIiv) - #define glTexParameterIuiv GLEGetCurrentFunction(glTexParameterIuiv) - #define glTransformFeedbackVaryings GLEGetCurrentFunction(glTransformFeedbackVaryings) - #define glUniform1ui GLEGetCurrentFunction(glUniform1ui) - #define glUniform1uiv GLEGetCurrentFunction(glUniform1uiv) - #define glUniform2ui GLEGetCurrentFunction(glUniform2ui) - #define glUniform2uiv GLEGetCurrentFunction(glUniform2uiv) - #define glUniform3ui GLEGetCurrentFunction(glUniform3ui) - #define glUniform3uiv GLEGetCurrentFunction(glUniform3uiv) - #define glUniform4ui GLEGetCurrentFunction(glUniform4ui) - #define glUniform4uiv GLEGetCurrentFunction(glUniform4uiv) - #define glVertexAttribI1i GLEGetCurrentFunction(glVertexAttribI1i) - #define glVertexAttribI1iv GLEGetCurrentFunction(glVertexAttribI1iv) - #define glVertexAttribI1ui GLEGetCurrentFunction(glVertexAttribI1ui) - #define glVertexAttribI1uiv GLEGetCurrentFunction(glVertexAttribI1uiv) - #define glVertexAttribI2i GLEGetCurrentFunction(glVertexAttribI2i) - #define glVertexAttribI2iv GLEGetCurrentFunction(glVertexAttribI2iv) - #define glVertexAttribI2ui GLEGetCurrentFunction(glVertexAttribI2ui) - #define glVertexAttribI2uiv GLEGetCurrentFunction(glVertexAttribI2uiv) - #define glVertexAttribI3i GLEGetCurrentFunction(glVertexAttribI3i) - #define glVertexAttribI3iv GLEGetCurrentFunction(glVertexAttribI3iv) - #define glVertexAttribI3ui GLEGetCurrentFunction(glVertexAttribI3ui) - #define glVertexAttribI3uiv GLEGetCurrentFunction(glVertexAttribI3uiv) - #define glVertexAttribI4bv GLEGetCurrentFunction(glVertexAttribI4bv) - #define glVertexAttribI4i GLEGetCurrentFunction(glVertexAttribI4i) - #define glVertexAttribI4iv GLEGetCurrentFunction(glVertexAttribI4iv) - #define glVertexAttribI4sv GLEGetCurrentFunction(glVertexAttribI4sv) - #define glVertexAttribI4ubv GLEGetCurrentFunction(glVertexAttribI4ubv) - #define glVertexAttribI4ui GLEGetCurrentFunction(glVertexAttribI4ui) - #define glVertexAttribI4uiv GLEGetCurrentFunction(glVertexAttribI4uiv) - #define glVertexAttribI4usv GLEGetCurrentFunction(glVertexAttribI4usv) - #define glVertexAttribIPointer GLEGetCurrentFunction(glVertexAttribIPointer) - -#endif // GL_VERSION_3_0 - - - - -#ifndef GL_VERSION_3_1 - #define GL_VERSION_3_1 1 - - #define GL_TEXTURE_RECTANGLE 0x84F5 - #define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 - #define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 - #define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 - #define GL_SAMPLER_2D_RECT 0x8B63 - #define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 - #define GL_TEXTURE_BUFFER 0x8C2A - #define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B - #define GL_TEXTURE_BINDING_BUFFER 0x8C2C - #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D - #define GL_TEXTURE_BUFFER_FORMAT 0x8C2E - #define GL_SAMPLER_BUFFER 0x8DC2 - #define GL_INT_SAMPLER_2D_RECT 0x8DCD - #define GL_INT_SAMPLER_BUFFER 0x8DD0 - #define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 - #define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 - #define GL_RED_SNORM 0x8F90 - #define GL_RG_SNORM 0x8F91 - #define GL_RGB_SNORM 0x8F92 - #define GL_RGBA_SNORM 0x8F93 - #define GL_R8_SNORM 0x8F94 - #define GL_RG8_SNORM 0x8F95 - #define GL_RGB8_SNORM 0x8F96 - #define GL_RGBA8_SNORM 0x8F97 - #define GL_R16_SNORM 0x8F98 - #define GL_RG16_SNORM 0x8F99 - #define GL_RGB16_SNORM 0x8F9A - #define GL_RGBA16_SNORM 0x8F9B - #define GL_SIGNED_NORMALIZED 0x8F9C - #define GL_PRIMITIVE_RESTART 0x8F9D - #define GL_PRIMITIVE_RESTART_INDEX 0x8F9E - #define GL_BUFFER_ACCESS_FLAGS 0x911F - #define GL_BUFFER_MAP_LENGTH 0x9120 - #define GL_BUFFER_MAP_OFFSET 0x9121 - - typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); - typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); - typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint buffer); - typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalFormat, GLuint buffer); - - #define glDrawArraysInstanced GLEGetCurrentFunction(glDrawArraysInstanced) - #define glDrawElementsInstanced GLEGetCurrentFunction(glDrawElementsInstanced) - #define glPrimitiveRestartIndex GLEGetCurrentFunction(glPrimitiveRestartIndex) - #define glTexBuffer GLEGetCurrentFunction(glTexBuffer) - -#endif // GL_VERSION_3_1 - - - -#ifndef GL_VERSION_3_2 - #define GL_VERSION_3_2 1 - - #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 - #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 - #define GL_LINES_ADJACENCY 0x000A - #define GL_LINE_STRIP_ADJACENCY 0x000B - #define GL_TRIANGLES_ADJACENCY 0x000C - #define GL_TRIANGLE_STRIP_ADJACENCY 0x000D - #define GL_PROGRAM_POINT_SIZE 0x8642 - #define GL_GEOMETRY_VERTICES_OUT 0x8916 - #define GL_GEOMETRY_INPUT_TYPE 0x8917 - #define GL_GEOMETRY_OUTPUT_TYPE 0x8918 - #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 - #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 - #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 - #define GL_GEOMETRY_SHADER 0x8DD9 - #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF - #define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 - #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 - #define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 - #define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 - #define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 - #define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 - #define GL_CONTEXT_PROFILE_MASK 0x9126 - - typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); - typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum value, GLint64 * data); - typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum pname, GLuint index, GLint64 * data); - - #define glFramebufferTexture GLEGetCurrentFunction(glFramebufferTexture) - #define glGetBufferParameteri64v GLEGetCurrentFunction(glGetBufferParameteri64v) - #define glGetInteger64i_v GLEGetCurrentFunction(glGetInteger64i_v) - -#endif // GL_VERSION_3_2 - - - -#ifndef GL_VERSION_3_3 - #define GL_VERSION_3_3 1 - - #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE - #define GL_RGB10_A2UI 0x906F - - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); - - #define glVertexAttribDivisor GLEGetCurrentFunction(glVertexAttribDivisor) -#endif - - - -#ifndef GL_VERSION_4_0 - #define GL_VERSION_4_0 1 - - #define GL_SAMPLE_SHADING 0x8C36 - #define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 - #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E - #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F - #define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F - #define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 - #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A - #define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B - #define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C - #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D - #define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E - #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F - - typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); - typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); - typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); - typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); - typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value); - - #define glBlendEquationSeparatei GLEGetCurrentFunction(glBlendEquationSeparatei) - #define glBlendEquationi GLEGetCurrentFunction(glBlendEquationi) - #define glBlendFuncSeparatei GLEGetCurrentFunction(glBlendFuncSeparatei) - #define glBlendFunci GLEGetCurrentFunction(glBlendFunci) - #define glMinSampleShading GLEGetCurrentFunction(glMinSampleShading) - -#endif // GL_VERSION_4_0 - - - - -#ifndef GL_VERSION_4_1 - #define GL_VERSION_4_1 1 - // Empty -#endif - - - -#ifndef GL_VERSION_4_2 - #define GL_VERSION_4_2 1 - - #define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C - #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D - #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E - #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F -#endif - - - -#ifndef GL_VERSION_4_3 - #define GL_VERSION_4_3 1 - - #define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 - #define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E -#endif - - - -#ifndef GL_VERSION_4_4 - #define GL_VERSION_4_4 1 - - #define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 - #define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 - #define GL_TEXTURE_BUFFER_BINDING 0x8C2A -#endif - - - -#ifndef GL_VERSION_4_5 - #define GL_VERSION_4_5 1 - // Empty -#endif - - - -#ifndef GL_AMD_debug_output - #define GL_AMD_debug_output 1 - - #define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 - #define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 - #define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 - #define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 - #define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 - #define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 - #define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 - #define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A - #define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B - #define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C - #define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D - #define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E - #define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F - #define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 - - typedef void (GLAPIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, void* userParam); - - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf); - typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message); - - #define glDebugMessageCallbackAMD GLEGetCurrentFunction(glDebugMessageCallbackAMD) - #define glDebugMessageEnableAMD GLEGetCurrentFunction(glDebugMessageEnableAMD) - #define glDebugMessageInsertAMD GLEGetCurrentFunction(glDebugMessageInsertAMD) - #define glGetDebugMessageLogAMD GLEGetCurrentFunction(glGetDebugMessageLogAMD) - - #define GLE_AMD_debug_output GLEGetCurrentVariable(gle_AMD_debug_output) - -#endif // GL_AMD_debug_output - - - -/* Disabled until needed -#ifndef GL_AMD_performance_monitor - #define GL_AMD_performance_monitor 1 - - #define GL_COUNTER_TYPE_AMD 0x8BC0 - #define GL_COUNTER_RANGE_AMD 0x8BC1 - #define GL_UNSIGNED_INT64_AMD 0x8BC2 - #define GL_PERCENTAGE_AMD 0x8BC3 - #define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 - #define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 - #define GL_PERFMON_RESULT_AMD 0x8BC6 - - typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); - typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); - typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); - typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); - typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten); - typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); - typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar *counterString); - typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters); - typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, GLchar *groupString); - typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups); - typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList); - - #define glBeginPerfMonitorAMD GLEGetCurrentFunction(glBeginPerfMonitorAMD) - #define glDeletePerfMonitorsAMD GLEGetCurrentFunction(glDeletePerfMonitorsAMD) - #define glEndPerfMonitorAMD GLEGetCurrentFunction(glEndPerfMonitorAMD) - #define glGenPerfMonitorsAMD GLEGetCurrentFunction(glGenPerfMonitorsAMD) - #define glGetPerfMonitorCounterDataAMD GLEGetCurrentFunction(glGetPerfMonitorCounterDataAMD) - #define glGetPerfMonitorCounterInfoAMD GLEGetCurrentFunction(glGetPerfMonitorCounterInfoAMD) - #define glGetPerfMonitorCounterStringAMD GLEGetCurrentFunction(glGetPerfMonitorCounterStringAMD) - #define glGetPerfMonitorCountersAMD GLEGetCurrentFunction(glGetPerfMonitorCountersAMD) - #define glGetPerfMonitorGroupStringAMD GLEGetCurrentFunction(glGetPerfMonitorGroupStringAMD) - #define glGetPerfMonitorGroupsAMD GLEGetCurrentFunction(glGetPerfMonitorGroupsAMD) - #define glSelectPerfMonitorCountersAMD GLEGetCurrentFunction(glSelectPerfMonitorCountersAMD) - - #define GLE_AMD_performance_monitor GLEGetCurrentVariable(gle_AMD_performance_monitor) - -#endif // GL_AMD_performance_monitor -*/ - - -#if defined(GLE_CGL_ENABLED) - #ifndef GL_APPLE_aux_depth_stencil - #define GL_APPLE_aux_depth_stencil 1 - - #define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14g - - #define GLE_APPLE_aux_depth_stencil GLEGetCurrentVariable(gle_APPLE_aux_depth_stencil) - #endif - - - - #ifndef GL_APPLE_client_storage - #define GL_APPLE_client_storage 1 - - #define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 - - #define GLE_APPLE_client_storage GLEGetCurrentVariable(gle_APPLE_client_storage) - #endif - - - - #ifndef GL_APPLE_element_array - #define GL_APPLE_element_array 1 - - #define GL_ELEMENT_ARRAY_APPLE 0x8A0C - #define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D - #define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E - - typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); - typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); - typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); - typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); - typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); - - #define glDrawElementArrayAPPLE GLEGetCurrentFunction(glDrawElementArrayAPPLE) - #define glDrawRangeElementArrayAPPLE GLEGetCurrentFunction(glDrawRangeElementArrayAPPLE) - #define glElementPointerAPPLE GLEGetCurrentFunction(glElementPointerAPPLE) - #define glMultiDrawElementArrayAPPLE GLEGetCurrentFunction(glMultiDrawElementArrayAPPLE) - #define glMultiDrawRangeElementArrayAPPLE GLEGetCurrentFunction(glMultiDrawRangeElementArrayAPPLE) - - #define GLE_APPLE_element_array GLEGetCurrentVariable(gle_APPLE_element_array) - #endif - - - - #ifndef GL_APPLE_fence - #define GL_APPLE_fence 1 - - #define GL_DRAW_PIXELS_APPLE 0x8A0A - #define GL_FENCE_APPLE 0x8A0B - - typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); - typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); - typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); - typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); - typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); - typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); - typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); - typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); - - #define glDeleteFencesAPPLE GLEGetCurrentFunction(glDeleteFencesAPPLE) - #define glFinishFenceAPPLE GLEGetCurrentFunction(glFinishFenceAPPLE) - #define glFinishObjectAPPLE GLEGetCurrentFunction(glFinishObjectAPPLE) - #define glGenFencesAPPLE GLEGetCurrentFunction(glGenFencesAPPLE) - #define glIsFenceAPPLE GLEGetCurrentFunction(glIsFenceAPPLE) - #define glSetFenceAPPLE GLEGetCurrentFunction(glSetFenceAPPLE) - #define glTestFenceAPPLE GLEGetCurrentFunction(glTestFenceAPPLE) - #define glTestObjectAPPLE GLEGetCurrentFunction(glTestObjectAPPLE) - - #define GLE_APPLE_fence GLEGetCurrentVariable(gle_APPLE_fence) - - #endif - - - - #ifndef GL_APPLE_float_pixels - #define GL_APPLE_float_pixels 1 - - #define GL_HALF_APPLE 0x140B - #define GL_RGBA_FLOAT32_APPLE 0x8814 - #define GL_RGB_FLOAT32_APPLE 0x8815 - #define GL_ALPHA_FLOAT32_APPLE 0x8816 - #define GL_INTENSITY_FLOAT32_APPLE 0x8817 - #define GL_LUMINANCE_FLOAT32_APPLE 0x8818 - #define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 - #define GL_RGBA_FLOAT16_APPLE 0x881A - #define GL_RGB_FLOAT16_APPLE 0x881B - #define GL_ALPHA_FLOAT16_APPLE 0x881C - #define GL_INTENSITY_FLOAT16_APPLE 0x881D - #define GL_LUMINANCE_FLOAT16_APPLE 0x881E - #define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F - #define GL_COLOR_FLOAT_APPLE 0x8A0F - - #define GLE_APPLE_float_pixels GLEGetCurrentVariable(gle_APPLE_float_pixels) - #endif - - - - #ifndef GL_APPLE_flush_buffer_range - #define GL_APPLE_flush_buffer_range 1 - - #define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 - #define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 - - typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); - typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); - - #define glBufferParameteriAPPLE GLEGetCurrentFunction(glBufferParameteriAPPLE) - #define glFlushMappedBufferRangeAPPLE GLEGetCurrentFunction(glFlushMappedBufferRangeAPPLE) - - #define GLE_APPLE_flush_buffer_range GLEGetCurrentVariable(gle_APPLE_flush_buffer_range) - #endif - - - - #ifndef GL_APPLE_object_purgeable - #define GL_APPLE_object_purgeable 1 - - #define GL_BUFFER_OBJECT_APPLE 0x85B3 - #define GL_RELEASED_APPLE 0x8A19 - #define GL_VOLATILE_APPLE 0x8A1A - #define GL_RETAINED_APPLE 0x8A1B - #define GL_UNDEFINED_APPLE 0x8A1C - #define GL_PURGEABLE_APPLE 0x8A1D - - typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params); - typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); - typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); - - #define glGetObjectParameterivAPPLE GLEGetCurrentFunction(glGetObjectParameterivAPPLE) - #define glObjectPurgeableAPPLE GLEGetCurrentFunction(glObjectPurgeableAPPLE) - #define glObjectUnpurgeableAPPLE GLEGetCurrentFunction(glObjectUnpurgeableAPPLE) - - #define GLE_APPLE_object_purgeable GLEGetCurrentVariable(gle_APPLE_object_purgeable) - #endif - - - - #ifndef GL_APPLE_pixel_buffer - #define GL_APPLE_pixel_buffer 1 - - #define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 - - #define GLE_APPLE_pixel_buffer GLEGetCurrentVariable(gle_APPLE_pixel_buffer) - #endif - - - - #ifndef GL_APPLE_rgb_422 - #define GL_APPLE_rgb_422 1 - - #define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA - #define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB - #define GL_RGB_422_APPLE 0x8A1F - #define GL_RGB_RAW_422_APPLE 0x8A51 - - #define GLE_APPLE_rgb_422 GLEGetCurrentVariable(gle_APPLE_rgb_422) - #endif - - - - #ifndef GL_APPLE_row_bytes - #define GL_APPLE_row_bytes 1 - - #define GL_PACK_ROW_BYTES_APPLE 0x8A15 - #define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 - - #define GLE_APPLE_row_bytes GLEGetCurrentVariable(gle_APPLE_row_bytes) - #endif - - - - #ifndef GL_APPLE_specular_vector - #define GL_APPLE_specular_vector 1 - - #define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 - - #define GLE_APPLE_specular_vector GLEGetCurrentVariable(gle_APPLE_specular_vector) - #endif - - - - #ifndef GL_APPLE_texture_range - #define GL_APPLE_texture_range 1 - - #define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 - #define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 - #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC - #define GL_STORAGE_PRIVATE_APPLE 0x85BD - #define GL_STORAGE_CACHED_APPLE 0x85BE - #define GL_STORAGE_SHARED_APPLE 0x85BF - - typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); - typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const void *pointer); - - #define glGetTexParameterPointervAPPLE GLEGetCurrentFunction(glGetTexParameterPointervAPPLE) - #define glTextureRangeAPPLE GLEGetCurrentFunction(glTextureRangeAPPLE) - - #define GLE_APPLE_texture_range GLEGetCurrentVariable(gle_APPLE_texture_range) - #endif - - - #ifndef GL_APPLE_transform_hint - #define GL_APPLE_transform_hint 1 - - #define GL_TRANSFORM_HINT_APPLE 0x85B1 - - #define GLE_APPLE_transform_hint GLEGetCurrentVariable(gle_APPLE_transform_hint) - #endif - - - - #ifndef GL_APPLE_vertex_array_object - #define GL_APPLE_vertex_array_object 1 - - // This has been superceded by GL_ARB_vertex_array_object, though if you are using Apple - // OpenGL prior to 3.x then only this interface will be available. However, we have made - // it so that glBindVertexArray maps to glBindVertexArrayApple when only the latter is present, - // thus allowing you to write cleaner code. You can always just call glBindVertexArray instead - // of glBindVertexArrayAPPLE, etc. - #define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 - - typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); - typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); - typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); // It's not clear whether arrays needs to be const or not. - typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); - - #define glBindVertexArrayAPPLE GLEGetCurrentFunction(glBindVertexArrayAPPLE) - #define glDeleteVertexArraysAPPLE GLEGetCurrentFunction(glDeleteVertexArraysAPPLE) - #define glGenVertexArraysAPPLE GLEGetCurrentFunction(glGenVertexArraysAPPLE) - #define glIsVertexArrayAPPLE GLEGetCurrentFunction(glIsVertexArrayAPPLE) - - #define GLE_APPLE_vertex_array_object GLEGetCurrentVariable(gle_APPLE_vertex_array_object) - #endif - - - - #ifndef GL_APPLE_vertex_array_range - #define GL_APPLE_vertex_array_range 1 - - #define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D - #define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E - #define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F - #define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 - #define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 - #define GL_STORAGE_CLIENT_APPLE 0x85B4 - #define GL_STORAGE_CACHED_APPLE 0x85BE - #define GL_STORAGE_SHARED_APPLE 0x85BF - - typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); - - #define glFlushVertexArrayRangeAPPLE GLEGetCurrentFunction(glFlushVertexArrayRangeAPPLE) - #define glVertexArrayParameteriAPPLE GLEGetCurrentFunction(glVertexArrayParameteriAPPLE) - #define glVertexArrayRangeAPPLE GLEGetCurrentFunction(glVertexArrayRangeAPPLE) - - #define GLE_APPLE_vertex_array_range GLEGetCurrentVariable(gle_APPLE_vertex_array_range) - #endif - - - - #ifndef GL_APPLE_vertex_program_evaluators - #define GL_APPLE_vertex_program_evaluators 1 - - #define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 - #define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 - #define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 - #define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 - #define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 - #define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 - #define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 - #define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 - #define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 - #define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 - - typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); - typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); - typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); - typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); - typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); - typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points); - typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points); - - #define glDisableVertexAttribAPPLE GLEGetCurrentFunction(glDisableVertexAttribAPPLE) - #define glEnableVertexAttribAPPLE GLEGetCurrentFunction(glEnableVertexAttribAPPLE) - #define glIsVertexAttribEnabledAPPLE GLEGetCurrentFunction(glIsVertexAttribEnabledAPPLE) - #define glMapVertexAttrib1dAPPLE GLEGetCurrentFunction(glMapVertexAttrib1dAPPLE) - #define glMapVertexAttrib1fAPPLE GLEGetCurrentFunction(glMapVertexAttrib1fAPPLE) - #define glMapVertexAttrib2dAPPLE GLEGetCurrentFunction(glMapVertexAttrib2dAPPLE) - #define glMapVertexAttrib2fAPPLE GLEGetCurrentFunction(glMapVertexAttrib2fAPPLE) - - #define GLE_APPLE_vertex_program_evaluators GLEGetCurrentVariable(gle_APPLE_vertex_program_evaluators) - #endif - -#endif // GLE_CGL_ENABLED - - -#ifndef GL_ARB_debug_output - #define GL_ARB_debug_output 1 - - #define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 - #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 - #define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 - #define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 - #define GL_DEBUG_SOURCE_API_ARB 0x8246 - #define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 - #define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 - #define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 - #define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A - #define GL_DEBUG_SOURCE_OTHER_ARB 0x824B - #define GL_DEBUG_TYPE_ERROR_ARB 0x824C - #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D - #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E - #define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F - #define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 - #define GL_DEBUG_TYPE_OTHER_ARB 0x8251 - #define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 - #define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 - #define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 - #define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 - #define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 - #define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 - - typedef void (GLAPIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); - - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); - typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); - - #define glDebugMessageCallbackARB GLEGetCurrentFunction(glDebugMessageCallbackARB) - #define glDebugMessageControlARB GLEGetCurrentFunction(glDebugMessageControlARB) - #define glDebugMessageInsertARB GLEGetCurrentFunction(glDebugMessageInsertARB) - #define glGetDebugMessageLogARB GLEGetCurrentFunction(glGetDebugMessageLogARB) - - #define GLE_ARB_debug_output GLEGetCurrentVariable(gle_ARB_debug_output) - -#endif // GL_ARB_debug_output - - - -#ifndef GL_ARB_depth_buffer_float - #define GL_ARB_depth_buffer_float 1 - - // Supercededs GL_NV_depth_buffer_float - #define GL_DEPTH_COMPONENT32F 0x8CAC - #define GL_DEPTH32F_STENCIL8 0x8CAD - #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD - - #define GLE_ARB_depth_buffer_float GLEGetCurrentVariable(gle_ARB_depth_buffer_float) -#endif - - -/* Disabled until needed -#ifndef GL_ARB_direct_state_access - #define GL_ARB_direct_state_access 1 - - #define GL_TEXTURE_TARGET 0x1006 - #define GL_QUERY_TARGET 0x82EA - #define GL_TEXTURE_BINDING 0x82EB - - typedef void (GLAPIENTRY * PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); - typedef void (GLAPIENTRY * PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); - typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); - typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); - typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLfloat depth, GLint stencil); - typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value); - typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value); - typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); - typedef void (GLAPIENTRY * PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); - typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); - typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); - typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - typedef void (GLAPIENTRY * PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint* buffers); - typedef void (GLAPIENTRY * PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); - typedef void (GLAPIENTRY * PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); - typedef void (GLAPIENTRY * PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint* ids); - typedef void (GLAPIENTRY * PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); - typedef void (GLAPIENTRY * PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint* samplers); - typedef void (GLAPIENTRY * PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint* textures); - typedef void (GLAPIENTRY * PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); - typedef void (GLAPIENTRY * PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); - typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); - typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); - typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); - typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); - typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); - typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64* params); - typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void** params); - typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); - typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint* param); - typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); - typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat* params); - typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint* params); - typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat* params); - typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64* param); - typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint* param); - typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint* param); - typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64* param); - typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); - typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint* param); - typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments); - typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); - typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); - typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); - typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); - typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); - typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); - typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum mode); - typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); - typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); - typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum mode); - typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); - typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); - typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); - typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); - typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); - typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); - typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint* params); - typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint* params); - typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); - typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat* param); - typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); - typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint* param); - typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); - typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); - typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); - typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); - typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); - typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); - typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); - typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); - typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); - typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides); - - #define glBindTextureUnit GLEGetCurrentFunction(glBindTextureUnit) - #define glBlitNamedFramebuffer GLEGetCurrentFunction(glBlitNamedFramebuffer) - #define glCheckNamedFramebufferStatus GLEGetCurrentFunction(glCheckNamedFramebufferStatus) - #define glClearNamedBufferData GLEGetCurrentFunction(glClearNamedBufferData) - #define glClearNamedBufferSubData GLEGetCurrentFunction(glClearNamedBufferSubData) - #define glClearNamedFramebufferfi GLEGetCurrentFunction(glClearNamedFramebufferfi) - #define glClearNamedFramebufferfv GLEGetCurrentFunction(glClearNamedFramebufferfv) - #define glClearNamedFramebufferiv GLEGetCurrentFunction(glClearNamedFramebufferiv) - #define glClearNamedFramebufferuiv GLEGetCurrentFunction(glClearNamedFramebufferuiv) - #define glCompressedTextureSubImage1D GLEGetCurrentFunction(glCompressedTextureSubImage1D) - #define glCompressedTextureSubImage2D GLEGetCurrentFunction(glCompressedTextureSubImage2D) - #define glCompressedTextureSubImage3D GLEGetCurrentFunction(glCompressedTextureSubImage3D) - #define glCopyNamedBufferSubData GLEGetCurrentFunction(glCopyNamedBufferSubData) - #define glCopyTextureSubImage1D GLEGetCurrentFunction(glCopyTextureSubImage1D) - #define glCopyTextureSubImage2D GLEGetCurrentFunction(glCopyTextureSubImage2D) - #define glCopyTextureSubImage3D GLEGetCurrentFunction(glCopyTextureSubImage3D) - #define glCreateBuffers GLEGetCurrentFunction(glCreateBuffers) - #define glCreateFramebuffers GLEGetCurrentFunction(glCreateFramebuffers) - #define glCreateProgramPipelines GLEGetCurrentFunction(glCreateProgramPipelines) - #define glCreateQueries GLEGetCurrentFunction(glCreateQueries) - #define glCreateRenderbuffers GLEGetCurrentFunction(glCreateRenderbuffers) - #define glCreateSamplers GLEGetCurrentFunction(glCreateSamplers) - #define glCreateTextures GLEGetCurrentFunction(glCreateTextures) - #define glCreateTransformFeedbacks GLEGetCurrentFunction(glCreateTransformFeedbacks) - #define glCreateVertexArrays GLEGetCurrentFunction(glCreateVertexArrays) - #define glDisableVertexArrayAttrib GLEGetCurrentFunction(glDisableVertexArrayAttrib) - #define glEnableVertexArrayAttrib GLEGetCurrentFunction(glEnableVertexArrayAttrib) - #define glFlushMappedNamedBufferRange GLEGetCurrentFunction(glFlushMappedNamedBufferRange) - #define glGenerateTextureMipmap GLEGetCurrentFunction(glGenerateTextureMipmap) - #define glGetCompressedTextureImage GLEGetCurrentFunction(glGetCompressedTextureImage) - #define glGetNamedBufferParameteri64v GLEGetCurrentFunction(glGetNamedBufferParameteri64v) - #define glGetNamedBufferParameteriv GLEGetCurrentFunction(glGetNamedBufferParameteriv) - #define glGetNamedBufferPointerv GLEGetCurrentFunction(glGetNamedBufferPointerv) - #define glGetNamedBufferSubData GLEGetCurrentFunction(glGetNamedBufferSubData) - #define glGetNamedFramebufferAttachmentParameteriv GLEGetCurrentFunction(glGetNamedFramebufferAttachmentParameteriv) - #define glGetNamedFramebufferParameteriv GLEGetCurrentFunction(glGetNamedFramebufferParameteriv) - #define glGetNamedRenderbufferParameteriv GLEGetCurrentFunction(glGetNamedRenderbufferParameteriv) - #define glGetTextureImage GLEGetCurrentFunction(glGetTextureImage) - #define glGetTextureLevelParameterfv GLEGetCurrentFunction(glGetTextureLevelParameterfv) - #define glGetTextureLevelParameteriv GLEGetCurrentFunction(glGetTextureLevelParameteriv) - #define glGetTextureParameterIiv GLEGetCurrentFunction(glGetTextureParameterIiv) - #define glGetTextureParameterIuiv GLEGetCurrentFunction(glGetTextureParameterIuiv) - #define glGetTextureParameterfv GLEGetCurrentFunction(glGetTextureParameterfv) - #define glGetTextureParameteriv GLEGetCurrentFunction(glGetTextureParameteriv) - #define glGetTransformFeedbacki64_v GLEGetCurrentFunction(glGetTransformFeedbacki64_v) - #define glGetTransformFeedbacki_v GLEGetCurrentFunction(glGetTransformFeedbacki_v) - #define glGetTransformFeedbackiv GLEGetCurrentFunction(glGetTransformFeedbackiv) - #define glGetVertexArrayIndexed64iv GLEGetCurrentFunction(glGetVertexArrayIndexed64iv) - #define glGetVertexArrayIndexediv GLEGetCurrentFunction(glGetVertexArrayIndexediv) - #define glGetVertexArrayiv GLEGetCurrentFunction(glGetVertexArrayiv) - #define glInvalidateNamedFramebufferData GLEGetCurrentFunction(glInvalidateNamedFramebufferData) - #define glInvalidateNamedFramebufferSubData GLEGetCurrentFunction(glInvalidateNamedFramebufferSubData) - #define glMapNamedBuffer GLEGetCurrentFunction(glMapNamedBuffer) - #define glMapNamedBufferRange GLEGetCurrentFunction(glMapNamedBufferRange) - #define glNamedBufferData GLEGetCurrentFunction(glNamedBufferData) - #define glNamedBufferStorage GLEGetCurrentFunction(glNamedBufferStorage) - #define glNamedBufferSubData GLEGetCurrentFunction(glNamedBufferSubData) - #define glNamedFramebufferDrawBuffer GLEGetCurrentFunction(glNamedFramebufferDrawBuffer) - #define glNamedFramebufferDrawBuffers GLEGetCurrentFunction(glNamedFramebufferDrawBuffers) - #define glNamedFramebufferParameteri GLEGetCurrentFunction(glNamedFramebufferParameteri) - #define glNamedFramebufferReadBuffer GLEGetCurrentFunction(glNamedFramebufferReadBuffer) - #define glNamedFramebufferRenderbuffer GLEGetCurrentFunction(glNamedFramebufferRenderbuffer) - #define glNamedFramebufferTexture GLEGetCurrentFunction(glNamedFramebufferTexture) - #define glNamedFramebufferTextureLayer GLEGetCurrentFunction(glNamedFramebufferTextureLayer) - #define glNamedRenderbufferStorage GLEGetCurrentFunction(glNamedRenderbufferStorage) - #define glNamedRenderbufferStorageMultisample GLEGetCurrentFunction(glNamedRenderbufferStorageMultisample) - #define glTextureBuffer GLEGetCurrentFunction(glTextureBuffer) - #define glTextureBufferRange GLEGetCurrentFunction(glTextureBufferRange) - #define glTextureParameterIiv GLEGetCurrentFunction(glTextureParameterIiv) - #define glTextureParameterIuiv GLEGetCurrentFunction(glTextureParameterIuiv) - #define glTextureParameterf GLEGetCurrentFunction(glTextureParameterf) - #define glTextureParameterfv GLEGetCurrentFunction(glTextureParameterfv) - #define glTextureParameteri GLEGetCurrentFunction(glTextureParameteri) - #define glTextureParameteriv GLEGetCurrentFunction(glTextureParameteriv) - #define glTextureStorage1D GLEGetCurrentFunction(glTextureStorage1D) - #define glTextureStorage2D GLEGetCurrentFunction(glTextureStorage2D) - #define glTextureStorage2DMultisample GLEGetCurrentFunction(glTextureStorage2DMultisample) - #define glTextureStorage3D GLEGetCurrentFunction(glTextureStorage3D) - #define glTextureStorage3DMultisample GLEGetCurrentFunction(glTextureStorage3DMultisample) - #define glTextureSubImage1D GLEGetCurrentFunction(glTextureSubImage1D) - #define glTextureSubImage2D GLEGetCurrentFunction(glTextureSubImage2D) - #define glTextureSubImage3D GLEGetCurrentFunction(glTextureSubImage3D) - #define glTransformFeedbackBufferBase GLEGetCurrentFunction(glTransformFeedbackBufferBase) - #define glTransformFeedbackBufferRange GLEGetCurrentFunction(glTransformFeedbackBufferRange) - #define glUnmapNamedBuffer GLEGetCurrentFunction(glUnmapNamedBuffer) - #define glVertexArrayAttribBinding GLEGetCurrentFunction(glVertexArrayAttribBinding) - #define glVertexArrayAttribFormat GLEGetCurrentFunction(glVertexArrayAttribFormat) - #define glVertexArrayAttribIFormat GLEGetCurrentFunction(glVertexArrayAttribIFormat) - #define glVertexArrayAttribLFormat GLEGetCurrentFunction(glVertexArrayAttribLFormat) - #define glVertexArrayBindingDivisor GLEGetCurrentFunction(glVertexArrayBindingDivisor) - #define glVertexArrayElementBuffer GLEGetCurrentFunction(glVertexArrayElementBuffer) - #define glVertexArrayVertexBuffer GLEGetCurrentFunction(glVertexArrayVertexBuffer) - #define glVertexArrayVertexBuffers GLEGetCurrentFunction(glVertexArrayVertexBuffers) - - #define GLE_ARB_direct_state_access GLEGetCurrentVariable(gle_ARB_direct_state_access) -#endif // GL_ARB_direct_state_access */ - - - -#ifndef GL_ARB_ES2_compatibility - #define GL_ARB_ES2_compatibility 1 - - // This is for OpenGL ES compatibility. - #define GL_FIXED 0x140C - #define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A - #define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B - #define GL_RGB565 0x8D62 - #define GL_LOW_FLOAT 0x8DF0 - #define GL_MEDIUM_FLOAT 0x8DF1 - #define GL_HIGH_FLOAT 0x8DF2 - #define GL_LOW_INT 0x8DF3 - #define GL_MEDIUM_INT 0x8DF4 - #define GL_HIGH_INT 0x8DF5 - #define GL_SHADER_BINARY_FORMATS 0x8DF8 - #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 - #define GL_SHADER_COMPILER 0x8DFA - #define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB - #define GL_MAX_VARYING_VECTORS 0x8DFC - #define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD - - typedef int GLfixed; - - typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf d); - typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f); - typedef void (GLAPIENTRY * PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint *precision); - typedef void (GLAPIENTRY * PFNGLRELEASESHADERCOMPILERPROC) (void); - typedef void (GLAPIENTRY * PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint* shaders, GLenum binaryformat, const void*binary, GLsizei length); - - #define glClearDepthf GLEGetCurrentFunction(glClearDepthf) - #define glDepthRangef GLEGetCurrentFunction(glDepthRangef) - #define glGetShaderPrecisionFormat GLEGetCurrentFunction(glGetShaderPrecisionFormat) - #define glReleaseShaderCompiler GLEGetCurrentFunction(glReleaseShaderCompiler) - #define glShaderBinary GLEGetCurrentFunction(glShaderBinary) - - #define GLE_ARB_ES2_compatibility GLEGetCurrentVariable(gle_ARB_ES2_compatibility) -#endif - - - -#ifndef GL_ARB_framebuffer_object - #define GL_ARB_framebuffer_object 1 - - // GL_ARB_framebuffer_object is part of the OpenGL 4.4 core profile. - #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 - #define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 - #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 - #define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 - #define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 - #define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 - #define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 - #define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 - #define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 - #define GL_FRAMEBUFFER_DEFAULT 0x8218 - #define GL_FRAMEBUFFER_UNDEFINED 0x8219 - #define GL_DEPTH_STENCIL_ATTACHMENT 0x821A - #define GL_INDEX 0x8222 - #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 - #define GL_DEPTH_STENCIL 0x84F9 - #define GL_UNSIGNED_INT_24_8 0x84FA - #define GL_DEPTH24_STENCIL8 0x88F0 - #define GL_TEXTURE_STENCIL_SIZE 0x88F1 - #define GL_UNSIGNED_NORMALIZED 0x8C17 - #define GL_SRGB 0x8C40 - #define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 - #define GL_FRAMEBUFFER_BINDING 0x8CA6 - #define GL_RENDERBUFFER_BINDING 0x8CA7 - #define GL_READ_FRAMEBUFFER 0x8CA8 - #define GL_DRAW_FRAMEBUFFER 0x8CA9 - #define GL_READ_FRAMEBUFFER_BINDING 0x8CAA - #define GL_RENDERBUFFER_SAMPLES 0x8CAB - #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 - #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 - #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 - #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 - #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 - #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 - #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 - #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 - #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB - #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC - #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD - #define GL_MAX_COLOR_ATTACHMENTS 0x8CDF - #define GL_COLOR_ATTACHMENT0 0x8CE0 - #define GL_COLOR_ATTACHMENT1 0x8CE1 - #define GL_COLOR_ATTACHMENT2 0x8CE2 - #define GL_COLOR_ATTACHMENT3 0x8CE3 - #define GL_COLOR_ATTACHMENT4 0x8CE4 - #define GL_COLOR_ATTACHMENT5 0x8CE5 - #define GL_COLOR_ATTACHMENT6 0x8CE6 - #define GL_COLOR_ATTACHMENT7 0x8CE7 - #define GL_COLOR_ATTACHMENT8 0x8CE8 - #define GL_COLOR_ATTACHMENT9 0x8CE9 - #define GL_COLOR_ATTACHMENT10 0x8CEA - #define GL_COLOR_ATTACHMENT11 0x8CEB - #define GL_COLOR_ATTACHMENT12 0x8CEC - #define GL_COLOR_ATTACHMENT13 0x8CED - #define GL_COLOR_ATTACHMENT14 0x8CEE - #define GL_COLOR_ATTACHMENT15 0x8CEF - #define GL_DEPTH_ATTACHMENT 0x8D00 - #define GL_STENCIL_ATTACHMENT 0x8D20 - #define GL_FRAMEBUFFER 0x8D40 - #define GL_RENDERBUFFER 0x8D41 - #define GL_RENDERBUFFER_WIDTH 0x8D42 - #define GL_RENDERBUFFER_HEIGHT 0x8D43 - #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 - #define GL_STENCIL_INDEX1 0x8D46 - #define GL_STENCIL_INDEX4 0x8D47 - #define GL_STENCIL_INDEX8 0x8D48 - #define GL_STENCIL_INDEX16 0x8D49 - #define GL_RENDERBUFFER_RED_SIZE 0x8D50 - #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 - #define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 - #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 - #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 - #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 - #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 - #define GL_MAX_SAMPLES 0x8D57 - - typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); - typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); - typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); - typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); - typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); - typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); - typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); - typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); - typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); - typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); - typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); - typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); - typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); - typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); - typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); - typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); - typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); - typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); - typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); - - #define glBindFramebuffer GLEGetCurrentFunction(glBindFramebuffer) - #define glBindRenderbuffer GLEGetCurrentFunction(glBindRenderbuffer) - #define glBlitFramebuffer GLEGetCurrentFunction(glBlitFramebuffer) - #define glCheckFramebufferStatus GLEGetCurrentFunction(glCheckFramebufferStatus) - #define glDeleteFramebuffers GLEGetCurrentFunction(glDeleteFramebuffers) - #define glDeleteRenderbuffers GLEGetCurrentFunction(glDeleteRenderbuffers) - #define glFramebufferRenderbuffer GLEGetCurrentFunction(glFramebufferRenderbuffer) - #define glFramebufferTexture1D GLEGetCurrentFunction(glFramebufferTexture1D) - #define glFramebufferTexture2D GLEGetCurrentFunction(glFramebufferTexture2D) - #define glFramebufferTexture3D GLEGetCurrentFunction(glFramebufferTexture3D) - #define glFramebufferTextureLayer GLEGetCurrentFunction(glFramebufferTextureLayer) - #define glGenFramebuffers GLEGetCurrentFunction(glGenFramebuffers) - #define glGenRenderbuffers GLEGetCurrentFunction(glGenRenderbuffers) - #define glGenerateMipmap GLEGetCurrentFunction(glGenerateMipmap) - #define glGetFramebufferAttachmentParameteriv GLEGetCurrentFunction(glGetFramebufferAttachmentParameteriv) - #define glGetRenderbufferParameteriv GLEGetCurrentFunction(glGetRenderbufferParameteriv) - #define glIsFramebuffer GLEGetCurrentFunction(glIsFramebuffer) - #define glIsRenderbuffer GLEGetCurrentFunction(glIsRenderbuffer) - #define glRenderbufferStorage GLEGetCurrentFunction(glRenderbufferStorage) - #define glRenderbufferStorageMultisample GLEGetCurrentFunction(glRenderbufferStorageMultisample) - - #define GLE_ARB_framebuffer_object GLEGetCurrentVariable(gle_ARB_framebuffer_object) - -#endif // GL_ARB_framebuffer_object - - - -#ifndef GL_ARB_framebuffer_sRGB - #define GL_ARB_framebuffer_sRGB 1 - - // GL_ARB_framebuffer_sRGB is part of the OpenGL 4.4 core profile. - #define GL_FRAMEBUFFER_SRGB 0x8DB9 - - #define GLE_ARB_framebuffer_sRGB GLEGetCurrentVariable(gle_ARB_framebuffer_sRGB) -#endif - - - -#ifndef GL_ARB_texture_multisample - #define GL_ARB_texture_multisample 1 - - #define GL_SAMPLE_POSITION 0x8E50 - #define GL_SAMPLE_MASK 0x8E51 - #define GL_SAMPLE_MASK_VALUE 0x8E52 - #define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 - #define GL_TEXTURE_2D_MULTISAMPLE 0x9100 - #define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 - #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 - #define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 - #define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 - #define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 - #define GL_TEXTURE_SAMPLES 0x9106 - #define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 - #define GL_SAMPLER_2D_MULTISAMPLE 0x9108 - #define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 - #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A - #define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B - #define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C - #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D - #define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E - #define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F - #define GL_MAX_INTEGER_SAMPLES 0x9110 - - typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val); - typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); - typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); - typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); - - #define glGetMultisamplefv GLEGetCurrentFunction(glGetMultisamplefv) - #define glSampleMaski GLEGetCurrentFunction(glSampleMaski) - #define glTexImage2DMultisample GLEGetCurrentFunction(glTexImage2DMultisample) - #define glTexImage3DMultisample GLEGetCurrentFunction(glTexImage3DMultisample) - - #define GLE_ARB_texture_multisample GLEGetCurrentVariable(gle_ARB_texture_multisample) - -#endif // GL_ARB_texture_multisample - - - -#ifndef GL_ARB_texture_non_power_of_two - #define GL_ARB_texture_non_power_of_two 1 - - #define GLE_ARB_texture_non_power_of_two GLEGetCurrentVariable(gle_ARB_texture_non_power_of_two) -#endif - - - -#ifndef GL_ARB_texture_rectangle - #define GL_ARB_texture_rectangle 1 - - // texture_rectangle was added to the OpenGL 3.1 core profile and so this extension is not needed - // unless using an earlier version of OpenGL. - // There are also the GL_EXT_texture_rectangle and GL_NV_texture_rectangle extensions. Apple reports - // the preseence of GL_EXT_texture_rectangle but not GL_ARB_texture_rectangle or GL_NV_texture_rectangle. - // You should check for GL_ARB_texture_rectangle instead of these other two. - #define GL_TEXTURE_RECTANGLE_ARB 0x84F5 - #define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 - #define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 - #define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 - #define GL_SAMPLER_2D_RECT_ARB 0x8B63 - #define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 - - #define GLE_ARB_texture_rectangle GLEGetCurrentVariable(gle_ARB_texture_rectangle) -#endif - - - -#ifndef GL_ARB_timer_query - #define GL_ARB_timer_query 1 - - #define GL_TIME_ELAPSED 0x88BF - #define GL_TIMESTAMP 0x8E28 - - typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params); - typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params); - typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); - - #define glGetQueryObjecti64v GLEGetCurrentFunction(glGetQueryObjecti64v) - #define glGetQueryObjectui64v GLEGetCurrentFunction(glGetQueryObjectui64v) - #define glQueryCounter GLEGetCurrentFunction(glQueryCounter) - - #define GLE_ARB_timer_query GLEGetCurrentVariable(gle_ARB_timer_query) -#endif - - - -#ifndef GL_ARB_vertex_array_object - #define GL_ARB_vertex_array_object 1 - - #define GL_VERTEX_ARRAY_BINDING 0x85B5 - - typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); - typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); - typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); - typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); - - #define glBindVertexArray GLEGetCurrentFunction(glBindVertexArray) - #define glDeleteVertexArrays GLEGetCurrentFunction(glDeleteVertexArrays) - #define glGenVertexArrays GLEGetCurrentFunction(glGenVertexArrays) - #define glIsVertexArray GLEGetCurrentFunction(glIsVertexArray) - - #define GLE_ARB_vertex_array_object GLEGetCurrentVariable(gle_ARB_vertex_array_object) -#endif - - - -/* Disabled until needed -#ifndef GL_ARB_vertex_attrib_binding - #define GL_ARB_vertex_attrib_binding 1 - - #define GL_VERTEX_ATTRIB_BINDING 0x82D4 - #define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 - #define GL_VERTEX_BINDING_DIVISOR 0x82D6 - #define GL_VERTEX_BINDING_OFFSET 0x82D7 - #define GL_VERTEX_BINDING_STRIDE 0x82D8 - #define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 - #define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA - #define GL_VERTEX_BINDING_BUFFER 0x8F4F - - typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); - typedef void (GLAPIENTRY * PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); - - #define glBindVertexBuffer GLEGetCurrentFunction(glBindVertexBuffer) - #define glVertexArrayBindVertexBufferEXT GLEGetCurrentFunction(glVertexArrayBindVertexBufferEXT) - #define glVertexArrayVertexAttribBindingEXT GLEGetCurrentFunction(glVertexArrayVertexAttribBindingEXT) - #define glVertexArrayVertexAttribFormatEXT GLEGetCurrentFunction(glVertexArrayVertexAttribFormatEXT) - #define glVertexArrayVertexAttribIFormatEXT GLEGetCurrentFunction(glVertexArrayVertexAttribIFormatEXT) - #define glVertexArrayVertexAttribLFormatEXT GLEGetCurrentFunction(glVertexArrayVertexAttribLFormatEXT) - #define glVertexArrayVertexBindingDivisorEXT GLEGetCurrentFunction(glVertexArrayVertexBindingDivisorEXT) - #define glVertexAttribBinding GLEGetCurrentFunction(glVertexAttribBinding) - #define glVertexAttribFormat GLEGetCurrentFunction(glVertexAttribFormat) - #define glVertexAttribIFormat GLEGetCurrentFunction(glVertexAttribIFormat) - #define glVertexAttribLFormat GLEGetCurrentFunction(glVertexAttribLFormat) - #define glVertexBindingDivisor GLEGetCurrentFunction(glVertexBindingDivisor) - - #define GLE_ARB_vertex_attrib_binding GLEGetCurrentVariable(gle_ARB_vertex_attrib_binding) -#endif -*/ - - -#ifndef GL_EXT_draw_buffers2 - #define GL_EXT_draw_buffers2 1 - - typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); - typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); - typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); - typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); - typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); - typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); - - #define glColorMaskIndexedEXT GLEGetCurrentFunction(glColorMaskIndexedEXT) - #define glDisableIndexedEXT GLEGetCurrentFunction(glDisableIndexedEXT) - #define glEnableIndexedEXT GLEGetCurrentFunction(glEnableIndexedEXT) - #define glGetBooleanIndexedvEXT GLEGetCurrentFunction(glGetBooleanIndexedvEXT) - #define glGetIntegerIndexedvEXT GLEGetCurrentFunction(glGetIntegerIndexedvEXT) - #define glIsEnabledIndexedEXT GLEGetCurrentFunction(glIsEnabledIndexedEXT) - - #define GLE_EXT_draw_buffers2 GLEGetCurrentVariable(gle_EXT_draw_buffers2) -#endif - - - -#ifndef GL_EXT_texture_compression_s3tc - #define GL_EXT_texture_compression_s3tc 1 - - #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 - #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 - #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 - #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 - - #define GLE_EXT_texture_compression_s3tc GLEGetCurrentVariable(gle_EXT_texture_compression_s3tc) -#endif - - - -#ifndef GL_EXT_texture_filter_anisotropic - #define GL_EXT_texture_filter_anisotropic 1 - - #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE - #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF - - #define GLE_EXT_texture_filter_anisotropic GLEGetCurrentVariable(gle_EXT_texture_filter_anisotropic) -#endif - - - -/* Disabled until needed -#ifndef GL_KHR_context_flush_control - #define GL_KHR_context_flush_control 1 - - #define GLE_KHR_context_flush_control GLEGetCurrentVariable(gle_KHR_context_flush_control) -#endif -*/ - - - -#ifndef GL_KHR_debug - #define GL_KHR_debug 1 - - #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 - #define GL_STACK_OVERFLOW 0x0503 - #define GL_STACK_UNDERFLOW 0x0504 - #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 - #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 - #define GL_DEBUG_CALLBACK_FUNCTION 0x8244 - #define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 - #define GL_DEBUG_SOURCE_API 0x8246 - #define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 - #define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 - #define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 - #define GL_DEBUG_SOURCE_APPLICATION 0x824A - #define GL_DEBUG_SOURCE_OTHER 0x824B - #define GL_DEBUG_TYPE_ERROR 0x824C - #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D - #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E - #define GL_DEBUG_TYPE_PORTABILITY 0x824F - #define GL_DEBUG_TYPE_PERFORMANCE 0x8250 - #define GL_DEBUG_TYPE_OTHER 0x8251 - #define GL_DEBUG_TYPE_MARKER 0x8268 - #define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 - #define GL_DEBUG_TYPE_POP_GROUP 0x826A - #define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B - #define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C - #define GL_DEBUG_GROUP_STACK_DEPTH 0x826D - #define GL_BUFFER 0x82E0 - #define GL_SHADER 0x82E1 - #define GL_PROGRAM 0x82E2 - #define GL_QUERY 0x82E3 - #define GL_PROGRAM_PIPELINE 0x82E4 - #define GL_SAMPLER 0x82E6 - #define GL_DISPLAY_LIST 0x82E7 - #define GL_MAX_LABEL_LENGTH 0x82E8 - #define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 - #define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 - #define GL_DEBUG_LOGGED_MESSAGES 0x9145 - #define GL_DEBUG_SEVERITY_HIGH 0x9146 - #define GL_DEBUG_SEVERITY_MEDIUM 0x9147 - #define GL_DEBUG_SEVERITY_LOW 0x9148 - #define GL_DEBUG_OUTPUT 0x92E0 - - typedef void (GLAPIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); - - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); - typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); - typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); - typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar *label); - typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei* length, GLchar *label); - typedef void (GLAPIENTRY * PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar* label); - typedef void (GLAPIENTRY * PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar* label); - typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (void); - typedef void (GLAPIENTRY * PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar * message); - - #define glDebugMessageCallback GLEGetCurrentFunction(glDebugMessageCallback) - #define glDebugMessageControl GLEGetCurrentFunction(glDebugMessageControl) - #define glDebugMessageInsert GLEGetCurrentFunction(glDebugMessageInsert) - #define glGetDebugMessageLog GLEGetCurrentFunction(glGetDebugMessageLog) - #define glGetObjectLabel GLEGetCurrentFunction(glGetObjectLabel) - #define glGetObjectPtrLabel GLEGetCurrentFunction(glGetObjectPtrLabel) - #define glObjectLabel GLEGetCurrentFunction(glObjectLabel) - #define glObjectPtrLabel GLEGetCurrentFunction(glObjectPtrLabel) - #define glPopDebugGroup GLEGetCurrentFunction(glPopDebugGroup) - #define glPushDebugGroup GLEGetCurrentFunction(glPushDebugGroup) - - #define GLE_KHR_debug GLEGetCurrentVariable(gle_KHR_debug) -#endif // GL_KHR_debug - - - -#ifndef GL_KHR_robust_buffer_access_behavior - #define GL_KHR_robust_buffer_access_behavior 1 - - #define GLE_KHR_robust_buffer_access_behavior GLEGetCurrentVariable(gle_KHR_robust_buffer_access_behavior) -#endif - - - -/* Disabled until needed -#ifndef GL_KHR_robustness - #define GL_KHR_robustness 1 - - #define GL_CONTEXT_LOST 0x0507 - #define GL_LOSE_CONTEXT_ON_RESET 0x8252 - #define GL_GUILTY_CONTEXT_RESET 0x8253 - #define GL_INNOCENT_CONTEXT_RESET 0x8254 - #define GL_UNKNOWN_CONTEXT_RESET 0x8255 - #define GL_RESET_NOTIFICATION_STRATEGY 0x8256 - #define GL_NO_RESET_NOTIFICATION 0x8261 - #define GL_CONTEXT_ROBUST_ACCESS 0x90F3 - - typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); - typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); - typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params); - typedef void (GLAPIENTRY * PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); - - #define glGetnUniformfv GLEGetCurrentFunction(glGetnUniformfv) - #define glGetnUniformiv GLEGetCurrentFunction(glGetnUniformiv) - #define glGetnUniformuiv GLEGetCurrentFunction(glGetnUniformuiv) - #define glReadnPixels GLEGetCurrentFunction(glReadnPixels) - - #define GLE_KHR_robustness GLEGetCurrentVariable(gle_KHR_robustness) - -#endif // GL_KHR_robustness -*/ - - - -#ifndef GL_WIN_swap_hint - #define GL_WIN_swap_hint 1 - - typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); - - #define glAddSwapHintRectWIN GLEGetCurrentFunction(glAddSwapHintRectWIN) - - #define GLE_WIN_swap_hint GLEGetCurrentVariable(gle_WIN_swap_hint) -#endif - - - -/************************************************************************************ - Windows-specific (WGL) functionality -************************************************************************************/ - -#if defined(GLE_WGL_ENABLED) - #ifdef __wglext_h_ - #error wglext.h was included before this header. This header needs to be inlcuded instead of or at least before wglext.h - #endif - #define __wglext_h_ // Prevent wglext.h from having any future effect if it's #included. - - // Declare shared types and structs from wglext.h - DECLARE_HANDLE(HPBUFFERARB); // This type is used by a couple extensions. - - // WGL functions from - #if 0 // defined(GLE_HOOKING_ENABLED) We currently don't hook these. - #define wglCopyContext(...) GLEGetCurrentFunction(wglCopyContext)(__VA_ARGS__) - #define wglCreateContext(...) GLEGetCurrentFunction(wglCreateContext)(__VA_ARGS__) - #define wglCreateLayerContext(...) GLEGetCurrentFunction(wglCreateLayerContext)(__VA_ARGS__) - #define wglDeleteContext(...) GLEGetCurrentFunction(wglDeleteContext)(__VA_ARGS__) - #define wglGetCurrentContext(...) GLEGetCurrentFunction(wglGetCurrentContext)(__VA_ARGS__) - #define wglGetCurrentDC(...) GLEGetCurrentFunction(wglGetCurrentDC)(__VA_ARGS__) - #define wglGetProcAddress(...) GLEGetCurrentFunction(wglGetProcAddress)(__VA_ARGS__) - #define wglMakeCurrent(...) GLEGetCurrentFunction(wglMakeCurrent)(__VA_ARGS__) - #define wglShareLists(...) GLEGetCurrentFunction(wglShareLists)(__VA_ARGS__) - #define wglUseFontBitmapsA(...) GLEGetCurrentFunction(wglUseFontBitmapsA)(__VA_ARGS__) - #define wglUseFontBitmapsW(...) GLEGetCurrentFunction(wglUseFontBitmapsW)(__VA_ARGS__) - #define wglUseFontOutlinesA(...) GLEGetCurrentFunction(wglUseFontOutlinesA)(__VA_ARGS__) - #define wglUseFontOutlinesW(...) GLEGetCurrentFunction(wglUseFontOutlinesW)(__VA_ARGS__) - #define wglDescribeLayerPlane(...) GLEGetCurrentFunction(wglDescribeLayerPlane)(__VA_ARGS__) - #define wglSetLayerPaletteEntries(...) GLEGetCurrentFunction(wglSetLayerPaletteEntries)(__VA_ARGS__) - #define wglGetLayerPaletteEntries(...) GLEGetCurrentFunction(wglGetLayerPaletteEntries)(__VA_ARGS__) - #define wglRealizeLayerPalette(...) GLEGetCurrentFunction(wglRealizeLayerPalette)(__VA_ARGS__) - #define wglSwapLayerBuffers(...) GLEGetCurrentFunction(wglSwapLayerBuffers)(__VA_ARGS__) - #define wglSwapMultipleBuffers(...) GLEGetCurrentFunction(wglSwapMultipleBuffers)(__VA_ARGS__) - #else - // The following functions are directly declared in Microsoft's without associated typedefs, and are exported from Opengl32.dll. - // We can link to them directly through Opengl32.lib/dll (same as OpenGL 1.1 functions) or we can dynamically link them from OpenGL32.dll at runtime. - typedef BOOL (WINAPI * PFNWGLCOPYCONTEXTPROC)(HGLRC, HGLRC, UINT); - typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTPROC)(HDC); - typedef HGLRC (WINAPI * PFNWGLCREATELAYERCONTEXTPROC)(HDC, int); - typedef BOOL (WINAPI * PFNWGLDELETECONTEXTPROC)(HGLRC); - typedef HGLRC (WINAPI * PFNWGLGETCURRENTCONTEXTPROC)(VOID); - typedef HDC (WINAPI * PFNWGLGETCURRENTDCPROC)(VOID); - typedef PROC (WINAPI * PFNWGLGETPROCADDRESSPROC)(LPCSTR); - typedef BOOL (WINAPI * PFNWGLMAKECURRENTPROC)(HDC, HGLRC); - typedef BOOL (WINAPI * PFNWGLSHARELISTSPROC)(HGLRC, HGLRC); - typedef BOOL (WINAPI * PFNWGLUSEFONTBITMAPSAPROC)(HDC, DWORD, DWORD, DWORD); - typedef BOOL (WINAPI * PFNWGLUSEFONTBITMAPSWPROC)(HDC, DWORD, DWORD, DWORD); - typedef BOOL (WINAPI * PFNWGLUSEFONTOUTLINESAPROC)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); - typedef BOOL (WINAPI * PFNWGLUSEFONTOUTLINESWPROC)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); - typedef BOOL (WINAPI * PFNWGLDESCRIBELAYERPLANEPROC)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); - typedef int (WINAPI * PFNWGLSETLAYERPALETTEENTRIESPROC)(HDC, int, int, int, CONST COLORREF *); - typedef int (WINAPI * PFNWGLGETLAYERPALETTEENTRIESPROC)(HDC, int, int, int, COLORREF *); - typedef BOOL (WINAPI * PFNWGLREALIZELAYERPALETTEPROC)(HDC, int, BOOL); - typedef BOOL (WINAPI * PFNWGLSWAPLAYERBUFFERSPROC)(HDC, UINT); - typedef DWORD (WINAPI * PFNWGLSWAPMULTIPLEBUFFERSPROC)(UINT, CONST WGLSWAP *); - - #if 0 - #define wglCopyContext GLEContext::GetCurrentContext()->wglCopyContext_Impl - #define wglCreateContext GLEContext::GetCurrentContext()->wglCreateContext_Impl - #define wglCreateLayerContext GLEContext::GetCurrentContext()->wglCreateLayerContext_Impl - #define wglDeleteContext GLEContext::GetCurrentContext()->wglDeleteContext_Impl - #define wglGetCurrentContext GLEContext::GetCurrentContext()->wglGetCurrentContext_Impl - #define wglGetCurrentDC GLEContext::GetCurrentContext()->wglGetCurrentDC_Impl - #define wglGetProcAddress GLEContext::GetCurrentContext()->wglGetProcAddress_Impl - #define wglMakeCurrent GLEContext::GetCurrentContext()->wglMakeCurrent_Impl - #define wglShareLists GLEContext::GetCurrentContext()->wglShareLists_Impl - #define wglUseFontBitmapsA GLEContext::GetCurrentContext()->wglUseFontBitmapsA_Impl - #define wglUseFontBitmapsW GLEContext::GetCurrentContext()->wglUseFontBitmapsW_Impl - #define wglUseFontOutlinesA GLEContext::GetCurrentContext()->wglUseFontOutlinesA_Impl - #define wglUseFontOutlinesW GLEContext::GetCurrentContext()->wglUseFontOutlinesW_Impl - #define wglDescribeLayerPlane GLEContext::GetCurrentContext()->wglDescribeLayerPlane_Impl - #define wglSetLayerPaletteEntries GLEContext::GetCurrentContext()->wglSetLayerPaletteEntries_Impl - #define wglGetLayerPaletteEntries GLEContext::GetCurrentContext()->wglGetLayerPaletteEntries_Impl - #define wglRealizeLayerPalette GLEContext::GetCurrentContext()->wglRealizeLayerPalette_Impl - #define wglSwapLayerBuffers GLEContext::GetCurrentContext()->wglSwapLayerBuffers_Impl - #define wglSwapMultipleBuffers GLEContext::GetCurrentContext()->wglSwapMultipleBuffers_Impl - #endif - #endif - - // Note: In order to detect the WGL extensions' availability, we need to call wglGetExtensionsStringARB or - // wglGetExtensionsStringEXT instead of glGetString(GL_EXTENSIONS). - #ifndef WGL_ARB_buffer_region - #define WGL_ARB_buffer_region 1 - - #define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 - #define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 - #define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 - #define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 - - typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); - typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); - typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); - typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); - - #define wglCreateBufferRegionARB GLEGetCurrentFunction(wglCreateBufferRegionARB) - #define wglDeleteBufferRegionARB GLEGetCurrentFunction(wglDeleteBufferRegionARB) - #define wglSaveBufferRegionARB GLEGetCurrentFunction(wglSaveBufferRegionARB) - #define wglRestoreBufferRegionARB GLEGetCurrentFunction(wglRestoreBufferRegionARB) - - #define GLE_WGL_ARB_buffer_region GLEGetCurrentVariable(gle_WGL_ARB_buffer_region) - #endif - - - #ifndef WGL_ARB_extensions_string - #define WGL_ARB_extensions_string 1 - - typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); - - #define wglGetExtensionsStringARB GLEGetCurrentFunction(wglGetExtensionsStringARB) - - #define GLE_WGL_ARB_extensions_string GLEGetCurrentVariable(gle_WGL_ARB_extensions_string) - #endif - - - #ifndef WGL_ARB_pixel_format - #define WGL_ARB_pixel_format 1 - - #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 - #define WGL_DRAW_TO_WINDOW_ARB 0x2001 - #define WGL_DRAW_TO_BITMAP_ARB 0x2002 - #define WGL_ACCELERATION_ARB 0x2003 - #define WGL_NEED_PALETTE_ARB 0x2004 - #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 - #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 - #define WGL_SWAP_METHOD_ARB 0x2007 - #define WGL_NUMBER_OVERLAYS_ARB 0x2008 - #define WGL_NUMBER_UNDERLAYS_ARB 0x2009 - #define WGL_TRANSPARENT_ARB 0x200A - #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 - #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 - #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 - #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A - #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B - #define WGL_SHARE_DEPTH_ARB 0x200C - #define WGL_SHARE_STENCIL_ARB 0x200D - #define WGL_SHARE_ACCUM_ARB 0x200E - #define WGL_SUPPORT_GDI_ARB 0x200F - #define WGL_SUPPORT_OPENGL_ARB 0x2010 - #define WGL_DOUBLE_BUFFER_ARB 0x2011 - #define WGL_STEREO_ARB 0x2012 - #define WGL_PIXEL_TYPE_ARB 0x2013 - #define WGL_COLOR_BITS_ARB 0x2014 - #define WGL_RED_BITS_ARB 0x2015 - #define WGL_RED_SHIFT_ARB 0x2016 - #define WGL_GREEN_BITS_ARB 0x2017 - #define WGL_GREEN_SHIFT_ARB 0x2018 - #define WGL_BLUE_BITS_ARB 0x2019 - #define WGL_BLUE_SHIFT_ARB 0x201A - #define WGL_ALPHA_BITS_ARB 0x201B - #define WGL_ALPHA_SHIFT_ARB 0x201C - #define WGL_ACCUM_BITS_ARB 0x201D - #define WGL_ACCUM_RED_BITS_ARB 0x201E - #define WGL_ACCUM_GREEN_BITS_ARB 0x201F - #define WGL_ACCUM_BLUE_BITS_ARB 0x2020 - #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 - #define WGL_DEPTH_BITS_ARB 0x2022 - #define WGL_STENCIL_BITS_ARB 0x2023 - #define WGL_AUX_BUFFERS_ARB 0x2024 - #define WGL_NO_ACCELERATION_ARB 0x2025 - #define WGL_GENERIC_ACCELERATION_ARB 0x2026 - #define WGL_FULL_ACCELERATION_ARB 0x2027 - #define WGL_SWAP_EXCHANGE_ARB 0x2028 - #define WGL_SWAP_COPY_ARB 0x2029 - #define WGL_SWAP_UNDEFINED_ARB 0x202A - #define WGL_TYPE_RGBA_ARB 0x202B - #define WGL_TYPE_COLORINDEX_ARB 0x202C - - typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); - typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); - typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); - - #define wglGetPixelFormatAttribivARB GLEGetCurrentFunction(wglGetPixelFormatAttribivARB) - #define wglGetPixelFormatAttribfvARB GLEGetCurrentFunction(wglGetPixelFormatAttribfvARB) - #define wglChoosePixelFormatARB GLEGetCurrentFunction(wglChoosePixelFormatARB) - - #define GLE_WGL_ARB_pixel_format GLEGetCurrentVariable(gle_WGL_ARB_pixel_format) - #endif - - - #ifndef WGL_ARB_make_current_read - #define WGL_ARB_make_current_read 1 - - #define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 - #define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 - - typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); - typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); - - #define wglMakeContextCurrentARB GLEGetCurrentFunction(wglMakeContextCurrentARB) - #define wglGetCurrentReadDCARB GLEGetCurrentFunction(wglGetCurrentReadDCARB) - - #define GLE_WGL_ARB_make_current_read GLEGetCurrentVariable(gle_WGL_ARB_make_current_read) - #endif - - - #ifndef WGL_ARB_pbuffer - #define WGL_ARB_pbuffer 1 - - #define WGL_DRAW_TO_PBUFFER_ARB 0x202D - #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E - #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F - #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 - #define WGL_PBUFFER_LARGEST_ARB 0x2033 - #define WGL_PBUFFER_WIDTH_ARB 0x2034 - #define WGL_PBUFFER_HEIGHT_ARB 0x2035 - - typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); - typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); - typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); - typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); - typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); - - #define wglCreatePbufferARB GLEGetCurrentFunction(wglCreatePbufferARB) - #define wglGetPbufferDCARB GLEGetCurrentFunction(wglGetPbufferDCARB) - #define wglReleasePbufferDCARB GLEGetCurrentFunction(wglReleasePbufferDCARB) - #define wglDestroyPbufferARB GLEGetCurrentFunction(wglDestroyPbufferARB) - #define wglQueryPbufferARB GLEGetCurrentFunction(wglQueryPbufferARB) - - #define GLE_WGL_ARB_pbuffer GLEGetCurrentVariable(gle_WGL_ARB_pbuffer) - #endif - - - #ifndef WGL_ARB_render_texture - #define WGL_ARB_render_texture 1 - - #define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 - #define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 - #define WGL_TEXTURE_FORMAT_ARB 0x2072 - #define WGL_TEXTURE_TARGET_ARB 0x2073 - #define WGL_MIPMAP_TEXTURE_ARB 0x2074 - #define WGL_TEXTURE_RGB_ARB 0x2075 - #define WGL_TEXTURE_RGBA_ARB 0x2076 - #define WGL_NO_TEXTURE_ARB 0x2077 - #define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 - #define WGL_TEXTURE_1D_ARB 0x2079 - #define WGL_TEXTURE_2D_ARB 0x207A - #define WGL_MIPMAP_LEVEL_ARB 0x207B - #define WGL_CUBE_MAP_FACE_ARB 0x207C - #define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D - #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E - #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F - #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 - #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 - #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 - #define WGL_FRONT_LEFT_ARB 0x2083 - #define WGL_FRONT_RIGHT_ARB 0x2084 - #define WGL_BACK_LEFT_ARB 0x2085 - #define WGL_BACK_RIGHT_ARB 0x2086 - #define WGL_AUX0_ARB 0x2087 - #define WGL_AUX1_ARB 0x2088 - #define WGL_AUX2_ARB 0x2089 - #define WGL_AUX3_ARB 0x208A - #define WGL_AUX4_ARB 0x208B - #define WGL_AUX5_ARB 0x208C - #define WGL_AUX6_ARB 0x208D - #define WGL_AUX7_ARB 0x208E - #define WGL_AUX8_ARB 0x208F - #define WGL_AUX9_ARB 0x2090 - - typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); - typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); - typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); - - #define wglBindTexImageARB GLEGetCurrentFunction(wglBindTexImageARB) - #define wglReleaseTexImageARB GLEGetCurrentFunction(wglReleaseTexImageARB) - #define wglSetPbufferAttribARB GLEGetCurrentFunction(wglSetPbufferAttribARB) - - #define GLE_WGL_ARB_render_texture GLEGetCurrentVariable(gle_WGL_ARB_render_texture) - #endif - - - #ifndef WGL_ARB_pixel_format_float - #define WGL_ARB_pixel_format_float 1 - - #define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 - - #define GLE_WGL_ARB_pixel_format_float GLEGetCurrentVariable(gle_WGL_ARB_pixel_format_float) - #endif - - - #ifndef WGL_ARB_framebuffer_sRGB - #define WGL_ARB_framebuffer_sRGB 1 - - // There is also the WGL_EXT_framebuffer_sRGB extension, which is the - // same as this. So use this one instead of that for checking. - #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 - - #define GLE_WGL_ARB_framebuffer_sRGB GLEGetCurrentVariable(gle_WGL_ARB_framebuffer_sRGB) - #endif - - - #ifndef WGL_NV_present_video - #define WGL_NV_present_video 1 - - DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); - - typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); - typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); - typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); - - #define wglEnumerateVideoDevicesNV GLEGetCurrentFunction(wglEnumerateVideoDevicesNV) - #define wglBindVideoDeviceNV GLEGetCurrentFunction(wglBindVideoDeviceNV) - #define wglQueryCurrentContextNV GLEGetCurrentFunction(wglQueryCurrentContextNV) - - #define GLE_WGL_NV_present_video GLEGetCurrentVariable(gle_WGL_NV_present_video) - #endif - - - #ifndef WGL_ARB_create_context - #define WGL_ARB_create_context 1 - - #define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 - #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 - #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 - #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 - #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 - #define WGL_CONTEXT_FLAGS_ARB 0x2094 - #define ERROR_INVALID_VERSION_ARB 0x2095 - - typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); - - #define wglCreateContextAttribsARB GLEGetCurrentFunction(wglCreateContextAttribsARB) - - #define GLE_WGL_ARB_create_context GLEGetCurrentVariable(gle_WGL_ARB_create_context) - #endif - - - #ifndef WGL_ARB_create_context_profile - #define WGL_ARB_create_context_profile 1 - - #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 - #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 - #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 - #define ERROR_INVALID_PROFILE_ARB 0x2096 - - #define GLE_WGL_ARB_create_context_profile GLEGetCurrentVariable(gle_WGL_ARB_create_context_profile) - #endif - - - #ifndef WGL_ARB_create_context_robustness - #define WGL_ARB_create_context_robustness 1 - - #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 - #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 - #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 - #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 - - #define GLE_WGL_ARB_create_context_robustness GLEGetCurrentVariable(gle_WGL_ARB_create_context_robustness) - #endif - - - - #ifndef WGL_ATI_render_texture_rectangle - #define WGL_ATI_render_texture_rectangle 1 - - #define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 - - #define GLE_WGL_ATI_render_texture_rectangle GLEGetCurrentVariable(gle_WGL_ATI_render_texture_rectangle) - #endif - - - #ifndef WGL_EXT_extensions_string - #define WGL_EXT_extensions_string 1 - - typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); - - #define wglGetExtensionsStringEXT GLEGetCurrentFunction(wglGetExtensionsStringEXT) - - #define GLE_WGL_EXT_extensions_string GLEGetCurrentVariable(gle_WGL_EXT_extensions_string) - #endif - - - #ifndef WGL_NV_render_texture_rectangle - #define WGL_NV_render_texture_rectangle 1 - - #define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 - #define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 - #define WGL_TEXTURE_RECTANGLE_NV 0x20A2 - - #define GLE_WGL_NV_render_texture_rectangle GLEGetCurrentVariable(gle_WGL_NV_render_texture_rectangle) - #endif - - - #ifndef WGL_EXT_swap_control - #define WGL_EXT_swap_control 1 - - typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); - typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); - - #define wglGetSwapIntervalEXT GLEGetCurrentFunction(wglGetSwapIntervalEXT) - #define wglSwapIntervalEXT GLEGetCurrentFunction(wglSwapIntervalEXT) - - #define GLE_WGL_EXT_swap_control GLEGetCurrentVariable(gle_WGL_EXT_swap_control) - #endif - - - #ifndef WGL_OML_sync_control - #define WGL_OML_sync_control 1 - - typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); - typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); - typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); - typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); - typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); - typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); - - #define wglGetSyncValuesOML GLEGetCurrentFunction(wglGetSyncValuesOML) - #define wglGetMscRateOML GLEGetCurrentFunction(wglGetMscRateOML) - #define wglSwapBuffersMscOML GLEGetCurrentFunction(wglSwapBuffersMscOML) - #define wglSwapLayerBuffersMscOML GLEGetCurrentFunction(wglSwapLayerBuffersMscOML) - #define wglWaitForMscOML GLEGetCurrentFunction(wglWaitForMscOML) - #define wglWaitForSbcOML GLEGetCurrentFunction(wglWaitForSbcOML) - - #define GLE_WGL_OML_sync_control GLEGetCurrentVariable(gle_WGL_OML_sync_control) - #endif - - - #ifndef WGL_NV_video_output - #define WGL_NV_video_output 1 - - DECLARE_HANDLE(HPVIDEODEV); - - typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); - typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); - typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); - typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); - typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); - typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); - - #define wglGetVideoDeviceNV GLEGetCurrentFunction(wglGetVideoDeviceNV) - #define wglReleaseVideoDeviceNV GLEGetCurrentFunction(wglReleaseVideoDeviceNV) - #define wglBindVideoImageNV GLEGetCurrentFunction(wglBindVideoImageNV) - #define wglReleaseVideoImageNV GLEGetCurrentFunction(wglReleaseVideoImageNV) - #define wglSendPbufferToVideoNV GLEGetCurrentFunction(wglSendPbufferToVideoNV) - #define wglGetVideoInfoNV GLEGetCurrentFunction(wglGetVideoInfoNV) - - #define GLE_WGL_NV_video_output GLEGetCurrentVariable(gle_WGL_NV_video_output) - #endif - - - #ifndef WGL_NV_swap_group - #define WGL_NV_swap_group 1 - - typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); - typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); - typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); - typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); - typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); - typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); - - #define wglJoinSwapGroupNV GLEGetCurrentFunction(wglJoinSwapGroupNV) - #define wglBindSwapBarrierNV GLEGetCurrentFunction(wglBindSwapBarrierNV) - #define wglQuerySwapGroupNV GLEGetCurrentFunction(wglQuerySwapGroupNV) - #define wglQueryMaxSwapGroupsNV GLEGetCurrentFunction(wglQueryMaxSwapGroupsNV) - #define wglQueryFrameCountNV GLEGetCurrentFunction(wglQueryFrameCountNV) - #define wglResetFrameCountNV GLEGetCurrentFunction(wglResetFrameCountNV) - - #define GLE_WGL_NV_swap_group GLEGetCurrentVariable(gle_WGL_NV_swap_group) - #endif - - - #ifndef WGL_NV_video_capture - #define WGL_NV_video_capture 1 - - #define WGL_UNIQUE_ID_NV 0x20CE - #define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF - - typedef struct _GPU_DEVICE { - DWORD cb; - CHAR DeviceName[32]; - CHAR DeviceString[128]; - DWORD Flags; - RECT rcVirtualScreen; - } GPU_DEVICE, *PGPU_DEVICE; - DECLARE_HANDLE(HVIDEOINPUTDEVICENV); - - typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); - typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); - typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); - typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); - typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); - - #define wglBindVideoCaptureDeviceNV GLEGetCurrentFunction(wglBindVideoCaptureDeviceNV) - #define wglEnumerateVideoCaptureDevicesNV GLEGetCurrentFunction(wglEnumerateVideoCaptureDevicesNV) - #define wglLockVideoCaptureDeviceNV GLEGetCurrentFunction(wglLockVideoCaptureDeviceNV) - #define wglQueryVideoCaptureDeviceNV GLEGetCurrentFunction(wglQueryVideoCaptureDeviceNV) - #define wglReleaseVideoCaptureDeviceNV GLEGetCurrentFunction(wglReleaseVideoCaptureDeviceNV) - - #define GLE_WGL_NV_video_capture GLEGetCurrentVariable(gle_WGL_NV_video_capture) - #endif - - - #ifndef WGL_NV_copy_image - #define WGL_NV_copy_image 1 - - typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); - - #define wglCopyImageSubDataNV GLEGetCurrentFunction(wglCopyImageSubDataNV) - - #define GLE_WGL_NV_copy_image GLEGetCurrentVariable(gle_WGL_NV_copy_image) - #endif - - - #ifndef WGL_NV_DX_interop - #define WGL_NV_DX_interop 1 - - // Note that modern AMD drivers support this NVidia extension. - #define WGL_ACCESS_READ_ONLY_NV 0x0000 - #define WGL_ACCESS_READ_WRITE_NV 0x0001 - #define WGL_ACCESS_WRITE_DISCARD_NV 0x0002 - - typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); - typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); - typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); - typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice); - typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access); - typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void* dxObject, HANDLE shareHandle); - typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); - typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); - - #define wglDXCloseDeviceNV GLEGetCurrentFunction(wglDXCloseDeviceNV) - #define wglDXLockObjectsNV GLEGetCurrentFunction(wglDXLockObjectsNV) - #define wglDXObjectAccessNV GLEGetCurrentFunction(wglDXObjectAccessNV) - #define wglDXOpenDeviceNV GLEGetCurrentFunction(wglDXOpenDeviceNV) - #define wglDXRegisterObjectNV GLEGetCurrentFunction(wglDXRegisterObjectNV) - #define wglDXSetResourceShareHandleNV GLEGetCurrentFunction(wglDXSetResourceShareHandleNV) - #define wglDXUnlockObjectsNV GLEGetCurrentFunction(wglDXUnlockObjectsNV) - #define wglDXUnregisterObjectNV GLEGetCurrentFunction(wglDXUnregisterObjectNV) - - #define GLE_WGL_NV_DX_interop GLEGetCurrentVariable(gle_WGL_NV_DX_interop) - #endif - - - #ifndef WGL_NV_DX_interop2 - #define WGL_NV_DX_interop2 1 - - // This is an update to WGL_NV_DX_interop to support DX10/DX11. - // https://www.opengl.org/registry/specs/NV/DX_interop2.txt - #define GLE_WGL_NV_DX_interop2 GLEGetCurrentVariable(gle_WGL_NV_DX_interop2) - - #endif - -#endif // GLE_WGL_ENABLED - - - -/************************************************************************************ - Apple-specific (CGL) functionality -************************************************************************************/ - -#if defined(GLE_CGL_ENABLED) - // We don't currently disable Apple's OpenGL/OpenGL.h and replicate its declarations here. - // We might want to do that if we intended to support hooking its functions here like we do for wgl functions. - #include -#endif - - - -/************************************************************************************ - Unix-specific (GLX) functionality -************************************************************************************/ - -#if defined(GLE_GLX_ENABLED) - #ifdef __glxext_h_ - #error glxext.h was included before this header. This header needs to be inlcuded instead of or at least before glxext.h - #endif - #define __glxext_h_ - - #if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__) - #error glx.h was included before this header. This header needs to be inlcuded instead of or at least before glx.h - #endif - #define GLX_H - #define __GLX_glx_h__ - #define __glx_h__ - - #include - #include - #include - - // GLX version 1.0 functions are assumed to always be present. - #ifndef GLX_VERSION_1_0 - #define GLX_VERSION_1_0 1 - - #define GLX_USE_GL 1 - #define GLX_BUFFER_SIZE 2 - #define GLX_LEVEL 3 - #define GLX_RGBA 4 - #define GLX_DOUBLEBUFFER 5 - #define GLX_STEREO 6 - #define GLX_AUX_BUFFERS 7 - #define GLX_RED_SIZE 8 - #define GLX_GREEN_SIZE 9 - #define GLX_BLUE_SIZE 10 - #define GLX_ALPHA_SIZE 11 - #define GLX_DEPTH_SIZE 12 - #define GLX_STENCIL_SIZE 13 - #define GLX_ACCUM_RED_SIZE 14 - #define GLX_ACCUM_GREEN_SIZE 15 - #define GLX_ACCUM_BLUE_SIZE 16 - #define GLX_ACCUM_ALPHA_SIZE 17 - #define GLX_BAD_SCREEN 1 - #define GLX_BAD_ATTRIBUTE 2 - #define GLX_NO_EXTENSION 3 - #define GLX_BAD_VISUAL 4 - #define GLX_BAD_CONTEXT 5 - #define GLX_BAD_VALUE 6 - #define GLX_BAD_ENUM 7 - - typedef XID GLXDrawable; - typedef XID GLXPixmap; - typedef unsigned int GLXVideoDeviceNV; - typedef struct __GLXcontextRec *GLXContext; - - // GLE_HOOKING_ENABLED - // We don't currently support hooking the following GLX 1.0 functions like we do with the analagous windows wgl functions. - // However, we can do this if needed. We would just have something like this: - // #define glXQueryExtension(...) GLEGetCurrentFunction(glXQueryExtension)(__VA_ARGS__) - // plus a member function like: - // Bool glXQueryExtension_Hook(Display*, int*, int*); - // See wglCopyContext for an example. - - extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); - extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); - extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); - extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); - extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); - extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); - extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); - extern void glXDestroyContext (Display *dpy, GLXContext ctx); - extern Bool glXIsDirect (Display *dpy, GLXContext ctx); - extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask); - extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); - extern GLXContext glXGetCurrentContext (void); - extern GLXDrawable glXGetCurrentDrawable (void); - extern void glXWaitGL (void); - extern void glXWaitX (void); - extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); - extern void glXUseXFont (Font font, int first, int count, int listBase); - - #endif // GLX_VERSION_1_0 - - - - #ifndef GLX_VERSION_1_1 - #define GLX_VERSION_1_1 - - #define GLX_VENDOR 0x1 - #define GLX_VERSION 0x2 - #define GLX_EXTENSIONS 0x3 - - // These function pointers are assumed to always be present. - extern const char* glXQueryExtensionsString (Display *dpy, int screen); - extern const char* glXGetClientString (Display *dpy, int name); - extern const char* glXQueryServerString (Display *dpy, int screen, int name); - #endif - - - #ifndef GLX_VERSION_1_2 - #define GLX_VERSION_1_2 1 - - typedef Display* (* PFNGLXGETCURRENTDISPLAYPROC) (void); - - #define glXGetCurrentDisplay GLEGetCurrentFunction(glXGetCurrentDisplay) - #endif - - - - #ifndef GLX_VERSION_1_3 - #define GLX_VERSION_1_3 1 - - #define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 - #define GLX_RGBA_BIT 0x00000001 - #define GLX_WINDOW_BIT 0x00000001 - #define GLX_COLOR_INDEX_BIT 0x00000002 - #define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 - #define GLX_PIXMAP_BIT 0x00000002 - #define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 - #define GLX_PBUFFER_BIT 0x00000004 - #define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 - #define GLX_AUX_BUFFERS_BIT 0x00000010 - #define GLX_CONFIG_CAVEAT 0x20 - #define GLX_DEPTH_BUFFER_BIT 0x00000020 - #define GLX_X_VISUAL_TYPE 0x22 - #define GLX_TRANSPARENT_TYPE 0x23 - #define GLX_TRANSPARENT_INDEX_VALUE 0x24 - #define GLX_TRANSPARENT_RED_VALUE 0x25 - #define GLX_TRANSPARENT_GREEN_VALUE 0x26 - #define GLX_TRANSPARENT_BLUE_VALUE 0x27 - #define GLX_TRANSPARENT_ALPHA_VALUE 0x28 - #define GLX_STENCIL_BUFFER_BIT 0x00000040 - #define GLX_ACCUM_BUFFER_BIT 0x00000080 - #define GLX_NONE 0x8000 - #define GLX_SLOW_CONFIG 0x8001 - #define GLX_TRUE_COLOR 0x8002 - #define GLX_DIRECT_COLOR 0x8003 - #define GLX_PSEUDO_COLOR 0x8004 - #define GLX_STATIC_COLOR 0x8005 - #define GLX_GRAY_SCALE 0x8006 - #define GLX_STATIC_GRAY 0x8007 - #define GLX_TRANSPARENT_RGB 0x8008 - #define GLX_TRANSPARENT_INDEX 0x8009 - #define GLX_VISUAL_ID 0x800B - #define GLX_SCREEN 0x800C - #define GLX_NON_CONFORMANT_CONFIG 0x800D - #define GLX_DRAWABLE_TYPE 0x8010 - #define GLX_RENDER_TYPE 0x8011 - #define GLX_X_RENDERABLE 0x8012 - #define GLX_FBCONFIG_ID 0x8013 - #define GLX_RGBA_TYPE 0x8014 - #define GLX_COLOR_INDEX_TYPE 0x8015 - #define GLX_MAX_PBUFFER_WIDTH 0x8016 - #define GLX_MAX_PBUFFER_HEIGHT 0x8017 - #define GLX_MAX_PBUFFER_PIXELS 0x8018 - #define GLX_PRESERVED_CONTENTS 0x801B - #define GLX_LARGEST_PBUFFER 0x801C - #define GLX_WIDTH 0x801D - #define GLX_HEIGHT 0x801E - #define GLX_EVENT_MASK 0x801F - #define GLX_DAMAGED 0x8020 - #define GLX_SAVED 0x8021 - #define GLX_WINDOW 0x8022 - #define GLX_PBUFFER 0x8023 - #define GLX_PBUFFER_HEIGHT 0x8040 - #define GLX_PBUFFER_WIDTH 0x8041 - #define GLX_PBUFFER_CLOBBER_MASK 0x08000000 - #define GLX_DONT_CARE 0xFFFFFFFF - - typedef XID GLXFBConfigID; - typedef XID GLXPbuffer; - typedef XID GLXWindow; - typedef struct __GLXFBConfigRec *GLXFBConfig; - - typedef struct { - int event_type; - int draw_type; - unsigned long serial; - Bool send_event; - Display *display; - GLXDrawable drawable; - unsigned int buffer_mask; - unsigned int aux_buffer; - int x, y; - int width, height; - int count; - } GLXPbufferClobberEvent; - - typedef union __GLXEvent { - GLXPbufferClobberEvent glxpbufferclobber; - long pad[24]; - } GLXEvent; - - typedef GLXFBConfig* (* PFNGLXCHOOSEFBCONFIGPROC) (::Display *dpy, int screen, const int *attrib_list, int *nelements); - typedef GLXContext (* PFNGLXCREATENEWCONTEXTPROC) (::Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); - typedef GLXPbuffer (* PFNGLXCREATEPBUFFERPROC) (::Display *dpy, GLXFBConfig config, const int *attrib_list); - typedef GLXPixmap (* PFNGLXCREATEPIXMAPPROC) (::Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); - typedef GLXWindow (* PFNGLXCREATEWINDOWPROC) (::Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); - typedef void (* PFNGLXDESTROYPBUFFERPROC) (::Display *dpy, GLXPbuffer pbuf); - typedef void (* PFNGLXDESTROYPIXMAPPROC) (::Display *dpy, GLXPixmap pixmap); - typedef void (* PFNGLXDESTROYWINDOWPROC) (::Display *dpy, GLXWindow win); - typedef GLXDrawable (* PFNGLXGETCURRENTREADDRAWABLEPROC) (void); - typedef int (* PFNGLXGETFBCONFIGATTRIBPROC) (::Display *dpy, GLXFBConfig config, int attribute, int *value); - typedef GLXFBConfig* (* PFNGLXGETFBCONFIGSPROC) (::Display *dpy, int screen, int *nelements); - typedef void (* PFNGLXGETSELECTEDEVENTPROC) (::Display *dpy, GLXDrawable draw, unsigned long *event_mask); - typedef XVisualInfo* (* PFNGLXGETVISUALFROMFBCONFIGPROC) (::Display *dpy, GLXFBConfig config); - typedef Bool (* PFNGLXMAKECONTEXTCURRENTPROC) (::Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); - typedef int (* PFNGLXQUERYCONTEXTPROC) (::Display *dpy, GLXContext ctx, int attribute, int *value); - typedef void (* PFNGLXQUERYDRAWABLEPROC) (::Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); - typedef void (* PFNGLXSELECTEVENTPROC) (::Display *dpy, GLXDrawable draw, unsigned long event_mask); - - #define glXChooseFBConfig GLEGetCurrentFunction(glXChooseFBConfig) - #define glXCreateNewContext GLEGetCurrentFunction(glXCreateNewContext) - #define glXCreatePbuffer GLEGetCurrentFunction(glXCreatePbuffer) - #define glXCreatePixmap GLEGetCurrentFunction(glXCreatePixmap) - #define glXCreateWindow GLEGetCurrentFunction(glXCreateWindow) - #define glXDestroyPbuffer GLEGetCurrentFunction(glXDestroyPbuffer) - #define glXDestroyPixmap GLEGetCurrentFunction(glXDestroyPixmap) - #define glXDestroyWindow GLEGetCurrentFunction(glXDestroyWindow) - #define glXGetCurrentReadDrawable GLEGetCurrentFunction(glXGetCurrentReadDrawable) - #define glXGetFBConfigAttrib GLEGetCurrentFunction(glXGetFBConfigAttrib) - #define glXGetFBConfigs GLEGetCurrentFunction(glXGetFBConfigs) - #define glXGetSelectedEvent GLEGetCurrentFunction(glXGetSelectedEvent) - #define glXGetVisualFromFBConfig GLEGetCurrentFunction(glXGetVisualFromFBConfig) - #define glXMakeContextCurrent GLEGetCurrentFunction(glXMakeContextCurrent) - #define glXQueryContext GLEGetCurrentFunction(glXQueryContext) - #define glXQueryDrawable GLEGetCurrentFunction(glXQueryDrawable) - #define glXSelectEvent GLEGetCurrentFunction(glXSelectEvent) - - #endif // GLX_VERSION_1_3 - - - - #ifndef GLX_VERSION_1_4 - #define GLX_VERSION_1_4 1 - - #define GLX_SAMPLE_BUFFERS 100000 - #define GLX_SAMPLES 100001 - - // This was glXGetProcAddressARB in GLX versions prior to v1.4. - // This function pointer is assumed to always be present. - extern void (* glXGetProcAddress(const GLubyte *procName)) (); - - // For backward compatibility - extern void (* glXGetProcAddressARB(const GLubyte *procName)) (); - #endif - - - - #ifndef GLX_ARB_create_context - #define GLX_ARB_create_context 1 - - #define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 - #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 - #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 - #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 - #define GLX_CONTEXT_FLAGS_ARB 0x2094 - - typedef GLXContext (* PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); - - #define glXCreateContextAttribsARB GLEGetCurrentFunction(glXCreateContextAttribsARB) - - #define GLE_GLX_ARB_create_context GLEGetCurrentVariable(gle_GLX_ARB_create_context) - #endif - - - #ifndef GLX_ARB_create_context_profile - #define GLX_ARB_create_context_profile 1 - - #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 - #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 - #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 - - #define GLE_GLX_ARB_create_context_profile GLEGetCurrentVariable(gle_GLX_ARB_create_context_profile) - #endif - - - #ifndef GLX_ARB_create_context_robustness - #define GLX_ARB_create_context_robustness 1 - - #define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 - #define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 - #define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 - #define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 - - #define GLE_GLX_ARB_create_context_robustness GLEGetCurrentVariable(gle_GLX_ARB_create_context_robustness) - #endif - - - // Note: In order to detect the GLX extensions' availability, we need to call glXQueryExtensionsString instead of glGetString(GL_EXTENSIONS). - #ifndef GLX_EXT_swap_control - #define GLX_EXT_swap_control 1 - - #define GLX_SWAP_INTERVAL_EXT 0x20F1 - #define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 - - typedef void (* PFNGLXSWAPINTERVALEXTPROC) (Display* dpy, GLXDrawable drawable, int interval); - - #define glXSwapIntervalEXT GLEGetCurrentFunction(glXSwapIntervalEXT) - - #define GLE_GLX_EXT_swap_control GLEGetCurrentVariable(gle_GLX_EXT_swap_control) - #endif - - - #ifndef GLX_OML_sync_control - #define GLX_OML_sync_control 1 - - typedef Bool (* PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); - typedef Bool (* PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); - typedef int64_t (* PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); - typedef Bool (* PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); - typedef Bool (* PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); - - #define glXGetMscRateOML GLEGetCurrentFunction(glXGetMscRateOML) - #define glXGetSyncValuesOML GLEGetCurrentFunction(glXGetSyncValuesOML) - #define glXSwapBuffersMscOML GLEGetCurrentFunction(glXSwapBuffersMscOML) - #define glXWaitForMscOML GLEGetCurrentFunction(glXWaitForMscOML) - #define glXWaitForSbcOML GLEGetCurrentFunction(glXWaitForSbcOML) - - #define GLE_GLX_OML_sync_control GLEGetCurrentVariable(gle_GLX_OML_sync_control) - #endif - - - #ifndef GLX_MESA_swap_control - #define GLX_MESA_swap_control 1 - - // GLX_MESA_swap_control has the same functionality as GLX_EXT_swap_control but with a different interface, so we have an independent entry for it here. - typedef int (* PFNGLXGETSWAPINTERVALMESAPROC) (void); - typedef int (* PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval); - - #define glXGetSwapIntervalMESA GLEGetCurrentFunction(glXGetSwapIntervalMESA) - #define glXSwapIntervalMESA GLEGetCurrentFunction(glXSwapIntervalMESA) - - #define GLE_MESA_swap_control GLEGetCurrentVariable(gle_MESA_swap_control) - #endif - -#endif // GLE_GLX_ENABLED - - -// Undo some defines, because the user may include after including this header. -#if defined(GLE_WINGDIAPI_DEFINED) - #undef WINGDIAPI -#endif - - -#ifdef __cplusplus -} // extern "C" -#endif - - - -#endif // Header include guard - - - - - diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp index 5ddbed2..431661e 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.cpp @@ -28,12 +28,10 @@ limitations under the License. #include "CAPI_GL_DistortionShaders.h" -#include "../../OVR_CAPI_GL.h" -#include "../../Kernel/OVR_Color.h" +#include "OVR_CAPI_GL.h" +#include "Kernel/OVR_Color.h" -#if defined(OVR_OS_LINUX) - #include "../../Displays/OVR_Linux_SDKWindow.h" -#elif defined(OVR_OS_MAC) +#if defined(OVR_OS_MAC) #include #include #endif @@ -42,13 +40,13 @@ namespace OVR { namespace CAPI { namespace GL { // Distortion pixel shader lookup. -// Bit 0: Chroma Correction -// Bit 1: Timewarp +// Bit 0: Orientation Timewarp +// Bit 1: Depth-based Timewarp enum { DistortionVertexShaderBitMask = 3, DistortionVertexShaderCount = DistortionVertexShaderBitMask + 1, - DistortionPixelShaderBitMask = 1, + DistortionPixelShaderBitMask = 0, DistortionPixelShaderCount = DistortionPixelShaderBitMask + 1 }; @@ -67,21 +65,19 @@ struct ShaderInfo static ShaderInfo DistortionVertexShaderLookup[DistortionVertexShaderCount] = { - SI_REFL__(Distortion_vs), SI_REFL__(DistortionChroma_vs), - SI_REFL__(DistortionTimewarp_vs), - SI_REFL__(DistortionTimewarpChroma_vs) + { NULL, 0, NULL, 0 }, + SI_REFL__(DistortionTimewarpChroma_vs), + { NULL, 0, NULL, 0 }, }; static ShaderInfo DistortionPixelShaderLookup[DistortionPixelShaderCount] = { - SI_NOREFL(Distortion_fs), SI_NOREFL(DistortionChroma_fs) }; void DistortionShaderBitIndexCheck() { - OVR_COMPILER_ASSERT(ovrDistortionCap_Chromatic == 1); OVR_COMPILER_ASSERT(ovrDistortionCap_TimeWarp == 2); } @@ -109,12 +105,9 @@ struct LatencyVertex //---------------------------------------------------------------------------- // ***** GL::DistortionRenderer -DistortionRenderer::DistortionRenderer(ovrHmd hmd, FrameTimeManager& timeManager, - const HMDRenderState& renderState) - : CAPI::DistortionRenderer(ovrRenderAPI_OpenGL, hmd, timeManager, renderState) - , RotateCCW90(false) - , LatencyVAO(0) - , OverdriveFbo(0) +DistortionRenderer::DistortionRenderer() : + LatencyVAO(0), + OverdriveFbo(0) { DistortionMeshVAOs[0] = 0; DistortionMeshVAOs[1] = 0; @@ -129,17 +122,15 @@ DistortionRenderer::~DistortionRenderer() } // static -CAPI::DistortionRenderer* DistortionRenderer::Create(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState) +CAPI::DistortionRenderer* DistortionRenderer::Create() { InitGLExtensions(); - return new DistortionRenderer(hmd, timeManager, renderState); + return new DistortionRenderer; } -bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) +bool DistortionRenderer::initializeRenderer(const ovrRenderAPIConfig* apiConfig) { const ovrGLConfig* config = (const ovrGLConfig*)apiConfig; @@ -158,12 +149,6 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) RParams.Window = (config->OGL.Window) ? config->OGL.Window : GetActiveWindow(); RParams.DC = config->OGL.DC; #elif defined(OVR_OS_LINUX) - RotateCCW90 = false; - if ( RState.DistortionCaps & ovrDistortionCap_LinuxDevFullscreen - && SDKWindow::getRotation(HMD) == DistRotateCCW90) - { - RotateCCW90 = true; - } if (config->OGL.Disp) { RParams.Disp = config->OGL.Disp; @@ -189,7 +174,10 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) pEyeTextures[0] = *new Texture(&RParams, 0, 0); pEyeTextures[1] = *new Texture(&RParams, 0, 0); - initBuffersAndShaders(); + if (!initBuffersAndShaders()) + { + return false; + } initOverdrive(); @@ -199,13 +187,13 @@ bool DistortionRenderer::Initialize(const ovrRenderAPIConfig* apiConfig) void DistortionRenderer::initOverdrive() { - if(RState.DistortionCaps & ovrDistortionCap_Overdrive) + if(RenderState->DistortionCaps & ovrDistortionCap_Overdrive) { LastUsedOverdriveTextureIndex = 0; glGenFramebuffers(1, &OverdriveFbo); - GLint internalFormat = (RState.DistortionCaps & ovrDistortionCap_SRGB) ? GL_SRGB_ALPHA : GL_RGBA; + GLint internalFormat = (RenderState->DistortionCaps & ovrDistortionCap_SRGB) ? GL_SRGB_ALPHA : GL_RGBA; for (int i = 0; i < NumOverdriveTextures ; i++) { @@ -264,11 +252,11 @@ void DistortionRenderer::initOverdrive() void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) { - // Doesn't do a lot in here?? - const ovrGLTexture* tex = (const ovrGLTexture*)eyeTexture; - - if (tex) + if (eyeTexture) { + // Doesn't do a lot in here?? + const ovrGLTexture* tex = (const ovrGLTexture*)eyeTexture; + // Write in values eachEye[eyeId].texture = tex->OGL.TexId; @@ -277,13 +265,16 @@ void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) eachEye[eyeId].TextureSize = tex->OGL.Header.TextureSize; eachEye[eyeId].RenderViewport = tex->OGL.Header.RenderViewport; - const ovrEyeRenderDesc& erd = RState.EyeRenderDesc[eyeId]; + const ovrEyeRenderDesc& erd = RenderState->EyeRenderDesc[eyeId]; + // Modify viewport offset since OpenGL uses bottom left as the origin + eachEye[eyeId].RenderViewport.y = eachEye[eyeId].TextureSize.h - eachEye[eyeId].RenderViewport.h - eachEye[eyeId].RenderViewport.y; + ovrHmd_GetRenderScaleAndOffset( erd.Fov, eachEye[eyeId].TextureSize, eachEye[eyeId].RenderViewport, eachEye[eyeId].UVScaleOffset ); - if (!(RState.DistortionCaps & ovrDistortionCap_FlipInput)) + if (!(RenderState->DistortionCaps & ovrDistortionCap_FlipInput)) { eachEye[eyeId].UVScaleOffset[0].y = -eachEye[eyeId].UVScaleOffset[0].y; eachEye[eyeId].UVScaleOffset[1].y = 1.0f - eachEye[eyeId].UVScaleOffset[1].y; @@ -294,6 +285,13 @@ void DistortionRenderer::SubmitEye(int eyeId, const ovrTexture* eyeTexture) } } +void DistortionRenderer::SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) +{ + SubmitEye(eyeId, eyeColorTexture); + + OVR_UNUSED(eyeDepthTexture); +} + void DistortionRenderer::renderEndFrame() { renderDistortion(pEyeTextures[0], pEyeTextures[1]); @@ -308,8 +306,11 @@ void DistortionRenderer::renderEndFrame() } } -void DistortionRenderer::EndFrame(bool swapBuffers) +void DistortionRenderer::EndFrame(uint32_t frameIndex, bool swapBuffers) { + // OGL does not support frame timing statistics. + Timing->CalculateTimewarpTiming(frameIndex); + Context currContext; currContext.InitFromCurrent(); #if defined(OVR_OS_MAC) @@ -317,13 +318,14 @@ void DistortionRenderer::EndFrame(bool swapBuffers) #endif // Don't spin if we are explicitly asked not to - if ((RState.DistortionCaps & ovrDistortionCap_TimeWarp) && - !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) + if ( (RenderState->DistortionCaps & ovrDistortionCap_TimeWarp) && + (RenderState->DistortionCaps & ovrDistortionCap_TimewarpJitDelay) && + !(RenderState->DistortionCaps & ovrDistortionCap_ProfileNoSpinWaits)) { - if (!TimeManager.NeedDistortionTimeMeasurement()) + if (!Timing->NeedDistortionTimeMeasurement()) { // Wait for timewarp distortion if it is time and Gpu idle - FlushGpuAndWaitTillTime(TimeManager.GetFrameTiming().TimewarpPointTime); + FlushGpuAndWaitTillTime(Timing->GetTimewarpTiming()->JIT_TimewarpTime); distortionContext.Bind(); renderEndFrame(); @@ -339,7 +341,7 @@ void DistortionRenderer::EndFrame(bool swapBuffers) renderEndFrame(); WaitUntilGpuIdle(); - TimeManager.AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); + Timing->AddDistortionTimeMeasurement(ovr_GetTimeInSeconds() - distortionStartTime); } } else @@ -355,7 +357,7 @@ void DistortionRenderer::EndFrame(bool swapBuffers) if (swapBuffers) { - bool useVsync = ((RState.EnabledHmdCaps & ovrHmdCap_NoVSync) == 0); + bool useVsync = ((RenderState->EnabledHmdCaps & ovrHmdCap_NoVSync) == 0); int ourSwapInterval = (useVsync) ? 1 : 0; int originalSwapInterval; @@ -412,10 +414,12 @@ void DistortionRenderer::EndFrame(bool swapBuffers) // below completing after the vsync. // With the display driver (direct mode) this flush is obsolete and theoretically // should be a no-op and so doesn't need to be done if running in direct mode. - if (RState.OurHMDInfo.InCompatibilityMode && - !(RState.DistortionCaps & ovrDistortionCap_ProfileNoTimewarpSpinWaits)) + if (RenderState->OurHMDInfo.InCompatibilityMode && + !(RenderState->DistortionCaps & ovrDistortionCap_ProfileNoSpinWaits)) + { WaitUntilGpuIdle(); - + } + // Restore the original swap interval if we changed it above. if (originalSwapInterval != ourSwapInterval) { @@ -454,21 +458,22 @@ double DistortionRenderer::FlushGpuAndWaitTillTime(double absTime) return WaitTillTime(absTime); } -void DistortionRenderer::initBuffersAndShaders() +bool DistortionRenderer::initBuffersAndShaders() { for ( int eyeNum = 0; eyeNum < 2; eyeNum++ ) { // Allocate & generate distortion mesh vertices. ovrDistortionMesh meshData; - if (!ovrHmd_CreateDistortionMesh( HMD, - RState.EyeRenderDesc[eyeNum].Eye, - RState.EyeRenderDesc[eyeNum].Fov, - RState.DistortionCaps, - &meshData) ) + if (!CalculateDistortionMeshFromFOV(RenderState->RenderInfo, + RenderState->Distortion[eyeNum], + (RenderState->EyeRenderDesc[eyeNum].Eye == ovrEye_Left ? StereoEye_Left : StereoEye_Right), + RenderState->EyeRenderDesc[eyeNum].Fov, + RenderState->DistortionCaps, + &meshData)) { OVR_ASSERT(false); - continue; + return false; } // Now parse the vertex data and create a render ready vertex buffer from it @@ -481,12 +486,6 @@ void DistortionRenderer::initBuffersAndShaders() pCurVBVert->ScreenPosNDC.x = pCurOvrVert->ScreenPosNDC.x; pCurVBVert->ScreenPosNDC.y = pCurOvrVert->ScreenPosNDC.y; - if (RotateCCW90) - { - OVR::Alg::Swap(pCurVBVert->ScreenPosNDC.x, pCurVBVert->ScreenPosNDC.y); - pCurVBVert->ScreenPosNDC.x = -pCurVBVert->ScreenPosNDC.x; - } - // Previous code here did this: pCurVBVert->TanEyeAnglesR = (*(Vector2f*)&pCurOvrVert->TanEyeAnglesR); However that's an usafe // cast of unrelated types which can result in undefined behavior by a conforming compiler. A safe equivalent is simply memcpy. static_assert(sizeof(OVR::Vector2f) == sizeof(ovrVector2f), "Mismatch of structs that are presumed binary equivalents."); @@ -495,9 +494,9 @@ void DistortionRenderer::initBuffersAndShaders() memcpy(&pCurVBVert->TanEyeAnglesB, &pCurOvrVert->TanEyeAnglesB, sizeof(pCurVBVert->TanEyeAnglesB)); // Convert [0.0f,1.0f] to [0,255] - if (RState.DistortionCaps & ovrDistortionCap_Vignette) + if (RenderState->DistortionCaps & ovrDistortionCap_Vignette) { - if(RState.DistortionCaps & ovrDistortionCap_SRGB) + if(RenderState->DistortionCaps & ovrDistortionCap_SRGB) pCurOvrVert->VignetteFactor = pow(pCurOvrVert->VignetteFactor, 2.1f); pCurVBVert->Col.R = (uint8_t)( Alg::Max ( pCurOvrVert->VignetteFactor, 0.0f ) * 255.99f ); @@ -522,6 +521,8 @@ void DistortionRenderer::initBuffersAndShaders() } initShaders(); + + return true; } void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* rightEyeTexture) @@ -551,7 +552,7 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ setViewport( Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h) ); - if (RState.DistortionCaps & ovrDistortionCap_SRGB) + if (RenderState->DistortionCaps & ovrDistortionCap_SRGB) glEnable(GL_FRAMEBUFFER_SRGB); else glDisable(GL_FRAMEBUFFER_SRGB); @@ -578,10 +579,10 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ } glClearColor( - RState.ClearColor[0], - RState.ClearColor[1], - RState.ClearColor[2], - RState.ClearColor[3] ); + RenderState->ClearColor[0], + RenderState->ClearColor[1], + RenderState->ClearColor[2], + RenderState->ClearColor[3] ); glClear(GL_COLOR_BUFFER_BIT); @@ -598,7 +599,7 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ float overdriveScaleRegularFall; GetOverdriveScales(overdriveScaleRegularRise, overdriveScaleRegularFall); DistortionShader->SetUniform3f("OverdriveScales_IsSrgb", overdriveScaleRegularRise, overdriveScaleRegularFall, - (RState.DistortionCaps & ovrDistortionCap_SRGB) ? 1.0f : -1.0f); + (RenderState->DistortionCaps & ovrDistortionCap_SRGB) ? 1.0f : -1.0f); } else { @@ -607,18 +608,21 @@ void DistortionRenderer::renderDistortion(Texture* leftEyeTexture, Texture* righ } DistortionShader->SetUniform2f("EyeToSourceUVScale", eachEye[eyeNum].UVScaleOffset[0].x, eachEye[eyeNum].UVScaleOffset[0].y); - // Convert Y to 1-Y as OpenGL is inverse of D3D - DistortionShader->SetUniform2f("EyeToSourceUVOffset", eachEye[eyeNum].UVScaleOffset[1].x, 1.0f - eachEye[eyeNum].UVScaleOffset[1].y); + DistortionShader->SetUniform2f("EyeToSourceUVOffset", eachEye[eyeNum].UVScaleOffset[1].x, eachEye[eyeNum].UVScaleOffset[1].y); - if (RState.DistortionCaps & ovrDistortionCap_TimeWarp) + if (RenderState->DistortionCaps & ovrDistortionCap_TimeWarp) { - ovrMatrix4f timeWarpMatrices[2]; - ovrHmd_GetEyeTimewarpMatrices(HMD, (ovrEyeType)eyeNum, - RState.EyeRenderPoses[eyeNum], timeWarpMatrices); + Matrix4f startEndMatrices[2]; + double timewarpIMUTime = 0.; + CalculateOrientationTimewarpFromSensors( + RenderState->EyeRenderPoses[eyeNum].Orientation, + SensorReader, Timing->GetTimewarpTiming()->EyeStartEndTimes[eyeNum], + startEndMatrices, timewarpIMUTime); + Timing->SetTimewarpIMUTime(timewarpIMUTime); // Feed identity like matrices in until we get proper timewarp calculation going on - DistortionShader->SetUniform4x4f("EyeRotationStart", Matrix4f(timeWarpMatrices[0]).Transposed()); - DistortionShader->SetUniform4x4f("EyeRotationEnd", Matrix4f(timeWarpMatrices[1]).Transposed()); + DistortionShader->SetUniform4x4f("EyeRotationStart", startEndMatrices[0].Transposed()); + DistortionShader->SetUniform4x4f("EyeRotationEnd", startEndMatrices[1].Transposed()); renderPrimitives(&distortionShaderFill, DistortionMeshVBs[eyeNum], DistortionMeshIBs[eyeNum], 0, (int)DistortionMeshIBs[eyeNum]->GetSize()/2, Prim_Triangles, &DistortionMeshVAOs[eyeNum], true); @@ -698,7 +702,7 @@ void DistortionRenderer::renderLatencyQuad(unsigned char* latencyTesterDrawColor createDrawQuad(); } - Ptr quadShader = (RState.DistortionCaps & ovrDistortionCap_SRGB) ? SimpleQuadGammaShader : SimpleQuadShader; + Ptr quadShader = (RenderState->DistortionCaps & ovrDistortionCap_SRGB) ? SimpleQuadGammaShader : SimpleQuadShader; ShaderFill quadFill(quadShader); //quadFill.SetInputLayout(SimpleQuadVertexIL); @@ -726,7 +730,7 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol createDrawQuad(); } - Ptr quadShader = (RState.DistortionCaps & ovrDistortionCap_SRGB) ? SimpleQuadGammaShader : SimpleQuadShader; + Ptr quadShader = (RenderState->DistortionCaps & ovrDistortionCap_SRGB) ? SimpleQuadGammaShader : SimpleQuadShader; ShaderFill quadFill(quadShader); setViewport(Recti(0,0, RParams.BackBufferSize.w, RParams.BackBufferSize.h)); @@ -747,11 +751,28 @@ void DistortionRenderer::renderLatencyPixel(unsigned char* latencyTesterPixelCol Vector2f scale(1.0f / RParams.BackBufferSize.w, 1.0f / RParams.BackBufferSize.h); #endif quadShader->SetUniform2f("Scale", scale.x, scale.y); - if (!RotateCCW90) - quadShader->SetUniform2f("PositionOffset", 1.0f-scale.x, 1.0f-scale.y); - else - quadShader->SetUniform2f("PositionOffset", -(1.0f-scale.x), 1.0f-scale.y); - renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false); + + float xOffset = RenderState->RenderInfo.OffsetLatencyTester ? -0.5f * scale.x : 1.0f - scale.x; + float yOffset = 1.0f - scale.y; + + // Render the latency tester quad in the correct location. + if (RenderState->RenderInfo.Rotation == 270) + { + xOffset = -xOffset; + } + else if (RenderState->RenderInfo.Rotation == 180) + { + xOffset = -xOffset; + yOffset = -yOffset; + } + else if (RenderState->RenderInfo.Rotation == 90) + { + yOffset = -yOffset; + } + + quadShader->SetUniform2f("PositionOffset", xOffset, yOffset); + + renderPrimitives(&quadFill, LatencyTesterQuadVB, NULL, 0, numQuadVerts, Prim_TriangleStrip, &LatencyVAO, false); } void DistortionRenderer::renderPrimitives( @@ -866,38 +887,50 @@ void DistortionRenderer::initShaders() const char* shaderPrefix = (GLEContext::GetCurrentContext()->WholeVersion >= 302) ? glsl3Prefix : glsl2Prefix; { - ShaderInfo vsInfo = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & RState.DistortionCaps]; - - size_t vsSize = strlen(shaderPrefix)+vsInfo.ShaderSize; - char* vsSource = new char[vsSize]; - OVR_strcpy(vsSource, vsSize, shaderPrefix); - OVR_strcat(vsSource, vsSize, vsInfo.ShaderData); - - Ptr vs = *new GL::VertexShader( - &RParams, - (void*)vsSource, vsSize, - vsInfo.ReflectionData, vsInfo.ReflectionSize); + ShaderInfo vsInfo = DistortionVertexShaderLookup[DistortionVertexShaderBitMask & RenderState->DistortionCaps]; + if(vsInfo.ShaderData != NULL) + { + size_t vsSize = strlen(shaderPrefix)+vsInfo.ShaderSize; + char* vsSource = new char[vsSize]; + OVR_strcpy(vsSource, vsSize, shaderPrefix); + OVR_strcat(vsSource, vsSize, vsInfo.ShaderData); - DistortionShader = *new ShaderSet; - DistortionShader->SetShader(vs); + Ptr vs = *new GL::VertexShader( + &RParams, + (void*)vsSource, vsSize, + vsInfo.ReflectionData, vsInfo.ReflectionSize); - delete[](vsSource); + DistortionShader = *new ShaderSet; + DistortionShader->SetShader(vs); - ShaderInfo psInfo = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & RState.DistortionCaps]; + delete[](vsSource); + } + else + { + OVR_ASSERT_M(false, "Unsupported distortion feature used\n"); + } - size_t psSize = strlen(shaderPrefix)+psInfo.ShaderSize; - char* psSource = new char[psSize]; - OVR_strcpy(psSource, psSize, shaderPrefix); - OVR_strcat(psSource, psSize, psInfo.ShaderData); + ShaderInfo psInfo = DistortionPixelShaderLookup[DistortionPixelShaderBitMask & RenderState->DistortionCaps]; + if(psInfo.ShaderData != NULL) + { + size_t psSize = strlen(shaderPrefix)+psInfo.ShaderSize; + char* psSource = new char[psSize]; + OVR_strcpy(psSource, psSize, shaderPrefix); + OVR_strcat(psSource, psSize, psInfo.ShaderData); - Ptr ps = *new GL::FragmentShader( - &RParams, - (void*)psSource, psSize, - psInfo.ReflectionData, psInfo.ReflectionSize); + Ptr ps = *new GL::FragmentShader( + &RParams, + (void*)psSource, psSize, + psInfo.ReflectionData, psInfo.ReflectionSize); - DistortionShader->SetShader(ps); + DistortionShader->SetShader(ps); - delete[](psSource); + delete[](psSource); + } + else + { + OVR_ASSERT_M(false, "Unsupported distortion feature used\n"); + } } { size_t vsSize = strlen(shaderPrefix)+sizeof(SimpleQuad_vs); diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h index f48e42d..033a7c6 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionRenderer.h @@ -29,11 +29,12 @@ limitations under the License. #include "../CAPI_DistortionRenderer.h" -#include "../../Kernel/OVR_Log.h" +#include "Kernel/OVR_Log.h" #include "CAPI_GL_Util.h" namespace OVR { namespace CAPI { namespace GL { + // ***** GL::DistortionRenderer // Implementation of DistortionRenderer for GL. @@ -41,25 +42,20 @@ namespace OVR { namespace CAPI { namespace GL { class DistortionRenderer : public CAPI::DistortionRenderer { public: - DistortionRenderer(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState); + DistortionRenderer(); virtual ~DistortionRenderer(); // Creation function for the device. - static CAPI::DistortionRenderer* Create(ovrHmd hmd, - FrameTimeManager& timeManager, - const HMDRenderState& renderState); + static CAPI::DistortionRenderer* Create(); // ***** Public DistortionRenderer interface - - virtual bool Initialize(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; - virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture); + virtual void SubmitEye(int eyeId, const ovrTexture* eyeTexture) OVR_OVERRIDE; + virtual void SubmitEyeWithDepth(int eyeId, const ovrTexture* eyeColorTexture, const ovrTexture* eyeDepthTexture) OVR_OVERRIDE; - virtual void EndFrame(bool swapBuffers); + virtual void EndFrame(uint32_t frameIndex, bool swapBuffers); void WaitUntilGpuIdle(); @@ -68,7 +64,6 @@ public: double FlushGpuAndWaitTillTime(double absTime); protected: - struct FOR_EACH_EYE { FOR_EACH_EYE() : numVerts(0), numIndices(0), texture(0), /*UVScaleOffset[],*/ TextureSize(0, 0), RenderViewport(0, 0, 0, 0) { } @@ -90,9 +85,11 @@ protected: RenderParams RParams; Context distortionContext; // We are currently using this private OpenGL context instead of using the CAPI SaveGraphicsState/RestoreGraphicsState mechanism. To consider: Move this Context into SaveGraphicsState/RestoreGraphicState so there's consistency between DirectX and OpenGL. + virtual bool initializeRenderer(const ovrRenderAPIConfig* apiConfig) OVR_OVERRIDE; + // Helpers void initOverdrive(); - void initBuffersAndShaders(); + bool initBuffersAndShaders(); void initShaders(); void initFullscreenQuad(); void destroy(); @@ -119,8 +116,6 @@ protected: Ptr DistortionShader; - bool RotateCCW90; - struct StandardUniformData { Matrix4f Proj; @@ -145,6 +140,7 @@ protected: GLint SavedBoundFrameBuffer; }; + }}} // OVR::CAPI::GL #endif // OVR_CAPI_GL_DistortionRenderer_h diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h index 6f48122..7fc6b9e 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_DistortionShaders.h @@ -164,105 +164,6 @@ namespace OVR { namespace CAPI { namespace GL { { { "Color", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 16 }, }; - - - static const char Distortion_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - - "_VS_IN vec2 Position;\n" - "_VS_IN vec4 Color;\n" - "_VS_IN vec2 TexCoord0;\n" - - "_VS_OUT vec4 oColor;\n" - "_VS_OUT vec2 oTexCoord0;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.5;\n" - " gl_Position.w = 1.0;\n" - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " oTexCoord0 = TexCoord0 * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oColor = Color;\n" // Used for vignette fade. - "}\n"; - - const OVR::CAPI::GL::ShaderBase::Uniform Distortion_vs_refl[] = - { - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, - }; - - static const char Distortion_fs[] = - "uniform sampler2D Texture0;\n" - - "_FS_IN vec4 oColor;\n" - "_FS_IN vec2 oTexCoord0;\n" - - "_FRAGCOLOR_DECLARATION\n" - - "void main()\n" - "{\n" - " _FRAGCOLOR = _TEXTURE(Texture0, oTexCoord0, 0.0);\n" - " _FRAGCOLOR.a = 1.0;\n" - "}\n"; - - - static const char DistortionTimewarp_vs[] = - "uniform vec2 EyeToSourceUVScale;\n" - "uniform vec2 EyeToSourceUVOffset;\n" - "uniform mat4 EyeRotationStart;\n" - "uniform mat4 EyeRotationEnd;\n" - - "_VS_IN vec2 Position;\n" - "_VS_IN vec4 Color;\n" - "_VS_IN vec2 TexCoord0;\n" - - "_VS_OUT vec4 oColor;\n" - "_VS_OUT vec2 oTexCoord0;\n" - - "void main()\n" - "{\n" - " gl_Position.x = Position.x;\n" - " gl_Position.y = Position.y;\n" - " gl_Position.z = 0.0;\n" - " gl_Position.w = 1.0;\n" - - // Vertex inputs are in TanEyeAngle space for the R,G,B channels (i.e. after chromatic aberration and distortion). - // These are now "real world" vectors in direction (x,y,1) relative to the eye of the HMD. - " vec3 TanEyeAngle = vec3 ( TexCoord0.x, TexCoord0.y, 1.0 );\n" - - // Accurate time warp lerp vs. faster -#if 1 - // Apply the two 3x3 timewarp rotations to these vectors. - " vec3 TransformedStart = (EyeRotationStart * vec4(TanEyeAngle, 0)).xyz;\n" - " vec3 TransformedEnd = (EyeRotationEnd * vec4(TanEyeAngle, 0)).xyz;\n" - // And blend between them. - " vec3 Transformed = mix ( TransformedStart, TransformedEnd, Color.a );\n" -#else - " mat4 EyeRotation = mix ( EyeRotationStart, EyeRotationEnd, Color.a );\n" - " vec3 Transformed = EyeRotation * TanEyeAngle;\n" -#endif - - // Project them back onto the Z=1 plane of the rendered images. - " float RecipZ = 1.0 / Transformed.z;\n" - " vec2 Flattened = vec2 ( Transformed.x * RecipZ, Transformed.y * RecipZ );\n" - - // These are now still in TanEyeAngle space. - // Scale them into the correct [0-1],[0-1] UV lookup space (depending on eye) - " vec2 SrcCoord = Flattened * EyeToSourceUVScale + EyeToSourceUVOffset;\n" - " oTexCoord0 = SrcCoord;\n" - " oColor = vec4(Color.r, Color.r, Color.r, Color.r);\n" // Used for vignette fade. - "}\n"; - - - const OVR::CAPI::GL::ShaderBase::Uniform DistortionTimewarp_vs_refl[] = - { - { "EyeToSourceUVScale", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 0, 8 }, - { "EyeToSourceUVOffset", OVR::CAPI::GL::ShaderBase::VARTYPE_FLOAT, 8, 8 }, - }; static const char DistortionChroma_vs[] = "uniform vec2 EyeToSourceUVScale;\n" diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp index a795fa9..782af5c 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_HSWDisplay.cpp @@ -27,11 +27,11 @@ limitations under the License. #include "CAPI_GL_HSWDisplay.h" #include "CAPI_GL_DistortionShaders.h" -#include "../../OVR_CAPI_GL.h" -#include "../../Kernel/OVR_File.h" -#include "../../Kernel/OVR_Math.h" -#include "../../Kernel/OVR_Allocator.h" -#include "../../Kernel/OVR_Color.h" +#include "OVR_CAPI_GL.h" +#include "Kernel/OVR_File.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Color.h" +#include "Extras/OVR_Math.h" OVR_DISABLE_MSVC_WARNING(4996) // "This function or variable may be unsafe..." @@ -71,6 +71,12 @@ uint8_t* LoadTextureTgaData(OVR::File* f, uint8_t alpha, int& width, int& height // imgType 2 is uncompressed true-color image. // imgType 10 is run-length encoded true-color image. + + // WARNING - this loader is potentially incorrect. The default TGA origin is bottom-left. + // You can change the origin, but that is non-standard, and this loader ignores that bit in the header. + // So just be aware that this texture will have the UV origin at the bottom lef of the image, even in DirectX + // (I fixed the other TGA loader, but I'm not "fixing" this one because the thing works, so leave it alone!) + if(((imgtype == ImgTypeBGRAUncompressed) || (imgtype == ImgTypeBGRARLECompressed)) && ((bpp == 24) || (bpp == 32))) { int imgsize = width * height * 4; @@ -313,25 +319,25 @@ void HSWDisplay::UnloadGraphics() currentGLContext.InitFromCurrent(); GLContext.Bind(); - // RenderParams: No need to clear. - if(FrameBuffer != 0) - { - glDeleteFramebuffers(1, &FrameBuffer); - FrameBuffer = 0; - } - pTexture.Clear(); - pShaderSet.Clear(); - pVertexShader.Clear(); - pFragmentShader.Clear(); - pVB.Clear(); - if(VAO) - { + // RenderParams: No need to clear. + if(FrameBuffer != 0) + { + glDeleteFramebuffers(1, &FrameBuffer); + FrameBuffer = 0; + } + pTexture.Clear(); + pShaderSet.Clear(); + pVertexShader.Clear(); + pFragmentShader.Clear(); + pVB.Clear(); + if(VAO) + { glDeleteVertexArrays(1, &VAO); + } currentGLContext.Bind(); GLContext.Destroy(); } } -} void HSWDisplay::LoadGraphics() @@ -389,6 +395,7 @@ void HSWDisplay::LoadGraphics() const float right = 1.0f; // API abstraction we may move this draw to an overlay layer or to a more formal const float bottom = 0.9f; // model/mesh scheme with a perspective projection. + // See warning in LoadTextureTgaData() about this TGA being loaded "upside down", i.e. UV origin is at bottom-left. pVertices[0] = HASWVertex(left, top, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 1.f : 0.f); pVertices[1] = HASWVertex(left, bottom, 0.f, Color(255, 255, 255, 255), 0.f, flip ? 0.f : 1.f); pVertices[2] = HASWVertex(right, top, 0.f, Color(255, 255, 255, 255), 1.f, flip ? 1.f : 0.f); diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp index e3fdaac..ed61324 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.cpp @@ -25,16 +25,46 @@ limitations under the License. ************************************************************************************/ #include "CAPI_GL_Util.h" -#include "../../Kernel/OVR_Log.h" +#include "Kernel/OVR_Log.h" #include #if defined(OVR_OS_LINUX) - #include "../../Displays/OVR_Linux_SDKWindow.h" + #include "Displays/OVR_Linux_SDKWindow.h" #endif #if defined(OVR_OS_MAC) #include #include + #import + + // Hides Objective C NSOpenGLContext. + class MacContextImpl + { + public: + MacContextImpl(NSOpenGLContext* ctxIn, NSOpenGLPixelFormat* fmt) : + ctx(ctxIn), + pixelFormat(fmt) + { } + MacContextImpl(NSOpenGLContext* ctxIn) : + MacContextImpl(ctxIn, nil) + { } + + ~MacContextImpl() + { +#if !__has_feature(objc_arc) + if (pixelFormat != nil) + { + [pixelFormat release]; + pixelFormat = nil; + } + [ctx release]; + ctx = nil; +#endif + } + // ARC will properly clean up NSOpenGLContext and NSOpenGLPixelFormat. + NSOpenGLPixelFormat* pixelFormat; + NSOpenGLContext* ctx; + }; typedef void *CGSConnectionID; typedef int32_t CGSWindowID; @@ -312,17 +342,17 @@ bool ShaderBase::SetUniformBool(const char* name, int n, const bool* v) void ShaderBase::InitUniforms(const Uniform* refl, size_t reflSize) { - if(!refl) + UniformsSize = 0; + if (UniformData) + { + OVR_FREE(UniformData); + UniformData = 0; + } + + if (!refl) { UniformRefl = NULL; UniformReflSize = 0; - - UniformsSize = 0; - if (UniformData) - { - OVR_FREE(UniformData); - UniformData = 0; - } return; // no reflection data } @@ -429,6 +459,10 @@ Context::Context() : initialized(false), ownsContext(true), incarnation(0) } +// This destructor is mandatory for unique_ptr destruction on forward +// declared MacContextImpl. +Context::~Context() { } + void Context::InitFromCurrent() { Destroy(); @@ -436,18 +470,14 @@ void Context::InitFromCurrent() initialized = true; ownsContext = false; incarnation++; - -#if defined(OVR_OS_MAC) - systemContext = CGLGetCurrentContext(); - { - CGSConnectionID cid; - CGSWindowID wid; - CGSSurfaceID sid; - CGLError e = kCGLNoError; - e = CGLGetSurface(systemContext, &cid, &wid, &sid); - OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e); - } +#if defined(OVR_OS_MAC) + NSOpenGLContext* glctx = [NSOpenGLContext currentContext]; +#if !__has_feature(objc_arc) + // MacContextImpl *will* release all given resources. Retain reference. + [glctx retain]; +#endif + systemContext.reset(new MacContextImpl(glctx)); #elif defined(OVR_OS_WIN32) hdc = wglGetCurrentDC(); systemContext = wglGetCurrentContext(); @@ -463,24 +493,30 @@ void Context::InitFromCurrent() #endif } - void Context::CreateShared( Context & ctx ) { - Destroy(); OVR_ASSERT( ctx.initialized == true ); if( ctx.initialized == false ) { return; } + Destroy(); + initialized = true; ownsContext = true; incarnation++; - + #if defined(OVR_OS_MAC) - CGLPixelFormatObj pixelFormat = CGLGetPixelFormat( ctx.systemContext ); - CGLError e = CGLCreateContext( pixelFormat, ctx.systemContext, &systemContext ); - OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e); + CGLContextObj shareCGL = (CGLContextObj)[ctx.systemContext->ctx CGLContextObj]; + CGLPixelFormatObj sharePixelFormat = CGLGetPixelFormat(shareCGL); + + NSOpenGLPixelFormat* nsOGLPixelFormat = + [[NSOpenGLPixelFormat alloc] initWithCGLPixelFormatObj:sharePixelFormat]; + systemContext.reset(new MacContextImpl( + [[NSOpenGLContext alloc] initWithFormat:nsOGLPixelFormat shareContext:ctx.systemContext->ctx], + nsOGLPixelFormat)); + SetSurface(ctx); #elif defined(OVR_OS_WIN32) hdc = ctx.hdc; @@ -492,24 +528,29 @@ void Context::CreateShared( Context & ctx ) x11Display = ctx.x11Display; x11Drawable = ctx.x11Drawable; x11Visual = ctx.x11Visual; - systemContext = glXCreateContext( ctx.x11Display, &x11Visual, ctx.systemContext, True ); - OVR_ASSERT( systemContext != NULL ); + systemContext = glXCreateContext( ctx.x11Display, &x11Visual, ctx.systemContext, True ); + OVR_ASSERT( systemContext != NULL ); #endif } #if defined(OVR_OS_MAC) -void Context::SetSurface( Context & ctx ) { +void Context::SetSurface( Context & ctx ) +{ + CGLContextObj cgl = (CGLContextObj)[systemContext->ctx CGLContextObj]; + CGLContextObj cglShared = (CGLContextObj)[ctx.systemContext->ctx CGLContextObj]; + CGLError e = kCGLNoError; CGSConnectionID cid, cid2; CGSWindowID wid, wid2; CGSSurfaceID sid, sid2; - e = CGLGetSurface(ctx.systemContext, &cid, &wid, &sid); + e = CGLGetSurface(cglShared, &cid, &wid, &sid); OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e); - e = CGLGetSurface(systemContext, &cid2, &wid2, &sid2); + e = CGLGetSurface(cgl, &cid2, &wid2, &sid2); OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e); - if( sid && sid != sid2 ) { - e = CGLSetSurface(systemContext, cid, wid, sid); + if( sid && sid != sid2 ) + { + e = CGLSetSurface(cgl, cid, wid, sid); OVR_ASSERT(e == kCGLNoError); OVR_UNUSED(e); } } @@ -525,7 +566,7 @@ void Context::Destroy() if (systemContext) { #if defined(OVR_OS_MAC) - CGLDestroyContext( systemContext ); + systemContext.reset(); #elif defined(OVR_OS_WIN32) BOOL success = wglDeleteContext( systemContext ); OVR_ASSERT( success == TRUE ); @@ -547,7 +588,10 @@ void Context::Bind() { #if defined(OVR_OS_MAC) glFlush(); //Apple doesn't automatically flush within CGLSetCurrentContext, unlike other platforms. - CGLSetCurrentContext( systemContext ); + CGLContextObj cgl = (CGLContextObj)[systemContext->ctx CGLContextObj]; + CGLSetCurrentContext(cgl); + // Consider the following instead of using CGLSetCurrentContext: + // [systemContext->ctx makeCurrentContext]; #elif defined(OVR_OS_WIN32) wglMakeCurrent( hdc, systemContext ); #elif defined(OVR_OS_LINUX) diff --git a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h index 69d4d08..c181d13 100644 --- a/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h +++ b/LibOVR/Src/CAPI/GL/CAPI_GL_Util.h @@ -24,30 +24,30 @@ limitations under the License. ************************************************************************************/ -#ifndef INC_OVR_CAPI_GL_Util_h -#define INC_OVR_CAPI_GL_Util_h - -#include "../../OVR_CAPI.h" -#include "../../Kernel/OVR_Array.h" -#include "../../Kernel/OVR_Math.h" -#include "../../Kernel/OVR_RefCount.h" -#include "../../Kernel/OVR_String.h" -#include "../../Kernel/OVR_Types.h" -#include "../../Kernel/OVR_Log.h" - +#ifndef OVR_CAPI_GL_Util_h +#define OVR_CAPI_GL_Util_h + +#include "OVR_CAPI.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_RefCount.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_Log.h" #if defined(OVR_OS_WIN32) -#define WIN32_LEAN_AND_MEAN -#include -#endif + #include "Kernel/OVR_Win32_IncludeWindows.h" +#endif // OVR_OS_WIN32 +#include "Extras/OVR_Math.h" #if !defined(OVR_DISABLE_GLE) // By default we use the GLE module in order to link to OpenGL functions. However, if an external user -#include "CAPI_GLE.h" // wants to use an alternative mechanism to connect to OpenGL functions, they can #define OVR_DISABLE_GLE. +#include "GL/CAPI_GLE.h" // wants to use an alternative mechanism to connect to OpenGL functions, they can #define OVR_DISABLE_GLE. #endif #if defined(OVR_OS_MAC) + #include #include #include + class MacContextImpl; #endif @@ -485,12 +485,13 @@ class Context GLXContext systemContext; XVisualInfo x11Visual; #elif defined(OVR_OS_MAC) - CGLContextObj systemContext; + std::unique_ptr systemContext; #endif - + public: Context(); + ~Context(); void InitFromCurrent(); void CreateShared( Context & ctx ); #if defined(OVR_OS_MAC) @@ -550,4 +551,4 @@ struct AutoContext }}} // namespace OVR::CAPI::GL -#endif // INC_OVR_CAPI_GL_Util_h +#endif // OVR_CAPI_GL_Util_h diff --git a/LibOVR/Src/CAPI/Textures/healthAndSafety.tga b/LibOVR/Src/CAPI/Textures/healthAndSafety.tga new file mode 100644 index 0000000..b2a781d Binary files /dev/null and b/LibOVR/Src/CAPI/Textures/healthAndSafety.tga differ diff --git a/LibOVR/Src/CAPI/Textures/overdriveLut_dk2.h b/LibOVR/Src/CAPI/Textures/overdriveLut_dk2.h new file mode 100644 index 0000000..8004939 --- /dev/null +++ b/LibOVR/Src/CAPI/Textures/overdriveLut_dk2.h @@ -0,0 +1,8194 @@ +const uint8_t overdriveLut_dk2[256*256*4] = { + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x23,0x19,0x00,0x19,0x24,0x1a,0x00,0x1a,0x25,0x1c,0x00,0x1c,0x25,0x1d,0x00, + 0x1d,0x26,0x1e,0x00,0x1e,0x27,0x1f,0x00,0x20,0x28,0x20,0x00,0x21,0x29,0x21,0x00,0x22,0x2a,0x22,0x00,0x23,0x2b,0x24,0x00,0x25,0x2c,0x25,0x00,0x26,0x2d,0x27,0x00, + 0x27,0x2e,0x28,0x00,0x28,0x2f,0x29,0x00,0x29,0x30,0x2b,0x00,0x2a,0x31,0x2c,0x00,0x2b,0x32,0x2d,0x00,0x2c,0x33,0x2e,0x00,0x2e,0x35,0x30,0x00,0x2f,0x36,0x31,0x00, + 0x30,0x37,0x32,0x00,0x31,0x38,0x33,0x00,0x33,0x3a,0x35,0x00,0x34,0x3b,0x36,0x00,0x35,0x3c,0x37,0x00,0x36,0x3d,0x38,0x00,0x38,0x3f,0x3a,0x00,0x39,0x40,0x3b,0x00, + 0x3a,0x41,0x3c,0x00,0x3c,0x42,0x3d,0x00,0x3d,0x43,0x3f,0x00,0x3f,0x43,0x40,0x00,0x40,0x44,0x41,0x00,0x41,0x45,0x42,0x00,0x42,0x47,0x43,0x00,0x43,0x48,0x44,0x00, + 0x44,0x49,0x45,0x00,0x45,0x4a,0x46,0x00,0x46,0x4b,0x48,0x00,0x47,0x4c,0x49,0x00,0x48,0x4d,0x4a,0x00,0x49,0x4e,0x4b,0x00,0x4a,0x4f,0x4c,0x00,0x4b,0x50,0x4d,0x00, + 0x4c,0x51,0x4e,0x00,0x4d,0x52,0x4f,0x00,0x4f,0x54,0x50,0x00,0x50,0x55,0x51,0x00,0x51,0x56,0x52,0x00,0x52,0x57,0x53,0x00,0x53,0x59,0x55,0x00,0x54,0x5a,0x56,0x00, + 0x55,0x5b,0x57,0x00,0x57,0x5d,0x58,0x00,0x58,0x5e,0x5a,0x00,0x5a,0x60,0x5b,0x00,0x5b,0x61,0x5c,0x00,0x5d,0x63,0x5e,0x00,0x5e,0x64,0x60,0x00,0x60,0x66,0x61,0x00, + 0x61,0x67,0x63,0x00,0x61,0x68,0x64,0x00,0x63,0x6a,0x66,0x00,0x64,0x6b,0x67,0x00,0x65,0x6c,0x68,0x00,0x66,0x6d,0x69,0x00,0x68,0x6f,0x6b,0x00,0x69,0x70,0x6c,0x00, + 0x6a,0x71,0x6d,0x00,0x6b,0x72,0x6e,0x00,0x6d,0x74,0x70,0x00,0x6e,0x75,0x71,0x00,0x6f,0x76,0x72,0x00,0x70,0x77,0x73,0x00,0x72,0x79,0x75,0x00,0x73,0x7a,0x76,0x00, + 0x74,0x7b,0x77,0x00,0x75,0x7c,0x78,0x00,0x76,0x7d,0x79,0x00,0x77,0x7e,0x7a,0x00,0x79,0x7f,0x7c,0x00,0x7a,0x80,0x7d,0x00,0x7b,0x81,0x7e,0x00,0x7c,0x82,0x7f,0x00, + 0x7d,0x84,0x80,0x00,0x7e,0x85,0x81,0x00,0x7f,0x86,0x82,0x00,0x80,0x87,0x83,0x00,0x82,0x88,0x85,0x00,0x83,0x89,0x86,0x00,0x84,0x8a,0x87,0x00,0x85,0x8b,0x88,0x00, + 0x86,0x8c,0x89,0x00,0x87,0x8d,0x8a,0x00,0x89,0x8e,0x8b,0x00,0x8a,0x90,0x8d,0x00,0x8b,0x91,0x8e,0x00,0x8c,0x92,0x8f,0x00,0x8e,0x93,0x90,0x00,0x8f,0x94,0x91,0x00, + 0x90,0x96,0x93,0x00,0x91,0x97,0x94,0x00,0x93,0x98,0x95,0x00,0x94,0x99,0x96,0x00,0x95,0x9a,0x97,0x00,0x96,0x9b,0x98,0x00,0x98,0x9d,0x9a,0x00,0x99,0x9e,0x9b,0x00, + 0x9a,0x9f,0x9c,0x00,0x9b,0xa0,0x9d,0x00,0x9c,0xa1,0x9e,0x00,0x9d,0xa2,0xa0,0x00,0x9f,0xa4,0xa1,0x00,0xa0,0xa5,0xa2,0x00,0xa1,0xa6,0xa3,0x00,0xa2,0xa7,0xa4,0x00, + 0xa3,0xa8,0xa6,0x00,0xa4,0xa9,0xa7,0x00,0xa5,0xaa,0xa8,0x00,0xa6,0xab,0xa9,0x00,0xa8,0xad,0xaa,0x00,0xa9,0xae,0xab,0x00,0xaa,0xaf,0xad,0x00,0xab,0xb0,0xae,0x00, + 0xac,0xb1,0xaf,0x00,0xad,0xb2,0xb0,0x00,0xaf,0xb3,0xb2,0x00,0xb0,0xb5,0xb3,0x00,0xb1,0xb6,0xb4,0x00,0xb2,0xb7,0xb5,0x00,0xb4,0xb8,0xb7,0x00,0xb5,0xb9,0xb8,0x00, + 0xb6,0xbb,0xb9,0x00,0xb7,0xbc,0xba,0x00,0xb9,0xbd,0xbc,0x00,0xba,0xbe,0xbd,0x00,0xbb,0xbf,0xbe,0x00,0xbc,0xc0,0xbf,0x00,0xbe,0xc2,0xc1,0x00,0xbf,0xc3,0xc2,0x00, + 0xc0,0xc4,0xc3,0x00,0xc1,0xc5,0xc4,0x00,0xc2,0xc6,0xc5,0x00,0xc4,0xc7,0xc6,0x00,0xc5,0xc9,0xc7,0x00,0xc6,0xca,0xc8,0x00,0xc7,0xcb,0xc9,0x00,0xc8,0xcc,0xca,0x00, + 0xca,0xcd,0xcc,0x00,0xcb,0xce,0xcd,0x00,0xcc,0xcf,0xce,0x00,0xcd,0xd0,0xcf,0x00,0xce,0xd2,0xd0,0x00,0xcf,0xd3,0xd1,0x00,0xd1,0xd4,0xd2,0x00,0xd2,0xd5,0xd3,0x00, + 0xd3,0xd6,0xd4,0x00,0xd4,0xd7,0xd5,0x00,0xd5,0xd8,0xd6,0x00,0xd7,0xd9,0xd8,0x00,0xd8,0xda,0xd9,0x00,0xd9,0xdb,0xda,0x00,0xda,0xdc,0xdb,0x00,0xdb,0xdd,0xdc,0x00, + 0xdd,0xdf,0xde,0x00,0xde,0xe0,0xdf,0x00,0xdf,0xe1,0xe0,0x00,0xe0,0xe2,0xe1,0x00,0xe1,0xe3,0xe2,0x00,0xe2,0xe4,0xe3,0x00,0xe4,0xe5,0xe5,0x00,0xe5,0xe6,0xe6,0x00, + 0xe6,0xe7,0xe7,0x00,0xe7,0xe8,0xe8,0x00,0xe8,0xe9,0xe9,0x00,0xe9,0xea,0xea,0x00,0xeb,0xec,0xeb,0x00,0xec,0xed,0xec,0x00,0xed,0xee,0xed,0x00,0xee,0xef,0xee,0x00, + 0xef,0xf0,0xf0,0x00,0xf0,0xf1,0xf1,0x00,0xf1,0xf2,0xf2,0x00,0xf2,0xf3,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf7,0xf8,0xf7,0x00, + 0xf8,0xf9,0xf8,0x00,0xf8,0xf9,0xf8,0x00,0xf9,0xfa,0xf9,0x00,0xf9,0xfa,0xf9,0x00,0xfa,0xfb,0xfa,0x00,0xfa,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfb,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfc,0x00,0xfc,0xfc,0xfc,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x21,0x19,0x00,0x18,0x21,0x1a,0x00,0x1a,0x22,0x1b,0x00,0x1b,0x23,0x1c,0x00, + 0x1d,0x24,0x1d,0x00,0x1e,0x25,0x1e,0x00,0x1f,0x26,0x1f,0x00,0x20,0x27,0x20,0x00,0x22,0x28,0x22,0x00,0x23,0x29,0x23,0x00,0x24,0x2a,0x24,0x00,0x25,0x2b,0x26,0x00, + 0x27,0x2c,0x27,0x00,0x28,0x2d,0x28,0x00,0x29,0x2e,0x2a,0x00,0x2a,0x2f,0x2b,0x00,0x2b,0x30,0x2c,0x00,0x2c,0x31,0x2d,0x00,0x2d,0x32,0x2f,0x00,0x2e,0x34,0x30,0x00, + 0x30,0x35,0x31,0x00,0x31,0x36,0x32,0x00,0x32,0x37,0x34,0x00,0x33,0x39,0x35,0x00,0x35,0x3a,0x36,0x00,0x36,0x3b,0x37,0x00,0x37,0x3c,0x39,0x00,0x39,0x3e,0x3a,0x00, + 0x3a,0x3f,0x3b,0x00,0x3b,0x40,0x3c,0x00,0x3d,0x40,0x3d,0x00,0x3e,0x41,0x3f,0x00,0x3f,0x42,0x40,0x00,0x40,0x43,0x41,0x00,0x41,0x45,0x42,0x00,0x42,0x46,0x43,0x00, + 0x44,0x47,0x44,0x00,0x45,0x48,0x45,0x00,0x46,0x49,0x46,0x00,0x47,0x4a,0x48,0x00,0x48,0x4b,0x49,0x00,0x49,0x4c,0x4a,0x00,0x4a,0x4d,0x4b,0x00,0x4b,0x4e,0x4c,0x00, + 0x4c,0x4f,0x4d,0x00,0x4d,0x50,0x4e,0x00,0x4e,0x52,0x4f,0x00,0x4f,0x53,0x50,0x00,0x51,0x54,0x51,0x00,0x52,0x55,0x52,0x00,0x53,0x57,0x53,0x00,0x54,0x58,0x55,0x00, + 0x55,0x59,0x56,0x00,0x56,0x5a,0x57,0x00,0x57,0x5c,0x58,0x00,0x59,0x5d,0x5a,0x00,0x5a,0x5f,0x5b,0x00,0x5c,0x60,0x5c,0x00,0x5d,0x62,0x5e,0x00,0x5f,0x63,0x60,0x00, + 0x60,0x65,0x62,0x00,0x61,0x67,0x64,0x00,0x62,0x69,0x65,0x00,0x63,0x6a,0x66,0x00,0x65,0x6b,0x67,0x00,0x66,0x6c,0x69,0x00,0x67,0x6e,0x6a,0x00,0x68,0x6f,0x6b,0x00, + 0x6a,0x70,0x6c,0x00,0x6b,0x71,0x6e,0x00,0x6c,0x73,0x6f,0x00,0x6d,0x74,0x70,0x00,0x6f,0x75,0x71,0x00,0x70,0x76,0x73,0x00,0x71,0x78,0x74,0x00,0x72,0x79,0x75,0x00, + 0x74,0x7a,0x76,0x00,0x75,0x7b,0x77,0x00,0x76,0x7c,0x79,0x00,0x77,0x7d,0x7a,0x00,0x78,0x7e,0x7b,0x00,0x79,0x7f,0x7c,0x00,0x7a,0x81,0x7d,0x00,0x7b,0x82,0x7e,0x00, + 0x7d,0x83,0x7f,0x00,0x7e,0x84,0x80,0x00,0x7f,0x85,0x82,0x00,0x80,0x86,0x83,0x00,0x81,0x87,0x84,0x00,0x82,0x88,0x85,0x00,0x83,0x89,0x86,0x00,0x84,0x8a,0x87,0x00, + 0x86,0x8b,0x88,0x00,0x87,0x8c,0x89,0x00,0x88,0x8e,0x8b,0x00,0x89,0x8f,0x8c,0x00,0x8b,0x90,0x8d,0x00,0x8c,0x91,0x8e,0x00,0x8d,0x92,0x8f,0x00,0x8e,0x93,0x91,0x00, + 0x8f,0x95,0x92,0x00,0x91,0x96,0x93,0x00,0x92,0x97,0x94,0x00,0x93,0x98,0x95,0x00,0x94,0x99,0x96,0x00,0x96,0x9b,0x98,0x00,0x97,0x9c,0x99,0x00,0x98,0x9d,0x9a,0x00, + 0x99,0x9e,0x9b,0x00,0x9b,0x9f,0x9c,0x00,0x9c,0xa0,0x9e,0x00,0x9d,0xa2,0x9f,0x00,0x9e,0xa3,0xa0,0x00,0x9f,0xa4,0xa1,0x00,0xa0,0xa5,0xa2,0x00,0xa1,0xa6,0xa3,0x00, + 0xa2,0xa7,0xa5,0x00,0xa4,0xa8,0xa6,0x00,0xa5,0xa9,0xa7,0x00,0xa6,0xab,0xa8,0x00,0xa7,0xac,0xa9,0x00,0xa8,0xad,0xab,0x00,0xa9,0xae,0xac,0x00,0xaa,0xaf,0xad,0x00, + 0xac,0xb0,0xae,0x00,0xad,0xb1,0xaf,0x00,0xae,0xb2,0xb1,0x00,0xaf,0xb4,0xb2,0x00,0xb0,0xb5,0xb3,0x00,0xb2,0xb6,0xb4,0x00,0xb3,0xb7,0xb6,0x00,0xb4,0xb8,0xb7,0x00, + 0xb5,0xba,0xb8,0x00,0xb7,0xbb,0xb9,0x00,0xb8,0xbc,0xbb,0x00,0xb9,0xbd,0xbc,0x00,0xba,0xbe,0xbd,0x00,0xbc,0xc0,0xbe,0x00,0xbd,0xc1,0xc0,0x00,0xbe,0xc2,0xc1,0x00, + 0xbf,0xc3,0xc2,0x00,0xc1,0xc4,0xc3,0x00,0xc2,0xc5,0xc4,0x00,0xc3,0xc6,0xc5,0x00,0xc4,0xc8,0xc6,0x00,0xc5,0xc9,0xc7,0x00,0xc6,0xca,0xc8,0x00,0xc8,0xcb,0xc9,0x00, + 0xc9,0xcc,0xcb,0x00,0xca,0xcd,0xcc,0x00,0xcb,0xce,0xcd,0x00,0xcc,0xcf,0xce,0x00,0xce,0xd1,0xcf,0x00,0xcf,0xd2,0xd0,0x00,0xd0,0xd3,0xd1,0x00,0xd1,0xd4,0xd2,0x00, + 0xd2,0xd5,0xd3,0x00,0xd3,0xd6,0xd4,0x00,0xd5,0xd7,0xd5,0x00,0xd6,0xd8,0xd7,0x00,0xd7,0xd9,0xd8,0x00,0xd8,0xda,0xd9,0x00,0xd9,0xdb,0xda,0x00,0xdb,0xdd,0xdb,0x00, + 0xdc,0xde,0xdd,0x00,0xdd,0xdf,0xde,0x00,0xde,0xe0,0xdf,0x00,0xdf,0xe1,0xe0,0x00,0xe1,0xe2,0xe1,0x00,0xe2,0xe3,0xe2,0x00,0xe3,0xe4,0xe4,0x00,0xe4,0xe5,0xe5,0x00, + 0xe5,0xe6,0xe6,0x00,0xe6,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xeb,0xea,0x00,0xeb,0xec,0xeb,0x00,0xec,0xed,0xec,0x00,0xed,0xee,0xed,0x00, + 0xee,0xef,0xee,0x00,0xef,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00, + 0xf7,0xf8,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf9,0xf8,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xfa,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x1e,0x18,0x00,0x18,0x1f,0x19,0x00,0x1a,0x20,0x1a,0x00,0x1b,0x21,0x1b,0x00, + 0x1d,0x22,0x1d,0x00,0x1e,0x23,0x1e,0x00,0x1f,0x24,0x1f,0x00,0x20,0x25,0x20,0x00,0x21,0x26,0x21,0x00,0x22,0x27,0x22,0x00,0x24,0x28,0x24,0x00,0x25,0x29,0x25,0x00, + 0x26,0x2a,0x26,0x00,0x27,0x2b,0x27,0x00,0x28,0x2c,0x29,0x00,0x29,0x2d,0x2a,0x00,0x2b,0x2e,0x2c,0x00,0x2c,0x2f,0x2d,0x00,0x2d,0x30,0x2e,0x00,0x2e,0x31,0x2f,0x00, + 0x2f,0x33,0x30,0x00,0x30,0x34,0x31,0x00,0x32,0x35,0x33,0x00,0x33,0x36,0x34,0x00,0x34,0x38,0x35,0x00,0x36,0x39,0x36,0x00,0x37,0x3a,0x38,0x00,0x39,0x3b,0x39,0x00, + 0x3a,0x3d,0x3a,0x00,0x3b,0x3d,0x3b,0x00,0x3c,0x3e,0x3c,0x00,0x3d,0x3f,0x3d,0x00,0x3f,0x40,0x3f,0x00,0x40,0x41,0x40,0x00,0x41,0x43,0x41,0x00,0x42,0x44,0x42,0x00, + 0x43,0x45,0x43,0x00,0x44,0x46,0x44,0x00,0x45,0x47,0x45,0x00,0x46,0x48,0x46,0x00,0x47,0x49,0x48,0x00,0x48,0x4a,0x49,0x00,0x49,0x4b,0x4a,0x00,0x4a,0x4c,0x4b,0x00, + 0x4b,0x4e,0x4c,0x00,0x4c,0x4f,0x4d,0x00,0x4e,0x50,0x4e,0x00,0x4f,0x51,0x4f,0x00,0x50,0x52,0x50,0x00,0x51,0x53,0x51,0x00,0x52,0x55,0x52,0x00,0x53,0x56,0x53,0x00, + 0x54,0x57,0x55,0x00,0x55,0x58,0x56,0x00,0x57,0x5a,0x57,0x00,0x58,0x5b,0x58,0x00,0x5a,0x5c,0x5a,0x00,0x5b,0x5e,0x5b,0x00,0x5d,0x5f,0x5d,0x00,0x5e,0x61,0x5e,0x00, + 0x60,0x62,0x60,0x00,0x60,0x67,0x63,0x00,0x62,0x68,0x64,0x00,0x63,0x69,0x65,0x00,0x64,0x6a,0x67,0x00,0x65,0x6c,0x68,0x00,0x67,0x6d,0x69,0x00,0x68,0x6e,0x6a,0x00, + 0x69,0x6f,0x6c,0x00,0x6a,0x71,0x6d,0x00,0x6c,0x72,0x6e,0x00,0x6d,0x73,0x6f,0x00,0x6e,0x74,0x71,0x00,0x6f,0x76,0x72,0x00,0x71,0x77,0x73,0x00,0x72,0x78,0x74,0x00, + 0x73,0x79,0x76,0x00,0x74,0x7a,0x77,0x00,0x75,0x7b,0x78,0x00,0x76,0x7c,0x79,0x00,0x78,0x7e,0x7a,0x00,0x79,0x7f,0x7b,0x00,0x7a,0x80,0x7c,0x00,0x7b,0x81,0x7d,0x00, + 0x7c,0x82,0x7f,0x00,0x7d,0x83,0x80,0x00,0x7e,0x84,0x81,0x00,0x7f,0x85,0x82,0x00,0x81,0x86,0x83,0x00,0x82,0x87,0x84,0x00,0x83,0x88,0x85,0x00,0x84,0x89,0x86,0x00, + 0x85,0x8a,0x88,0x00,0x86,0x8c,0x89,0x00,0x88,0x8d,0x8a,0x00,0x89,0x8e,0x8b,0x00,0x8a,0x8f,0x8c,0x00,0x8b,0x90,0x8d,0x00,0x8c,0x91,0x8f,0x00,0x8e,0x93,0x90,0x00, + 0x8f,0x94,0x91,0x00,0x90,0x95,0x92,0x00,0x91,0x96,0x93,0x00,0x93,0x97,0x94,0x00,0x94,0x99,0x96,0x00,0x95,0x9a,0x97,0x00,0x96,0x9b,0x98,0x00,0x98,0x9c,0x99,0x00, + 0x99,0x9d,0x9a,0x00,0x9a,0x9e,0x9c,0x00,0x9b,0xa0,0x9d,0x00,0x9c,0xa1,0x9e,0x00,0x9d,0xa2,0x9f,0x00,0x9e,0xa3,0xa0,0x00,0xa0,0xa4,0xa1,0x00,0xa1,0xa5,0xa3,0x00, + 0xa2,0xa6,0xa4,0x00,0xa3,0xa7,0xa5,0x00,0xa4,0xa9,0xa6,0x00,0xa5,0xaa,0xa7,0x00,0xa6,0xab,0xa8,0x00,0xa8,0xac,0xaa,0x00,0xa9,0xad,0xab,0x00,0xaa,0xae,0xac,0x00, + 0xab,0xaf,0xad,0x00,0xac,0xb0,0xae,0x00,0xad,0xb2,0xb0,0x00,0xaf,0xb3,0xb1,0x00,0xb0,0xb4,0xb2,0x00,0xb1,0xb5,0xb3,0x00,0xb2,0xb6,0xb5,0x00,0xb4,0xb8,0xb6,0x00, + 0xb5,0xb9,0xb7,0x00,0xb6,0xba,0xb8,0x00,0xb7,0xbb,0xba,0x00,0xb9,0xbc,0xbb,0x00,0xba,0xbd,0xbc,0x00,0xbb,0xbf,0xbd,0x00,0xbc,0xc0,0xbf,0x00,0xbe,0xc1,0xc0,0x00, + 0xbf,0xc2,0xc1,0x00,0xc0,0xc3,0xc2,0x00,0xc1,0xc4,0xc3,0x00,0xc2,0xc6,0xc4,0x00,0xc3,0xc7,0xc5,0x00,0xc5,0xc8,0xc6,0x00,0xc6,0xc9,0xc7,0x00,0xc7,0xca,0xc8,0x00, + 0xc8,0xcb,0xca,0x00,0xc9,0xcc,0xcb,0x00,0xcb,0xcd,0xcc,0x00,0xcc,0xcf,0xcd,0x00,0xcd,0xd0,0xce,0x00,0xce,0xd1,0xcf,0x00,0xcf,0xd2,0xd0,0x00,0xd0,0xd3,0xd1,0x00, + 0xd2,0xd4,0xd2,0x00,0xd3,0xd5,0xd3,0x00,0xd4,0xd6,0xd4,0x00,0xd5,0xd7,0xd6,0x00,0xd6,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00,0xd9,0xdb,0xd9,0x00,0xda,0xdc,0xda,0x00, + 0xdb,0xdd,0xdc,0x00,0xdc,0xde,0xdd,0x00,0xdd,0xdf,0xde,0x00,0xdf,0xe0,0xdf,0x00,0xe0,0xe1,0xe0,0x00,0xe1,0xe2,0xe1,0x00,0xe2,0xe3,0xe3,0x00,0xe3,0xe4,0xe4,0x00, + 0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xe9,0xea,0xe9,0x00,0xea,0xeb,0xea,0x00,0xeb,0xec,0xeb,0x00,0xec,0xed,0xec,0x00, + 0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf2,0xf1,0x00,0xf2,0xf3,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00, + 0xf7,0xf7,0xf6,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x1c,0x18,0x00,0x18,0x1c,0x19,0x00,0x19,0x1d,0x1a,0x00,0x1b,0x1e,0x1b,0x00, + 0x1c,0x1f,0x1c,0x00,0x1d,0x20,0x1d,0x00,0x1e,0x21,0x1e,0x00,0x1f,0x22,0x1f,0x00,0x21,0x23,0x21,0x00,0x22,0x24,0x22,0x00,0x23,0x25,0x23,0x00,0x24,0x26,0x24,0x00, + 0x26,0x27,0x25,0x00,0x27,0x28,0x26,0x00,0x28,0x2a,0x28,0x00,0x29,0x2b,0x29,0x00,0x2a,0x2c,0x2b,0x00,0x2b,0x2d,0x2c,0x00,0x2c,0x2e,0x2d,0x00,0x2d,0x2f,0x2e,0x00, + 0x2f,0x30,0x2f,0x00,0x30,0x32,0x30,0x00,0x31,0x33,0x32,0x00,0x32,0x34,0x33,0x00,0x34,0x35,0x34,0x00,0x35,0x37,0x35,0x00,0x37,0x38,0x37,0x00,0x38,0x39,0x38,0x00, + 0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x41,0x40,0x00,0x41,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4b,0x4a,0x00, + 0x4b,0x4c,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x53,0x51,0x00,0x53,0x54,0x52,0x00, + 0x54,0x55,0x53,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5d,0x00, + 0x5f,0x60,0x5f,0x00,0x60,0x66,0x62,0x00,0x61,0x67,0x63,0x00,0x62,0x68,0x65,0x00,0x64,0x69,0x66,0x00,0x65,0x6b,0x67,0x00,0x66,0x6c,0x68,0x00,0x67,0x6d,0x6a,0x00, + 0x69,0x6e,0x6b,0x00,0x6a,0x70,0x6c,0x00,0x6b,0x71,0x6d,0x00,0x6c,0x72,0x6f,0x00,0x6e,0x73,0x70,0x00,0x6f,0x75,0x71,0x00,0x70,0x76,0x72,0x00,0x71,0x77,0x74,0x00, + 0x73,0x78,0x75,0x00,0x74,0x79,0x76,0x00,0x75,0x7b,0x77,0x00,0x76,0x7c,0x78,0x00,0x77,0x7d,0x79,0x00,0x78,0x7e,0x7a,0x00,0x79,0x7f,0x7c,0x00,0x7a,0x80,0x7d,0x00, + 0x7c,0x81,0x7e,0x00,0x7d,0x82,0x7f,0x00,0x7e,0x83,0x80,0x00,0x7f,0x84,0x81,0x00,0x80,0x85,0x82,0x00,0x81,0x86,0x83,0x00,0x82,0x87,0x85,0x00,0x84,0x88,0x86,0x00, + 0x85,0x8a,0x87,0x00,0x86,0x8b,0x88,0x00,0x87,0x8c,0x89,0x00,0x88,0x8d,0x8a,0x00,0x8a,0x8e,0x8b,0x00,0x8b,0x8f,0x8d,0x00,0x8c,0x91,0x8e,0x00,0x8d,0x92,0x8f,0x00, + 0x8e,0x93,0x90,0x00,0x90,0x94,0x91,0x00,0x91,0x95,0x93,0x00,0x92,0x96,0x94,0x00,0x93,0x98,0x95,0x00,0x94,0x99,0x96,0x00,0x96,0x9a,0x97,0x00,0x97,0x9b,0x98,0x00, + 0x98,0x9c,0x9a,0x00,0x99,0x9e,0x9b,0x00,0x9a,0x9f,0x9c,0x00,0x9c,0xa0,0x9d,0x00,0x9d,0xa1,0x9e,0x00,0x9e,0xa2,0x9f,0x00,0x9f,0xa3,0xa1,0x00,0xa0,0xa4,0xa2,0x00, + 0xa1,0xa5,0xa3,0x00,0xa2,0xa7,0xa4,0x00,0xa4,0xa8,0xa5,0x00,0xa5,0xa9,0xa6,0x00,0xa6,0xaa,0xa8,0x00,0xa7,0xab,0xa9,0x00,0xa8,0xac,0xaa,0x00,0xa9,0xad,0xab,0x00, + 0xab,0xae,0xac,0x00,0xac,0xb0,0xad,0x00,0xad,0xb1,0xaf,0x00,0xae,0xb2,0xb0,0x00,0xaf,0xb3,0xb1,0x00,0xb1,0xb4,0xb2,0x00,0xb2,0xb5,0xb4,0x00,0xb3,0xb7,0xb5,0x00, + 0xb4,0xb8,0xb6,0x00,0xb6,0xb9,0xb7,0x00,0xb7,0xba,0xb9,0x00,0xb8,0xbb,0xba,0x00,0xb9,0xbc,0xbb,0x00,0xba,0xbe,0xbc,0x00,0xbc,0xbf,0xbe,0x00,0xbd,0xc0,0xbf,0x00, + 0xbe,0xc1,0xc0,0x00,0xbf,0xc2,0xc1,0x00,0xc0,0xc3,0xc2,0x00,0xc2,0xc5,0xc3,0x00,0xc3,0xc6,0xc4,0x00,0xc4,0xc7,0xc5,0x00,0xc5,0xc8,0xc6,0x00,0xc6,0xc9,0xc8,0x00, + 0xc8,0xca,0xc9,0x00,0xc9,0xcb,0xca,0x00,0xca,0xcc,0xcb,0x00,0xcb,0xce,0xcc,0x00,0xcc,0xcf,0xcd,0x00,0xcd,0xd0,0xce,0x00,0xcf,0xd1,0xcf,0x00,0xd0,0xd2,0xd0,0x00, + 0xd1,0xd3,0xd1,0x00,0xd2,0xd4,0xd2,0x00,0xd3,0xd5,0xd4,0x00,0xd4,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd9,0xd7,0x00,0xd8,0xda,0xd8,0x00,0xd9,0xdb,0xd9,0x00, + 0xda,0xdc,0xdb,0x00,0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xde,0xdf,0xde,0x00,0xdf,0xe0,0xdf,0x00,0xe0,0xe1,0xe0,0x00,0xe1,0xe2,0xe1,0x00,0xe3,0xe3,0xe3,0x00, + 0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xe9,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf1,0xf0,0x00,0xf1,0xf2,0xf1,0x00,0xf2,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00, + 0xf6,0xf6,0xf5,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf8,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x19,0x17,0x00,0x18,0x1a,0x18,0x00,0x19,0x1b,0x19,0x00,0x1b,0x1c,0x1a,0x00, + 0x1c,0x1d,0x1b,0x00,0x1d,0x1e,0x1c,0x00,0x1e,0x1f,0x1e,0x00,0x1f,0x20,0x1f,0x00,0x20,0x21,0x20,0x00,0x21,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00, + 0x25,0x25,0x24,0x00,0x26,0x26,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00, + 0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x34,0x34,0x00,0x37,0x36,0x36,0x00,0x38,0x37,0x37,0x00, + 0x3a,0x38,0x38,0x00,0x3b,0x39,0x39,0x00,0x3c,0x3a,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00,0x3e,0x3d,0x3d,0x00,0x40,0x3f,0x3f,0x00,0x41,0x40,0x40,0x00, + 0x42,0x41,0x41,0x00,0x43,0x42,0x42,0x00,0x44,0x43,0x43,0x00,0x45,0x44,0x44,0x00,0x46,0x45,0x45,0x00,0x47,0x46,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4d,0x4c,0x4c,0x00,0x4e,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x56,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x58,0x57,0x57,0x00,0x5a,0x59,0x59,0x00,0x5b,0x5a,0x5a,0x00,0x5d,0x5c,0x5c,0x00, + 0x5e,0x5d,0x5d,0x00,0x5f,0x65,0x61,0x00,0x61,0x66,0x63,0x00,0x62,0x67,0x64,0x00,0x63,0x69,0x65,0x00,0x64,0x6a,0x66,0x00,0x66,0x6b,0x68,0x00,0x67,0x6c,0x69,0x00, + 0x68,0x6e,0x6a,0x00,0x69,0x6f,0x6b,0x00,0x6b,0x70,0x6d,0x00,0x6c,0x71,0x6e,0x00,0x6d,0x73,0x6f,0x00,0x6e,0x74,0x70,0x00,0x70,0x75,0x72,0x00,0x71,0x76,0x73,0x00, + 0x72,0x78,0x74,0x00,0x73,0x79,0x75,0x00,0x74,0x7a,0x76,0x00,0x75,0x7b,0x77,0x00,0x77,0x7c,0x79,0x00,0x78,0x7d,0x7a,0x00,0x79,0x7e,0x7b,0x00,0x7a,0x7f,0x7c,0x00, + 0x7b,0x80,0x7d,0x00,0x7c,0x81,0x7e,0x00,0x7d,0x82,0x7f,0x00,0x7f,0x83,0x80,0x00,0x80,0x84,0x82,0x00,0x81,0x86,0x83,0x00,0x82,0x87,0x84,0x00,0x83,0x88,0x85,0x00, + 0x84,0x89,0x86,0x00,0x85,0x8a,0x87,0x00,0x87,0x8b,0x88,0x00,0x88,0x8c,0x8a,0x00,0x89,0x8d,0x8b,0x00,0x8a,0x8f,0x8c,0x00,0x8b,0x90,0x8d,0x00,0x8d,0x91,0x8e,0x00, + 0x8e,0x92,0x8f,0x00,0x8f,0x93,0x91,0x00,0x90,0x94,0x92,0x00,0x91,0x96,0x93,0x00,0x93,0x97,0x94,0x00,0x94,0x98,0x95,0x00,0x95,0x99,0x96,0x00,0x96,0x9a,0x98,0x00, + 0x98,0x9c,0x99,0x00,0x99,0x9d,0x9a,0x00,0x9a,0x9e,0x9b,0x00,0x9b,0x9f,0x9c,0x00,0x9c,0xa0,0x9d,0x00,0x9d,0xa1,0x9f,0x00,0x9e,0xa2,0xa0,0x00,0xa0,0xa3,0xa1,0x00, + 0xa1,0xa5,0xa2,0x00,0xa2,0xa6,0xa3,0x00,0xa3,0xa7,0xa4,0x00,0xa4,0xa8,0xa5,0x00,0xa5,0xa9,0xa7,0x00,0xa7,0xaa,0xa8,0x00,0xa8,0xab,0xa9,0x00,0xa9,0xac,0xaa,0x00, + 0xaa,0xae,0xab,0x00,0xab,0xaf,0xac,0x00,0xac,0xb0,0xae,0x00,0xae,0xb1,0xaf,0x00,0xaf,0xb2,0xb0,0x00,0xb0,0xb3,0xb1,0x00,0xb1,0xb5,0xb3,0x00,0xb3,0xb6,0xb4,0x00, + 0xb4,0xb7,0xb5,0x00,0xb5,0xb8,0xb6,0x00,0xb6,0xb9,0xb8,0x00,0xb7,0xba,0xb9,0x00,0xb9,0xbc,0xba,0x00,0xba,0xbd,0xbb,0x00,0xbb,0xbe,0xbd,0x00,0xbc,0xbf,0xbe,0x00, + 0xbe,0xc0,0xbf,0x00,0xbf,0xc1,0xc0,0x00,0xc0,0xc3,0xc1,0x00,0xc1,0xc4,0xc2,0x00,0xc2,0xc5,0xc3,0x00,0xc3,0xc6,0xc4,0x00,0xc5,0xc7,0xc5,0x00,0xc6,0xc8,0xc7,0x00, + 0xc7,0xc9,0xc8,0x00,0xc8,0xca,0xc9,0x00,0xc9,0xcc,0xca,0x00,0xca,0xcd,0xcb,0x00,0xcc,0xce,0xcc,0x00,0xcd,0xcf,0xcd,0x00,0xce,0xd0,0xce,0x00,0xcf,0xd1,0xcf,0x00, + 0xd0,0xd2,0xd0,0x00,0xd1,0xd3,0xd1,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd7,0xd5,0x00,0xd6,0xd8,0xd6,0x00,0xd7,0xd9,0xd7,0x00,0xd8,0xda,0xd8,0x00, + 0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00,0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xde,0xdf,0xde,0x00,0xdf,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe2,0x00, + 0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00, + 0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x19,0x17,0x00,0x17,0x1a,0x18,0x00,0x19,0x1b,0x19,0x00,0x1a,0x1c,0x1a,0x00, + 0x1c,0x1d,0x1b,0x00,0x1d,0x1e,0x1c,0x00,0x1e,0x1f,0x1d,0x00,0x1f,0x20,0x1e,0x00,0x20,0x21,0x20,0x00,0x21,0x22,0x21,0x00,0x22,0x23,0x22,0x00,0x24,0x24,0x23,0x00, + 0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00, + 0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x32,0x32,0x31,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x35,0x35,0x00,0x38,0x37,0x36,0x00, + 0x3a,0x38,0x38,0x00,0x3a,0x39,0x39,0x00,0x3b,0x3a,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00,0x3e,0x3d,0x3d,0x00,0x3f,0x3e,0x3e,0x00,0x41,0x40,0x3f,0x00, + 0x42,0x41,0x41,0x00,0x43,0x42,0x42,0x00,0x44,0x43,0x43,0x00,0x45,0x44,0x44,0x00,0x46,0x45,0x45,0x00,0x47,0x46,0x46,0x00,0x48,0x47,0x47,0x00,0x49,0x49,0x48,0x00, + 0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4e,0x4d,0x4c,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00,0x51,0x50,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x57,0x56,0x55,0x00,0x58,0x57,0x57,0x00,0x59,0x58,0x58,0x00,0x5b,0x5a,0x59,0x00,0x5c,0x5b,0x5b,0x00, + 0x5e,0x5d,0x5c,0x00,0x5f,0x64,0x61,0x00,0x60,0x65,0x62,0x00,0x62,0x66,0x63,0x00,0x63,0x68,0x64,0x00,0x64,0x69,0x66,0x00,0x65,0x6a,0x67,0x00,0x66,0x6b,0x68,0x00, + 0x68,0x6d,0x69,0x00,0x69,0x6e,0x6b,0x00,0x6a,0x6f,0x6c,0x00,0x6b,0x70,0x6d,0x00,0x6d,0x72,0x6e,0x00,0x6e,0x73,0x70,0x00,0x6f,0x74,0x71,0x00,0x70,0x75,0x72,0x00, + 0x72,0x77,0x73,0x00,0x73,0x78,0x74,0x00,0x74,0x79,0x76,0x00,0x75,0x7a,0x77,0x00,0x76,0x7b,0x78,0x00,0x77,0x7c,0x79,0x00,0x78,0x7d,0x7a,0x00,0x7a,0x7e,0x7b,0x00, + 0x7b,0x7f,0x7c,0x00,0x7c,0x80,0x7d,0x00,0x7d,0x81,0x7f,0x00,0x7e,0x83,0x80,0x00,0x7f,0x84,0x81,0x00,0x80,0x85,0x82,0x00,0x82,0x86,0x83,0x00,0x83,0x87,0x84,0x00, + 0x84,0x88,0x85,0x00,0x85,0x89,0x86,0x00,0x86,0x8a,0x88,0x00,0x87,0x8b,0x89,0x00,0x89,0x8d,0x8a,0x00,0x8a,0x8e,0x8b,0x00,0x8b,0x8f,0x8c,0x00,0x8c,0x90,0x8d,0x00, + 0x8d,0x91,0x8f,0x00,0x8f,0x92,0x90,0x00,0x90,0x94,0x91,0x00,0x91,0x95,0x92,0x00,0x92,0x96,0x93,0x00,0x93,0x97,0x94,0x00,0x94,0x98,0x96,0x00,0x96,0x99,0x97,0x00, + 0x97,0x9b,0x98,0x00,0x98,0x9c,0x99,0x00,0x99,0x9d,0x9a,0x00,0x9a,0x9e,0x9b,0x00,0x9c,0x9f,0x9d,0x00,0x9d,0xa0,0x9e,0x00,0x9e,0xa1,0x9f,0x00,0x9f,0xa3,0xa0,0x00, + 0xa0,0xa4,0xa1,0x00,0xa1,0xa5,0xa2,0x00,0xa3,0xa6,0xa3,0x00,0xa4,0xa7,0xa5,0x00,0xa5,0xa8,0xa6,0x00,0xa6,0xa9,0xa7,0x00,0xa7,0xaa,0xa8,0x00,0xa8,0xac,0xa9,0x00, + 0xaa,0xad,0xaa,0x00,0xab,0xae,0xac,0x00,0xac,0xaf,0xad,0x00,0xad,0xb0,0xae,0x00,0xae,0xb1,0xaf,0x00,0xb0,0xb2,0xb0,0x00,0xb1,0xb4,0xb2,0x00,0xb2,0xb5,0xb3,0x00, + 0xb3,0xb6,0xb4,0x00,0xb4,0xb7,0xb5,0x00,0xb6,0xb8,0xb7,0x00,0xb7,0xb9,0xb8,0x00,0xb8,0xbb,0xb9,0x00,0xb9,0xbc,0xba,0x00,0xba,0xbd,0xbc,0x00,0xbc,0xbe,0xbd,0x00, + 0xbd,0xbf,0xbe,0x00,0xbe,0xc0,0xbf,0x00,0xbf,0xc2,0xc0,0x00,0xc0,0xc3,0xc1,0x00,0xc2,0xc4,0xc2,0x00,0xc3,0xc5,0xc3,0x00,0xc4,0xc6,0xc4,0x00,0xc5,0xc7,0xc6,0x00, + 0xc6,0xc8,0xc7,0x00,0xc7,0xc9,0xc8,0x00,0xc9,0xcb,0xc9,0x00,0xca,0xcc,0xca,0x00,0xcb,0xcd,0xcb,0x00,0xcc,0xce,0xcc,0x00,0xcd,0xcf,0xcd,0x00,0xce,0xd0,0xce,0x00, + 0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd5,0xd3,0x00,0xd4,0xd6,0xd4,0x00,0xd5,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00, + 0xd9,0xda,0xd9,0x00,0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00,0xdc,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfa,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x19,0x17,0x00,0x17,0x1a,0x18,0x00,0x19,0x1b,0x19,0x00,0x1a,0x1c,0x1a,0x00, + 0x1c,0x1d,0x1b,0x00,0x1d,0x1e,0x1c,0x00,0x1e,0x1f,0x1d,0x00,0x1f,0x20,0x1e,0x00,0x20,0x21,0x1f,0x00,0x21,0x22,0x20,0x00,0x22,0x23,0x21,0x00,0x23,0x24,0x22,0x00, + 0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2c,0x2c,0x2b,0x00,0x2d,0x2d,0x2c,0x00, + 0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x36,0x35,0x35,0x00,0x37,0x36,0x36,0x00, + 0x39,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3c,0x00,0x3e,0x3d,0x3d,0x00,0x3f,0x3e,0x3e,0x00,0x40,0x3f,0x3f,0x00, + 0x42,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x46,0x45,0x00,0x48,0x47,0x46,0x00,0x49,0x48,0x47,0x00, + 0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4f,0x4e,0x4d,0x00,0x50,0x4f,0x4e,0x00,0x51,0x50,0x4f,0x00,0x52,0x51,0x50,0x00, + 0x53,0x53,0x51,0x00,0x54,0x54,0x52,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x58,0x57,0x56,0x00,0x59,0x58,0x57,0x00,0x5b,0x5a,0x59,0x00,0x5c,0x5b,0x5a,0x00, + 0x5e,0x5d,0x5c,0x00,0x5f,0x63,0x60,0x00,0x60,0x64,0x61,0x00,0x61,0x66,0x62,0x00,0x62,0x67,0x64,0x00,0x64,0x68,0x65,0x00,0x65,0x69,0x66,0x00,0x66,0x6b,0x67,0x00, + 0x67,0x6c,0x69,0x00,0x68,0x6d,0x6a,0x00,0x6a,0x6e,0x6b,0x00,0x6b,0x70,0x6c,0x00,0x6c,0x71,0x6e,0x00,0x6d,0x72,0x6f,0x00,0x6f,0x73,0x70,0x00,0x70,0x75,0x71,0x00, + 0x71,0x76,0x73,0x00,0x72,0x77,0x74,0x00,0x73,0x78,0x75,0x00,0x74,0x79,0x76,0x00,0x76,0x7a,0x77,0x00,0x77,0x7b,0x78,0x00,0x78,0x7c,0x79,0x00,0x79,0x7d,0x7a,0x00, + 0x7a,0x7e,0x7c,0x00,0x7b,0x80,0x7d,0x00,0x7c,0x81,0x7e,0x00,0x7e,0x82,0x7f,0x00,0x7f,0x83,0x80,0x00,0x80,0x84,0x81,0x00,0x81,0x85,0x82,0x00,0x82,0x86,0x83,0x00, + 0x83,0x87,0x85,0x00,0x85,0x88,0x86,0x00,0x86,0x89,0x87,0x00,0x87,0x8b,0x88,0x00,0x88,0x8c,0x89,0x00,0x89,0x8d,0x8a,0x00,0x8a,0x8e,0x8b,0x00,0x8c,0x8f,0x8d,0x00, + 0x8d,0x90,0x8e,0x00,0x8e,0x92,0x8f,0x00,0x8f,0x93,0x90,0x00,0x90,0x94,0x91,0x00,0x92,0x95,0x92,0x00,0x93,0x96,0x94,0x00,0x94,0x97,0x95,0x00,0x95,0x99,0x96,0x00, + 0x96,0x9a,0x97,0x00,0x97,0x9b,0x98,0x00,0x99,0x9c,0x99,0x00,0x9a,0x9d,0x9b,0x00,0x9b,0x9e,0x9c,0x00,0x9c,0x9f,0x9d,0x00,0x9d,0xa1,0x9e,0x00,0x9e,0xa2,0x9f,0x00, + 0xa0,0xa3,0xa0,0x00,0xa1,0xa4,0xa1,0x00,0xa2,0xa5,0xa3,0x00,0xa3,0xa6,0xa4,0x00,0xa4,0xa7,0xa5,0x00,0xa5,0xa8,0xa6,0x00,0xa7,0xaa,0xa7,0x00,0xa8,0xab,0xa8,0x00, + 0xa9,0xac,0xa9,0x00,0xaa,0xad,0xab,0x00,0xab,0xae,0xac,0x00,0xad,0xaf,0xad,0x00,0xae,0xb0,0xae,0x00,0xaf,0xb2,0xb0,0x00,0xb0,0xb3,0xb1,0x00,0xb1,0xb4,0xb2,0x00, + 0xb3,0xb5,0xb3,0x00,0xb4,0xb6,0xb4,0x00,0xb5,0xb7,0xb6,0x00,0xb6,0xb9,0xb7,0x00,0xb7,0xba,0xb8,0x00,0xb9,0xbb,0xb9,0x00,0xba,0xbc,0xbb,0x00,0xbb,0xbd,0xbc,0x00, + 0xbc,0xbe,0xbd,0x00,0xbd,0xc0,0xbe,0x00,0xbf,0xc1,0xbf,0x00,0xc0,0xc2,0xc0,0x00,0xc1,0xc3,0xc1,0x00,0xc2,0xc4,0xc2,0x00,0xc3,0xc5,0xc4,0x00,0xc4,0xc6,0xc5,0x00, + 0xc6,0xc7,0xc6,0x00,0xc7,0xc9,0xc7,0x00,0xc8,0xca,0xc8,0x00,0xc9,0xcb,0xc9,0x00,0xca,0xcc,0xca,0x00,0xcb,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xd0,0x00,0xd1,0xd3,0xd1,0x00,0xd2,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00, + 0xd8,0xd9,0xd8,0x00,0xd9,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xeb,0xea,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf4,0xf3,0xf2,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf7,0xf6,0x00,0xf9,0xf8,0xf7,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xf9,0xf8,0x00,0xfb,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfb,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x18,0x16,0x00,0x17,0x19,0x17,0x00,0x19,0x1a,0x18,0x00,0x1a,0x1b,0x19,0x00, + 0x1b,0x1c,0x1a,0x00,0x1c,0x1d,0x1b,0x00,0x1e,0x1e,0x1c,0x00,0x1f,0x1f,0x1d,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00, + 0x24,0x24,0x23,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00, + 0x2d,0x2d,0x2d,0x00,0x2f,0x2f,0x2e,0x00,0x30,0x30,0x2f,0x00,0x31,0x31,0x30,0x00,0x32,0x32,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x37,0x36,0x35,0x00, + 0x39,0x37,0x37,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x39,0x00,0x3b,0x3a,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3e,0x3d,0x3c,0x00,0x3f,0x3e,0x3d,0x00,0x40,0x3f,0x3e,0x00, + 0x41,0x40,0x40,0x00,0x42,0x41,0x41,0x00,0x43,0x42,0x42,0x00,0x44,0x43,0x43,0x00,0x45,0x44,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00, + 0x49,0x49,0x48,0x00,0x4b,0x4a,0x49,0x00,0x4c,0x4b,0x4a,0x00,0x4d,0x4c,0x4b,0x00,0x4e,0x4d,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00, + 0x52,0x52,0x51,0x00,0x54,0x53,0x52,0x00,0x55,0x54,0x53,0x00,0x56,0x55,0x54,0x00,0x57,0x56,0x56,0x00,0x59,0x58,0x57,0x00,0x5a,0x59,0x58,0x00,0x5c,0x5b,0x59,0x00, + 0x5d,0x5c,0x5b,0x00,0x5e,0x62,0x5f,0x00,0x5f,0x63,0x60,0x00,0x61,0x65,0x62,0x00,0x62,0x66,0x63,0x00,0x63,0x67,0x64,0x00,0x64,0x68,0x65,0x00,0x65,0x6a,0x67,0x00, + 0x67,0x6b,0x68,0x00,0x68,0x6c,0x69,0x00,0x69,0x6d,0x6a,0x00,0x6a,0x6f,0x6c,0x00,0x6c,0x70,0x6d,0x00,0x6d,0x71,0x6e,0x00,0x6e,0x72,0x6f,0x00,0x6f,0x74,0x71,0x00, + 0x71,0x75,0x72,0x00,0x72,0x76,0x73,0x00,0x73,0x77,0x74,0x00,0x74,0x78,0x75,0x00,0x75,0x79,0x76,0x00,0x76,0x7a,0x77,0x00,0x77,0x7b,0x79,0x00,0x79,0x7d,0x7a,0x00, + 0x7a,0x7e,0x7b,0x00,0x7b,0x7f,0x7c,0x00,0x7c,0x80,0x7d,0x00,0x7d,0x81,0x7e,0x00,0x7e,0x82,0x7f,0x00,0x7f,0x83,0x80,0x00,0x81,0x84,0x82,0x00,0x82,0x85,0x83,0x00, + 0x83,0x86,0x84,0x00,0x84,0x87,0x85,0x00,0x85,0x89,0x86,0x00,0x86,0x8a,0x87,0x00,0x88,0x8b,0x88,0x00,0x89,0x8c,0x8a,0x00,0x8a,0x8d,0x8b,0x00,0x8b,0x8e,0x8c,0x00, + 0x8c,0x90,0x8d,0x00,0x8d,0x91,0x8e,0x00,0x8f,0x92,0x8f,0x00,0x90,0x93,0x91,0x00,0x91,0x94,0x92,0x00,0x92,0x95,0x93,0x00,0x93,0x97,0x94,0x00,0x94,0x98,0x95,0x00, + 0x96,0x99,0x96,0x00,0x97,0x9a,0x97,0x00,0x98,0x9b,0x99,0x00,0x99,0x9c,0x9a,0x00,0x9a,0x9d,0x9b,0x00,0x9c,0x9f,0x9c,0x00,0x9d,0xa0,0x9d,0x00,0x9e,0xa1,0x9e,0x00, + 0x9f,0xa2,0x9f,0x00,0xa0,0xa3,0xa1,0x00,0xa1,0xa4,0xa2,0x00,0xa3,0xa5,0xa3,0x00,0xa4,0xa6,0xa4,0x00,0xa5,0xa8,0xa5,0x00,0xa6,0xa9,0xa6,0x00,0xa7,0xaa,0xa7,0x00, + 0xa9,0xab,0xa8,0x00,0xaa,0xac,0xaa,0x00,0xab,0xad,0xab,0x00,0xac,0xae,0xac,0x00,0xad,0xb0,0xad,0x00,0xae,0xb1,0xaf,0x00,0xb0,0xb2,0xb0,0x00,0xb1,0xb3,0xb1,0x00, + 0xb2,0xb4,0xb2,0x00,0xb3,0xb5,0xb3,0x00,0xb4,0xb6,0xb5,0x00,0xb6,0xb8,0xb6,0x00,0xb7,0xb9,0xb7,0x00,0xb8,0xba,0xb8,0x00,0xb9,0xbb,0xba,0x00,0xba,0xbc,0xbb,0x00, + 0xbc,0xbd,0xbc,0x00,0xbd,0xbf,0xbd,0x00,0xbe,0xc0,0xbe,0x00,0xbf,0xc1,0xbf,0x00,0xc0,0xc2,0xc0,0x00,0xc1,0xc3,0xc1,0x00,0xc3,0xc4,0xc3,0x00,0xc4,0xc5,0xc4,0x00, + 0xc5,0xc6,0xc5,0x00,0xc6,0xc8,0xc6,0x00,0xc7,0xc9,0xc7,0x00,0xc8,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xe0,0xdf,0xde,0x00, + 0xe1,0xe0,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe8,0xe7,0xe6,0x00,0xe9,0xe8,0xe7,0x00, + 0xea,0xe9,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf1,0xf0,0xee,0x00,0xf2,0xf1,0xf0,0x00, + 0xf3,0xf2,0xf1,0x00,0xf4,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf5,0xf4,0x00,0xf7,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf7,0xf6,0x00, + 0xf9,0xf8,0xf7,0x00,0xfa,0xf9,0xf7,0x00,0xfa,0xf9,0xf8,0x00,0xfb,0xfa,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x18,0x16,0x00,0x17,0x19,0x17,0x00,0x19,0x1a,0x18,0x00,0x1a,0x1b,0x19,0x00, + 0x1b,0x1c,0x1a,0x00,0x1c,0x1d,0x1b,0x00,0x1e,0x1e,0x1c,0x00,0x1f,0x1f,0x1d,0x00,0x20,0x20,0x1e,0x00,0x21,0x21,0x1f,0x00,0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00, + 0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00, + 0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x30,0x30,0x2f,0x00,0x31,0x31,0x30,0x00,0x32,0x32,0x31,0x00,0x34,0x33,0x32,0x00,0x35,0x35,0x34,0x00,0x37,0x36,0x35,0x00, + 0x38,0x37,0x36,0x00,0x39,0x38,0x37,0x00,0x3a,0x39,0x39,0x00,0x3b,0x3a,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00,0x3f,0x3e,0x3d,0x00,0x40,0x3f,0x3e,0x00, + 0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x47,0x45,0x00,0x48,0x48,0x46,0x00, + 0x49,0x49,0x47,0x00,0x4a,0x4a,0x48,0x00,0x4c,0x4b,0x4a,0x00,0x4d,0x4c,0x4b,0x00,0x4e,0x4d,0x4c,0x00,0x4f,0x4e,0x4d,0x00,0x50,0x50,0x4e,0x00,0x51,0x51,0x4f,0x00, + 0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x55,0x54,0x53,0x00,0x56,0x55,0x54,0x00,0x57,0x56,0x55,0x00,0x59,0x58,0x56,0x00,0x5a,0x59,0x58,0x00,0x5c,0x5b,0x59,0x00, + 0x5d,0x5c,0x5a,0x00,0x5e,0x61,0x5e,0x00,0x5f,0x63,0x60,0x00,0x60,0x64,0x61,0x00,0x61,0x65,0x62,0x00,0x63,0x66,0x63,0x00,0x64,0x68,0x65,0x00,0x65,0x69,0x66,0x00, + 0x66,0x6a,0x67,0x00,0x67,0x6b,0x68,0x00,0x69,0x6d,0x6a,0x00,0x6a,0x6e,0x6b,0x00,0x6b,0x6f,0x6c,0x00,0x6c,0x70,0x6d,0x00,0x6e,0x72,0x6f,0x00,0x6f,0x73,0x70,0x00, + 0x70,0x74,0x71,0x00,0x71,0x75,0x72,0x00,0x72,0x76,0x73,0x00,0x73,0x77,0x74,0x00,0x75,0x78,0x76,0x00,0x76,0x79,0x77,0x00,0x77,0x7b,0x78,0x00,0x78,0x7c,0x79,0x00, + 0x79,0x7d,0x7a,0x00,0x7a,0x7e,0x7b,0x00,0x7c,0x7f,0x7c,0x00,0x7d,0x80,0x7d,0x00,0x7e,0x81,0x7f,0x00,0x7f,0x82,0x80,0x00,0x80,0x83,0x81,0x00,0x81,0x84,0x82,0x00, + 0x83,0x86,0x83,0x00,0x84,0x87,0x84,0x00,0x85,0x88,0x85,0x00,0x86,0x89,0x86,0x00,0x87,0x8a,0x88,0x00,0x88,0x8b,0x89,0x00,0x89,0x8c,0x8a,0x00,0x8b,0x8e,0x8b,0x00, + 0x8c,0x8f,0x8c,0x00,0x8d,0x90,0x8d,0x00,0x8e,0x91,0x8f,0x00,0x8f,0x92,0x90,0x00,0x90,0x93,0x91,0x00,0x92,0x95,0x92,0x00,0x93,0x96,0x93,0x00,0x94,0x97,0x94,0x00, + 0x95,0x98,0x96,0x00,0x96,0x99,0x97,0x00,0x97,0x9a,0x98,0x00,0x99,0x9b,0x99,0x00,0x9a,0x9d,0x9a,0x00,0x9b,0x9e,0x9b,0x00,0x9c,0x9f,0x9c,0x00,0x9d,0xa0,0x9d,0x00, + 0x9f,0xa1,0x9f,0x00,0xa0,0xa2,0xa0,0x00,0xa1,0xa3,0xa1,0x00,0xa2,0xa4,0xa2,0x00,0xa3,0xa6,0xa3,0x00,0xa4,0xa7,0xa4,0x00,0xa6,0xa8,0xa5,0x00,0xa7,0xa9,0xa6,0x00, + 0xa8,0xaa,0xa8,0x00,0xa9,0xab,0xa9,0x00,0xaa,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xaf,0xac,0x00,0xae,0xb0,0xae,0x00,0xaf,0xb1,0xaf,0x00,0xb0,0xb2,0xb0,0x00, + 0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb6,0xb4,0x00,0xb5,0xb7,0xb5,0x00,0xb6,0xb8,0xb6,0x00,0xb7,0xb9,0xb7,0x00,0xb9,0xba,0xb9,0x00,0xba,0xbb,0xba,0x00, + 0xbb,0xbd,0xbb,0x00,0xbc,0xbe,0xbc,0x00,0xbd,0xbf,0xbd,0x00,0xbe,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc2,0x00,0xc3,0xc4,0xc3,0x00, + 0xc4,0xc6,0xc4,0x00,0xc5,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00, + 0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdd,0xdc,0xdb,0x00,0xde,0xdd,0xdc,0x00,0xdf,0xde,0xdd,0x00, + 0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe5,0xe4,0xe3,0x00,0xe6,0xe5,0xe4,0x00,0xe7,0xe6,0xe5,0x00,0xe8,0xe7,0xe6,0x00, + 0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xee,0xec,0x00,0xf0,0xef,0xed,0x00,0xf1,0xf0,0xee,0x00, + 0xf2,0xf2,0xf0,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf5,0xf4,0x00,0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf5,0x00, + 0xf9,0xf8,0xf6,0x00,0xf9,0xf8,0xf7,0x00,0xfa,0xf9,0xf8,0x00,0xfb,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00,0xfd,0xfb,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x18,0x16,0x00,0x17,0x19,0x17,0x00,0x18,0x1a,0x18,0x00,0x1a,0x1b,0x19,0x00, + 0x1b,0x1c,0x1a,0x00,0x1c,0x1d,0x1b,0x00,0x1d,0x1e,0x1c,0x00,0x1f,0x1f,0x1d,0x00,0x20,0x20,0x1e,0x00,0x21,0x21,0x1f,0x00,0x22,0x22,0x20,0x00,0x23,0x23,0x22,0x00, + 0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2c,0x2c,0x2b,0x00, + 0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x31,0x30,0x00,0x32,0x32,0x31,0x00,0x33,0x33,0x32,0x00,0x35,0x34,0x33,0x00,0x36,0x36,0x35,0x00, + 0x38,0x37,0x36,0x00,0x39,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00,0x3e,0x3d,0x3d,0x00,0x40,0x3f,0x3e,0x00, + 0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x46,0x45,0x00,0x48,0x47,0x46,0x00, + 0x49,0x49,0x47,0x00,0x4a,0x4a,0x48,0x00,0x4b,0x4b,0x49,0x00,0x4c,0x4c,0x4a,0x00,0x4e,0x4d,0x4c,0x00,0x4f,0x4e,0x4d,0x00,0x50,0x4f,0x4e,0x00,0x51,0x51,0x4f,0x00, + 0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x52,0x00,0x55,0x55,0x53,0x00,0x57,0x56,0x55,0x00,0x58,0x57,0x56,0x00,0x5a,0x59,0x57,0x00,0x5b,0x5a,0x58,0x00, + 0x5d,0x5c,0x5a,0x00,0x5d,0x60,0x5e,0x00,0x5e,0x62,0x5f,0x00,0x60,0x63,0x60,0x00,0x61,0x64,0x61,0x00,0x62,0x65,0x63,0x00,0x63,0x67,0x64,0x00,0x65,0x68,0x65,0x00, + 0x66,0x69,0x66,0x00,0x67,0x6a,0x68,0x00,0x68,0x6c,0x69,0x00,0x69,0x6d,0x6a,0x00,0x6b,0x6e,0x6b,0x00,0x6c,0x6f,0x6d,0x00,0x6d,0x71,0x6e,0x00,0x6e,0x72,0x6f,0x00, + 0x70,0x73,0x70,0x00,0x71,0x74,0x71,0x00,0x72,0x75,0x73,0x00,0x73,0x76,0x74,0x00,0x74,0x78,0x75,0x00,0x75,0x79,0x76,0x00,0x76,0x7a,0x77,0x00,0x78,0x7b,0x78,0x00, + 0x79,0x7c,0x79,0x00,0x7a,0x7d,0x7a,0x00,0x7b,0x7e,0x7c,0x00,0x7c,0x7f,0x7d,0x00,0x7d,0x80,0x7e,0x00,0x7f,0x81,0x7f,0x00,0x80,0x82,0x80,0x00,0x81,0x84,0x81,0x00, + 0x82,0x85,0x82,0x00,0x83,0x86,0x83,0x00,0x84,0x87,0x85,0x00,0x85,0x88,0x86,0x00,0x87,0x89,0x87,0x00,0x88,0x8a,0x88,0x00,0x89,0x8c,0x89,0x00,0x8a,0x8d,0x8a,0x00, + 0x8b,0x8e,0x8b,0x00,0x8c,0x8f,0x8d,0x00,0x8e,0x90,0x8e,0x00,0x8f,0x91,0x8f,0x00,0x90,0x93,0x90,0x00,0x91,0x94,0x91,0x00,0x92,0x95,0x92,0x00,0x93,0x96,0x94,0x00, + 0x94,0x97,0x95,0x00,0x96,0x98,0x96,0x00,0x97,0x99,0x97,0x00,0x98,0x9b,0x98,0x00,0x99,0x9c,0x99,0x00,0x9a,0x9d,0x9a,0x00,0x9c,0x9e,0x9b,0x00,0x9d,0x9f,0x9d,0x00, + 0x9e,0xa0,0x9e,0x00,0x9f,0xa1,0x9f,0x00,0xa0,0xa2,0xa0,0x00,0xa2,0xa4,0xa1,0x00,0xa3,0xa5,0xa2,0x00,0xa4,0xa6,0xa3,0x00,0xa5,0xa7,0xa4,0x00,0xa6,0xa8,0xa5,0x00, + 0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xad,0xaa,0x00,0xac,0xae,0xab,0x00,0xad,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00, + 0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb5,0xb3,0x00,0xb4,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb8,0x00,0xb9,0xba,0xb9,0x00, + 0xba,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc1,0x00,0xc2,0xc3,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xdb,0xda,0xd9,0x00,0xdc,0xdb,0xda,0x00,0xdd,0xdc,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xdf,0x00,0xe2,0xe1,0xe0,0x00,0xe3,0xe2,0xe1,0x00,0xe4,0xe3,0xe2,0x00,0xe5,0xe4,0xe3,0x00,0xe6,0xe5,0xe4,0x00,0xe7,0xe6,0xe5,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00,0xed,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xee,0xec,0x00,0xf0,0xef,0xed,0x00, + 0xf1,0xf1,0xee,0x00,0xf2,0xf1,0xef,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf6,0xf5,0xf4,0x00,0xf7,0xf6,0xf4,0x00, + 0xf8,0xf7,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfb,0xf9,0xf8,0x00,0xfc,0xfa,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfd,0xfc,0xfa,0x00,0xfe,0xfd,0xfb,0x00, + 0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x17,0x16,0x00,0x17,0x18,0x17,0x00,0x18,0x19,0x18,0x00,0x19,0x1a,0x19,0x00, + 0x1b,0x1c,0x1a,0x00,0x1c,0x1d,0x1b,0x00,0x1d,0x1e,0x1c,0x00,0x1e,0x1f,0x1d,0x00,0x20,0x20,0x1e,0x00,0x21,0x21,0x1f,0x00,0x22,0x22,0x20,0x00,0x23,0x23,0x21,0x00, + 0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2c,0x2c,0x2b,0x00, + 0x2d,0x2d,0x2c,0x00,0x2e,0x2e,0x2d,0x00,0x2f,0x2f,0x2e,0x00,0x31,0x30,0x2f,0x00,0x32,0x32,0x31,0x00,0x33,0x33,0x32,0x00,0x35,0x34,0x33,0x00,0x36,0x35,0x35,0x00, + 0x38,0x37,0x36,0x00,0x39,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3b,0x00,0x3e,0x3d,0x3c,0x00,0x3f,0x3e,0x3d,0x00, + 0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x46,0x45,0x00,0x48,0x47,0x46,0x00, + 0x49,0x48,0x47,0x00,0x4a,0x49,0x48,0x00,0x4b,0x4a,0x49,0x00,0x4c,0x4b,0x4a,0x00,0x4d,0x4d,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4f,0x4d,0x00,0x50,0x50,0x4e,0x00, + 0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x52,0x00,0x55,0x55,0x53,0x00,0x56,0x56,0x54,0x00,0x58,0x57,0x55,0x00,0x59,0x59,0x57,0x00,0x5b,0x5a,0x58,0x00, + 0x5c,0x5c,0x59,0x00,0x5d,0x60,0x5d,0x00,0x5e,0x61,0x5e,0x00,0x5f,0x62,0x5f,0x00,0x60,0x63,0x61,0x00,0x62,0x65,0x62,0x00,0x63,0x66,0x63,0x00,0x64,0x67,0x64,0x00, + 0x65,0x68,0x66,0x00,0x67,0x6a,0x67,0x00,0x68,0x6b,0x68,0x00,0x69,0x6c,0x69,0x00,0x6a,0x6d,0x6b,0x00,0x6b,0x6f,0x6c,0x00,0x6d,0x70,0x6d,0x00,0x6e,0x71,0x6e,0x00, + 0x6f,0x72,0x70,0x00,0x70,0x73,0x71,0x00,0x71,0x74,0x72,0x00,0x72,0x76,0x73,0x00,0x74,0x77,0x74,0x00,0x75,0x78,0x75,0x00,0x76,0x79,0x76,0x00,0x77,0x7a,0x77,0x00, + 0x78,0x7b,0x79,0x00,0x79,0x7c,0x7a,0x00,0x7b,0x7d,0x7b,0x00,0x7c,0x7e,0x7c,0x00,0x7d,0x7f,0x7d,0x00,0x7e,0x81,0x7e,0x00,0x7f,0x82,0x7f,0x00,0x80,0x83,0x80,0x00, + 0x82,0x84,0x82,0x00,0x83,0x85,0x83,0x00,0x84,0x86,0x84,0x00,0x85,0x87,0x85,0x00,0x86,0x88,0x86,0x00,0x87,0x8a,0x87,0x00,0x88,0x8b,0x88,0x00,0x8a,0x8c,0x8a,0x00, + 0x8b,0x8d,0x8b,0x00,0x8c,0x8e,0x8c,0x00,0x8d,0x8f,0x8d,0x00,0x8e,0x91,0x8e,0x00,0x8f,0x92,0x8f,0x00,0x90,0x93,0x90,0x00,0x91,0x94,0x92,0x00,0x93,0x95,0x93,0x00, + 0x94,0x96,0x94,0x00,0x95,0x97,0x95,0x00,0x96,0x99,0x96,0x00,0x97,0x9a,0x97,0x00,0x99,0x9b,0x98,0x00,0x9a,0x9c,0x99,0x00,0x9b,0x9d,0x9b,0x00,0x9c,0x9e,0x9c,0x00, + 0x9d,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa2,0x9f,0x00,0xa1,0xa3,0xa0,0x00,0xa2,0xa4,0xa1,0x00,0xa3,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa5,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00, + 0xb0,0xb1,0xaf,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00, + 0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00, + 0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcc,0xca,0x00, + 0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd8,0xd7,0xd6,0x00,0xd9,0xd8,0xd7,0x00,0xda,0xd9,0xd8,0x00,0xdb,0xda,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xdf,0xde,0xdc,0x00,0xe0,0xdf,0xdd,0x00,0xe1,0xe0,0xdf,0x00,0xe2,0xe1,0xe0,0x00,0xe3,0xe2,0xe1,0x00,0xe4,0xe3,0xe2,0x00,0xe5,0xe4,0xe3,0x00,0xe6,0xe6,0xe4,0x00, + 0xe8,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00,0xed,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xef,0xec,0x00, + 0xf1,0xf0,0xed,0x00,0xf1,0xf0,0xee,0x00,0xf2,0xf1,0xef,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00, + 0xf8,0xf6,0xf5,0x00,0xf9,0xf7,0xf6,0x00,0xfa,0xf8,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00,0xfd,0xfb,0xfa,0x00,0xfe,0xfc,0xfb,0x00, + 0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x17,0x15,0x00,0x17,0x18,0x16,0x00,0x18,0x19,0x17,0x00,0x19,0x1a,0x18,0x00, + 0x1a,0x1b,0x19,0x00,0x1c,0x1c,0x1a,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00, + 0x23,0x23,0x22,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00, + 0x2c,0x2c,0x2c,0x00,0x2e,0x2e,0x2d,0x00,0x2f,0x2f,0x2e,0x00,0x31,0x30,0x2f,0x00,0x32,0x31,0x30,0x00,0x33,0x33,0x32,0x00,0x35,0x34,0x33,0x00,0x36,0x35,0x35,0x00, + 0x37,0x36,0x36,0x00,0x38,0x37,0x37,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x39,0x00,0x3b,0x3a,0x3a,0x00,0x3d,0x3c,0x3b,0x00,0x3e,0x3d,0x3c,0x00,0x3f,0x3e,0x3d,0x00, + 0x40,0x3f,0x3e,0x00,0x41,0x40,0x3f,0x00,0x42,0x42,0x40,0x00,0x43,0x43,0x41,0x00,0x44,0x44,0x42,0x00,0x45,0x45,0x43,0x00,0x46,0x46,0x44,0x00,0x47,0x47,0x45,0x00, + 0x48,0x48,0x46,0x00,0x49,0x49,0x47,0x00,0x4a,0x4a,0x48,0x00,0x4b,0x4b,0x49,0x00,0x4d,0x4c,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4f,0x4d,0x00,0x50,0x50,0x4e,0x00, + 0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x52,0x00,0x56,0x55,0x54,0x00,0x57,0x57,0x55,0x00,0x59,0x58,0x56,0x00,0x5a,0x5a,0x57,0x00, + 0x5c,0x5b,0x59,0x00,0x5c,0x5f,0x5c,0x00,0x5e,0x60,0x5d,0x00,0x5f,0x61,0x5f,0x00,0x60,0x62,0x60,0x00,0x61,0x64,0x61,0x00,0x62,0x65,0x62,0x00,0x64,0x66,0x64,0x00, + 0x65,0x67,0x65,0x00,0x66,0x69,0x66,0x00,0x67,0x6a,0x67,0x00,0x68,0x6b,0x69,0x00,0x6a,0x6c,0x6a,0x00,0x6b,0x6e,0x6b,0x00,0x6c,0x6f,0x6c,0x00,0x6d,0x70,0x6e,0x00, + 0x6f,0x71,0x6f,0x00,0x70,0x72,0x70,0x00,0x71,0x74,0x71,0x00,0x72,0x75,0x72,0x00,0x73,0x76,0x73,0x00,0x74,0x77,0x74,0x00,0x76,0x78,0x76,0x00,0x77,0x79,0x77,0x00, + 0x78,0x7a,0x78,0x00,0x79,0x7b,0x79,0x00,0x7a,0x7c,0x7a,0x00,0x7b,0x7e,0x7b,0x00,0x7d,0x7f,0x7c,0x00,0x7e,0x80,0x7d,0x00,0x7f,0x81,0x7f,0x00,0x80,0x82,0x80,0x00, + 0x81,0x83,0x81,0x00,0x82,0x84,0x82,0x00,0x83,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x88,0x85,0x00,0x87,0x89,0x86,0x00,0x88,0x8a,0x88,0x00,0x89,0x8b,0x89,0x00, + 0x8a,0x8c,0x8a,0x00,0x8b,0x8d,0x8b,0x00,0x8c,0x8f,0x8c,0x00,0x8e,0x90,0x8d,0x00,0x8f,0x91,0x8e,0x00,0x90,0x92,0x90,0x00,0x91,0x93,0x91,0x00,0x92,0x94,0x92,0x00, + 0x93,0x95,0x93,0x00,0x94,0x97,0x94,0x00,0x96,0x98,0x95,0x00,0x97,0x99,0x96,0x00,0x98,0x9a,0x97,0x00,0x99,0x9b,0x99,0x00,0x9a,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00, + 0x9d,0x9e,0x9c,0x00,0x9e,0xa0,0x9d,0x00,0x9f,0xa1,0x9e,0x00,0xa0,0xa2,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa3,0xa4,0xa1,0x00,0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00, + 0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00, + 0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00, + 0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xcb,0xc9,0x00, + 0xcb,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00, + 0xd5,0xd4,0xd3,0x00,0xd6,0xd5,0xd4,0x00,0xd7,0xd6,0xd5,0x00,0xd8,0xd7,0xd6,0x00,0xd9,0xd8,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00, + 0xde,0xdd,0xdb,0x00,0xdf,0xde,0xdc,0x00,0xe0,0xdf,0xdd,0x00,0xe1,0xe0,0xdf,0x00,0xe2,0xe1,0xe0,0x00,0xe3,0xe2,0xe1,0x00,0xe5,0xe3,0xe2,0x00,0xe6,0xe5,0xe3,0x00, + 0xe7,0xe6,0xe4,0x00,0xe8,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00,0xee,0xec,0xea,0x00,0xef,0xee,0xeb,0x00, + 0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf0,0xee,0x00,0xf3,0xf1,0xef,0x00,0xf4,0xf2,0xf0,0x00,0xf5,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00, + 0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xf8,0xf7,0x00,0xfb,0xf9,0xf8,0x00,0xfc,0xfa,0xf9,0x00,0xfd,0xfb,0xfa,0x00,0xfe,0xfc,0xfb,0x00, + 0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x16,0x15,0x00,0x16,0x17,0x16,0x00,0x18,0x19,0x17,0x00,0x19,0x1a,0x18,0x00, + 0x1a,0x1b,0x19,0x00,0x1b,0x1c,0x1a,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00, + 0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00, + 0x2c,0x2c,0x2b,0x00,0x2e,0x2d,0x2c,0x00,0x2f,0x2f,0x2e,0x00,0x31,0x30,0x2f,0x00,0x32,0x31,0x30,0x00,0x33,0x32,0x32,0x00,0x35,0x34,0x33,0x00,0x36,0x35,0x35,0x00, + 0x37,0x36,0x36,0x00,0x38,0x37,0x37,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3e,0x3d,0x3c,0x00,0x3f,0x3e,0x3d,0x00, + 0x40,0x3f,0x3e,0x00,0x41,0x40,0x3f,0x00,0x42,0x42,0x40,0x00,0x43,0x43,0x41,0x00,0x44,0x44,0x42,0x00,0x45,0x45,0x43,0x00,0x46,0x46,0x44,0x00,0x47,0x46,0x45,0x00, + 0x48,0x47,0x46,0x00,0x49,0x48,0x47,0x00,0x4a,0x4a,0x48,0x00,0x4b,0x4b,0x49,0x00,0x4c,0x4c,0x4a,0x00,0x4d,0x4d,0x4b,0x00,0x4f,0x4f,0x4d,0x00,0x50,0x50,0x4e,0x00, + 0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x52,0x00,0x55,0x55,0x53,0x00,0x57,0x57,0x54,0x00,0x58,0x58,0x56,0x00,0x5a,0x5a,0x57,0x00, + 0x5b,0x5b,0x58,0x00,0x5c,0x5e,0x5b,0x00,0x5d,0x5f,0x5d,0x00,0x5e,0x60,0x5e,0x00,0x60,0x62,0x5f,0x00,0x61,0x63,0x60,0x00,0x62,0x64,0x62,0x00,0x63,0x65,0x63,0x00, + 0x64,0x67,0x64,0x00,0x66,0x68,0x65,0x00,0x67,0x69,0x67,0x00,0x68,0x6a,0x68,0x00,0x69,0x6c,0x69,0x00,0x6a,0x6d,0x6a,0x00,0x6c,0x6e,0x6c,0x00,0x6d,0x6f,0x6d,0x00, + 0x6e,0x71,0x6e,0x00,0x6f,0x72,0x6f,0x00,0x70,0x73,0x70,0x00,0x72,0x74,0x71,0x00,0x73,0x75,0x73,0x00,0x74,0x76,0x74,0x00,0x75,0x77,0x75,0x00,0x76,0x78,0x76,0x00, + 0x77,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7c,0x79,0x00,0x7b,0x7d,0x7a,0x00,0x7c,0x7e,0x7c,0x00,0x7d,0x7f,0x7d,0x00,0x7e,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00, + 0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x85,0x82,0x00,0x84,0x86,0x83,0x00,0x85,0x87,0x85,0x00,0x86,0x88,0x86,0x00,0x87,0x89,0x87,0x00,0x89,0x8a,0x88,0x00, + 0x8a,0x8b,0x89,0x00,0x8b,0x8d,0x8a,0x00,0x8c,0x8e,0x8b,0x00,0x8d,0x8f,0x8d,0x00,0x8e,0x90,0x8e,0x00,0x8f,0x91,0x8f,0x00,0x90,0x92,0x90,0x00,0x91,0x93,0x91,0x00, + 0x93,0x95,0x92,0x00,0x94,0x96,0x93,0x00,0x95,0x97,0x94,0x00,0x96,0x98,0x96,0x00,0x97,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00, + 0x9c,0x9e,0x9b,0x00,0x9d,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa1,0xa2,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00, + 0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00, + 0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00, + 0xd4,0xd3,0xd2,0x00,0xd5,0xd4,0xd3,0x00,0xd6,0xd5,0xd4,0x00,0xd7,0xd6,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00, + 0xdd,0xdc,0xda,0x00,0xde,0xdd,0xdb,0x00,0xdf,0xde,0xdc,0x00,0xe0,0xdf,0xdd,0x00,0xe2,0xe0,0xdf,0x00,0xe3,0xe1,0xe0,0x00,0xe4,0xe3,0xe1,0x00,0xe5,0xe4,0xe2,0x00, + 0xe6,0xe5,0xe3,0x00,0xe7,0xe6,0xe4,0x00,0xe8,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xeb,0xe9,0xe7,0x00,0xec,0xea,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00, + 0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf2,0xf0,0x00,0xf5,0xf3,0xf1,0x00,0xf6,0xf4,0xf2,0x00, + 0xf7,0xf5,0xf3,0x00,0xf8,0xf6,0xf4,0x00,0xf9,0xf7,0xf5,0x00,0xfa,0xf8,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfc,0xfa,0xf8,0x00,0xfd,0xfb,0xf9,0x00,0xfe,0xfc,0xfa,0x00, + 0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x16,0x15,0x00,0x16,0x17,0x16,0x00,0x17,0x18,0x17,0x00,0x19,0x19,0x18,0x00, + 0x1a,0x1b,0x19,0x00,0x1b,0x1c,0x1a,0x00,0x1c,0x1d,0x1b,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00, + 0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00, + 0x2c,0x2c,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2f,0x2e,0x2e,0x00,0x30,0x30,0x2f,0x00,0x32,0x31,0x30,0x00,0x33,0x32,0x31,0x00,0x34,0x33,0x33,0x00,0x35,0x35,0x34,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3b,0x00,0x3e,0x3d,0x3d,0x00, + 0x40,0x3f,0x3e,0x00,0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x44,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x46,0x45,0x00, + 0x48,0x47,0x46,0x00,0x49,0x48,0x47,0x00,0x4a,0x49,0x48,0x00,0x4b,0x4b,0x49,0x00,0x4c,0x4c,0x4a,0x00,0x4d,0x4d,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x50,0x50,0x4e,0x00, + 0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x52,0x00,0x55,0x55,0x53,0x00,0x56,0x56,0x54,0x00,0x58,0x58,0x55,0x00,0x59,0x59,0x57,0x00, + 0x5b,0x5b,0x58,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x61,0x5e,0x00,0x60,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00, + 0x64,0x66,0x63,0x00,0x65,0x67,0x65,0x00,0x66,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6b,0x68,0x00,0x6a,0x6c,0x6a,0x00,0x6b,0x6d,0x6b,0x00,0x6c,0x6e,0x6c,0x00, + 0x6e,0x70,0x6d,0x00,0x6f,0x71,0x6e,0x00,0x70,0x72,0x70,0x00,0x71,0x73,0x71,0x00,0x72,0x74,0x72,0x00,0x73,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x79,0x76,0x00,0x78,0x7a,0x77,0x00,0x79,0x7b,0x79,0x00,0x7a,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x83,0x80,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8b,0x88,0x00,0x8a,0x8c,0x89,0x00,0x8b,0x8d,0x8b,0x00,0x8c,0x8e,0x8c,0x00,0x8d,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00, + 0x92,0x94,0x91,0x00,0x93,0x95,0x93,0x00,0x94,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9c,0x99,0x00, + 0x9c,0x9d,0x9a,0x00,0x9d,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa2,0x00, + 0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xae,0xae,0xab,0x00, + 0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00, + 0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbe,0xbd,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00, + 0xd3,0xd2,0xd1,0x00,0xd4,0xd3,0xd2,0x00,0xd5,0xd4,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00, + 0xdc,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00,0xe1,0xdf,0xdd,0x00,0xe2,0xe0,0xdf,0x00,0xe3,0xe2,0xe0,0x00,0xe4,0xe3,0xe1,0x00, + 0xe5,0xe4,0xe2,0x00,0xe6,0xe5,0xe3,0x00,0xe8,0xe6,0xe4,0x00,0xe9,0xe7,0xe5,0x00,0xea,0xe8,0xe6,0x00,0xeb,0xe9,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00, + 0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf2,0x00, + 0xf7,0xf5,0xf3,0x00,0xf8,0xf6,0xf4,0x00,0xf9,0xf7,0xf5,0x00,0xfa,0xf8,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfc,0xfa,0xf8,0x00,0xfd,0xfb,0xf9,0x00,0xfe,0xfc,0xfa,0x00, + 0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x16,0x15,0x00,0x16,0x17,0x16,0x00,0x17,0x18,0x17,0x00,0x18,0x19,0x18,0x00, + 0x1a,0x1a,0x19,0x00,0x1b,0x1b,0x1a,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00, + 0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00, + 0x2c,0x2c,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00,0x31,0x31,0x30,0x00,0x32,0x32,0x31,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3b,0x00,0x3e,0x3d,0x3c,0x00, + 0x3f,0x3e,0x3e,0x00,0x40,0x3f,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00, + 0x48,0x47,0x46,0x00,0x49,0x48,0x47,0x00,0x4a,0x49,0x48,0x00,0x4b,0x4a,0x49,0x00,0x4c,0x4c,0x4a,0x00,0x4d,0x4d,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4f,0x4d,0x00, + 0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x52,0x00,0x55,0x55,0x53,0x00,0x56,0x56,0x54,0x00,0x57,0x57,0x55,0x00,0x59,0x59,0x56,0x00, + 0x5a,0x5a,0x58,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5f,0x5c,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x64,0x61,0x00, + 0x63,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x69,0x66,0x00,0x68,0x6a,0x68,0x00,0x69,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6e,0x6b,0x00, + 0x6d,0x6f,0x6d,0x00,0x6e,0x70,0x6e,0x00,0x6f,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x77,0x74,0x00, + 0x76,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x80,0x7d,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x89,0x86,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x92,0x8f,0x00, + 0x91,0x93,0x91,0x00,0x92,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x9a,0x97,0x00,0x9a,0x9b,0x98,0x00, + 0x9b,0x9c,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00, + 0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xaa,0xa9,0xa7,0x00,0xab,0xaa,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00, + 0xae,0xae,0xab,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xb0,0x00,0xb4,0xb3,0xb1,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00, + 0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00, + 0xd2,0xd1,0xd0,0x00,0xd4,0xd2,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00, + 0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xdf,0x00,0xe3,0xe2,0xe0,0x00, + 0xe5,0xe3,0xe1,0x00,0xe6,0xe4,0xe2,0x00,0xe7,0xe5,0xe3,0x00,0xe8,0xe6,0xe4,0x00,0xe9,0xe7,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00, + 0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xee,0x00,0xf3,0xf1,0xef,0x00,0xf4,0xf2,0xf0,0x00,0xf5,0xf3,0xf1,0x00, + 0xf6,0xf4,0xf2,0x00,0xf7,0xf5,0xf3,0x00,0xf8,0xf6,0xf4,0x00,0xfa,0xf7,0xf5,0x00,0xfb,0xf8,0xf6,0x00,0xfc,0xf9,0xf7,0x00,0xfd,0xfa,0xf8,0x00,0xfe,0xfb,0xfa,0x00, + 0xff,0xfc,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x19,0x1a,0x19,0x00,0x1b,0x1b,0x1a,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00, + 0x22,0x22,0x21,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x32,0x32,0x31,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x37,0x37,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00, + 0x3f,0x3e,0x3d,0x00,0x40,0x3f,0x3e,0x00,0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x43,0x43,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00, + 0x47,0x46,0x45,0x00,0x48,0x48,0x46,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4d,0x4d,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4f,0x4d,0x00, + 0x50,0x50,0x4e,0x00,0x51,0x51,0x4f,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x56,0x56,0x54,0x00,0x57,0x57,0x55,0x00,0x58,0x58,0x56,0x00, + 0x5a,0x5a,0x57,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x62,0x63,0x61,0x00, + 0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00, + 0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0xa0,0x9f,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00, + 0xa5,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa3,0x00,0xa8,0xa7,0xa5,0x00,0xa9,0xa8,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00, + 0xae,0xad,0xaa,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00, + 0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00, + 0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00, + 0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd1,0xcf,0xcd,0x00, + 0xd2,0xd0,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xda,0xd8,0xd6,0x00, + 0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe2,0xe0,0xdd,0x00,0xe3,0xe1,0xdf,0x00, + 0xe4,0xe2,0xe0,0x00,0xe5,0xe3,0xe1,0x00,0xe6,0xe4,0xe2,0x00,0xe7,0xe5,0xe3,0x00,0xe8,0xe6,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00, + 0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xed,0x00,0xf2,0xf0,0xee,0x00,0xf4,0xf1,0xef,0x00,0xf5,0xf2,0xf0,0x00, + 0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf5,0x00,0xfa,0xf8,0xf6,0x00,0xfc,0xf9,0xf7,0x00,0xfd,0xfa,0xf8,0x00,0xfe,0xfb,0xf9,0x00, + 0xff,0xfc,0xfa,0x00,0xff,0xfc,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00, + 0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x33,0x33,0x00,0x33,0x34,0x34,0x00, + 0x34,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00, + 0x3e,0x3d,0x3d,0x00,0x3f,0x3e,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00, + 0x47,0x46,0x45,0x00,0x48,0x47,0x46,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4f,0x4d,0x00, + 0x50,0x50,0x4e,0x00,0x51,0x51,0x4f,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x57,0x57,0x55,0x00,0x58,0x58,0x56,0x00, + 0x59,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00, + 0x63,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00, + 0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x70,0x70,0x6e,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00, + 0x76,0x76,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00, + 0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00, + 0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x98,0x98,0x95,0x00,0x99,0x99,0x96,0x00, + 0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9d,0x9c,0x9a,0x00,0x9e,0x9d,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa2,0xa1,0x9e,0x00,0xa3,0xa2,0x9f,0x00, + 0xa4,0xa3,0xa0,0x00,0xa5,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa4,0x00,0xa9,0xa8,0xa5,0x00,0xaa,0xa9,0xa6,0x00,0xab,0xaa,0xa7,0x00,0xac,0xab,0xa8,0x00, + 0xad,0xac,0xaa,0x00,0xae,0xad,0xab,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb2,0xb1,0xae,0x00,0xb3,0xb2,0xaf,0x00,0xb4,0xb3,0xb1,0x00,0xb5,0xb4,0xb2,0x00, + 0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00, + 0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00, + 0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcd,0xcb,0xc9,0x00,0xce,0xcc,0xca,0x00,0xcf,0xcd,0xcb,0x00,0xd0,0xce,0xcc,0x00, + 0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd6,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00,0xd9,0xd7,0xd5,0x00, + 0xda,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xdf,0xdd,0xda,0x00,0xe0,0xde,0xdb,0x00,0xe1,0xdf,0xdc,0x00,0xe2,0xe0,0xdd,0x00, + 0xe3,0xe1,0xdf,0x00,0xe4,0xe2,0xe0,0x00,0xe5,0xe3,0xe1,0x00,0xe6,0xe4,0xe2,0x00,0xe8,0xe6,0xe3,0x00,0xe9,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00, + 0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xf0,0xed,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00, + 0xf6,0xf3,0xf1,0x00,0xf7,0xf4,0xf2,0x00,0xf8,0xf5,0xf3,0x00,0xf9,0xf6,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00,0xfd,0xfa,0xf8,0x00,0xfe,0xfb,0xf9,0x00, + 0xff,0xfc,0xfa,0x00,0xff,0xfc,0xfa,0x00,0xff,0xfc,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00, + 0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00, + 0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x34,0x34,0x00, + 0x34,0x35,0x35,0x00,0x35,0x36,0x36,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3c,0x00, + 0x3e,0x3d,0x3d,0x00,0x3f,0x3e,0x3e,0x00,0x40,0x3f,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00, + 0x47,0x46,0x45,0x00,0x48,0x47,0x46,0x00,0x49,0x48,0x47,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4f,0x4f,0x4d,0x00, + 0x50,0x50,0x4e,0x00,0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x58,0x56,0x00, + 0x59,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00,0x61,0x62,0x60,0x00, + 0x62,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6b,0x6c,0x6a,0x00, + 0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00, + 0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00, + 0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8e,0x00, + 0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00, + 0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9f,0x9e,0x9b,0x00,0xa0,0x9f,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00, + 0xa4,0xa3,0xa0,0x00,0xa5,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa3,0x00,0xa8,0xa7,0xa4,0x00,0xa9,0xa8,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xac,0xab,0xa8,0x00, + 0xad,0xac,0xa9,0x00,0xae,0xad,0xaa,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb5,0xb4,0xb2,0x00, + 0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbe,0xbd,0xbb,0x00, + 0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc7,0xc6,0xc4,0x00, + 0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xd0,0xce,0xcc,0x00, + 0xd1,0xcf,0xcd,0x00,0xd2,0xd0,0xce,0x00,0xd3,0xd1,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd5,0xd4,0xd1,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd9,0xd7,0xd5,0x00, + 0xda,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe2,0xe0,0xdd,0x00, + 0xe3,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe5,0xe3,0xe0,0x00,0xe6,0xe4,0xe1,0x00,0xe7,0xe5,0xe3,0x00,0xe8,0xe6,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00, + 0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf2,0xef,0xed,0x00,0xf3,0xf0,0xee,0x00,0xf4,0xf2,0xef,0x00, + 0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf8,0xf5,0xf3,0x00,0xf9,0xf6,0xf4,0x00,0xfa,0xf7,0xf5,0x00,0xfb,0xf8,0xf6,0x00,0xfc,0xf9,0xf7,0x00,0xfd,0xfb,0xf8,0x00, + 0xff,0xfc,0xfa,0x00,0xff,0xfc,0xfa,0x00,0xff,0xfc,0xfa,0x00,0xff,0xfc,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00, + 0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00, + 0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x35,0x35,0x00,0x35,0x36,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00, + 0x3e,0x3d,0x3d,0x00,0x3f,0x3e,0x3e,0x00,0x40,0x3f,0x3f,0x00,0x41,0x40,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00, + 0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00, + 0x50,0x50,0x4e,0x00,0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00, + 0x58,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00, + 0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00, + 0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x73,0x73,0x71,0x00,0x74,0x74,0x72,0x00, + 0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00, + 0x87,0x88,0x85,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00, + 0x99,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0xa0,0x9f,0x9c,0x00,0xa1,0xa0,0x9d,0x00,0xa2,0xa1,0x9e,0x00, + 0xa3,0xa3,0xa0,0x00,0xa5,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa3,0x00,0xa8,0xa7,0xa4,0x00,0xa9,0xa8,0xa5,0x00,0xaa,0xa9,0xa7,0x00,0xab,0xaa,0xa8,0x00, + 0xac,0xac,0xa9,0x00,0xae,0xad,0xaa,0x00,0xaf,0xae,0xab,0x00,0xb0,0xaf,0xac,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xb0,0x00,0xb4,0xb3,0xb1,0x00, + 0xb5,0xb5,0xb2,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00, + 0xbe,0xbe,0xbb,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00, + 0xc7,0xc7,0xc4,0x00,0xc9,0xc8,0xc5,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00, + 0xd0,0xcf,0xcd,0x00,0xd2,0xd0,0xce,0x00,0xd3,0xd1,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd5,0xd3,0xd1,0x00,0xd6,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00, + 0xd9,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00,0xe1,0xdf,0xdd,0x00, + 0xe2,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe5,0xe3,0xe0,0x00,0xe6,0xe4,0xe1,0x00,0xe7,0xe5,0xe2,0x00,0xe8,0xe6,0xe3,0x00,0xe9,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00, + 0xeb,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xee,0x00,0xf4,0xf1,0xef,0x00, + 0xf5,0xf2,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xfa,0xf7,0xf5,0x00,0xfb,0xf8,0xf6,0x00,0xfc,0xf9,0xf7,0x00,0xfd,0xfa,0xf8,0x00, + 0xfe,0xfb,0xf9,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfb,0x00,0xfe,0xfd,0xfb,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfc,0x00, + 0xff,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x17,0x16,0x00,0x17,0x18,0x17,0x00, + 0x18,0x19,0x18,0x00,0x1a,0x1a,0x19,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00, + 0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x44,0x43,0x00,0x44,0x45,0x44,0x00, + 0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4c,0x4c,0x4a,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00, + 0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x55,0x53,0x00,0x55,0x56,0x54,0x00,0x56,0x57,0x55,0x00, + 0x58,0x58,0x56,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00, + 0x62,0x62,0x60,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00, + 0x6b,0x6c,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x74,0x74,0x72,0x00, + 0x75,0x75,0x73,0x00,0x76,0x76,0x74,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00, + 0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x81,0x7e,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00, + 0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00, + 0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa1,0xa0,0x9d,0x00,0xa2,0xa1,0x9e,0x00, + 0xa3,0xa2,0x9f,0x00,0xa4,0xa3,0xa0,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00,0xa8,0xa7,0xa4,0x00,0xa9,0xa8,0xa5,0x00,0xaa,0xa9,0xa6,0x00,0xab,0xaa,0xa7,0x00, + 0xac,0xab,0xa9,0x00,0xad,0xac,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb1,0xb0,0xad,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xb0,0x00,0xb4,0xb3,0xb1,0x00, + 0xb5,0xb4,0xb2,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00, + 0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00, + 0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcc,0xcb,0xc8,0x00,0xcd,0xcc,0xc9,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00, + 0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd5,0xd3,0xd1,0x00,0xd6,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00, + 0xd9,0xd7,0xd5,0x00,0xda,0xd8,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00,0xe1,0xdf,0xdd,0x00, + 0xe2,0xe0,0xde,0x00,0xe3,0xe1,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe7,0xe5,0xe2,0x00,0xe8,0xe6,0xe3,0x00,0xe9,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00, + 0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00, + 0xf4,0xf2,0xf0,0x00,0xf6,0xf3,0xf1,0x00,0xf7,0xf4,0xf2,0x00,0xf8,0xf5,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfc,0xf9,0xf7,0x00,0xfd,0xfa,0xf8,0x00, + 0xfe,0xfb,0xf9,0x00,0xfe,0xfb,0xf9,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfb,0x00,0xfe,0xfd,0xfb,0x00,0xfe,0xfd,0xfc,0x00, + 0xfe,0xfd,0xfc,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x17,0x16,0x00,0x17,0x18,0x17,0x00, + 0x18,0x19,0x18,0x00,0x19,0x1a,0x19,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00, + 0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x44,0x43,0x00,0x44,0x45,0x44,0x00, + 0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00, + 0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x56,0x54,0x00,0x56,0x57,0x55,0x00, + 0x57,0x58,0x56,0x00,0x59,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00, + 0x62,0x62,0x60,0x00,0x63,0x64,0x61,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x69,0x66,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00, + 0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6e,0x6e,0x6c,0x00,0x6f,0x70,0x6d,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00, + 0x75,0x75,0x73,0x00,0x76,0x76,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00, + 0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x98,0x98,0x95,0x00, + 0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x99,0x00,0x9d,0x9c,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa2,0xa1,0x9e,0x00, + 0xa3,0xa2,0x9f,0x00,0xa4,0xa3,0xa0,0x00,0xa5,0xa4,0xa1,0x00,0xa6,0xa5,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xaa,0xa9,0xa6,0x00,0xab,0xaa,0xa7,0x00, + 0xac,0xab,0xa8,0x00,0xad,0xac,0xaa,0x00,0xae,0xad,0xab,0x00,0xaf,0xae,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb3,0xb2,0xaf,0x00,0xb4,0xb3,0xb1,0x00, + 0xb5,0xb4,0xb2,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00, + 0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00, + 0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xce,0xcc,0xca,0x00,0xcf,0xcd,0xcb,0x00, + 0xd0,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00, + 0xd9,0xd7,0xd5,0x00,0xda,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xe0,0xde,0xdb,0x00,0xe1,0xdf,0xdc,0x00, + 0xe2,0xe0,0xde,0x00,0xe3,0xe1,0xdf,0x00,0xe4,0xe2,0xe0,0x00,0xe5,0xe3,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe9,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00, + 0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00, + 0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf2,0x00,0xf8,0xf5,0xf3,0x00,0xf9,0xf6,0xf4,0x00,0xfa,0xf7,0xf5,0x00,0xfb,0xf9,0xf6,0x00,0xfc,0xfa,0xf7,0x00, + 0xfe,0xfb,0xf9,0x00,0xfe,0xfb,0xf9,0x00,0xfe,0xfb,0xf9,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfb,0x00,0xfe,0xfc,0xfb,0x00,0xfe,0xfd,0xfb,0x00, + 0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x18,0x17,0x00, + 0x18,0x19,0x18,0x00,0x19,0x1a,0x19,0x00,0x1a,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3c,0x3c,0x3b,0x00, + 0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x45,0x44,0x00, + 0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4e,0x4e,0x4d,0x00, + 0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x57,0x55,0x00, + 0x57,0x58,0x56,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00, + 0x62,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x65,0x62,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x69,0x6a,0x67,0x00,0x6a,0x6b,0x69,0x00, + 0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6f,0x6f,0x6d,0x00,0x70,0x70,0x6e,0x00,0x71,0x72,0x6f,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00, + 0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00, + 0x8f,0x90,0x8d,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00, + 0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9e,0x9d,0x9a,0x00,0x9f,0x9e,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00, + 0xa2,0xa2,0x9f,0x00,0xa4,0xa3,0xa0,0x00,0xa5,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa3,0x00,0xa8,0xa7,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00, + 0xab,0xab,0xa8,0x00,0xad,0xac,0xa9,0x00,0xae,0xad,0xaa,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00, + 0xb4,0xb4,0xb1,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00, + 0xbd,0xbd,0xba,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00, + 0xc6,0xc6,0xc3,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00, + 0xcf,0xce,0xcc,0x00,0xd1,0xcf,0xcd,0x00,0xd2,0xd0,0xce,0x00,0xd3,0xd1,0xcf,0x00,0xd4,0xd3,0xd0,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00, + 0xd8,0xd7,0xd5,0x00,0xda,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00, + 0xe1,0xe0,0xdd,0x00,0xe3,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe5,0xe3,0xe0,0x00,0xe6,0xe4,0xe2,0x00,0xe7,0xe5,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00, + 0xea,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xed,0x00,0xf3,0xf0,0xee,0x00, + 0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf4,0x00,0xfa,0xf7,0xf5,0x00,0xfb,0xf8,0xf6,0x00,0xfc,0xf9,0xf7,0x00, + 0xfd,0xfa,0xf8,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xf9,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfb,0x00,0xfe,0xfc,0xfb,0x00, + 0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x19,0x18,0x00,0x19,0x1a,0x19,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00, + 0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00, + 0x57,0x58,0x56,0x00,0x59,0x59,0x57,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x60,0x61,0x5f,0x00, + 0x61,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x66,0x63,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x69,0x69,0x67,0x00,0x6a,0x6b,0x68,0x00, + 0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x74,0x71,0x00, + 0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00, + 0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00, + 0x98,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0xa0,0x9f,0x9c,0x00,0xa1,0xa0,0x9d,0x00, + 0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa3,0x00,0xa8,0xa7,0xa4,0x00,0xa9,0xa8,0xa5,0x00,0xaa,0xa9,0xa7,0x00, + 0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xaf,0xae,0xab,0x00,0xb0,0xaf,0xac,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xb0,0x00, + 0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00, + 0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00, + 0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xca,0xc9,0xc6,0x00,0xcb,0xca,0xc7,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00, + 0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd3,0xd1,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd5,0xd3,0xd1,0x00,0xd6,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00, + 0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00, + 0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe5,0xe3,0xe0,0x00,0xe6,0xe4,0xe1,0x00,0xe7,0xe5,0xe2,0x00,0xe8,0xe6,0xe3,0x00,0xe9,0xe7,0xe4,0x00, + 0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00, + 0xf3,0xf1,0xef,0x00,0xf5,0xf2,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfc,0xf9,0xf7,0x00, + 0xfd,0xfa,0xf8,0x00,0xfd,0xfa,0xf8,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xfa,0x00,0xfd,0xfc,0xfa,0x00,0xfe,0xfc,0xfa,0x00,0xfe,0xfc,0xfb,0x00, + 0xfe,0xfd,0xfb,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00, + 0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00, + 0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x54,0x52,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00, + 0x56,0x57,0x56,0x00,0x59,0x59,0x57,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00, + 0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x67,0x64,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00, + 0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x73,0x73,0x71,0x00, + 0x74,0x74,0x72,0x00,0x75,0x76,0x73,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00, + 0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x80,0x7d,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x96,0x96,0x93,0x00,0x97,0x97,0x94,0x00, + 0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa1,0xa0,0x9d,0x00, + 0xa2,0xa1,0x9e,0x00,0xa3,0xa2,0x9f,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa9,0xa8,0xa5,0x00,0xaa,0xa9,0xa6,0x00, + 0xab,0xaa,0xa8,0x00,0xac,0xab,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb2,0xb1,0xae,0x00,0xb3,0xb2,0xb0,0x00, + 0xb4,0xb3,0xb1,0x00,0xb5,0xb4,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00, + 0xbd,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00, + 0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcd,0xcc,0xc9,0x00,0xce,0xcd,0xca,0x00, + 0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd6,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00, + 0xd8,0xd6,0xd4,0x00,0xd9,0xd7,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00, + 0xe1,0xdf,0xdd,0x00,0xe2,0xe0,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe8,0xe6,0xe3,0x00,0xe9,0xe7,0xe4,0x00, + 0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00, + 0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf1,0x00,0xf7,0xf4,0xf2,0x00,0xf8,0xf5,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00, + 0xfc,0xfa,0xf7,0x00,0xfd,0xfa,0xf8,0x00,0xfd,0xfa,0xf8,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xfa,0x00,0xfd,0xfc,0xfa,0x00,0xfe,0xfc,0xfb,0x00, + 0xfe,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00, + 0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00, + 0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00, + 0x56,0x57,0x56,0x00,0x59,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00, + 0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x67,0x64,0x00,0x67,0x68,0x65,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00, + 0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00, + 0x74,0x74,0x72,0x00,0x75,0x75,0x73,0x00,0x76,0x76,0x74,0x00,0x77,0x78,0x75,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x82,0x7f,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x97,0x97,0x94,0x00, + 0x98,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00, + 0xa2,0xa1,0x9e,0x00,0xa3,0xa2,0x9f,0x00,0xa4,0xa3,0xa0,0x00,0xa5,0xa4,0xa1,0x00,0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00, + 0xab,0xaa,0xa7,0x00,0xac,0xab,0xa8,0x00,0xad,0xac,0xaa,0x00,0xae,0xad,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00, + 0xb4,0xb3,0xb1,0x00,0xb5,0xb4,0xb2,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00, + 0xbd,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00, + 0xcf,0xce,0xcb,0x00,0xd0,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00, + 0xd8,0xd6,0xd4,0x00,0xd9,0xd7,0xd5,0x00,0xda,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00, + 0xe1,0xdf,0xdd,0x00,0xe2,0xe0,0xde,0x00,0xe3,0xe1,0xdf,0x00,0xe4,0xe2,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00, + 0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xea,0x00,0xef,0xed,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00, + 0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf3,0x00,0xf9,0xf6,0xf4,0x00,0xfa,0xf7,0xf5,0x00,0xfb,0xf8,0xf6,0x00, + 0xfc,0xfa,0xf7,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfa,0xf8,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xfa,0x00,0xfd,0xfc,0xfa,0x00,0xfd,0xfc,0xfb,0x00, + 0xfe,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00, + 0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4d,0x4d,0x4c,0x00, + 0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00, + 0x56,0x57,0x56,0x00,0x59,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00, + 0x61,0x61,0x5f,0x00,0x62,0x63,0x60,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x68,0x65,0x00,0x68,0x69,0x66,0x00,0x69,0x6a,0x68,0x00, + 0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6d,0x6d,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6d,0x00,0x70,0x71,0x6e,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00, + 0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00, + 0x85,0x86,0x83,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00, + 0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00, + 0x97,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9e,0x9d,0x9a,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00, + 0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa5,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00, + 0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xae,0xad,0xaa,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00, + 0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00, + 0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc9,0xc8,0xc5,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00, + 0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd2,0xd0,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00, + 0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00, + 0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe5,0xe3,0xe1,0x00,0xe6,0xe4,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00, + 0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xed,0x00, + 0xf2,0xf0,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf6,0x00, + 0xfc,0xf9,0xf7,0x00,0xfc,0xfa,0xf7,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00,0xfd,0xfb,0xf9,0x00,0xfd,0xfb,0xfa,0x00,0xfd,0xfc,0xfa,0x00, + 0xfd,0xfc,0xfb,0x00,0xfe,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00, + 0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00, + 0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00, + 0x56,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00, + 0x61,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x64,0x61,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x69,0x66,0x00,0x69,0x6a,0x67,0x00, + 0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6f,0x6f,0x6d,0x00,0x70,0x71,0x6e,0x00,0x71,0x72,0x6f,0x00,0x72,0x73,0x70,0x00, + 0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x84,0x84,0x82,0x00, + 0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x94,0x94,0x91,0x00,0x95,0x95,0x92,0x00,0x96,0x96,0x94,0x00, + 0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0xa0,0x9f,0x9c,0x00, + 0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa7,0xa6,0xa3,0x00,0xa8,0xa7,0xa4,0x00,0xa9,0xa8,0xa6,0x00, + 0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xb0,0xaf,0xac,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00, + 0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00, + 0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xcb,0xca,0xc7,0x00,0xcc,0xcb,0xc8,0x00,0xcd,0xcc,0xca,0x00, + 0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd5,0xd3,0xd1,0x00,0xd6,0xd4,0xd2,0x00, + 0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00, + 0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe6,0xe4,0xe1,0x00,0xe7,0xe5,0xe2,0x00,0xe8,0xe6,0xe3,0x00, + 0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00, + 0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xf0,0x00,0xf6,0xf3,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00, + 0xfb,0xf9,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfc,0xfa,0xf7,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00,0xfd,0xfb,0xfa,0x00,0xfd,0xfc,0xfa,0x00, + 0xfd,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x16,0x00, + 0x18,0x17,0x17,0x00,0x19,0x18,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x23,0x22,0x00,0x23,0x24,0x23,0x00,0x24,0x25,0x24,0x00,0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00, + 0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00, + 0x56,0x56,0x55,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x60,0x5e,0x00, + 0x60,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x65,0x62,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x69,0x6a,0x67,0x00, + 0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x71,0x71,0x6f,0x00,0x72,0x73,0x70,0x00, + 0x73,0x74,0x71,0x00,0x74,0x75,0x72,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7e,0x7f,0x7c,0x00,0x7f,0x80,0x7d,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x96,0x96,0x93,0x00, + 0x97,0x97,0x94,0x00,0x98,0x98,0x96,0x00,0x99,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00, + 0xa1,0xa0,0x9d,0x00,0xa2,0xa1,0x9e,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00, + 0xaa,0xa9,0xa6,0x00,0xab,0xaa,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00, + 0xb3,0xb2,0xb0,0x00,0xb4,0xb3,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00, + 0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00, + 0xce,0xcd,0xca,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00, + 0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00,0xde,0xdd,0xdb,0x00, + 0xe0,0xde,0xdc,0x00,0xe1,0xdf,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe9,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00, + 0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf3,0x00,0xf9,0xf6,0xf4,0x00,0xfa,0xf7,0xf5,0x00, + 0xfb,0xf9,0xf6,0x00,0xfb,0xf9,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00,0xfc,0xfb,0xf9,0x00,0xfd,0xfb,0xfa,0x00, + 0xfd,0xfc,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x16,0x00, + 0x18,0x17,0x17,0x00,0x19,0x18,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x23,0x22,0x00,0x23,0x24,0x23,0x00,0x24,0x25,0x24,0x00,0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00, + 0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00, + 0x56,0x56,0x55,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x60,0x5e,0x00, + 0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x65,0x62,0x00,0x65,0x66,0x63,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x69,0x6a,0x67,0x00, + 0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00, + 0x73,0x73,0x71,0x00,0x74,0x74,0x72,0x00,0x75,0x76,0x73,0x00,0x76,0x77,0x74,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x81,0x7e,0x00,0x81,0x82,0x7f,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00, + 0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x91,0x91,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00, + 0x97,0x97,0x94,0x00,0x98,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00, + 0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa3,0xa2,0x9f,0x00,0xa4,0xa3,0xa0,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00, + 0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xac,0xab,0xa8,0x00,0xad,0xac,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00, + 0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb5,0xb4,0xb2,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00, + 0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc7,0xc6,0xc3,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xd0,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00, + 0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd9,0xd7,0xd5,0x00,0xda,0xd8,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00, + 0xdf,0xde,0xdc,0x00,0xe0,0xdf,0xdd,0x00,0xe2,0xe0,0xde,0x00,0xe3,0xe1,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xeb,0x00,0xf0,0xef,0xec,0x00, + 0xf1,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00, + 0xfb,0xf8,0xf6,0x00,0xfb,0xf9,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfb,0xfa,0xf7,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00, + 0xfd,0xfc,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00,0x17,0x16,0x16,0x00, + 0x18,0x17,0x17,0x00,0x19,0x18,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x24,0x23,0x00,0x24,0x25,0x24,0x00,0x25,0x26,0x25,0x00,0x26,0x27,0x26,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3b,0x3b,0x3a,0x00, + 0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00,0x55,0x55,0x54,0x00, + 0x56,0x56,0x55,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00, + 0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x66,0x63,0x00,0x66,0x67,0x64,0x00,0x67,0x68,0x65,0x00,0x68,0x69,0x67,0x00, + 0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6d,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00, + 0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x76,0x76,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x79,0x76,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x81,0x00, + 0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00, + 0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x92,0x92,0x8f,0x00,0x93,0x93,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00, + 0x96,0x97,0x94,0x00,0x98,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00, + 0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00, + 0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xaf,0xae,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00, + 0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00, + 0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00, + 0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00, + 0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00, + 0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xe0,0x00,0xe5,0xe3,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00, + 0xf1,0xef,0xec,0x00,0xf2,0xf0,0xee,0x00,0xf3,0xf1,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00, + 0xfa,0xf8,0xf5,0x00,0xfa,0xf8,0xf6,0x00,0xfb,0xf9,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfc,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00,0xfc,0xfb,0xf9,0x00, + 0xfd,0xfb,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x18,0x17,0x17,0x00,0x19,0x18,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x25,0x24,0x00,0x25,0x26,0x25,0x00,0x26,0x27,0x26,0x00,0x27,0x28,0x27,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00, + 0x56,0x56,0x55,0x00,0x58,0x58,0x56,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00, + 0x60,0x60,0x5e,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x67,0x64,0x00,0x67,0x68,0x65,0x00,0x68,0x69,0x66,0x00, + 0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6d,0x00,0x70,0x71,0x6e,0x00,0x71,0x72,0x6f,0x00, + 0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x8a,0x00, + 0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x94,0x94,0x91,0x00,0x95,0x95,0x92,0x00, + 0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00, + 0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00,0xa8,0xa7,0xa4,0x00, + 0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb1,0xb0,0xad,0x00, + 0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xba,0xb9,0xb7,0x00, + 0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc3,0xc2,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcc,0xcb,0xc8,0x00, + 0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd5,0xd3,0xd1,0x00, + 0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00, + 0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe7,0xe5,0xe2,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00, + 0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf2,0x00,0xf7,0xf5,0xf3,0x00,0xf9,0xf7,0xf4,0x00, + 0xfa,0xf8,0xf5,0x00,0xfa,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfb,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfc,0xfa,0xf9,0x00,0xfc,0xfb,0xf9,0x00, + 0xfc,0xfb,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x27,0x26,0x00,0x27,0x28,0x27,0x00, + 0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x35,0x00,0x37,0x36,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x54,0x52,0x00,0x54,0x55,0x53,0x00, + 0x55,0x56,0x54,0x00,0x57,0x57,0x56,0x00,0x59,0x59,0x57,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00, + 0x60,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x62,0x63,0x60,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x68,0x65,0x00,0x68,0x69,0x66,0x00, + 0x69,0x6a,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6f,0x70,0x6d,0x00,0x70,0x71,0x6e,0x00,0x71,0x72,0x6f,0x00, + 0x72,0x73,0x70,0x00,0x73,0x74,0x71,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00, + 0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7e,0x7b,0x00,0x7e,0x7f,0x7c,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00, + 0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x95,0x95,0x92,0x00, + 0x96,0x96,0x93,0x00,0x97,0x97,0x94,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00, + 0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00, + 0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00, + 0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00, + 0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00, + 0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00, + 0xde,0xdd,0xdb,0x00,0xdf,0xde,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00, + 0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00, + 0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00, + 0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfa,0xf8,0xf6,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfb,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00, + 0xfc,0xfb,0xfa,0x00,0xfd,0xfc,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x27,0x26,0x00,0x27,0x28,0x27,0x00, + 0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x35,0x00,0x37,0x36,0x36,0x00,0x38,0x37,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x54,0x52,0x00,0x54,0x55,0x53,0x00, + 0x55,0x56,0x54,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00, + 0x60,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x62,0x63,0x60,0x00,0x63,0x64,0x61,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x68,0x65,0x00,0x68,0x69,0x66,0x00, + 0x69,0x6a,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00, + 0x72,0x73,0x70,0x00,0x73,0x74,0x71,0x00,0x74,0x75,0x72,0x00,0x75,0x76,0x73,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00, + 0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x80,0x7d,0x00,0x80,0x81,0x7e,0x00,0x81,0x82,0x7f,0x00,0x82,0x83,0x80,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00, + 0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x90,0x90,0x8d,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00, + 0x96,0x96,0x93,0x00,0x97,0x97,0x94,0x00,0x98,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9b,0x98,0x00,0x9b,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00, + 0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00, + 0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00, + 0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00, + 0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00, + 0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00, + 0xde,0xdd,0xdb,0x00,0xdf,0xde,0xdc,0x00,0xe0,0xdf,0xdd,0x00,0xe1,0xe0,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00, + 0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00, + 0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00, + 0xf9,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xf9,0xf7,0x00,0xfb,0xfa,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00, + 0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1d,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x28,0x27,0x00, + 0x28,0x29,0x28,0x00,0x29,0x2a,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x35,0x35,0x00,0x37,0x36,0x36,0x00,0x38,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x55,0x53,0x00, + 0x55,0x56,0x54,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5f,0x5d,0x00, + 0x5f,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x64,0x61,0x00,0x64,0x65,0x62,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x68,0x69,0x66,0x00, + 0x69,0x6a,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00, + 0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x75,0x76,0x73,0x00,0x76,0x77,0x74,0x00,0x77,0x78,0x75,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00, + 0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x82,0x7f,0x00,0x82,0x83,0x80,0x00, + 0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00, + 0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x91,0x91,0x8e,0x00,0x92,0x92,0x8f,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00, + 0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x98,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00, + 0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00, + 0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00, + 0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00, + 0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00, + 0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00, + 0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00, + 0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xdf,0x00,0xe3,0xe2,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00, + 0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xef,0xed,0xea,0x00, + 0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf2,0xee,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00, + 0xf9,0xf7,0xf4,0x00,0xf9,0xf7,0xf5,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf8,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfb,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfb,0xfa,0xf9,0x00, + 0xfc,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1d,0x1e,0x1e,0x00,0x1e,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x29,0x28,0x00,0x29,0x2a,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00, + 0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x36,0x36,0x00,0x38,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x39,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00, + 0x55,0x56,0x54,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00, + 0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x65,0x62,0x00,0x65,0x66,0x63,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00, + 0x69,0x6a,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6d,0x00,0x70,0x71,0x6f,0x00, + 0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x78,0x79,0x76,0x00,0x79,0x7a,0x78,0x00, + 0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x82,0x83,0x80,0x00, + 0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8c,0x89,0x00, + 0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x92,0x92,0x8f,0x00,0x93,0x93,0x90,0x00,0x94,0x94,0x92,0x00, + 0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9b,0x00, + 0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa4,0x00, + 0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xad,0x00, + 0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb6,0x00, + 0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdc,0xd9,0x00, + 0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe5,0xe1,0x00, + 0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00, + 0xef,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf3,0x00, + 0xf8,0xf7,0xf4,0x00,0xf9,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf8,0xf6,0x00,0xfa,0xf9,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfb,0xfa,0xf9,0x00, + 0xfc,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1e,0x1e,0x00,0x1e,0x1f,0x1f,0x00, + 0x1f,0x20,0x20,0x00,0x20,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x30,0x30,0x2f,0x00,0x31,0x31,0x30,0x00, + 0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x39,0x00, + 0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00, + 0x55,0x55,0x54,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5e,0x5d,0x00, + 0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x66,0x63,0x00,0x66,0x67,0x64,0x00,0x67,0x68,0x66,0x00, + 0x68,0x69,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6d,0x00,0x70,0x71,0x6e,0x00, + 0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7a,0x78,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00, + 0x82,0x83,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x94,0x94,0x91,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00, + 0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00, + 0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00, + 0xb0,0xb0,0xad,0x00,0xb1,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00, + 0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00, + 0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00, + 0xd4,0xd3,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00, + 0xdd,0xdc,0xda,0x00,0xde,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xea,0xe9,0xe5,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00, + 0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf6,0xf2,0x00, + 0xf8,0xf7,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xf9,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfb,0xfa,0xf8,0x00, + 0xfc,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1e,0x1e,0x00,0x1e,0x1f,0x1f,0x00, + 0x1f,0x20,0x20,0x00,0x20,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x30,0x30,0x2f,0x00,0x31,0x31,0x30,0x00, + 0x32,0x32,0x31,0x00,0x33,0x33,0x32,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x39,0x00, + 0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00, + 0x55,0x55,0x54,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00, + 0x5f,0x5f,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x66,0x63,0x00,0x66,0x67,0x64,0x00,0x67,0x68,0x65,0x00, + 0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6d,0x00,0x70,0x71,0x6e,0x00, + 0x71,0x72,0x6f,0x00,0x72,0x73,0x70,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7c,0x7d,0x7a,0x00,0x7d,0x7e,0x7b,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00, + 0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00, + 0x95,0x95,0x92,0x00,0x96,0x96,0x93,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x9a,0x97,0x00,0x9a,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00, + 0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00, + 0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00, + 0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00, + 0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00, + 0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00, + 0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00, + 0xdd,0xdc,0xda,0x00,0xde,0xdd,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xea,0xe6,0x00,0xec,0xeb,0xe7,0x00,0xed,0xec,0xe8,0x00,0xee,0xed,0xea,0x00, + 0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00, + 0xf8,0xf7,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfa,0xf8,0x00, + 0xfb,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1f,0x1f,0x00, + 0x1f,0x20,0x20,0x00,0x20,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x31,0x30,0x00, + 0x32,0x32,0x31,0x00,0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00, + 0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x54,0x54,0x53,0x00, + 0x55,0x55,0x54,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00, + 0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x67,0x64,0x00,0x67,0x68,0x65,0x00, + 0x68,0x69,0x66,0x00,0x69,0x6a,0x67,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x70,0x71,0x6e,0x00, + 0x71,0x72,0x6f,0x00,0x72,0x73,0x70,0x00,0x73,0x74,0x71,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7f,0x7c,0x00,0x7f,0x80,0x7d,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00, + 0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00, + 0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00, + 0x94,0x95,0x92,0x00,0x96,0x96,0x93,0x00,0x97,0x97,0x94,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00, + 0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa3,0x00, + 0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00, + 0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00, + 0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00, + 0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00, + 0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd2,0xd1,0xcf,0x00,0xd3,0xd2,0xd0,0x00, + 0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00, + 0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00, + 0xef,0xee,0xea,0x00,0xf0,0xef,0xeb,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00, + 0xf7,0xf6,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf8,0xf7,0xf5,0x00,0xf9,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfa,0xf8,0x00, + 0xfb,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x20,0x20,0x00,0x20,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2b,0x2b,0x00,0x2b,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00, + 0x32,0x32,0x31,0x00,0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00, + 0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00, + 0x5e,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x68,0x65,0x00, + 0x68,0x69,0x66,0x00,0x69,0x6a,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00, + 0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x73,0x74,0x71,0x00,0x74,0x75,0x72,0x00,0x75,0x76,0x73,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x80,0x7d,0x00,0x80,0x81,0x7e,0x00,0x81,0x82,0x7f,0x00, + 0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00, + 0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x94,0x91,0x00, + 0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x97,0x97,0x94,0x00,0x98,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00, + 0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa3,0x00, + 0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00, + 0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb8,0xb5,0x00, + 0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc7,0x00, + 0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00, + 0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00, + 0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xed,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00, + 0xf7,0xf6,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf8,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfa,0xf8,0x00, + 0xfb,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x22,0x21,0x21,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2b,0x2b,0x00,0x2b,0x2c,0x2c,0x00,0x2c,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00, + 0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00, + 0x54,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x58,0x56,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5c,0x00, + 0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x67,0x65,0x00, + 0x68,0x69,0x66,0x00,0x69,0x6a,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00, + 0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x76,0x77,0x74,0x00,0x77,0x78,0x75,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x82,0x7f,0x00, + 0x82,0x83,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8b,0x88,0x00, + 0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00, + 0x94,0x94,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x99,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xaf,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb5,0x00, + 0xb8,0xb8,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00, + 0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00, + 0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe4,0xe0,0x00, + 0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00, + 0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf4,0xf3,0xef,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00, + 0xf7,0xf6,0xf3,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x22,0x21,0x21,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2b,0x2b,0x00,0x2b,0x2c,0x2c,0x00,0x2c,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00, + 0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00, + 0x54,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x59,0x5a,0x59,0x00,0x5a,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5c,0x00, + 0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x68,0x69,0x66,0x00,0x69,0x6a,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00, + 0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00, + 0x82,0x83,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00, + 0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00, + 0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00, + 0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00, + 0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00, + 0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00, + 0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00, + 0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00, + 0xf7,0xf6,0xf3,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2c,0x2c,0x00,0x2c,0x2d,0x2d,0x00,0x2d,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x32,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x54,0x53,0x00, + 0x54,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00, + 0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6b,0x6c,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6e,0x00, + 0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00, + 0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00, + 0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x91,0x00, + 0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00, + 0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00,0xa5,0xa5,0xa2,0x00, + 0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00, + 0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00, + 0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00, + 0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00, + 0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00, + 0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00, + 0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00, + 0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xed,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00, + 0xf6,0xf6,0xf2,0x00,0xf7,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfb,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2d,0x00,0x2d,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00, + 0x5e,0x5e,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6e,0x6f,0x6c,0x00,0x6f,0x70,0x6d,0x00, + 0x70,0x71,0x6e,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7c,0x7d,0x7a,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00, + 0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00, + 0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00, + 0x93,0x94,0x91,0x00,0x94,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00, + 0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa2,0x00, + 0xa6,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00, + 0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00, + 0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00, + 0xd3,0xd2,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00, + 0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00, + 0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00, + 0xf6,0xf6,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf7,0xf5,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00, + 0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x19,0x19,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2f,0x2f,0x00,0x2f,0x30,0x30,0x00, + 0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5c,0x00, + 0x5d,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x66,0x63,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x71,0x72,0x6f,0x00,0x72,0x73,0x70,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7f,0x7c,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00, + 0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x88,0x00, + 0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x93,0x90,0x00, + 0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00, + 0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00, + 0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00, + 0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb7,0xb4,0x00, + 0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00, + 0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd5,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00, + 0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00, + 0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf5,0xf1,0x00, + 0xf6,0xf6,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00, + 0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x19,0x19,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2f,0x2f,0x00,0x2f,0x30,0x30,0x00, + 0x30,0x31,0x31,0x00,0x31,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00, + 0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x66,0x67,0x64,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x74,0x75,0x72,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x80,0x7d,0x00,0x80,0x81,0x7f,0x00, + 0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00, + 0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00, + 0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00, + 0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00, + 0xa5,0xa5,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xab,0x00, + 0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00, + 0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00, + 0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00, + 0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00, + 0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00, + 0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf6,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf6,0xf7,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00, + 0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x30,0x30,0x00, + 0x30,0x31,0x31,0x00,0x31,0x32,0x32,0x00,0x32,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00, + 0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00, + 0x67,0x68,0x65,0x00,0x68,0x69,0x66,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x77,0x78,0x75,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x81,0x82,0x7f,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x90,0x00, + 0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00, + 0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa2,0x9f,0x00,0xa3,0xa3,0xa0,0x00,0xa4,0xa4,0xa1,0x00, + 0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00, + 0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00, + 0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc8,0xc5,0x00, + 0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00, + 0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00, + 0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00, + 0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xee,0xea,0x00,0xee,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf2,0x00,0xf6,0xf7,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00, + 0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1d,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x2a,0x00,0x2a,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x31,0x31,0x00,0x31,0x32,0x32,0x00,0x32,0x33,0x33,0x00,0x33,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00, + 0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00, + 0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x69,0x6a,0x67,0x00,0x6a,0x6b,0x68,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x79,0x7a,0x77,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00, + 0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa3,0xa4,0xa1,0x00, + 0xa5,0xa5,0xa2,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00, + 0xae,0xae,0xab,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00, + 0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc9,0xc8,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00, + 0xd2,0xd1,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00, + 0xdb,0xda,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00, + 0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00, + 0xec,0xec,0xe8,0x00,0xed,0xed,0xea,0x00,0xee,0xef,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00, + 0xf5,0xf5,0xf1,0x00,0xf5,0xf6,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x2a,0x00,0x2a,0x2b,0x2b,0x00,0x2b,0x2c,0x2c,0x00,0x2c,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x40,0x3f,0x00,0x40,0x41,0x40,0x00, + 0x41,0x42,0x41,0x00,0x42,0x43,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00, + 0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00, + 0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x56,0x57,0x55,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x59,0x00,0x5a,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00, + 0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x60,0x00,0x61,0x62,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6c,0x6d,0x6a,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00, + 0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa4,0xa1,0x00, + 0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00, + 0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00, + 0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00, + 0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00, + 0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00, + 0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00, + 0xf4,0xf5,0xf1,0x00,0xf5,0xf6,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x2a,0x00,0x2a,0x2b,0x2b,0x00,0x2b,0x2c,0x2c,0x00,0x2c,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x40,0x3f,0x00,0x40,0x41,0x40,0x00, + 0x41,0x42,0x41,0x00,0x42,0x43,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00, + 0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00, + 0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x57,0x58,0x56,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x59,0x00,0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00, + 0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x61,0x00,0x62,0x63,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00, + 0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00, + 0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00, + 0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00, + 0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00, + 0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00, + 0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00, + 0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00, + 0xf4,0xf5,0xf1,0x00,0xf5,0xf6,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2b,0x2b,0x00,0x2b,0x2c,0x2c,0x00,0x2c,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x41,0x40,0x00, + 0x41,0x42,0x41,0x00,0x42,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x49,0x00, + 0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x53,0x52,0x00, + 0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x59,0x5a,0x59,0x00,0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00, + 0x5c,0x5d,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x66,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x71,0x71,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00, + 0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00, + 0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00, + 0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00, + 0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00, + 0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00, + 0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00, + 0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00, + 0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00, + 0xeb,0xec,0xe8,0x00,0xec,0xed,0xe9,0x00,0xed,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00, + 0xf4,0xf5,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2c,0x2c,0x00,0x2c,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x42,0x41,0x00,0x42,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00, + 0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x63,0x00,0x65,0x65,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00, + 0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00, + 0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00, + 0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb5,0xb5,0xb3,0x00, + 0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00, + 0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00, + 0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd9,0xd9,0xd5,0x00, + 0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00, + 0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xec,0xe8,0x00,0xec,0xed,0xe9,0x00,0xed,0xee,0xea,0x00,0xee,0xef,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf5,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x25,0x00, + 0x27,0x26,0x26,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5b,0x00, + 0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x64,0x00, + 0x66,0x66,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00, + 0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa1,0xa2,0x9f,0x00,0xa3,0xa3,0xa1,0x00, + 0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xac,0xac,0xaa,0x00, + 0xad,0xad,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00, + 0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbb,0x00, + 0xbe,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc7,0xc4,0x00, + 0xc7,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xd0,0xcd,0x00, + 0xd0,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00, + 0xe2,0xe2,0xde,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00, + 0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe9,0x00,0xed,0xee,0xea,0x00,0xee,0xef,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00, + 0xf4,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf5,0xf6,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x25,0x00, + 0x27,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5a,0x00, + 0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00, + 0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa2,0x9f,0x00,0xa2,0xa3,0xa1,0x00, + 0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00, + 0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00, + 0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00, + 0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00, + 0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00, + 0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00, + 0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00, + 0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00, + 0xf4,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00, + 0x27,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00, + 0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00, + 0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00, + 0x76,0x77,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00, + 0x9a,0x9a,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa3,0xa0,0x00, + 0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00, + 0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00, + 0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00, + 0xbe,0xbe,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00, + 0xc7,0xc7,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00, + 0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00, + 0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00, + 0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x13,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x27,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00, + 0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00, + 0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x75,0x00, + 0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x98,0x00, + 0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00, + 0xa3,0xa4,0xa1,0x00,0xa4,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00, + 0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00, + 0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00, + 0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00, + 0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00, + 0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00, + 0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xea,0xe6,0x00, + 0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00, + 0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x65,0x63,0x00, + 0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00, + 0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00, + 0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00, + 0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00, + 0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00, + 0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xbb,0x00, + 0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00, + 0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00, + 0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd5,0xd1,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00, + 0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00, + 0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe6,0x00, + 0xea,0xea,0xe7,0x00,0xeb,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00, + 0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00, + 0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00, + 0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00, + 0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00, + 0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00, + 0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00, + 0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00, + 0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00, + 0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00, + 0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00, + 0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00, + 0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3f,0x3e,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00, + 0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00, + 0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6c,0x00, + 0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x72,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00, + 0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00, + 0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00, + 0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb4,0xb4,0xb2,0x00, + 0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00, + 0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00, + 0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00, + 0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd8,0xd4,0x00, + 0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00, + 0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00, + 0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x30,0x00,0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3f,0x3e,0x00,0x3f,0x40,0x3f,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x59,0x00,0x5a,0x5b,0x5a,0x00, + 0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x62,0x00,0x64,0x64,0x63,0x00, + 0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x72,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00, + 0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00, + 0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00, + 0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00, + 0xb4,0xb5,0xb2,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00, + 0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00, + 0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00, + 0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00, + 0xd8,0xd8,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00, + 0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00, + 0xf3,0xf3,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x18,0x19,0x19,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3f,0x3e,0x00,0x3f,0x40,0x3f,0x00, + 0x40,0x41,0x40,0x00,0x41,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x5a,0x00, + 0x5b,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x63,0x00, + 0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00, + 0x91,0x91,0x8f,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00, + 0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa2,0xa2,0xa0,0x00, + 0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xab,0xab,0xa9,0x00, + 0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00, + 0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbd,0xba,0x00, + 0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00, + 0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xcf,0xcc,0x00, + 0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00, + 0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe9,0xe5,0x00, + 0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00, + 0xf3,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x18,0x19,0x19,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3f,0x3e,0x00,0x3f,0x40,0x3f,0x00, + 0x40,0x41,0x40,0x00,0x41,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00, + 0x5b,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x64,0x62,0x00, + 0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00, + 0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xab,0xa8,0x00, + 0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00, + 0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00, + 0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00, + 0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00, + 0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00, + 0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00, + 0xf3,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x18,0x19,0x19,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x40,0x3f,0x00, + 0x40,0x41,0x40,0x00,0x41,0x42,0x41,0x00,0x42,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00, + 0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00, + 0x6d,0x6d,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00, + 0x75,0x76,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00, + 0x7e,0x7f,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00, + 0x90,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00, + 0xb4,0xb4,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00, + 0xbd,0xbd,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc6,0xc6,0xc3,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00, + 0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00, + 0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00, + 0xe9,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00, + 0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x18,0x19,0x19,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x41,0x40,0x00,0x41,0x42,0x41,0x00,0x42,0x43,0x42,0x00,0x43,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x52,0x00,0x54,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00, + 0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00, + 0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00, + 0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00, + 0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00, + 0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00, + 0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00, + 0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00, + 0xce,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00, + 0xd7,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00, + 0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00, + 0xf2,0xf2,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf7,0xf6,0x00, + 0xf9,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x24,0x25,0x24,0x00, + 0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00, + 0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00, + 0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00, + 0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00, + 0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7d,0x00, + 0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00, + 0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00, + 0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00, + 0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00, + 0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00, + 0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00, + 0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00, + 0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf6,0x00, + 0xf9,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x24,0x25,0x24,0x00, + 0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00, + 0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00, + 0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00, + 0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00, + 0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x81,0x82,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00, + 0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00, + 0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00, + 0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00, + 0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00, + 0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00, + 0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00, + 0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf5,0x00, + 0xf9,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x24,0x25,0x24,0x00, + 0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x51,0x51,0x50,0x00, + 0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00, + 0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00, + 0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00, + 0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x80,0x00,0x81,0x82,0x81,0x00,0x82,0x83,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00, + 0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00, + 0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00, + 0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00, + 0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00, + 0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00, + 0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00, + 0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00, + 0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00, + 0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00, + 0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x72,0x71,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00, + 0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x82,0x00,0x83,0x84,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x8f,0x8e,0x00, + 0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00, + 0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb3,0xb0,0x00, + 0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbc,0xb9,0x00, + 0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xce,0xcb,0x00, + 0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00, + 0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe8,0xe7,0xe4,0x00, + 0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf1,0xf0,0xed,0x00, + 0xf2,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2c,0x00,0x2d,0x2e,0x2d,0x00, + 0x2e,0x2f,0x2e,0x00,0x2f,0x30,0x2f,0x00,0x31,0x31,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00, + 0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00, + 0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x5a,0x5a,0x59,0x00, + 0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6c,0x6b,0x00, + 0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x75,0x74,0x00, + 0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00, + 0x98,0x99,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa1,0x9f,0x00, + 0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xaa,0xa8,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00, + 0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00, + 0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00, + 0xce,0xce,0xcb,0x00,0xcf,0xd0,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00, + 0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00, + 0xdf,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00, + 0xe8,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xf0,0xec,0x00, + 0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2c,0x00,0x2d,0x2e,0x2d,0x00, + 0x2e,0x2f,0x2e,0x00,0x2f,0x30,0x2f,0x00,0x31,0x31,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00, + 0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00, + 0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x59,0x00, + 0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00, + 0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00, + 0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00, + 0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00, + 0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00, + 0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00,0xd5,0xd6,0xd2,0x00, + 0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00, + 0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00, + 0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00, + 0xf1,0xf1,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfa,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x13,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2e,0x2d,0x00, + 0x2e,0x2f,0x2e,0x00,0x2f,0x30,0x2f,0x00,0x30,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3f,0x3f,0x00, + 0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x48,0x47,0x00, + 0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00, + 0x5a,0x5a,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00, + 0x6c,0x6c,0x6b,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00, + 0x7d,0x7e,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00, + 0x98,0x98,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00, + 0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00, + 0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00, + 0xc4,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00, + 0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd6,0xd2,0x00, + 0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00, + 0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00, + 0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00, + 0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfa,0xf9,0x00,0xfc,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x13,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2f,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00,0x42,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00, + 0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00, + 0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00, + 0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00, + 0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xab,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00, + 0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00, + 0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00, + 0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00, + 0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00, + 0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00, + 0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xf9,0xf8,0x00,0xfb,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x13,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00, + 0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x42,0x41,0x00,0x42,0x43,0x42,0x00,0x43,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00, + 0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00, + 0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00, + 0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x97,0x97,0x96,0x00, + 0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00, + 0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xbb,0xb8,0x00, + 0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc4,0xc1,0x00, + 0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcd,0xca,0x00, + 0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00, + 0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xf0,0xef,0xec,0x00, + 0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00, + 0xf8,0xf8,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xf9,0xf8,0x00,0xfb,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x13,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00, + 0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x42,0x41,0x00,0x42,0x43,0x42,0x00,0x43,0x44,0x43,0x00,0x44,0x45,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00, + 0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00, + 0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00, + 0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00, + 0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00, + 0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00, + 0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00, + 0xf1,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00, + 0xf8,0xf8,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x13,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x35,0x36,0x00, + 0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x43,0x42,0x00,0x43,0x44,0x43,0x00,0x44,0x45,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00, + 0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00, + 0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x81,0x82,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8d,0x00, + 0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00, + 0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc1,0x00, + 0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00, + 0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe3,0x00, + 0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00, + 0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf6,0xf4,0x00, + 0xf8,0xf7,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x12,0x00,0x14,0x13,0x13,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x44,0x43,0x00,0x44,0x45,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00, + 0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00, + 0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x81,0x00,0x82,0x83,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00, + 0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00, + 0xa0,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00, + 0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00, + 0xd5,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00, + 0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00, + 0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00, + 0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00, + 0xf8,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00, + 0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00, + 0x50,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x59,0x59,0x58,0x00, + 0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6b,0x6a,0x00, + 0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x72,0x72,0x71,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00, + 0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0xa0,0x9e,0x00, + 0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa7,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00, + 0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00, + 0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00, + 0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xef,0xeb,0x00, + 0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00, + 0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00, + 0x50,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00, + 0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00, + 0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00, + 0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9e,0x00, + 0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00, + 0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00, + 0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00, + 0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe6,0xe2,0x00, + 0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00, + 0xf0,0xf0,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2d,0x2d,0x00, + 0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x50,0x4f,0x00, + 0x50,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00, + 0x59,0x59,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00, + 0x6b,0x6b,0x6a,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00, + 0x7c,0x7d,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00, + 0x97,0x97,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00, + 0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00, + 0xc3,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdd,0xd9,0x00, + 0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00, + 0xe7,0xe6,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00, + 0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x51,0x50,0x00,0x51,0x51,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00, + 0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x65,0x64,0x00,0x65,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00, + 0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00, + 0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00, + 0x96,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00, + 0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00, + 0xc3,0xc3,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xcf,0xcb,0x00,0xcf,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00, + 0xdd,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00, + 0xe6,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00, + 0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00, + 0x1d,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x58,0x00, + 0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00, + 0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00, + 0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00, + 0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00, + 0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00, + 0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00, + 0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00, + 0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00, + 0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00, + 0x1d,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00, + 0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00, + 0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00, + 0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00, + 0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00, + 0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1d,0x1d,0x1d,0x00, + 0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00, + 0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00, + 0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00, + 0x9f,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00, + 0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00, + 0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00, + 0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00, + 0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x80,0x00,0x81,0x82,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00, + 0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00, + 0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00, + 0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe5,0xe1,0x00, + 0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xee,0xea,0x00, + 0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x68,0x00,0x69,0x6a,0x69,0x00, + 0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00, + 0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9f,0x9d,0x00, + 0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00, + 0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00, + 0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xee,0xed,0xea,0x00, + 0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00, + 0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00, + 0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00, + 0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00, + 0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1c,0x1d,0x1d,0x00,0x1d,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x69,0x00, + 0x6a,0x6a,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x72,0x72,0x00, + 0x73,0x73,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00, + 0x7c,0x7c,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00, + 0x96,0x96,0x94,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00, + 0xb9,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00, + 0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00, + 0xdc,0xdc,0xda,0x00,0xde,0xdd,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00, + 0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00, + 0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1c,0x1d,0x1d,0x00,0x1d,0x1e,0x1e,0x00,0x1e,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x69,0x00, + 0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x72,0x72,0x72,0x00, + 0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00, + 0x7b,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x93,0x00, + 0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb9,0xb7,0x00, + 0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc2,0xc2,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00, + 0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00, + 0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xdf,0xde,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00, + 0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfc,0xfb,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1c,0x1d,0x1d,0x00,0x1d,0x1e,0x1e,0x00,0x1e,0x1f,0x1f,0x00,0x1f,0x20,0x20,0x00,0x20,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x65,0x64,0x00,0x65,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00, + 0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00, + 0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00, + 0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc8,0x00, + 0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd9,0x00, + 0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xe0,0xdf,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xed,0xea,0x00, + 0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfd,0xfc,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1c,0x1d,0x1d,0x00,0x1d,0x1e,0x1e,0x00,0x1e,0x1f,0x1f,0x00,0x1f,0x20,0x20,0x00,0x20,0x21,0x21,0x00,0x21,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00, + 0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00, + 0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00, + 0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe1,0xe0,0xde,0x00,0xe2,0xe1,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00, + 0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00, + 0x61,0x61,0x60,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x69,0x69,0x68,0x00, + 0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00, + 0x72,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00, + 0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00, + 0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xb0,0xae,0x00, + 0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00, + 0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe2,0xe1,0xdf,0x00,0xe3,0xe2,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00, + 0xee,0xed,0xea,0x00,0xef,0xee,0xec,0x00,0xf0,0xef,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00, + 0x61,0x61,0x60,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00, + 0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00, + 0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00, + 0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00, + 0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00, + 0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00, + 0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe3,0xe2,0xe0,0x00,0xe4,0xe3,0xe1,0x00, + 0xe5,0xe4,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00, + 0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xed,0x00,0xf1,0xf0,0xee,0x00,0xf2,0xf1,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x60,0x60,0x5f,0x00, + 0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x69,0x68,0x00, + 0x69,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x72,0x71,0x00, + 0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x81,0x82,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00, + 0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9e,0x9c,0x00, + 0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00, + 0xb0,0xb0,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00, + 0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe4,0xe3,0xe1,0x00, + 0xe5,0xe4,0xe2,0x00,0xe6,0xe5,0xe3,0x00,0xe7,0xe6,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00, + 0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xee,0x00,0xf2,0xf1,0xef,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfb,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00, + 0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00, + 0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00, + 0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00, + 0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00, + 0xe5,0xe4,0xe2,0x00,0xe6,0xe5,0xe3,0x00,0xe7,0xe6,0xe4,0x00,0xe8,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00, + 0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xef,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00, + 0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00, + 0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb8,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00, + 0xc1,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00, + 0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00, + 0xdb,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00, + 0xe4,0xe4,0xe2,0x00,0xe6,0xe5,0xe3,0x00,0xe7,0xe6,0xe4,0x00,0xe8,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00, + 0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00, + 0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x63,0x62,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00, + 0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00, + 0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00, + 0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00, + 0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00, + 0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xde,0xdd,0xdb,0x00,0xdf,0xde,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00, + 0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe7,0xe6,0xe4,0x00,0xe8,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00, + 0xed,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf1,0x00,0xf5,0xf4,0xf2,0x00, + 0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x64,0x63,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00, + 0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00, + 0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbf,0x00, + 0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xd0,0x00, + 0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00, + 0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xdf,0xde,0xdc,0x00,0xe0,0xdf,0xdd,0x00,0xe1,0xe0,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe1,0x00, + 0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe8,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00, + 0xed,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xee,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf5,0xf4,0xf2,0x00, + 0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00, + 0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00, + 0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00, + 0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xe0,0xdf,0xdd,0x00,0xe1,0xe0,0xde,0x00,0xe2,0xe1,0xdf,0x00,0xe3,0xe2,0xe0,0x00, + 0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00, + 0xed,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xee,0xec,0x00,0xf0,0xef,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf6,0xf5,0xf3,0x00,0xf7,0xf6,0xf4,0x00,0xf8,0xf7,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x1f,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00, + 0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00, + 0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00, + 0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe2,0xe1,0xdf,0x00,0xe3,0xe2,0xe0,0x00, + 0xe4,0xe3,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00, + 0xed,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xee,0xec,0x00,0xf0,0xef,0xed,0x00,0xf1,0xf0,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf9,0xf8,0xf6,0x00,0xfa,0xf9,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x1f,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00, + 0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00, + 0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00, + 0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe3,0xe2,0xe0,0x00, + 0xe4,0xe3,0xe1,0x00,0xe5,0xe4,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xec,0xeb,0xe9,0x00, + 0xed,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xee,0xec,0x00,0xf0,0xef,0xed,0x00,0xf1,0xf0,0xee,0x00,0xf2,0xf1,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf7,0x00,0xfb,0xfa,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x1f,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x7a,0x79,0x00, + 0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00, + 0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xad,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb8,0xb6,0x00, + 0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00, + 0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00, + 0xe4,0xe3,0xe1,0x00,0xe5,0xe4,0xe2,0x00,0xe6,0xe5,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00, + 0xec,0xec,0xea,0x00,0xee,0xed,0xeb,0x00,0xef,0xee,0xec,0x00,0xf0,0xef,0xed,0x00,0xf1,0xf0,0xee,0x00,0xf2,0xf1,0xef,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x1f,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4d,0x4d,0x00,0x4d,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00, + 0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00, + 0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xad,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00, + 0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe6,0xe5,0xe3,0x00,0xe7,0xe6,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf1,0xf0,0xee,0x00,0xf2,0xf1,0xef,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1c,0x1c,0x1c,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x1f,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4e,0x4e,0x00, + 0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x79,0x00, + 0x7a,0x7a,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00, + 0x94,0x94,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9b,0x00, + 0x9d,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00, + 0xc0,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00, + 0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe7,0xe6,0xe4,0x00,0xe8,0xe7,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf3,0xf2,0xf0,0x00,0xf4,0xf3,0xf1,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x1f,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x45,0x45,0x00, + 0x45,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4e,0x4e,0x00, + 0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00, + 0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00, + 0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9b,0x00, + 0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xaf,0xad,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00, + 0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00, + 0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00, + 0xf5,0xf4,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x1f,0x20,0x21,0x00,0x20,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x46,0x46,0x00,0x46,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00, + 0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x80,0x00,0x81,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x92,0x00, + 0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00, + 0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00, + 0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00, + 0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1c,0x1d,0x00,0x1c,0x1d,0x1e,0x00,0x1d,0x1e,0x1f,0x00,0x1e,0x1f,0x20,0x00,0x1f,0x20,0x21,0x00,0x20,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00, + 0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x46,0x46,0x00,0x46,0x47,0x47,0x00,0x47,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00, + 0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00, + 0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00, + 0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00, + 0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x47,0x47,0x00,0x47,0x48,0x48,0x00,0x48,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x79,0x78,0x00, + 0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00, + 0x82,0x83,0x81,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00, + 0x94,0x94,0x92,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00, + 0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd1,0xce,0x00, + 0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00, + 0xda,0xda,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00, + 0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00, + 0xeb,0xeb,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x47,0x47,0x00,0x47,0x48,0x48,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00, + 0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00, + 0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00, + 0x94,0x94,0x92,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00, + 0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00, + 0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00, + 0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x48,0x48,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00, + 0x56,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x79,0x78,0x00, + 0x79,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x82,0x80,0x00, + 0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00, + 0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00, + 0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00, + 0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00, + 0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x48,0x48,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00,0x4c,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00, + 0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00, + 0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00,0x4c,0x4d,0x4d,0x00, + 0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x54,0x54,0x00,0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00, + 0x79,0x79,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00, + 0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00, + 0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00, + 0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00, + 0xf3,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00,0x4c,0x4d,0x4d,0x00, + 0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00, + 0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00, + 0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00, + 0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00, + 0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00, + 0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00, + 0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00,0x42,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00,0x4c,0x4d,0x4d,0x00, + 0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x56,0x56,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x59,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x78,0x00, + 0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xac,0x00, + 0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00, + 0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00, + 0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf3,0xf0,0x00, + 0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00,0x4c,0x4d,0x4d,0x00, + 0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x59,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00, + 0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x97,0x95,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00, + 0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00, + 0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00, + 0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x23,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x42,0x42,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00, + 0x44,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00,0x4c,0x4d,0x4d,0x00, + 0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x59,0x59,0x00,0x59,0x5a,0x5a,0x00,0x5a,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00, + 0x79,0x79,0x78,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00, + 0xad,0xae,0xac,0x00,0xae,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00, + 0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00, + 0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00, + 0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00, + 0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4c,0x4c,0x00,0x4c,0x4d,0x4d,0x00, + 0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5b,0x5b,0x00,0x5b,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00, + 0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00, + 0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00, + 0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00, + 0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00, + 0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x44,0x44,0x00, + 0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x46,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4d,0x4d,0x00, + 0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x78,0x78,0x77,0x00, + 0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00, + 0xa5,0xa5,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00, + 0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xd0,0xcd,0x00, + 0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00, + 0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00, + 0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x44,0x44,0x00, + 0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x46,0x47,0x47,0x00,0x47,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa2,0x00,0xa3,0xa4,0xa3,0x00, + 0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00, + 0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xd0,0xcd,0x00, + 0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00, + 0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x44,0x00, + 0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x46,0x47,0x47,0x00,0x47,0x48,0x48,0x00,0x48,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x55,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa3,0x00, + 0xa4,0xa5,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00, + 0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00, + 0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00, + 0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00, + 0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00, + 0xe9,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00, + 0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x44,0x00, + 0x44,0x44,0x45,0x00,0x45,0x46,0x46,0x00,0x46,0x47,0x47,0x00,0x47,0x48,0x48,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x52,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x55,0x55,0x00, + 0x55,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9b,0x9a,0x00, + 0x9b,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa3,0x00, + 0xa4,0xa5,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00, + 0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00, + 0xbe,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc7,0xc5,0x00, + 0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00, + 0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00, + 0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00, + 0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00, + 0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x47,0x47,0x00,0x47,0x48,0x48,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x55,0x55,0x00, + 0x55,0x56,0x56,0x00,0x56,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9c,0x9b,0x00,0x9c,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa4,0xa2,0x00, + 0xa4,0xa5,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb4,0x00, + 0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00, + 0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc5,0x00, + 0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd6,0x00, + 0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe7,0x00, + 0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00, + 0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf8,0x00, + 0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00, + 0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00, + 0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x48,0x48,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00, + 0x55,0x56,0x56,0x00,0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9c,0x9b,0x00,0x9c,0x9d,0x9c,0x00,0x9d,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa5,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00, + 0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00, + 0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00, + 0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00, + 0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00, + 0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00, + 0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1b,0x1b,0x1b,0x00, + 0x1a,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x49,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00, + 0x4c,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00, + 0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x66,0x00, + 0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x6f,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00, + 0x81,0x81,0x80,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x89,0x89,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9e,0x9d,0x00,0x9e,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00, + 0xb5,0xb6,0xb4,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbe,0xbc,0x00, + 0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00, + 0xc7,0xc7,0xc5,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00, + 0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00, + 0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00, + 0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00, + 0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00, + 0x4c,0x4d,0x4d,0x00,0x4d,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00, + 0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x5a,0x5a,0x00,0x5a,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00, + 0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9f,0x9e,0x00,0x9f,0xa0,0x9f,0x00,0xa0,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00,0xab,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00, + 0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00, + 0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00, + 0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00, + 0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00, + 0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00, + 0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4c,0x4c,0x00, + 0x4c,0x4d,0x4d,0x00,0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x7f,0x00, + 0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0xa0,0x9f,0x00,0xa0,0xa1,0xa0,0x00,0xa1,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xab,0xaa,0x00,0xab,0xac,0xab,0x00, + 0xac,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb5,0xb3,0x00, + 0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00, + 0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd8,0xd5,0x00, + 0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00, + 0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00, + 0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00, + 0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4d,0x4d,0x00,0x4d,0x4e,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa2,0xa1,0x00,0xa2,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xac,0xab,0x00, + 0xac,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00, + 0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00, + 0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4f,0x4f,0x00,0x4f,0x50,0x50,0x00,0x50,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00, + 0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00, + 0xa3,0xa4,0xa3,0x00,0xa4,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00, + 0xac,0xac,0xac,0x00,0xad,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00, + 0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00, + 0xf1,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x51,0x51,0x00,0x51,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00, + 0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00, + 0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00, + 0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00, + 0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00, + 0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00, + 0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00, + 0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xab,0x00, + 0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xde,0x00, + 0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xef,0x00, + 0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00, + 0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00, + 0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00, + 0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00, + 0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf4,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00, + 0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00, + 0x89,0x89,0x88,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00, + 0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00, + 0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00, + 0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00, + 0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf3,0x00,0xf5,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00, + 0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00, + 0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00, + 0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00, + 0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00, + 0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00, + 0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00, + 0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x65,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x88,0x88,0x87,0x00, + 0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x91,0x91,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x99,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa2,0x00, + 0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xab,0xab,0xaa,0x00, + 0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbd,0xbb,0x00, + 0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00, + 0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00, + 0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00, + 0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf9,0xf9,0xf7,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x65,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x88,0x88,0x87,0x00, + 0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x99,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xab,0xab,0xaa,0x00, + 0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00, + 0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00, + 0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00, + 0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00, + 0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00, + 0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x37,0x38,0x38,0x00,0x38,0x39,0x39,0x00,0x39,0x3a,0x3a,0x00, + 0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00, + 0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00, + 0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00, + 0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00, + 0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00, + 0xf9,0xfa,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x39,0x39,0x00,0x39,0x3a,0x3a,0x00, + 0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x4a,0x4a,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00, + 0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00, + 0xab,0xab,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00, + 0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd6,0xd6,0xd5,0x00, + 0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00, + 0xf0,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf9,0xf6,0x00, + 0xf9,0xfa,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x3a,0x3a,0x00, + 0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00, + 0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00, + 0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00, + 0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00, + 0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00, + 0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00, + 0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00, + 0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x42,0x42,0x42,0x00, + 0x43,0x43,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00, + 0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00, + 0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x64,0x64,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x76,0x00, + 0x76,0x76,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x99,0x99,0x98,0x00, + 0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, + 0xa2,0xa2,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00, + 0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcd,0xcd,0xcc,0x00, + 0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd6,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00, + 0xe7,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xf0,0xed,0x00, + 0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfa,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00, + 0x43,0x43,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00, + 0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00, + 0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, + 0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00, + 0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00, + 0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00, + 0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00, + 0x42,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00, + 0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00, + 0x64,0x64,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa1,0x00, + 0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbc,0xba,0x00, + 0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00, + 0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00, + 0xf0,0xf0,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00, + 0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00, + 0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xed,0x00, + 0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x1a,0x1a,0x1a,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x38,0x39,0x39,0x00, + 0x39,0x3a,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00, + 0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00, + 0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00, + 0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00, + 0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x37,0x38,0x38,0x00,0x38,0x39,0x39,0x00, + 0x39,0x3a,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x41,0x41,0x00,0x41,0x42,0x42,0x00, + 0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00, + 0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00, + 0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00, + 0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x36,0x37,0x37,0x00,0x37,0x38,0x38,0x00,0x38,0x39,0x39,0x00, + 0x39,0x3a,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x42,0x42,0x00, + 0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x64,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00, + 0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00, + 0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xef,0xef,0xec,0x00, + 0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x36,0x37,0x37,0x00,0x37,0x38,0x38,0x00,0x38,0x39,0x39,0x00, + 0x39,0x3a,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00, + 0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00, + 0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00, + 0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x35,0x36,0x36,0x00,0x36,0x37,0x37,0x00,0x37,0x38,0x38,0x00,0x38,0x39,0x39,0x00, + 0x39,0x3a,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x46,0x47,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00, + 0x64,0x64,0x64,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00, + 0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x89,0x88,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00, + 0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00, + 0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00, + 0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x35,0x36,0x36,0x00,0x36,0x37,0x37,0x00,0x37,0x38,0x38,0x00,0x38,0x39,0x39,0x00, + 0x39,0x3a,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x46,0x46,0x00,0x46,0x47,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00, + 0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00, + 0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x73,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00, + 0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00, + 0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x37,0x37,0x00,0x37,0x38,0x38,0x00,0x38,0x39,0x39,0x00, + 0x39,0x3a,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x47,0x47,0x00,0x47,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x61,0x62,0x00,0x63,0x63,0x63,0x00, + 0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00,0x6c,0x6c,0x6c,0x00, + 0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x74,0x73,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xbb,0xb9,0x00, + 0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbd,0x00,0xbe,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00, + 0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xef,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00, + 0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2b,0x00,0x2d,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x3a,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x61,0x62,0x00,0x63,0x63,0x63,0x00, + 0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00, + 0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x98,0x98,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00, + 0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbd,0x00,0xbe,0xbf,0xbe,0x00,0xbf,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00, + 0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xef,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00, + 0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x29,0x27,0x28,0x00,0x2a,0x28,0x29,0x00, + 0x2b,0x29,0x2a,0x00,0x2c,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3c,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x49,0x49,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x63,0x62,0x63,0x00, + 0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00, + 0x6d,0x6c,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x75,0x74,0x75,0x00, + 0x76,0x75,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7e,0x7d,0x7e,0x00, + 0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00, + 0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00, + 0xb2,0xb2,0xb2,0x00,0xb3,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00, + 0xbb,0xbb,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbd,0x00,0xbe,0xbf,0xbe,0x00,0xbf,0xc0,0xbf,0x00,0xc0,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00, + 0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfd,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x2a,0x28,0x29,0x00, + 0x2b,0x29,0x2a,0x00,0x2c,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3d,0x3d,0x00,0x3d,0x3e,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x63,0x62,0x63,0x00, + 0x64,0x63,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00, + 0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x75,0x74,0x75,0x00, + 0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7e,0x7d,0x7e,0x00, + 0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8e,0x8d,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00, + 0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00, + 0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00, + 0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbe,0x00,0xbf,0xc0,0xbf,0x00,0xc0,0xc1,0xc0,0x00,0xc1,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xcb,0x00, + 0xcc,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe6,0xe3,0x00, + 0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00, + 0x2b,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3f,0x3f,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00, + 0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00, + 0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00, + 0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8f,0x8e,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0xa0,0x00, + 0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb1,0x00, + 0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb6,0xb5,0x00,0xb6,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00, + 0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbe,0x00,0xbf,0xc0,0xbf,0x00,0xc0,0xc1,0xc0,0x00,0xc1,0xc2,0xc1,0x00,0xc2,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00, + 0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00, + 0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00, + 0x2b,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x40,0x40,0x00,0x40,0x41,0x41,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00, + 0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00, + 0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00, + 0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00, + 0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb7,0xb6,0x00,0xb7,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00, + 0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xc0,0xbf,0x00,0xc0,0xc1,0xc0,0x00,0xc1,0xc2,0xc1,0x00,0xc2,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00, + 0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfc,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00, + 0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x38,0x39,0x39,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x41,0x41,0x00, + 0x41,0x42,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00, + 0x6c,0x6c,0x6c,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00, + 0x75,0x75,0x75,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00, + 0x7e,0x7e,0x7e,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x84,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00, + 0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb8,0xb7,0x00,0xb8,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00, + 0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc1,0xc0,0x00,0xc1,0xc2,0xc1,0x00,0xc2,0xc3,0xc2,0x00, + 0xc3,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdd,0xdb,0x00, + 0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00, + 0xe6,0xe6,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00, + 0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x38,0x39,0x39,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x42,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5c,0x5b,0x5c,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00, + 0x6c,0x6c,0x6c,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00, + 0x75,0x75,0x75,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00, + 0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00, + 0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb9,0xb8,0x00,0xb9,0xba,0xb9,0x00, + 0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc2,0xc1,0x00,0xc2,0xc3,0xc2,0x00, + 0xc3,0xc4,0xc3,0x00,0xc4,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00, + 0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00, + 0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x30,0x00, + 0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x37,0x38,0x38,0x00, + 0x38,0x39,0x39,0x00,0x39,0x3a,0x3a,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x43,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5d,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6b,0x6b,0x00, + 0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x74,0x74,0x00, + 0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00, + 0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00, + 0x87,0x86,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00, + 0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xba,0xb9,0x00, + 0xba,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc3,0xc2,0x00, + 0xc3,0xc4,0xc3,0x00,0xc4,0xc5,0xc4,0x00,0xc5,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00, + 0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xec,0x00, + 0xee,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00, + 0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x37,0x38,0x38,0x00, + 0x38,0x39,0x39,0x00,0x39,0x3a,0x3a,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00, + 0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00, + 0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00, + 0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00, + 0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xbb,0xba,0x00,0xbb,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc4,0xc3,0x00,0xc4,0xc5,0xc4,0x00,0xc5,0xc6,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xec,0x00, + 0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf8,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3b,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x44,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00, + 0x75,0x74,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00, + 0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x84,0x83,0x84,0x00,0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00, + 0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc6,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xec,0x00, + 0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00, + 0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x77,0x77,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00, + 0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00, + 0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc8,0xc7,0x00,0xc8,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00, + 0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00, + 0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x78,0x78,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00, + 0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x86,0x85,0x86,0x00, + 0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb5,0xb4,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xee,0xeb,0x00, + 0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x31,0x31,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00, + 0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00, + 0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x19,0x19,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00, + 0x21,0x20,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00, + 0x63,0x62,0x63,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00, + 0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00, + 0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00, + 0xdc,0xdd,0xdb,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00, + 0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00, + 0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00, + 0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00, + 0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x61,0x62,0x00, + 0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x65,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x72,0x73,0x00,0x74,0x73,0x74,0x00, + 0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00, + 0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdc,0xda,0x00, + 0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x61,0x62,0x00, + 0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00, + 0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00,0x9e,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdc,0xda,0x00, + 0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00, + 0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7d,0x00, + 0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x84,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00, + 0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9e,0x9e,0x00,0x9e,0x9f,0x9f,0x00, + 0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb9,0xb9,0xb8,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc2,0xc2,0xc1,0x00, + 0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00, + 0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00, + 0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7d,0x00, + 0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x84,0x85,0x00, + 0x86,0x85,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00, + 0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9f,0x9f,0x00, + 0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb9,0xb9,0xb8,0x00, + 0xba,0xba,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc2,0xc2,0xc1,0x00, + 0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00, + 0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00, + 0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6f,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00, + 0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x84,0x83,0x84,0x00,0x85,0x84,0x85,0x00, + 0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8e,0x00, + 0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9f,0x00, + 0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00, + 0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00, + 0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00, + 0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x95,0x95,0x00,0x95,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x37,0x00, + 0x37,0x37,0x38,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5a,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00, + 0x6b,0x6a,0x6b,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00, + 0x74,0x73,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00, + 0x7d,0x7c,0x7d,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x96,0x96,0x00, + 0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00, + 0xe4,0xe5,0xe3,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xed,0xeb,0x00, + 0xed,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00, + 0x6b,0x6a,0x6b,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00, + 0x74,0x73,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00, + 0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00, + 0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00,0xa6,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00, + 0xe4,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x69,0x6a,0x00, + 0x6b,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x73,0x72,0x73,0x00, + 0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00, + 0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00, + 0x96,0x96,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9a,0x00,0x9a,0x9b,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00,0xa6,0xa7,0xa7,0x00, + 0xa7,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe4,0xe2,0x00, + 0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6b,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9a,0x00,0x9a,0x9b,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00,0xa6,0xa7,0xa7,0x00, + 0xa7,0xa8,0xa8,0x00,0xa8,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9a,0x00,0x9a,0x9b,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00,0xa6,0xa7,0xa7,0x00, + 0xa7,0xa8,0xa8,0x00,0xa8,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00, + 0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x9a,0x9a,0x00,0x9a,0x9b,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa6,0xa6,0x00,0xa6,0xa7,0xa7,0x00, + 0xa7,0xa8,0xa8,0x00,0xa8,0xa9,0xa9,0x00,0xa9,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00, + 0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x61,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x92,0x92,0x00,0x92,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x96,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9b,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa7,0xa7,0x00, + 0xa7,0xa8,0xa8,0x00,0xa8,0xa9,0xa9,0x00,0xa9,0xaa,0xaa,0x00,0xaa,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00, + 0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x92,0x92,0x00,0x92,0x93,0x93,0x00,0x93,0x94,0x94,0x00,0x94,0x95,0x95,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9b,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa8,0xa8,0x00,0xa8,0xa9,0xa9,0x00,0xa9,0xaa,0xaa,0x00,0xaa,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00, + 0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x86,0x86,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x93,0x93,0x00,0x93,0x94,0x94,0x00,0x94,0x95,0x95,0x00, + 0x95,0x96,0x96,0x00,0x96,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xaa,0xaa,0x00,0xaa,0xab,0xab,0x00,0xab,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00, + 0xb9,0xb9,0xb8,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00, + 0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00, + 0xed,0xed,0xeb,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x4f,0x51,0x00, + 0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x87,0x87,0x00,0x87,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x93,0x93,0x00,0x93,0x94,0x94,0x00,0x94,0x95,0x95,0x00, + 0x95,0x96,0x96,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00, + 0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00, + 0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00, + 0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00, + 0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x88,0x88,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x94,0x94,0x00,0x94,0x95,0x95,0x00, + 0x95,0x96,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb8,0xb8,0xb7,0x00, + 0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc1,0xc1,0xc0,0x00, + 0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xec,0xec,0xea,0x00, + 0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00, + 0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x89,0x89,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00,0x8b,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x94,0x94,0x00,0x94,0x95,0x95,0x00, + 0x95,0x96,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xae,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb8,0xb7,0xb7,0x00, + 0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00, + 0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xec,0xec,0xea,0x00, + 0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x18,0x18,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00, + 0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x72,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8a,0x8b,0x8c,0x00,0x8b,0x8c,0x8d,0x00, + 0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x95,0x95,0x00, + 0x95,0x96,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00, + 0xb0,0xaf,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb9,0xb8,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00, + 0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00, + 0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00, + 0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00, + 0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x72,0x00, + 0x73,0x73,0x73,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8b,0x8b,0x00,0x8b,0x8c,0x8d,0x00, + 0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x95,0x95,0x00, + 0x95,0x96,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9d,0x9e,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00, + 0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xba,0xb9,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00, + 0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd2,0xd1,0x00, + 0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00, + 0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00, + 0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8c,0x8c,0x00, + 0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00, + 0x95,0x96,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xaf,0x00, + 0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xbb,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xc0,0x00, + 0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd1,0x00, + 0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf3,0x00, + 0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x49,0x49,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00, + 0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00, + 0x95,0x96,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9e,0x9f,0x9f,0x00,0x9f,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbc,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc8,0xc7,0x00,0xc8,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00, + 0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00, + 0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x36,0x36,0x37,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00, + 0x61,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00, + 0x7b,0x7b,0x7c,0x00,0x7c,0x7d,0x7d,0x00,0x7d,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x94,0x94,0x95,0x00, + 0x95,0x95,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00, + 0xa6,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbc,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc9,0xc8,0x00, + 0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00, + 0xd2,0xd2,0xd1,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00, + 0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x56,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x61,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00, + 0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x7f,0x80,0x80,0x00,0x80,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8e,0x8e,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x95,0x95,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa5,0xa5,0x00,0xa5,0xa6,0xa6,0x00, + 0xa6,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00, + 0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00,0xd9,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00, + 0xf5,0xf5,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7b,0x00, + 0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x7f,0x80,0x80,0x00,0x80,0x81,0x81,0x00,0x81,0x82,0x82,0x00,0x82,0x83,0x83,0x00, + 0x83,0x84,0x84,0x00,0x84,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00, + 0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00,0xd9,0xda,0xd9,0x00, + 0xda,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf4,0xf4,0xf2,0x00, + 0xf5,0xf5,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x80,0x80,0x00,0x80,0x81,0x81,0x00,0x81,0x82,0x82,0x00,0x82,0x83,0x83,0x00, + 0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x87,0x00,0x86,0x87,0x88,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8f,0x8f,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00,0xb7,0xb6,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00,0xd9,0xda,0xd9,0x00, + 0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf5,0xf5,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x81,0x81,0x00,0x81,0x82,0x82,0x00,0x82,0x83,0x83,0x00, + 0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x87,0x00,0x86,0x87,0x88,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00, + 0x8b,0x8c,0x8d,0x00,0x8c,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00, + 0xaf,0xae,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00,0xb7,0xb6,0xb7,0x00, + 0xb8,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00,0xd9,0xda,0xd9,0x00, + 0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x82,0x82,0x00,0x82,0x83,0x83,0x00, + 0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x86,0x87,0x88,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00, + 0x8b,0x8c,0x8d,0x00,0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8f,0x90,0x90,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x96,0x97,0x98,0x00,0x98,0x99,0x99,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00, + 0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb6,0xb5,0xb6,0x00,0xb7,0xb6,0xb7,0x00, + 0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd8,0x00,0xd9,0xda,0xd9,0x00, + 0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00,0xdc,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x83,0x83,0x00, + 0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x86,0x87,0x87,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00, + 0x8b,0x8c,0x8d,0x00,0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa0,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00, + 0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb7,0xb6,0xb7,0x00, + 0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc5,0xc4,0x00,0xc5,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xda,0xd9,0x00, + 0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00,0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x20,0x00, + 0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x86,0x87,0x87,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00, + 0x8b,0x8c,0x8d,0x00,0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x90,0x91,0x92,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa0,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00, + 0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc5,0xc4,0x00,0xc5,0xc6,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00,0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x20,0x00, + 0x1f,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x86,0x86,0x00,0x86,0x87,0x87,0x00,0x87,0x88,0x88,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00, + 0x8b,0x8c,0x8d,0x00,0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa0,0xa1,0xa2,0x00,0xa1,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00, + 0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbc,0xbb,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc6,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xde,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xed,0xec,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x88,0x88,0x00,0x88,0x89,0x89,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00, + 0x8b,0x8c,0x8d,0x00,0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x93,0x94,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9c,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa0,0xa1,0xa2,0x00,0xa1,0xa2,0xa3,0x00,0xa2,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00, + 0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbc,0xbb,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xee,0xed,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8a,0x8b,0x8c,0x00, + 0x8b,0x8c,0x8d,0x00,0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x94,0x95,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9b,0x9b,0x9d,0x00,0x9c,0x9d,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa0,0xa1,0xa2,0x00,0xa1,0xa2,0xa3,0x00,0xa2,0xa3,0xa4,0x00,0xa3,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xae,0xad,0xae,0x00, + 0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xbb,0x00,0xbc,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc8,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xef,0xee,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x70,0x71,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8c,0x8d,0x00,0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x95,0x96,0x00,0x95,0x96,0x97,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9e,0x00, + 0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa0,0xa1,0xa2,0x00,0xa1,0xa2,0xa3,0x00,0xa2,0xa3,0xa4,0x00,0xa3,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc8,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00,0xe2,0xe1,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x68,0x67,0x69,0x00, + 0x69,0x68,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x7a,0x7a,0x00, + 0x7a,0x7b,0x7b,0x00,0x7b,0x7c,0x7c,0x00,0x7c,0x7d,0x7d,0x00,0x7d,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8d,0x8e,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x96,0x00,0x95,0x96,0x97,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9c,0x9c,0x9e,0x00, + 0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa4,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe2,0xe1,0xe1,0x00, + 0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf1,0xf0,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00, + 0x60,0x5f,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x68,0x67,0x69,0x00, + 0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7b,0x7b,0x00,0x7b,0x7c,0x7c,0x00,0x7c,0x7d,0x7d,0x00,0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x7f,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8e,0x8f,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x97,0x00,0x96,0x97,0x98,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00, + 0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa4,0xa4,0xa6,0x00, + 0xa5,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xe0,0x00,0xe2,0xe1,0xe1,0x00, + 0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf2,0xf1,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7b,0x7b,0x00,0x7b,0x7c,0x7c,0x00,0x7c,0x7d,0x7d,0x00,0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x7f,0x80,0x80,0x00,0x80,0x81,0x81,0x00,0x82,0x82,0x82,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8f,0x90,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x98,0x00,0x97,0x98,0x99,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00, + 0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa4,0xa4,0xa6,0x00, + 0xa5,0xa5,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe1,0x00, + 0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf3,0xf2,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x48,0x48,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7b,0x7b,0x00,0x7b,0x7c,0x7c,0x00,0x7c,0x7d,0x7d,0x00,0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x7f,0x80,0x80,0x00,0x80,0x81,0x81,0x00,0x81,0x82,0x82,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x90,0x91,0x00,0x90,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x99,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00, + 0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa4,0xa4,0xa6,0x00, + 0xa5,0xa5,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa7,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00, + 0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf4,0xf4,0xf3,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x17,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x35,0x35,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00, + 0x56,0x56,0x58,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x7f,0x80,0x80,0x00,0x80,0x81,0x81,0x00,0x81,0x82,0x82,0x00, + 0x82,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x91,0x00,0x90,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x99,0x9a,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00, + 0x9c,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00, + 0xae,0xad,0xae,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00, + 0xb7,0xb6,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00, + 0xd0,0xd1,0xd0,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xdb,0xda,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00, + 0xe2,0xe2,0xe1,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x75,0x76,0x00,0x75,0x76,0x77,0x00,0x76,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x81,0x81,0x00,0x81,0x82,0x82,0x00, + 0x82,0x83,0x83,0x00,0x83,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9b,0x9c,0x00,0x9b,0x9c,0x9d,0x00, + 0x9c,0x9d,0x9e,0x00,0x9d,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00, + 0xae,0xad,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb7,0xb6,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00, + 0xd0,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xdb,0xda,0xda,0x00,0xdc,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00, + 0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x59,0x58,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x76,0x77,0x00,0x76,0x77,0x78,0x00,0x77,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9c,0x9d,0x00, + 0x9c,0x9d,0x9e,0x00,0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xac,0xad,0x00, + 0xae,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xd0,0xcf,0x00, + 0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdc,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00, + 0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00, + 0xeb,0xea,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x76,0x77,0x00,0x76,0x77,0x78,0x00,0x77,0x78,0x79,0x00,0x78,0x79,0x7a,0x00, + 0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x93,0x00,0x93,0x92,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9d,0x9e,0x00,0x9d,0x9e,0x9f,0x00,0x9e,0x9f,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xae,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdc,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00, + 0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00, + 0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x77,0x78,0x00,0x77,0x78,0x79,0x00,0x78,0x79,0x7a,0x00, + 0x79,0x7a,0x7b,0x00,0x7a,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x93,0x92,0x94,0x00, + 0x94,0x93,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0xa0,0xa1,0x00,0xa0,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00, + 0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x77,0x78,0x00,0x77,0x78,0x79,0x00,0x78,0x79,0x7a,0x00, + 0x79,0x7a,0x7b,0x00,0x7a,0x7b,0x7c,0x00,0x7b,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x94,0x00, + 0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd4,0xd3,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00, + 0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x77,0x78,0x00,0x77,0x78,0x79,0x00,0x78,0x79,0x7a,0x00, + 0x79,0x7a,0x7b,0x00,0x7a,0x7b,0x7c,0x00,0x7b,0x7c,0x7d,0x00,0x7c,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd5,0xd4,0xd4,0x00,0xd6,0xd5,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xea,0xe9,0xe9,0x00, + 0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00,0x77,0x78,0x79,0x00,0x78,0x79,0x7a,0x00, + 0x79,0x7a,0x7b,0x00,0x7a,0x7b,0x7c,0x00,0x7b,0x7c,0x7d,0x00,0x7c,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd5,0xd4,0xd4,0x00,0xd6,0xd5,0xd5,0x00,0xd7,0xd6,0xd6,0x00,0xd8,0xd7,0xd7,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00,0x77,0x78,0x79,0x00,0x78,0x79,0x7a,0x00, + 0x79,0x7a,0x7b,0x00,0x7a,0x7b,0x7c,0x00,0x7b,0x7c,0x7d,0x00,0x7c,0x7d,0x7e,0x00,0x7d,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00, + 0xa4,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd6,0xd5,0xd5,0x00,0xd7,0xd6,0xd6,0x00,0xd8,0xd7,0xd7,0x00, + 0xd9,0xd8,0xd8,0x00,0xda,0xd9,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00,0x78,0x79,0x7a,0x00, + 0x79,0x7a,0x7b,0x00,0x7a,0x7b,0x7c,0x00,0x7b,0x7c,0x7d,0x00,0x7c,0x7d,0x7e,0x00,0x7d,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00, + 0xa4,0xa4,0xa6,0x00,0xa5,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd7,0xd6,0xd6,0x00,0xd8,0xd7,0xd7,0x00, + 0xd9,0xd8,0xd8,0x00,0xda,0xd9,0xd9,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x79,0x00,0x78,0x78,0x7a,0x00, + 0x79,0x7a,0x7b,0x00,0x7a,0x7b,0x7c,0x00,0x7b,0x7c,0x7d,0x00,0x7c,0x7d,0x7e,0x00,0x7d,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9b,0x9c,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00, + 0xa4,0xa4,0xa6,0x00,0xa5,0xa5,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd8,0xd7,0xd7,0x00, + 0xd9,0xd8,0xd8,0x00,0xda,0xd9,0xd9,0x00,0xdb,0xda,0xda,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe1,0xe0,0xe0,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x7a,0x7b,0x00,0x7a,0x7b,0x7c,0x00,0x7b,0x7c,0x7d,0x00,0x7c,0x7d,0x7e,0x00,0x7d,0x7e,0x7f,0x00,0x7e,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00, + 0xa4,0xa4,0xa6,0x00,0xa5,0xa5,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa7,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd8,0xd7,0xd7,0x00, + 0xd9,0xd8,0xd8,0x00,0xda,0xd9,0xd9,0x00,0xdb,0xda,0xda,0x00,0xdc,0xdb,0xdb,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00,0xf2,0xf1,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00, + 0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa5,0x00, + 0xa4,0xa4,0xa6,0x00,0xa5,0xa5,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa7,0xa7,0xa9,0x00,0xa8,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00, + 0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00, + 0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd9,0xd8,0xd8,0x00,0xda,0xd9,0xd9,0x00,0xdb,0xda,0xda,0x00,0xdc,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00,0xf2,0xf1,0xf1,0x00, + 0xf3,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00, + 0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x81,0x00,0x81,0x80,0x82,0x00, + 0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00, + 0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa9,0x00,0xa8,0xa8,0xaa,0x00,0xa9,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00, + 0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00, + 0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xda,0xd9,0xd9,0x00,0xdb,0xda,0xda,0x00,0xdc,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00, + 0xea,0xe9,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf2,0xf1,0xf1,0x00, + 0xf3,0xf2,0xf2,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x66,0x68,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x82,0x00, + 0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00, + 0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xac,0x00,0xac,0xab,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbe,0x00, + 0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xcf,0x00, + 0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xda,0xda,0x00,0xdc,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00, + 0xea,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf1,0x00, + 0xf3,0xf2,0xf2,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x47,0x47,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00,0x6e,0x6d,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00, + 0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00, + 0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00, + 0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdc,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00, + 0xea,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00, + 0xf3,0xf2,0xf2,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00, + 0xf9,0xf9,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x35,0x00, + 0x34,0x34,0x36,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00, + 0x55,0x55,0x57,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00,0x6e,0x6d,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00, + 0x81,0x81,0x82,0x00,0x82,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x89,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x92,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00, + 0x9b,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00, + 0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdd,0xdc,0xdc,0x00,0xde,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00, + 0xe1,0xe0,0xe0,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe9,0xe8,0xe8,0x00, + 0xea,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00, + 0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x57,0x56,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x76,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00, + 0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00, + 0x9b,0x9b,0x9d,0x00,0x9c,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00, + 0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xdf,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00, + 0xe1,0xe0,0xe0,0x00,0xe2,0xe1,0xe1,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xea,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00, + 0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00, + 0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x92,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x9a,0x9c,0x00, + 0x9b,0x9b,0x9d,0x00,0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbd,0xbd,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00, + 0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xe0,0xdf,0xdf,0x00, + 0xe1,0xe0,0xe0,0x00,0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf1,0xf0,0x00, + 0xf2,0xf2,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00, + 0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9b,0x9d,0x00,0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00, + 0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe1,0xe0,0xe0,0x00,0xe2,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf2,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x16,0x16,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00, + 0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00, + 0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00, + 0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe3,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00, + 0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00, + 0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x93,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00, + 0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe4,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00, + 0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x80,0x81,0x00, + 0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x91,0x92,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd7,0xd6,0xd7,0x00, + 0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00, + 0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00, + 0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe6,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00, + 0xe9,0xe8,0xe8,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfb,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00, + 0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb7,0xb6,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe7,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00, + 0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfb,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x27,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x68,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x78,0x00, + 0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb8,0xb7,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00, + 0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00, + 0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00, + 0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb8,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe7,0xe7,0x00, + 0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00, + 0x66,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6e,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x77,0x78,0x00, + 0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xdd,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe9,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00, + 0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x77,0x78,0x00, + 0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xba,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xde,0xdd,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xea,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x65,0x67,0x00, + 0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x77,0x00,0x77,0x76,0x78,0x00, + 0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x88,0x89,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbc,0xbb,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xdf,0xde,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xeb,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfa,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x18,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x46,0x46,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00, + 0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xec,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfa,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00, + 0x33,0x33,0x35,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x55,0x00, + 0x54,0x54,0x56,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00, + 0x78,0x77,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00, + 0x80,0x80,0x81,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xed,0xec,0xec,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00, + 0xf1,0xf0,0xf0,0x00,0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x27,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2d,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00, + 0x78,0x77,0x78,0x00,0x79,0x78,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00, + 0x80,0x80,0x81,0x00,0x81,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00,0xb3,0xb2,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00, + 0xf1,0xf0,0xf0,0x00,0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x27,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2c,0x00, + 0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x76,0x77,0x00, + 0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00, + 0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00,0xb3,0xb2,0xb4,0x00, + 0xb4,0xb3,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbf,0xbe,0xbf,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xef,0xef,0x00, + 0xf1,0xf0,0xf0,0x00,0xf2,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xf9,0xf9,0x00,0xfb,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1d,0x00, + 0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00, + 0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00, + 0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00,0xb3,0xb2,0xb4,0x00, + 0xb4,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbf,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf1,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1d,0x00, + 0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00, + 0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00, + 0x6e,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00, + 0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00,0xb3,0xb2,0xb4,0x00, + 0xb4,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00, + 0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00, + 0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00, + 0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb1,0xb3,0x00,0xb3,0xb2,0xb4,0x00, + 0xb4,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00, + 0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00, + 0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6f,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7f,0x80,0x00, + 0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb2,0xb4,0x00, + 0xb4,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb6,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00, + 0x1e,0x1d,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00, + 0x2c,0x2c,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb4,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb6,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb6,0xb8,0x00,0xb8,0xb7,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00, + 0xd6,0xd6,0xd6,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa5,0x00,0xa4,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00,0xb7,0xb6,0xb8,0x00,0xb8,0xb7,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00, + 0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4a,0x4d,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa6,0x00,0xa5,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb7,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00, + 0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x49,0x4c,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa6,0x00,0xa5,0xa4,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00, + 0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1b,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3b,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x48,0x4b,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa6,0x00,0xa5,0xa4,0xa7,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00, + 0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd5,0xd5,0x00, + 0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3b,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x47,0x4a,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x86,0x87,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa7,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00, + 0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd5,0xd5,0x00, + 0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x64,0x64,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x87,0x88,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00,0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa7,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa9,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00, + 0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xde,0xdd,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x45,0x47,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x63,0x63,0x66,0x00, + 0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00,0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa7,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa8,0xab,0x00, + 0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00, + 0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xf0,0xf0,0xf0,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x63,0x63,0x66,0x00, + 0x64,0x64,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00, + 0x99,0x98,0x9a,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00,0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa7,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa8,0xab,0x00, + 0xaa,0xa9,0xac,0x00,0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00, + 0xbb,0xbb,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xde,0xde,0xde,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x19,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x63,0x63,0x66,0x00, + 0x64,0x64,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00, + 0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9b,0x9d,0x00,0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa8,0xab,0x00, + 0xaa,0xa9,0xac,0x00,0xab,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00, + 0xbb,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x19,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x63,0x63,0x66,0x00, + 0x64,0x64,0x67,0x00,0x65,0x65,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00, + 0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00, + 0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9d,0x00,0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa8,0xab,0x00, + 0xaa,0xa9,0xac,0x00,0xab,0xaa,0xad,0x00,0xac,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00, + 0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x19,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x2f,0x32,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x50,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x63,0x63,0x66,0x00, + 0x64,0x64,0x67,0x00,0x65,0x65,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00, + 0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00, + 0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa8,0xab,0x00, + 0xaa,0xa9,0xac,0x00,0xab,0xaa,0xad,0x00,0xac,0xac,0xae,0x00,0xad,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00, + 0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00,0xbf,0xbe,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x19,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2e,0x31,0x00,0x30,0x2f,0x32,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3d,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x4f,0x52,0x00,0x51,0x50,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x63,0x63,0x66,0x00, + 0x64,0x64,0x67,0x00,0x65,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00, + 0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00, + 0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9e,0x00,0x9d,0x9c,0x9f,0x00,0x9e,0x9e,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa8,0xab,0x00, + 0xaa,0xa9,0xac,0x00,0xab,0xaa,0xad,0x00,0xac,0xab,0xae,0x00,0xad,0xad,0xaf,0x00,0xae,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00, + 0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbf,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xce,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x19,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2d,0x30,0x00,0x30,0x2e,0x31,0x00,0x30,0x2f,0x32,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3d,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4e,0x51,0x00,0x50,0x4f,0x52,0x00,0x51,0x50,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x63,0x63,0x66,0x00, + 0x64,0x64,0x67,0x00,0x65,0x65,0x68,0x00,0x66,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00, + 0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00, + 0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9f,0x00,0x9e,0x9d,0xa0,0x00,0x9f,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa8,0xab,0x00, + 0xaa,0xa9,0xac,0x00,0xab,0xaa,0xad,0x00,0xac,0xab,0xae,0x00,0xad,0xad,0xaf,0x00,0xae,0xae,0xb0,0x00,0xaf,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00, + 0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbe,0x00,0xbf,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xce,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x19,0x1b,0x00,0x1c,0x1a,0x1c,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2c,0x2f,0x00,0x2f,0x2d,0x30,0x00,0x30,0x2e,0x31,0x00,0x30,0x2f,0x32,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x35,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3d,0x40,0x00,0x3f,0x3e,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00, + 0x4d,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4d,0x50,0x00,0x4f,0x4e,0x51,0x00,0x50,0x4f,0x52,0x00,0x51,0x50,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5f,0x00,0x5d,0x5d,0x60,0x00,0x5e,0x5e,0x61,0x00,0x5f,0x5f,0x62,0x00,0x60,0x60,0x63,0x00,0x61,0x61,0x64,0x00,0x62,0x62,0x65,0x00,0x63,0x63,0x66,0x00, + 0x64,0x64,0x67,0x00,0x65,0x65,0x68,0x00,0x66,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7e,0x7f,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8f,0x91,0x00, + 0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00, + 0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00,0x9d,0x9c,0x9f,0x00,0x9e,0x9d,0xa0,0x00,0x9f,0x9e,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa4,0xa4,0xa6,0x00,0xa6,0xa5,0xa8,0x00,0xa7,0xa6,0xa9,0x00,0xa8,0xa7,0xaa,0x00,0xa9,0xa8,0xab,0x00, + 0xaa,0xa9,0xac,0x00,0xab,0xaa,0xad,0x00,0xac,0xab,0xae,0x00,0xad,0xac,0xaf,0x00,0xae,0xae,0xb0,0x00,0xaf,0xaf,0xb1,0x00,0xb0,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00, + 0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc3,0xc3,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xce,0xd0,0x00,0xd0,0xcf,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00, + 0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00, + 0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00 +}; diff --git a/LibOVR/Src/CAPI/Textures/overdriveLut_dk2_2.h b/LibOVR/Src/CAPI/Textures/overdriveLut_dk2_2.h new file mode 100644 index 0000000..d66b2b7 --- /dev/null +++ b/LibOVR/Src/CAPI/Textures/overdriveLut_dk2_2.h @@ -0,0 +1,8194 @@ +const uint8_t overdriveLut_dk2[256*256*4] = { + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x23,0x19,0x00,0x19,0x24,0x1a,0x00,0x1b,0x25,0x1b,0x00,0x1d,0x26,0x1d,0x00, + 0x1d,0x26,0x1e,0x00,0x1f,0x28,0x1f,0x00,0x20,0x28,0x20,0x00,0x21,0x29,0x21,0x00,0x22,0x2a,0x22,0x00,0x23,0x2b,0x23,0x00,0x24,0x2c,0x25,0x00,0x25,0x2d,0x26,0x00, + 0x27,0x2e,0x28,0x00,0x28,0x2f,0x29,0x00,0x29,0x30,0x2b,0x00,0x2b,0x32,0x2c,0x00,0x2b,0x33,0x2d,0x00,0x2d,0x34,0x2f,0x00,0x2d,0x35,0x2f,0x00,0x2f,0x36,0x32,0x00, + 0x2f,0x37,0x32,0x00,0x32,0x38,0x34,0x00,0x32,0x39,0x34,0x00,0x34,0x3a,0x36,0x00,0x36,0x3c,0x38,0x00,0x37,0x3d,0x39,0x00,0x38,0x3e,0x3a,0x00,0x39,0x3f,0x3b,0x00, + 0x3c,0x41,0x3d,0x00,0x3c,0x41,0x3d,0x00,0x3d,0x42,0x3e,0x00,0x3f,0x44,0x40,0x00,0x40,0x45,0x41,0x00,0x41,0x46,0x42,0x00,0x42,0x47,0x43,0x00,0x43,0x48,0x44,0x00, + 0x44,0x49,0x45,0x00,0x45,0x4a,0x46,0x00,0x46,0x4b,0x47,0x00,0x47,0x4c,0x48,0x00,0x49,0x4d,0x4a,0x00,0x4a,0x4e,0x4b,0x00,0x4b,0x4f,0x4c,0x00,0x4b,0x50,0x4d,0x00, + 0x4c,0x51,0x4e,0x00,0x4e,0x53,0x4f,0x00,0x4f,0x54,0x50,0x00,0x50,0x55,0x51,0x00,0x51,0x56,0x52,0x00,0x52,0x57,0x54,0x00,0x53,0x58,0x55,0x00,0x54,0x5a,0x56,0x00, + 0x56,0x5c,0x57,0x00,0x56,0x5c,0x58,0x00,0x58,0x5e,0x5a,0x00,0x5a,0x60,0x5c,0x00,0x5b,0x61,0x5d,0x00,0x5c,0x63,0x5e,0x00,0x5e,0x64,0x60,0x00,0x5f,0x66,0x61,0x00, + 0x61,0x67,0x62,0x00,0x62,0x68,0x64,0x00,0x63,0x6a,0x65,0x00,0x65,0x6b,0x67,0x00,0x66,0x6d,0x68,0x00,0x68,0x6e,0x6a,0x00,0x69,0x6f,0x6b,0x00,0x6b,0x71,0x6c,0x00, + 0x6c,0x72,0x6e,0x00,0x6d,0x73,0x6f,0x00,0x6e,0x74,0x70,0x00,0x6f,0x75,0x71,0x00,0x70,0x76,0x72,0x00,0x71,0x77,0x73,0x00,0x73,0x78,0x74,0x00,0x73,0x79,0x76,0x00, + 0x75,0x7b,0x77,0x00,0x76,0x7b,0x78,0x00,0x77,0x7d,0x79,0x00,0x78,0x7e,0x7a,0x00,0x79,0x7f,0x7b,0x00,0x7a,0x80,0x7c,0x00,0x7b,0x81,0x7e,0x00,0x7c,0x82,0x7f,0x00, + 0x7d,0x83,0x7f,0x00,0x7f,0x84,0x80,0x00,0x80,0x85,0x81,0x00,0x81,0x86,0x83,0x00,0x82,0x87,0x84,0x00,0x83,0x88,0x85,0x00,0x84,0x8a,0x86,0x00,0x86,0x8a,0x87,0x00, + 0x87,0x8c,0x88,0x00,0x88,0x8d,0x89,0x00,0x89,0x8e,0x8b,0x00,0x8a,0x8f,0x8b,0x00,0x8c,0x90,0x8d,0x00,0x8c,0x91,0x8f,0x00,0x8e,0x93,0x90,0x00,0x8f,0x94,0x91,0x00, + 0x90,0x95,0x92,0x00,0x91,0x95,0x93,0x00,0x92,0x97,0x94,0x00,0x93,0x98,0x95,0x00,0x95,0x99,0x97,0x00,0x96,0x9a,0x98,0x00,0x97,0x9b,0x99,0x00,0x98,0x9d,0x9a,0x00, + 0x99,0x9e,0x9c,0x00,0x9a,0x9f,0x9c,0x00,0x9c,0xa1,0x9e,0x00,0x9d,0xa2,0x9f,0x00,0x9f,0xa3,0xa1,0x00,0xa0,0xa4,0xa2,0x00,0xa1,0xa5,0xa3,0x00,0xa2,0xa7,0xa4,0x00, + 0xa3,0xa8,0xa6,0x00,0xa4,0xa8,0xa7,0x00,0xa5,0xaa,0xa8,0x00,0xa7,0xab,0xa9,0x00,0xa8,0xac,0xab,0x00,0xa9,0xae,0xac,0x00,0xaa,0xae,0xad,0x00,0xab,0xaf,0xae,0x00, + 0xad,0xb1,0xaf,0x00,0xae,0xb2,0xb1,0x00,0xaf,0xb3,0xb2,0x00,0xb0,0xb4,0xb3,0x00,0xb2,0xb6,0xb4,0x00,0xb3,0xb7,0xb6,0x00,0xb5,0xb8,0xb7,0x00,0xb6,0xb9,0xb8,0x00, + 0xb7,0xba,0xb9,0x00,0xb8,0xbb,0xba,0x00,0xb9,0xbc,0xbb,0x00,0xba,0xbd,0xbc,0x00,0xbb,0xbf,0xbd,0x00,0xbc,0xc0,0xbf,0x00,0xbd,0xc1,0xc0,0x00,0xbe,0xc2,0xc1,0x00, + 0xc0,0xc3,0xc2,0x00,0xc2,0xc4,0xc3,0x00,0xc3,0xc6,0xc5,0x00,0xc3,0xc7,0xc6,0x00,0xc5,0xc8,0xc7,0x00,0xc6,0xc9,0xc8,0x00,0xc7,0xca,0xc9,0x00,0xc8,0xcb,0xca,0x00, + 0xc9,0xcc,0xcc,0x00,0xca,0xce,0xcc,0x00,0xcc,0xce,0xce,0x00,0xcd,0xcf,0xcf,0x00,0xce,0xd1,0xd0,0x00,0xcf,0xd2,0xd1,0x00,0xd0,0xd3,0xd2,0x00,0xd1,0xd4,0xd3,0x00, + 0xd3,0xd5,0xd5,0x00,0xd3,0xd6,0xd5,0x00,0xd5,0xd7,0xd7,0x00,0xd6,0xd9,0xd7,0x00,0xd7,0xd9,0xd8,0x00,0xd9,0xdb,0xda,0x00,0xd9,0xdc,0xdb,0x00,0xdb,0xdd,0xdc,0x00, + 0xdc,0xde,0xdd,0x00,0xdd,0xdf,0xde,0x00,0xde,0xe0,0xdf,0x00,0xdf,0xe2,0xe1,0x00,0xe0,0xe3,0xe2,0x00,0xe1,0xe4,0xe3,0x00,0xe3,0xe5,0xe4,0x00,0xe4,0xe5,0xe4,0x00, + 0xe6,0xe7,0xe5,0x00,0xe6,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe9,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xeb,0x00,0xed,0xed,0xeb,0x00,0xed,0xee,0xed,0x00, + 0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf5,0xf3,0x00,0xf5,0xf6,0xf4,0x00,0xf5,0xf7,0xf5,0x00,0xf6,0xf8,0xf6,0x00, + 0xf7,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xf9,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00,0xfd,0xff,0xfc,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x22,0x19,0x00,0x18,0x24,0x1a,0x00,0x1a,0x24,0x1b,0x00,0x1c,0x25,0x1d,0x00, + 0x1e,0x26,0x1e,0x00,0x1f,0x27,0x1f,0x00,0x20,0x28,0x20,0x00,0x21,0x29,0x21,0x00,0x22,0x2a,0x22,0x00,0x23,0x2b,0x23,0x00,0x24,0x2c,0x25,0x00,0x25,0x2c,0x26,0x00, + 0x26,0x2d,0x28,0x00,0x28,0x2f,0x2a,0x00,0x28,0x30,0x2b,0x00,0x2b,0x31,0x2c,0x00,0x2b,0x32,0x2d,0x00,0x2c,0x33,0x2e,0x00,0x2d,0x34,0x2f,0x00,0x2f,0x36,0x30,0x00, + 0x2f,0x36,0x31,0x00,0x32,0x37,0x33,0x00,0x32,0x38,0x34,0x00,0x33,0x3a,0x36,0x00,0x36,0x3b,0x36,0x00,0x37,0x3c,0x38,0x00,0x37,0x3d,0x39,0x00,0x39,0x3e,0x3b,0x00, + 0x3b,0x40,0x3b,0x00,0x3c,0x41,0x3d,0x00,0x3c,0x42,0x3e,0x00,0x3e,0x43,0x3f,0x00,0x3f,0x44,0x40,0x00,0x41,0x45,0x41,0x00,0x41,0x46,0x42,0x00,0x42,0x47,0x44,0x00, + 0x44,0x48,0x45,0x00,0x45,0x49,0x46,0x00,0x46,0x4a,0x47,0x00,0x47,0x4b,0x48,0x00,0x48,0x4d,0x49,0x00,0x49,0x4d,0x4a,0x00,0x4a,0x4f,0x4b,0x00,0x4b,0x50,0x4c,0x00, + 0x4c,0x51,0x4d,0x00,0x4d,0x52,0x4e,0x00,0x4e,0x53,0x50,0x00,0x4f,0x54,0x51,0x00,0x50,0x55,0x52,0x00,0x52,0x56,0x53,0x00,0x53,0x57,0x54,0x00,0x54,0x59,0x55,0x00, + 0x55,0x5b,0x57,0x00,0x56,0x5c,0x58,0x00,0x57,0x5d,0x59,0x00,0x59,0x5f,0x5b,0x00,0x5a,0x60,0x5c,0x00,0x5c,0x62,0x5e,0x00,0x5d,0x63,0x5f,0x00,0x5f,0x65,0x60,0x00, + 0x60,0x66,0x62,0x00,0x62,0x67,0x63,0x00,0x63,0x69,0x65,0x00,0x64,0x6a,0x66,0x00,0x66,0x6b,0x68,0x00,0x67,0x6d,0x69,0x00,0x68,0x6f,0x6b,0x00,0x6a,0x70,0x6c,0x00, + 0x6c,0x71,0x6e,0x00,0x6c,0x72,0x6e,0x00,0x6d,0x73,0x6f,0x00,0x6e,0x74,0x70,0x00,0x70,0x75,0x71,0x00,0x71,0x76,0x73,0x00,0x71,0x77,0x74,0x00,0x73,0x78,0x75,0x00, + 0x74,0x79,0x76,0x00,0x75,0x7b,0x77,0x00,0x76,0x7c,0x78,0x00,0x77,0x7d,0x79,0x00,0x79,0x7e,0x7b,0x00,0x7a,0x7f,0x7b,0x00,0x7b,0x80,0x7d,0x00,0x7c,0x81,0x7e,0x00, + 0x7d,0x82,0x7f,0x00,0x7e,0x83,0x80,0x00,0x80,0x84,0x81,0x00,0x80,0x85,0x82,0x00,0x81,0x86,0x83,0x00,0x82,0x87,0x84,0x00,0x83,0x89,0x85,0x00,0x84,0x89,0x86,0x00, + 0x85,0x8b,0x88,0x00,0x86,0x8c,0x89,0x00,0x88,0x8d,0x8b,0x00,0x89,0x8e,0x8c,0x00,0x8a,0x8f,0x8d,0x00,0x8b,0x91,0x8e,0x00,0x8c,0x92,0x8f,0x00,0x8e,0x93,0x90,0x00, + 0x8f,0x94,0x91,0x00,0x90,0x95,0x92,0x00,0x91,0x96,0x93,0x00,0x92,0x97,0x95,0x00,0x94,0x98,0x96,0x00,0x95,0x99,0x96,0x00,0x95,0x9a,0x97,0x00,0x96,0x9b,0x99,0x00, + 0x99,0x9e,0x9b,0x00,0x9a,0x9f,0x9c,0x00,0x9b,0xa0,0x9e,0x00,0x9c,0xa1,0x9f,0x00,0x9e,0xa2,0xa0,0x00,0x9f,0xa3,0xa1,0x00,0xa0,0xa4,0xa2,0x00,0xa1,0xa5,0xa3,0x00, + 0xa2,0xa7,0xa5,0x00,0xa3,0xa8,0xa6,0x00,0xa5,0xa9,0xa7,0x00,0xa6,0xaa,0xa9,0x00,0xa7,0xab,0xaa,0x00,0xa8,0xac,0xaa,0x00,0xa9,0xae,0xab,0x00,0xaa,0xae,0xac,0x00, + 0xac,0xb0,0xae,0x00,0xac,0xb1,0xaf,0x00,0xae,0xb2,0xb0,0x00,0xaf,0xb3,0xb1,0x00,0xb1,0xb4,0xb3,0x00,0xb1,0xb6,0xb4,0x00,0xb4,0xb7,0xb6,0x00,0xb4,0xb8,0xb6,0x00, + 0xb6,0xb9,0xb8,0x00,0xb7,0xba,0xb9,0x00,0xb8,0xbb,0xbb,0x00,0xb9,0xbd,0xbc,0x00,0xba,0xbe,0xbd,0x00,0xbb,0xbf,0xbd,0x00,0xbc,0xc0,0xbf,0x00,0xbe,0xc1,0xbf,0x00, + 0xbf,0xc3,0xc1,0x00,0xc0,0xc3,0xc2,0x00,0xc2,0xc5,0xc4,0x00,0xc3,0xc6,0xc5,0x00,0xc4,0xc7,0xc6,0x00,0xc5,0xc8,0xc7,0x00,0xc6,0xca,0xc8,0x00,0xc7,0xca,0xc9,0x00, + 0xc8,0xcc,0xca,0x00,0xca,0xcd,0xcb,0x00,0xcb,0xce,0xcd,0x00,0xcb,0xcf,0xcd,0x00,0xcd,0xd0,0xcf,0x00,0xce,0xd1,0xd0,0x00,0xcf,0xd3,0xd1,0x00,0xd0,0xd3,0xd2,0x00, + 0xd2,0xd4,0xd3,0x00,0xd3,0xd6,0xd4,0x00,0xd4,0xd7,0xd5,0x00,0xd5,0xd8,0xd7,0x00,0xd6,0xd9,0xd8,0x00,0xd7,0xdb,0xd9,0x00,0xd9,0xdb,0xda,0x00,0xda,0xdc,0xdb,0x00, + 0xdb,0xde,0xdc,0x00,0xdc,0xdf,0xdd,0x00,0xdd,0xe0,0xde,0x00,0xde,0xe1,0xdf,0x00,0xdf,0xe2,0xe1,0x00,0xe1,0xe4,0xe1,0x00,0xe2,0xe4,0xe3,0x00,0xe3,0xe5,0xe4,0x00, + 0xe4,0xe6,0xe5,0x00,0xe5,0xe8,0xe6,0x00,0xe7,0xe9,0xe7,0x00,0xe8,0xea,0xe9,0x00,0xe9,0xeb,0xea,0x00,0xea,0xec,0xeb,0x00,0xec,0xee,0xeb,0x00,0xed,0xee,0xec,0x00, + 0xee,0xef,0xed,0x00,0xef,0xf1,0xef,0x00,0xf0,0xf2,0xf0,0x00,0xf1,0xf3,0xf0,0x00,0xf3,0xf4,0xf2,0x00,0xf3,0xf5,0xf2,0x00,0xf5,0xf6,0xf4,0x00,0xf6,0xf7,0xf5,0x00, + 0xf7,0xf8,0xf6,0x00,0xf8,0xfa,0xf7,0x00,0xf9,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00,0xfd,0xff,0xfc,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x17,0x22,0x19,0x00,0x19,0x23,0x1a,0x00,0x1a,0x24,0x1c,0x00,0x1d,0x25,0x1c,0x00, + 0x1d,0x26,0x1d,0x00,0x1f,0x27,0x1f,0x00,0x20,0x27,0x20,0x00,0x20,0x28,0x21,0x00,0x22,0x29,0x22,0x00,0x22,0x2a,0x23,0x00,0x23,0x2b,0x24,0x00,0x25,0x2c,0x26,0x00, + 0x27,0x2d,0x27,0x00,0x28,0x2e,0x29,0x00,0x29,0x2f,0x2a,0x00,0x2a,0x30,0x2c,0x00,0x2b,0x31,0x2d,0x00,0x2c,0x33,0x2e,0x00,0x2d,0x33,0x2f,0x00,0x2e,0x35,0x30,0x00, + 0x2f,0x36,0x31,0x00,0x30,0x37,0x32,0x00,0x31,0x38,0x33,0x00,0x33,0x39,0x35,0x00,0x34,0x3b,0x36,0x00,0x35,0x3c,0x37,0x00,0x37,0x3c,0x38,0x00,0x38,0x3d,0x3a,0x00, + 0x39,0x3f,0x3b,0x00,0x3b,0x40,0x3c,0x00,0x3c,0x41,0x3d,0x00,0x3e,0x42,0x3f,0x00,0x3f,0x43,0x40,0x00,0x40,0x44,0x41,0x00,0x41,0x45,0x42,0x00,0x42,0x47,0x43,0x00, + 0x43,0x47,0x44,0x00,0x44,0x48,0x45,0x00,0x45,0x4a,0x46,0x00,0x46,0x4b,0x47,0x00,0x47,0x4c,0x49,0x00,0x49,0x4d,0x4a,0x00,0x4a,0x4e,0x4b,0x00,0x4b,0x4f,0x4c,0x00, + 0x4c,0x50,0x4d,0x00,0x4d,0x51,0x4e,0x00,0x4e,0x52,0x4f,0x00,0x4f,0x53,0x50,0x00,0x50,0x54,0x51,0x00,0x51,0x56,0x53,0x00,0x52,0x56,0x54,0x00,0x53,0x58,0x55,0x00, + 0x55,0x5a,0x56,0x00,0x56,0x5b,0x57,0x00,0x57,0x5c,0x58,0x00,0x59,0x5e,0x5a,0x00,0x5a,0x60,0x5c,0x00,0x5b,0x61,0x5d,0x00,0x5d,0x63,0x5f,0x00,0x5e,0x64,0x60,0x00, + 0x60,0x65,0x61,0x00,0x61,0x67,0x62,0x00,0x62,0x68,0x64,0x00,0x64,0x69,0x66,0x00,0x65,0x6b,0x67,0x00,0x67,0x6c,0x68,0x00,0x68,0x6e,0x6a,0x00,0x69,0x6f,0x6b,0x00, + 0x6a,0x70,0x6d,0x00,0x6c,0x71,0x6e,0x00,0x6d,0x72,0x6e,0x00,0x6e,0x73,0x70,0x00,0x6f,0x74,0x71,0x00,0x70,0x75,0x72,0x00,0x71,0x77,0x73,0x00,0x72,0x77,0x74,0x00, + 0x73,0x79,0x75,0x00,0x74,0x7a,0x76,0x00,0x76,0x7b,0x78,0x00,0x77,0x7c,0x79,0x00,0x78,0x7d,0x7a,0x00,0x79,0x7e,0x7b,0x00,0x7a,0x7f,0x7c,0x00,0x7b,0x81,0x7d,0x00, + 0x7c,0x81,0x7f,0x00,0x7d,0x83,0x80,0x00,0x7f,0x83,0x81,0x00,0x80,0x84,0x82,0x00,0x81,0x85,0x83,0x00,0x82,0x87,0x84,0x00,0x83,0x88,0x85,0x00,0x84,0x89,0x86,0x00, + 0x86,0x8a,0x87,0x00,0x87,0x8b,0x88,0x00,0x88,0x8c,0x89,0x00,0x89,0x8e,0x8a,0x00,0x8a,0x8f,0x8c,0x00,0x8b,0x90,0x8e,0x00,0x8c,0x91,0x8f,0x00,0x8d,0x92,0x90,0x00, + 0x8f,0x93,0x91,0x00,0x8f,0x94,0x92,0x00,0x91,0x95,0x93,0x00,0x92,0x96,0x94,0x00,0x93,0x97,0x95,0x00,0x94,0x98,0x96,0x00,0x95,0x9a,0x97,0x00,0x96,0x9b,0x98,0x00, + 0x98,0x9d,0x9a,0x00,0x99,0x9e,0x9b,0x00,0x9a,0x9f,0x9e,0x00,0x9b,0xa0,0x9f,0x00,0x9d,0xa0,0x9f,0x00,0x9e,0xa2,0xa0,0x00,0x9f,0xa3,0xa2,0x00,0xa0,0xa5,0xa3,0x00, + 0xa2,0xa6,0xa4,0x00,0xa3,0xa7,0xa5,0x00,0xa4,0xa8,0xa7,0x00,0xa5,0xa9,0xa8,0x00,0xa7,0xaa,0xa9,0x00,0xa8,0xab,0xaa,0x00,0xa9,0xad,0xab,0x00,0xaa,0xad,0xac,0x00, + 0xac,0xaf,0xad,0x00,0xad,0xb0,0xae,0x00,0xae,0xb1,0xb0,0x00,0xaf,0xb2,0xb1,0x00,0xb0,0xb4,0xb2,0x00,0xb1,0xb5,0xb3,0x00,0xb3,0xb6,0xb5,0x00,0xb4,0xb7,0xb6,0x00, + 0xb5,0xb9,0xb8,0x00,0xb6,0xba,0xb9,0x00,0xb8,0xbb,0xba,0x00,0xb9,0xbc,0xbb,0x00,0xba,0xbd,0xbd,0x00,0xba,0xbe,0xbd,0x00,0xbc,0xbf,0xbe,0x00,0xbd,0xc0,0xbf,0x00, + 0xbe,0xc1,0xc1,0x00,0xc0,0xc3,0xc2,0x00,0xc1,0xc4,0xc3,0x00,0xc2,0xc5,0xc4,0x00,0xc3,0xc6,0xc5,0x00,0xc4,0xc7,0xc6,0x00,0xc5,0xc8,0xc8,0x00,0xc7,0xc9,0xc9,0x00, + 0xc8,0xca,0xca,0x00,0xc9,0xcc,0xcb,0x00,0xca,0xcd,0xcc,0x00,0xcb,0xcd,0xce,0x00,0xcc,0xcf,0xcf,0x00,0xcd,0xd0,0xd0,0x00,0xcf,0xd1,0xd1,0x00,0xd0,0xd3,0xd2,0x00, + 0xd1,0xd3,0xd3,0x00,0xd2,0xd4,0xd4,0x00,0xd3,0xd5,0xd5,0x00,0xd4,0xd7,0xd6,0x00,0xd6,0xd8,0xd8,0x00,0xd7,0xd9,0xd8,0x00,0xd8,0xda,0xda,0x00,0xd9,0xdb,0xdb,0x00, + 0xda,0xdc,0xdc,0x00,0xdc,0xde,0xdd,0x00,0xdd,0xde,0xde,0x00,0xde,0xe0,0xdf,0x00,0xdf,0xe1,0xe0,0x00,0xe0,0xe1,0xe1,0x00,0xe1,0xe3,0xe2,0x00,0xe2,0xe4,0xe4,0x00, + 0xe4,0xe5,0xe5,0x00,0xe4,0xe6,0xe6,0x00,0xe6,0xe7,0xe7,0x00,0xe7,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xec,0xec,0x00,0xec,0xed,0xed,0x00, + 0xed,0xee,0xed,0x00,0xee,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf6,0xf5,0xf6,0x00, + 0xf6,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfd,0xfd,0x00,0xfd,0xfd,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x19,0x17,0x00,0x18,0x1b,0x18,0x00,0x19,0x1b,0x1a,0x00,0x1b,0x1c,0x1a,0x00, + 0x1c,0x1e,0x1b,0x00,0x1d,0x1f,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00, + 0x25,0x25,0x25,0x00,0x26,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x2a,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2b,0x00,0x2c,0x2c,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2e,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00,0x30,0x30,0x31,0x00,0x32,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x3a,0x38,0x38,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3d,0x3c,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3f,0x3e,0x3e,0x00,0x40,0x3f,0x3f,0x00,0x41,0x40,0x41,0x00, + 0x42,0x41,0x42,0x00,0x43,0x42,0x42,0x00,0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x47,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x48,0x48,0x00,0x4a,0x49,0x49,0x00, + 0x4b,0x4a,0x4a,0x00,0x4c,0x4b,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00, + 0x54,0x53,0x53,0x00,0x54,0x53,0x54,0x00,0x56,0x55,0x55,0x00,0x57,0x56,0x57,0x00,0x59,0x57,0x58,0x00,0x5a,0x59,0x59,0x00,0x5c,0x5a,0x5b,0x00,0x5d,0x5c,0x5c,0x00, + 0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5f,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00,0x64,0x63,0x63,0x00,0x65,0x64,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x67,0x67,0x00, + 0x69,0x69,0x68,0x00,0x6a,0x69,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6c,0x6d,0x00,0x6f,0x6e,0x6e,0x00,0x70,0x6f,0x6f,0x00,0x71,0x71,0x70,0x00, + 0x72,0x72,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x77,0x00,0x79,0x78,0x78,0x00,0x7a,0x79,0x79,0x00, + 0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7e,0x7e,0x00,0x80,0x7f,0x7f,0x00,0x81,0x7f,0x81,0x00,0x82,0x80,0x82,0x00,0x83,0x81,0x83,0x00, + 0x84,0x83,0x84,0x00,0x86,0x84,0x85,0x00,0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x89,0x87,0x89,0x00,0x8a,0x88,0x8a,0x00,0x8b,0x89,0x8b,0x00,0x8c,0x8a,0x8c,0x00, + 0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x8f,0x8f,0x00,0x91,0x8e,0x90,0x00,0x92,0x90,0x91,0x00,0x93,0x91,0x92,0x00,0x94,0x92,0x93,0x00,0x95,0x93,0x95,0x00, + 0x96,0x95,0x96,0x00,0x98,0x96,0x97,0x00,0x99,0x97,0x98,0x00,0x9a,0x98,0x99,0x00,0x9b,0x99,0x9b,0x00,0x9c,0x9a,0x9c,0x00,0x9e,0x9b,0x9d,0x00,0x9f,0x9c,0x9e,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa0,0xa0,0x00,0xa3,0xa1,0xa2,0x00,0xa4,0xa3,0xa3,0x00,0xa5,0xa4,0xa4,0x00,0xa7,0xa3,0xa6,0x00,0xa8,0xa5,0xa7,0x00,0xa9,0xa5,0xa8,0x00, + 0xab,0xa7,0xa9,0x00,0xac,0xa8,0xaa,0x00,0xad,0xaa,0xab,0x00,0xae,0xab,0xad,0x00,0xaf,0xac,0xaf,0x00,0xb0,0xad,0xb0,0x00,0xb1,0xaf,0xb1,0x00,0xb3,0xb0,0xb2,0x00, + 0xb4,0xb1,0xb3,0x00,0xb5,0xb2,0xb3,0x00,0xb7,0xb3,0xb5,0x00,0xb7,0xb4,0xb6,0x00,0xb9,0xb5,0xb7,0x00,0xba,0xb5,0xb8,0x00,0xbb,0xb9,0xba,0x00,0xbb,0xb9,0xbb,0x00, + 0xbd,0xbb,0xbc,0x00,0xbe,0xbc,0xbd,0x00,0xbf,0xbd,0xbe,0x00,0xc1,0xbe,0xbf,0x00,0xc2,0xbf,0xc0,0x00,0xc3,0xbf,0xc1,0x00,0xc4,0xc0,0xc2,0x00,0xc5,0xc1,0xc4,0x00, + 0xc7,0xc2,0xc5,0x00,0xc7,0xc3,0xc7,0x00,0xc9,0xc4,0xc8,0x00,0xc9,0xc5,0xc9,0x00,0xcb,0xc7,0xca,0x00,0xcc,0xc9,0xcb,0x00,0xcd,0xca,0xcc,0x00,0xce,0xcb,0xcc,0x00, + 0xd0,0xcc,0xce,0x00,0xd1,0xcc,0xcf,0x00,0xd2,0xce,0xd0,0x00,0xd3,0xcf,0xd1,0x00,0xd5,0xcf,0xd2,0x00,0xd5,0xd1,0xd3,0x00,0xd6,0xd1,0xd4,0x00,0xd7,0xd3,0xd6,0x00, + 0xd9,0xd4,0xd7,0x00,0xda,0xd5,0xd8,0x00,0xdb,0xd6,0xd9,0x00,0xdd,0xd8,0xda,0x00,0xde,0xda,0xdc,0x00,0xde,0xdc,0xdd,0x00,0xe0,0xdd,0xdd,0x00,0xe1,0xde,0xde,0x00, + 0xe3,0xdf,0xdf,0x00,0xe3,0xdf,0xe0,0x00,0xe5,0xe1,0xe1,0x00,0xe6,0xe2,0xe2,0x00,0xe7,0xe3,0xe3,0x00,0xe8,0xe2,0xe4,0x00,0xe9,0xe3,0xe6,0x00,0xea,0xe4,0xe7,0x00, + 0xec,0xe5,0xe8,0x00,0xed,0xe6,0xe9,0x00,0xee,0xe7,0xea,0x00,0xef,0xe8,0xeb,0x00,0xf0,0xe9,0xec,0x00,0xf1,0xeb,0xee,0x00,0xf3,0xed,0xee,0x00,0xf4,0xee,0xef,0x00, + 0xf5,0xef,0xf0,0x00,0xf6,0xf0,0xf1,0x00,0xf7,0xf2,0xf2,0x00,0xf8,0xf3,0xf3,0x00,0xfa,0xf3,0xf5,0x00,0xfb,0xf4,0xf5,0x00,0xfc,0xf5,0xf7,0x00,0xfc,0xf7,0xf8,0x00, + 0xfd,0xf7,0xf9,0x00,0xfe,0xf8,0xfa,0x00,0xff,0xf9,0xfc,0x00,0xff,0xfb,0xfc,0x00,0xff,0xfb,0xfe,0x00,0xff,0xfd,0xff,0x00,0xff,0xfe,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x19,0x17,0x00,0x18,0x1a,0x18,0x00,0x19,0x1b,0x19,0x00,0x1b,0x1c,0x1a,0x00, + 0x1d,0x1d,0x1b,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x1f,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x21,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00, + 0x25,0x25,0x24,0x00,0x26,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2e,0x2e,0x00, + 0x2e,0x2e,0x2e,0x00,0x30,0x30,0x30,0x00,0x30,0x30,0x30,0x00,0x32,0x32,0x32,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00, + 0x3a,0x38,0x39,0x00,0x3a,0x39,0x39,0x00,0x3b,0x3a,0x3a,0x00,0x3d,0x3c,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3f,0x3d,0x3d,0x00,0x40,0x3e,0x3f,0x00,0x41,0x40,0x40,0x00, + 0x42,0x41,0x41,0x00,0x43,0x42,0x42,0x00,0x44,0x43,0x43,0x00,0x45,0x44,0x44,0x00,0x47,0x45,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x48,0x48,0x00,0x4a,0x48,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4a,0x4b,0x00,0x4d,0x4c,0x4c,0x00,0x4e,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00,0x51,0x50,0x50,0x00,0x52,0x51,0x52,0x00, + 0x54,0x53,0x53,0x00,0x54,0x53,0x54,0x00,0x55,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x58,0x57,0x57,0x00,0x5a,0x58,0x59,0x00,0x5b,0x5a,0x5a,0x00,0x5c,0x5b,0x5b,0x00, + 0x5e,0x5d,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x61,0x60,0x60,0x00,0x62,0x61,0x61,0x00,0x64,0x63,0x63,0x00,0x65,0x64,0x64,0x00,0x66,0x66,0x66,0x00,0x68,0x67,0x67,0x00, + 0x6a,0x68,0x68,0x00,0x6a,0x69,0x69,0x00,0x6b,0x6a,0x6a,0x00,0x6c,0x6b,0x6b,0x00,0x6d,0x6c,0x6c,0x00,0x6f,0x6d,0x6d,0x00,0x70,0x6e,0x6e,0x00,0x71,0x6f,0x6f,0x00, + 0x72,0x71,0x71,0x00,0x73,0x72,0x72,0x00,0x74,0x73,0x73,0x00,0x75,0x74,0x74,0x00,0x76,0x75,0x75,0x00,0x77,0x76,0x76,0x00,0x78,0x77,0x78,0x00,0x7a,0x78,0x78,0x00, + 0x7b,0x79,0x7a,0x00,0x7c,0x7a,0x7b,0x00,0x7d,0x7c,0x7c,0x00,0x7e,0x7c,0x7d,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x7f,0x00,0x81,0x80,0x80,0x00,0x82,0x81,0x81,0x00, + 0x83,0x82,0x82,0x00,0x85,0x83,0x83,0x00,0x85,0x84,0x85,0x00,0x87,0x85,0x85,0x00,0x87,0x86,0x87,0x00,0x89,0x87,0x88,0x00,0x8a,0x89,0x89,0x00,0x8b,0x8a,0x8a,0x00, + 0x8d,0x8b,0x8c,0x00,0x8e,0x8c,0x8d,0x00,0x8f,0x8d,0x8e,0x00,0x90,0x8e,0x8f,0x00,0x91,0x8f,0x90,0x00,0x93,0x90,0x91,0x00,0x93,0x92,0x93,0x00,0x95,0x93,0x93,0x00, + 0x96,0x94,0x95,0x00,0x97,0x95,0x96,0x00,0x99,0x96,0x97,0x00,0x99,0x97,0x99,0x00,0x9b,0x99,0x9a,0x00,0x9c,0x9a,0x9b,0x00,0x9d,0x9b,0x9c,0x00,0x9e,0x9c,0x9d,0x00, + 0xa0,0x9e,0x9e,0x00,0xa1,0x9e,0xa0,0x00,0xa2,0xa0,0xa0,0x00,0xa4,0xa1,0xa2,0x00,0xa5,0xa2,0xa3,0x00,0xa6,0xa2,0xa5,0x00,0xa8,0xa4,0xa6,0x00,0xa8,0xa5,0xa7,0x00, + 0xaa,0xa7,0xa9,0x00,0xab,0xa7,0xaa,0x00,0xac,0xa9,0xab,0x00,0xad,0xaa,0xac,0x00,0xaf,0xab,0xad,0x00,0xb0,0xac,0xae,0x00,0xb1,0xae,0xaf,0x00,0xb2,0xaf,0xb0,0x00, + 0xb3,0xb0,0xb2,0x00,0xb5,0xb1,0xb2,0x00,0xb6,0xb2,0xb4,0x00,0xb6,0xb3,0xb5,0x00,0xb8,0xb4,0xb6,0x00,0xba,0xb5,0xb7,0x00,0xba,0xb6,0xb9,0x00,0xbb,0xb7,0xba,0x00, + 0xbc,0xb9,0xba,0x00,0xbe,0xba,0xbb,0x00,0xbf,0xbb,0xbc,0x00,0xc0,0xbb,0xbe,0x00,0xc1,0xbd,0xbf,0x00,0xc2,0xbe,0xc0,0x00,0xc3,0xbf,0xc1,0x00,0xc4,0xc1,0xc3,0x00, + 0xc6,0xc2,0xc4,0x00,0xc6,0xc3,0xc4,0x00,0xc8,0xc4,0xc6,0x00,0xc9,0xc5,0xc6,0x00,0xca,0xc6,0xc8,0x00,0xcb,0xc7,0xc9,0x00,0xcc,0xc9,0xca,0x00,0xcd,0xca,0xcb,0x00, + 0xcf,0xcb,0xcc,0x00,0xd0,0xcc,0xcd,0x00,0xd1,0xcd,0xcf,0x00,0xd2,0xce,0xd0,0x00,0xd4,0xcf,0xd1,0x00,0xd5,0xd0,0xd2,0x00,0xd6,0xd1,0xd3,0x00,0xd7,0xd2,0xd4,0x00, + 0xd8,0xd4,0xd5,0x00,0xd9,0xd5,0xd6,0x00,0xda,0xd5,0xd7,0x00,0xdc,0xd6,0xd9,0x00,0xdd,0xd8,0xda,0x00,0xdf,0xd9,0xdb,0x00,0xdf,0xdb,0xdc,0x00,0xe0,0xdb,0xdd,0x00, + 0xe2,0xdc,0xdf,0x00,0xe2,0xdd,0xdf,0x00,0xe4,0xdf,0xe0,0x00,0xe4,0xdf,0xe1,0x00,0xe5,0xe1,0xe3,0x00,0xe6,0xe1,0xe3,0x00,0xe8,0xe3,0xe4,0x00,0xe9,0xe3,0xe5,0x00, + 0xea,0xe5,0xe6,0x00,0xeb,0xe6,0xe6,0x00,0xec,0xe7,0xe8,0x00,0xed,0xe8,0xe9,0x00,0xef,0xe9,0xea,0x00,0xef,0xea,0xeb,0x00,0xf1,0xec,0xed,0x00,0xf2,0xed,0xed,0x00, + 0xf3,0xee,0xef,0x00,0xf4,0xef,0xf0,0x00,0xf5,0xf0,0xf1,0x00,0xf6,0xf1,0xf2,0x00,0xf8,0xf2,0xf3,0x00,0xf9,0xf3,0xf4,0x00,0xfa,0xf4,0xf5,0x00,0xfc,0xf6,0xf6,0x00, + 0xfe,0xf7,0xf7,0x00,0xfe,0xf8,0xf9,0x00,0xff,0xf9,0xfa,0x00,0xff,0xfa,0xfb,0x00,0xff,0xfb,0xfc,0x00,0xff,0xfc,0xfd,0x00,0xff,0xfe,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x19,0x17,0x00,0x18,0x1a,0x18,0x00,0x19,0x1b,0x18,0x00,0x1b,0x1c,0x1a,0x00, + 0x1c,0x1d,0x1b,0x00,0x1d,0x1e,0x1c,0x00,0x1e,0x1f,0x1e,0x00,0x1f,0x20,0x1e,0x00,0x20,0x21,0x1f,0x00,0x21,0x22,0x20,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00, + 0x24,0x25,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2b,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00, + 0x2e,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x32,0x32,0x31,0x00,0x34,0x33,0x32,0x00,0x35,0x34,0x34,0x00,0x36,0x35,0x35,0x00,0x37,0x36,0x36,0x00, + 0x39,0x38,0x37,0x00,0x3a,0x39,0x39,0x00,0x3b,0x3a,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00,0x3e,0x3d,0x3d,0x00,0x3f,0x3e,0x3e,0x00,0x41,0x40,0x40,0x00, + 0x42,0x41,0x41,0x00,0x43,0x41,0x42,0x00,0x44,0x43,0x43,0x00,0x45,0x44,0x44,0x00,0x46,0x45,0x45,0x00,0x47,0x46,0x46,0x00,0x48,0x47,0x47,0x00,0x49,0x48,0x48,0x00, + 0x4a,0x49,0x49,0x00,0x4b,0x4a,0x4a,0x00,0x4d,0x4c,0x4c,0x00,0x4d,0x4c,0x4d,0x00,0x4e,0x4e,0x4d,0x00,0x50,0x4f,0x4f,0x00,0x51,0x50,0x50,0x00,0x52,0x51,0x51,0x00, + 0x53,0x52,0x52,0x00,0x54,0x53,0x53,0x00,0x55,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x58,0x57,0x57,0x00,0x59,0x58,0x58,0x00,0x5b,0x5a,0x5a,0x00,0x5c,0x5b,0x5b,0x00, + 0x5e,0x5c,0x5c,0x00,0x5f,0x5e,0x5e,0x00,0x60,0x5f,0x5f,0x00,0x62,0x61,0x61,0x00,0x63,0x62,0x62,0x00,0x64,0x64,0x64,0x00,0x66,0x65,0x65,0x00,0x67,0x66,0x66,0x00, + 0x69,0x68,0x67,0x00,0x6a,0x68,0x68,0x00,0x6b,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6d,0x6c,0x6c,0x00,0x6e,0x6d,0x6d,0x00,0x6f,0x6e,0x6e,0x00,0x70,0x6f,0x6f,0x00, + 0x71,0x70,0x70,0x00,0x72,0x71,0x71,0x00,0x74,0x73,0x72,0x00,0x75,0x74,0x74,0x00,0x76,0x75,0x74,0x00,0x77,0x76,0x76,0x00,0x78,0x77,0x77,0x00,0x79,0x78,0x78,0x00, + 0x7a,0x79,0x79,0x00,0x7b,0x7a,0x7a,0x00,0x7d,0x7b,0x7b,0x00,0x7d,0x7c,0x7d,0x00,0x7f,0x7e,0x7e,0x00,0x80,0x7e,0x7f,0x00,0x81,0x7f,0x80,0x00,0x82,0x80,0x80,0x00, + 0x84,0x81,0x81,0x00,0x84,0x83,0x83,0x00,0x86,0x84,0x84,0x00,0x87,0x85,0x86,0x00,0x88,0x86,0x87,0x00,0x89,0x87,0x88,0x00,0x8a,0x88,0x89,0x00,0x8b,0x89,0x8a,0x00, + 0x8d,0x8b,0x8a,0x00,0x8d,0x8c,0x8b,0x00,0x8f,0x8d,0x8d,0x00,0x90,0x8e,0x8e,0x00,0x91,0x8f,0x8f,0x00,0x92,0x90,0x91,0x00,0x93,0x91,0x92,0x00,0x94,0x93,0x93,0x00, + 0x95,0x94,0x95,0x00,0x97,0x95,0x96,0x00,0x98,0x96,0x96,0x00,0x99,0x97,0x97,0x00,0x9a,0x98,0x98,0x00,0x9b,0x99,0x9a,0x00,0x9e,0x9b,0x9c,0x00,0x9f,0x9c,0x9d,0x00, + 0xa0,0x9e,0x9f,0x00,0xa0,0x9e,0x9f,0x00,0xa2,0x9f,0xa0,0x00,0xa3,0xa0,0xa2,0x00,0xa4,0xa1,0xa2,0x00,0xa5,0xa2,0xa3,0x00,0xa6,0xa4,0xa4,0x00,0xa7,0xa5,0xa5,0x00, + 0xa9,0xa6,0xa6,0x00,0xaa,0xa7,0xa8,0x00,0xab,0xa8,0xa9,0x00,0xac,0xaa,0xaa,0x00,0xad,0xab,0xac,0x00,0xae,0xac,0xac,0x00,0xb1,0xad,0xaf,0x00,0xb1,0xaf,0xaf,0x00, + 0xb3,0xb0,0xb1,0x00,0xb4,0xb1,0xb2,0x00,0xb5,0xb2,0xb3,0x00,0xb6,0xb3,0xb4,0x00,0xb7,0xb4,0xb5,0x00,0xb8,0xb5,0xb5,0x00,0xb9,0xb6,0xb7,0x00,0xba,0xb7,0xb8,0x00, + 0xbc,0xb9,0xb9,0x00,0xbd,0xb9,0xbb,0x00,0xbe,0xbb,0xbc,0x00,0xc0,0xbb,0xbd,0x00,0xc1,0xbd,0xbe,0x00,0xc1,0xbe,0xbf,0x00,0xc3,0xbf,0xc1,0x00,0xc4,0xc0,0xc1,0x00, + 0xc5,0xc1,0xc3,0x00,0xc6,0xc3,0xc3,0x00,0xc7,0xc4,0xc5,0x00,0xc9,0xc5,0xc6,0x00,0xca,0xc6,0xc7,0x00,0xcb,0xc7,0xc8,0x00,0xcc,0xc8,0xc9,0x00,0xcd,0xc9,0xca,0x00, + 0xce,0xca,0xcb,0x00,0xd0,0xcb,0xcd,0x00,0xd1,0xcd,0xce,0x00,0xd2,0xcd,0xcf,0x00,0xd3,0xcf,0xd0,0x00,0xd4,0xd0,0xd1,0x00,0xd5,0xd1,0xd2,0x00,0xd7,0xd2,0xd3,0x00, + 0xd8,0xd3,0xd4,0x00,0xd9,0xd4,0xd5,0x00,0xda,0xd6,0xd6,0x00,0xdb,0xd7,0xd7,0x00,0xdc,0xd8,0xd8,0x00,0xdd,0xd9,0xd9,0x00,0xde,0xda,0xda,0x00,0xdf,0xdb,0xdc,0x00, + 0xe1,0xdc,0xdd,0x00,0xe1,0xdd,0xde,0x00,0xe3,0xde,0xdf,0x00,0xe4,0xdf,0xe0,0x00,0xe6,0xe1,0xe1,0x00,0xe7,0xe1,0xe2,0x00,0xe8,0xe3,0xe3,0x00,0xe9,0xe3,0xe4,0x00, + 0xeb,0xe5,0xe5,0x00,0xec,0xe6,0xe6,0x00,0xed,0xe7,0xe7,0x00,0xee,0xe8,0xe8,0x00,0xef,0xe9,0xea,0x00,0xf0,0xea,0xea,0x00,0xf1,0xeb,0xec,0x00,0xf3,0xed,0xec,0x00, + 0xf4,0xed,0xee,0x00,0xf5,0xee,0xef,0x00,0xf6,0xf0,0xf0,0x00,0xf7,0xf1,0xf1,0x00,0xf8,0xf2,0xf2,0x00,0xf9,0xf3,0xf3,0x00,0xfa,0xf4,0xf4,0x00,0xfb,0xf5,0xf6,0x00, + 0xfd,0xf6,0xf7,0x00,0xfd,0xf7,0xf8,0x00,0xff,0xf8,0xf9,0x00,0xff,0xfa,0xf9,0x00,0xff,0xfb,0xfc,0x00,0xff,0xfc,0xfc,0x00,0xff,0xfd,0xfd,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x18,0x16,0x00,0x17,0x19,0x18,0x00,0x19,0x1b,0x18,0x00,0x1a,0x1c,0x1a,0x00, + 0x1c,0x1d,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1f,0x1d,0x00,0x1f,0x20,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00, + 0x24,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x29,0x29,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2d,0x2d,0x2d,0x00, + 0x2d,0x2d,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x33,0x32,0x00,0x35,0x34,0x33,0x00,0x35,0x35,0x35,0x00,0x37,0x36,0x36,0x00, + 0x39,0x37,0x37,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x39,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00,0x3e,0x3d,0x3d,0x00,0x3f,0x3e,0x3e,0x00,0x41,0x40,0x3f,0x00, + 0x41,0x40,0x40,0x00,0x42,0x41,0x41,0x00,0x43,0x42,0x42,0x00,0x44,0x44,0x43,0x00,0x46,0x45,0x45,0x00,0x47,0x46,0x46,0x00,0x48,0x47,0x47,0x00,0x49,0x48,0x48,0x00, + 0x4a,0x49,0x49,0x00,0x4b,0x4a,0x4a,0x00,0x4c,0x4b,0x4b,0x00,0x4d,0x4c,0x4c,0x00,0x4e,0x4d,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x52,0x51,0x51,0x00, + 0x53,0x52,0x52,0x00,0x54,0x53,0x52,0x00,0x55,0x54,0x54,0x00,0x56,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x58,0x58,0x57,0x00,0x5a,0x59,0x59,0x00,0x5c,0x5b,0x5b,0x00, + 0x5d,0x5c,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x60,0x5f,0x5f,0x00,0x61,0x60,0x60,0x00,0x63,0x62,0x61,0x00,0x64,0x63,0x63,0x00,0x66,0x65,0x64,0x00,0x67,0x66,0x65,0x00, + 0x69,0x67,0x66,0x00,0x69,0x68,0x67,0x00,0x6a,0x69,0x69,0x00,0x6b,0x6a,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6c,0x6c,0x00,0x6f,0x6e,0x6d,0x00,0x70,0x6f,0x6e,0x00, + 0x71,0x70,0x6f,0x00,0x72,0x71,0x70,0x00,0x73,0x72,0x71,0x00,0x74,0x73,0x73,0x00,0x76,0x74,0x74,0x00,0x76,0x75,0x75,0x00,0x78,0x76,0x76,0x00,0x79,0x77,0x77,0x00, + 0x7a,0x79,0x78,0x00,0x7b,0x7a,0x79,0x00,0x7c,0x7b,0x7b,0x00,0x7d,0x7c,0x7c,0x00,0x7e,0x7d,0x7d,0x00,0x7f,0x7e,0x7e,0x00,0x81,0x7f,0x7f,0x00,0x82,0x80,0x80,0x00, + 0x83,0x81,0x81,0x00,0x84,0x82,0x82,0x00,0x85,0x83,0x83,0x00,0x86,0x85,0x84,0x00,0x88,0x86,0x85,0x00,0x88,0x87,0x86,0x00,0x8a,0x88,0x87,0x00,0x8b,0x89,0x89,0x00, + 0x8c,0x8a,0x89,0x00,0x8d,0x8b,0x8a,0x00,0x8e,0x8d,0x8c,0x00,0x8f,0x8d,0x8d,0x00,0x90,0x8f,0x8f,0x00,0x92,0x90,0x90,0x00,0x92,0x91,0x91,0x00,0x94,0x92,0x92,0x00, + 0x95,0x93,0x94,0x00,0x96,0x95,0x95,0x00,0x98,0x96,0x96,0x00,0x99,0x97,0x97,0x00,0x9a,0x98,0x98,0x00,0x9b,0x99,0x99,0x00,0x9c,0x9a,0x9a,0x00,0x9d,0x9b,0x9b,0x00, + 0x9f,0x9d,0x9e,0x00,0xa0,0x9e,0x9f,0x00,0xa1,0x9f,0xa0,0x00,0xa3,0xa0,0xa1,0x00,0xa4,0xa1,0xa2,0x00,0xa5,0xa2,0xa2,0x00,0xa6,0xa3,0xa3,0x00,0xa7,0xa4,0xa4,0x00, + 0xa9,0xa6,0xa6,0x00,0xaa,0xa7,0xa6,0x00,0xac,0xa8,0xa8,0x00,0xac,0xa9,0xa9,0x00,0xae,0xab,0xab,0x00,0xaf,0xab,0xab,0x00,0xb0,0xad,0xae,0x00,0xb1,0xae,0xaf,0x00, + 0xb2,0xb0,0xb0,0x00,0xb3,0xb0,0xb1,0x00,0xb5,0xb1,0xb2,0x00,0xb5,0xb2,0xb3,0x00,0xb7,0xb4,0xb4,0x00,0xb8,0xb5,0xb4,0x00,0xb9,0xb6,0xb6,0x00,0xba,0xb7,0xb7,0x00, + 0xbb,0xb8,0xb8,0x00,0xbc,0xb9,0xb9,0x00,0xbd,0xbb,0xbb,0x00,0xbf,0xbb,0xbc,0x00,0xc0,0xbc,0xbd,0x00,0xc1,0xbd,0xbe,0x00,0xc2,0xbf,0xc0,0x00,0xc3,0xc0,0xc0,0x00, + 0xc5,0xc1,0xc1,0x00,0xc6,0xc3,0xc3,0x00,0xc7,0xc3,0xc4,0x00,0xc8,0xc4,0xc5,0x00,0xc9,0xc5,0xc6,0x00,0xca,0xc7,0xc7,0x00,0xcb,0xc8,0xc8,0x00,0xcc,0xc9,0xca,0x00, + 0xce,0xca,0xca,0x00,0xce,0xcb,0xcb,0x00,0xd0,0xcc,0xcd,0x00,0xd1,0xcd,0xce,0x00,0xd2,0xcf,0xcf,0x00,0xd3,0xcf,0xd0,0x00,0xd5,0xd1,0xd1,0x00,0xd6,0xd2,0xd2,0x00, + 0xd7,0xd3,0xd3,0x00,0xd8,0xd4,0xd4,0x00,0xda,0xd5,0xd5,0x00,0xda,0xd7,0xd6,0x00,0xdb,0xd8,0xd7,0x00,0xdd,0xd8,0xd8,0x00,0xde,0xda,0xda,0x00,0xdf,0xda,0xdb,0x00, + 0xe0,0xdb,0xdc,0x00,0xe2,0xdd,0xdd,0x00,0xe3,0xde,0xde,0x00,0xe4,0xdf,0xdf,0x00,0xe5,0xe0,0xe0,0x00,0xe6,0xe0,0xe1,0x00,0xe7,0xe2,0xe2,0x00,0xe9,0xe3,0xe4,0x00, + 0xea,0xe4,0xe4,0x00,0xeb,0xe5,0xe5,0x00,0xec,0xe6,0xe7,0x00,0xed,0xe7,0xe8,0x00,0xef,0xe8,0xe9,0x00,0xf0,0xea,0xea,0x00,0xf0,0xeb,0xeb,0x00,0xf1,0xec,0xec,0x00, + 0xf2,0xed,0xee,0x00,0xf3,0xee,0xef,0x00,0xf4,0xef,0xf0,0x00,0xf5,0xf0,0xf0,0x00,0xf6,0xf2,0xf2,0x00,0xf8,0xf2,0xf2,0x00,0xf9,0xf4,0xf4,0x00,0xf9,0xf5,0xf5,0x00, + 0xfb,0xf6,0xf6,0x00,0xfc,0xf7,0xf8,0x00,0xfd,0xf8,0xf8,0x00,0xff,0xf9,0xfa,0x00,0xff,0xfa,0xfa,0x00,0xff,0xfb,0xfc,0x00,0xff,0xfd,0xfd,0x00,0xff,0xfe,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x18,0x16,0x00,0x17,0x19,0x17,0x00,0x19,0x1a,0x18,0x00,0x1b,0x1b,0x19,0x00, + 0x1b,0x1c,0x1a,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00, + 0x25,0x24,0x23,0x00,0x26,0x26,0x24,0x00,0x27,0x27,0x26,0x00,0x29,0x28,0x28,0x00,0x29,0x29,0x28,0x00,0x2a,0x2b,0x2b,0x00,0x2b,0x2b,0x2b,0x00,0x2d,0x2d,0x2c,0x00, + 0x2d,0x2d,0x2c,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x2f,0x2f,0x00,0x31,0x31,0x30,0x00,0x32,0x32,0x32,0x00,0x33,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x36,0x36,0x35,0x00, + 0x37,0x37,0x37,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3e,0x3c,0x3c,0x00,0x3f,0x3e,0x3d,0x00,0x40,0x3f,0x3f,0x00, + 0x41,0x40,0x40,0x00,0x42,0x41,0x41,0x00,0x43,0x42,0x42,0x00,0x44,0x43,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x46,0x45,0x00,0x48,0x47,0x46,0x00,0x48,0x48,0x47,0x00, + 0x4a,0x49,0x48,0x00,0x4b,0x4a,0x49,0x00,0x4c,0x4b,0x4b,0x00,0x4d,0x4c,0x4b,0x00,0x4e,0x4d,0x4c,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x4f,0x4e,0x00,0x51,0x51,0x50,0x00, + 0x53,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x55,0x54,0x53,0x00,0x56,0x55,0x54,0x00,0x57,0x56,0x55,0x00,0x58,0x57,0x57,0x00,0x5a,0x59,0x57,0x00,0x5b,0x5b,0x59,0x00, + 0x5d,0x5c,0x5b,0x00,0x5e,0x5d,0x5c,0x00,0x5f,0x5f,0x5e,0x00,0x61,0x60,0x5f,0x00,0x63,0x62,0x61,0x00,0x64,0x63,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x66,0x65,0x00, + 0x68,0x67,0x66,0x00,0x69,0x68,0x67,0x00,0x6a,0x69,0x68,0x00,0x6b,0x6a,0x69,0x00,0x6c,0x6c,0x6a,0x00,0x6d,0x6d,0x6b,0x00,0x6e,0x6e,0x6c,0x00,0x70,0x6f,0x6e,0x00, + 0x71,0x70,0x6f,0x00,0x72,0x71,0x70,0x00,0x73,0x72,0x71,0x00,0x74,0x73,0x72,0x00,0x75,0x74,0x73,0x00,0x76,0x75,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x78,0x77,0x00, + 0x79,0x79,0x77,0x00,0x7b,0x7a,0x79,0x00,0x7c,0x7b,0x7a,0x00,0x7d,0x7c,0x7b,0x00,0x7e,0x7d,0x7c,0x00,0x7f,0x7e,0x7d,0x00,0x80,0x7f,0x7e,0x00,0x81,0x80,0x7f,0x00, + 0x82,0x82,0x80,0x00,0x83,0x82,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x8a,0x89,0x87,0x00, + 0x8b,0x8a,0x89,0x00,0x8c,0x8b,0x8a,0x00,0x8e,0x8d,0x8b,0x00,0x8f,0x8d,0x8d,0x00,0x90,0x8f,0x8e,0x00,0x91,0x90,0x8f,0x00,0x92,0x91,0x90,0x00,0x94,0x92,0x91,0x00, + 0x95,0x94,0x94,0x00,0x96,0x95,0x94,0x00,0x97,0x96,0x95,0x00,0x98,0x97,0x96,0x00,0x99,0x98,0x97,0x00,0x9b,0x99,0x98,0x00,0x9c,0x9a,0x99,0x00,0x9e,0x9b,0x9b,0x00, + 0x9f,0x9d,0x9c,0x00,0xa0,0x9e,0x9d,0x00,0xa1,0x9f,0x9e,0x00,0xa2,0xa0,0x9f,0x00,0xa3,0xa2,0xa1,0x00,0xa4,0xa2,0xa2,0x00,0xa5,0xa4,0xa3,0x00,0xa6,0xa4,0xa4,0x00, + 0xa8,0xa6,0xa6,0x00,0xa8,0xa7,0xa7,0x00,0xaa,0xa8,0xa8,0x00,0xab,0xa9,0xa9,0x00,0xac,0xab,0xab,0x00,0xad,0xab,0xab,0x00,0xb0,0xad,0xad,0x00,0xb0,0xae,0xae,0x00, + 0xb2,0xaf,0xaf,0x00,0xb3,0xb0,0xb0,0x00,0xb4,0xb2,0xb2,0x00,0xb5,0xb3,0xb2,0x00,0xb7,0xb4,0xb3,0x00,0xb8,0xb5,0xb5,0x00,0xb9,0xb6,0xb6,0x00,0xba,0xb7,0xb7,0x00, + 0xbb,0xb8,0xb8,0x00,0xbb,0xb9,0xb9,0x00,0xbc,0xba,0xba,0x00,0xbe,0xbb,0xbb,0x00,0xc0,0xbd,0xbc,0x00,0xc1,0xbe,0xbc,0x00,0xc2,0xbf,0xbf,0x00,0xc3,0xc0,0xc0,0x00, + 0xc4,0xc1,0xc1,0x00,0xc5,0xc2,0xc2,0x00,0xc7,0xc3,0xc3,0x00,0xc7,0xc4,0xc4,0x00,0xc9,0xc6,0xc5,0x00,0xca,0xc7,0xc6,0x00,0xcb,0xc8,0xc7,0x00,0xcc,0xc9,0xc9,0x00, + 0xce,0xca,0xca,0x00,0xce,0xcb,0xcb,0x00,0xd0,0xcc,0xcc,0x00,0xd0,0xcd,0xcd,0x00,0xd2,0xcf,0xce,0x00,0xd3,0xcf,0xcf,0x00,0xd4,0xd1,0xd0,0x00,0xd5,0xd2,0xd2,0x00, + 0xd6,0xd3,0xd3,0x00,0xd8,0xd4,0xd4,0x00,0xd9,0xd5,0xd5,0x00,0xdb,0xd6,0xd6,0x00,0xdc,0xd7,0xd8,0x00,0xdd,0xd9,0xd9,0x00,0xde,0xda,0xd9,0x00,0xde,0xda,0xda,0x00, + 0xe0,0xdc,0xdb,0x00,0xe1,0xdd,0xdc,0x00,0xe2,0xde,0xdd,0x00,0xe3,0xdf,0xdf,0x00,0xe4,0xe0,0xdf,0x00,0xe5,0xe1,0xe0,0x00,0xe6,0xe2,0xe1,0x00,0xe7,0xe3,0xe3,0x00, + 0xe8,0xe4,0xe4,0x00,0xe9,0xe5,0xe4,0x00,0xeb,0xe6,0xe6,0x00,0xeb,0xe7,0xe6,0x00,0xed,0xe9,0xe8,0x00,0xee,0xea,0xe8,0x00,0xef,0xeb,0xea,0x00,0xf0,0xec,0xeb,0x00, + 0xf1,0xee,0xec,0x00,0xf3,0xee,0xed,0x00,0xf4,0xf0,0xef,0x00,0xf5,0xf1,0xef,0x00,0xf6,0xf2,0xf1,0x00,0xf8,0xf3,0xf1,0x00,0xf8,0xf4,0xf2,0x00,0xf9,0xf5,0xf4,0x00, + 0xfb,0xf6,0xf5,0x00,0xfc,0xf7,0xf6,0x00,0xfd,0xf8,0xf7,0x00,0xfe,0xfa,0xf8,0x00,0xff,0xfb,0xf9,0x00,0xff,0xfc,0xfb,0x00,0xff,0xfd,0xfc,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x17,0x16,0x00,0x17,0x19,0x16,0x00,0x18,0x1a,0x18,0x00,0x1b,0x1b,0x19,0x00, + 0x1c,0x1c,0x1a,0x00,0x1d,0x1d,0x1b,0x00,0x1e,0x1e,0x1c,0x00,0x1f,0x1f,0x1d,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x20,0x00,0x23,0x23,0x22,0x00, + 0x24,0x24,0x23,0x00,0x26,0x26,0x24,0x00,0x26,0x27,0x26,0x00,0x28,0x28,0x28,0x00,0x28,0x29,0x28,0x00,0x2b,0x2b,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2c,0x2c,0x2c,0x00, + 0x2d,0x2d,0x2d,0x00,0x2f,0x2f,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x31,0x30,0x00,0x33,0x32,0x31,0x00,0x34,0x33,0x32,0x00,0x35,0x34,0x33,0x00,0x36,0x36,0x35,0x00, + 0x38,0x37,0x36,0x00,0x39,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3c,0x3b,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00,0x3e,0x3d,0x3d,0x00,0x40,0x3f,0x3e,0x00, + 0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x44,0x00,0x46,0x45,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x47,0x47,0x00, + 0x4a,0x49,0x47,0x00,0x4b,0x4a,0x49,0x00,0x4c,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4e,0x4d,0x4c,0x00,0x4f,0x4e,0x4d,0x00,0x50,0x4f,0x4e,0x00,0x51,0x51,0x50,0x00, + 0x52,0x52,0x51,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x53,0x00,0x56,0x55,0x54,0x00,0x57,0x56,0x55,0x00,0x58,0x57,0x56,0x00,0x5a,0x59,0x57,0x00,0x5b,0x5a,0x58,0x00, + 0x5c,0x5c,0x5a,0x00,0x5e,0x5d,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x61,0x60,0x5e,0x00,0x62,0x62,0x60,0x00,0x63,0x63,0x62,0x00,0x65,0x64,0x63,0x00,0x66,0x66,0x64,0x00, + 0x68,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x6a,0x69,0x67,0x00,0x6b,0x6a,0x68,0x00,0x6c,0x6b,0x6a,0x00,0x6d,0x6c,0x6a,0x00,0x6e,0x6d,0x6c,0x00,0x6f,0x6e,0x6c,0x00, + 0x70,0x70,0x6e,0x00,0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x73,0x71,0x00,0x75,0x74,0x73,0x00,0x76,0x75,0x73,0x00,0x77,0x76,0x74,0x00,0x78,0x77,0x76,0x00, + 0x79,0x78,0x77,0x00,0x7a,0x79,0x78,0x00,0x7c,0x7b,0x79,0x00,0x7d,0x7c,0x7a,0x00,0x7e,0x7d,0x7b,0x00,0x7f,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7f,0x00, + 0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x84,0x83,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x87,0x87,0x00,0x8a,0x89,0x88,0x00, + 0x8b,0x8a,0x89,0x00,0x8c,0x8b,0x89,0x00,0x8e,0x8c,0x8b,0x00,0x8f,0x8d,0x8c,0x00,0x90,0x8f,0x8d,0x00,0x91,0x90,0x8e,0x00,0x92,0x91,0x8f,0x00,0x93,0x92,0x91,0x00, + 0x95,0x93,0x92,0x00,0x96,0x95,0x93,0x00,0x97,0x95,0x94,0x00,0x98,0x96,0x95,0x00,0x99,0x98,0x97,0x00,0x9a,0x99,0x97,0x00,0x9c,0x9a,0x99,0x00,0x9e,0x9b,0x9a,0x00, + 0x9f,0x9d,0x9b,0x00,0x9f,0x9d,0x9c,0x00,0xa1,0x9f,0x9d,0x00,0xa2,0xa0,0x9e,0x00,0xa3,0xa1,0xa0,0x00,0xa3,0xa2,0xa1,0x00,0xa5,0xa3,0xa2,0x00,0xa6,0xa4,0xa4,0x00, + 0xa7,0xa6,0xa5,0x00,0xa8,0xa6,0xa6,0x00,0xaa,0xa8,0xa7,0x00,0xab,0xa9,0xa8,0x00,0xac,0xaa,0xa9,0x00,0xad,0xab,0xab,0x00,0xaf,0xad,0xac,0x00,0xb0,0xae,0xad,0x00, + 0xb2,0xaf,0xae,0x00,0xb2,0xb0,0xaf,0x00,0xb4,0xb1,0xb0,0x00,0xb5,0xb3,0xb1,0x00,0xb6,0xb3,0xb3,0x00,0xb7,0xb4,0xb4,0x00,0xb8,0xb6,0xb5,0x00,0xb8,0xb6,0xb6,0x00, + 0xbb,0xb8,0xb7,0x00,0xbc,0xb9,0xb8,0x00,0xbd,0xba,0xba,0x00,0xbe,0xbb,0xba,0x00,0xbf,0xbc,0xbb,0x00,0xc0,0xbd,0xbc,0x00,0xc1,0xbf,0xbe,0x00,0xc3,0xbf,0xbf,0x00, + 0xc4,0xc0,0xc0,0x00,0xc4,0xc2,0xc1,0x00,0xc6,0xc3,0xc2,0x00,0xc7,0xc4,0xc3,0x00,0xc8,0xc5,0xc4,0x00,0xc9,0xc6,0xc5,0x00,0xca,0xc8,0xc7,0x00,0xcb,0xc9,0xc7,0x00, + 0xcd,0xca,0xc9,0x00,0xce,0xcb,0xca,0x00,0xcf,0xcc,0xcb,0x00,0xd0,0xcd,0xcb,0x00,0xd1,0xce,0xcd,0x00,0xd3,0xcf,0xce,0x00,0xd4,0xd0,0xd0,0x00,0xd5,0xd2,0xd0,0x00, + 0xd6,0xd2,0xd1,0x00,0xd7,0xd3,0xd3,0x00,0xd9,0xd4,0xd4,0x00,0xda,0xd6,0xd5,0x00,0xdb,0xd7,0xd6,0x00,0xdb,0xd8,0xd8,0x00,0xdd,0xd9,0xd8,0x00,0xde,0xda,0xd9,0x00, + 0xdf,0xdc,0xda,0x00,0xe0,0xdc,0xdb,0x00,0xe2,0xde,0xdc,0x00,0xe3,0xde,0xdd,0x00,0xe4,0xe0,0xde,0x00,0xe5,0xe0,0xdf,0x00,0xe7,0xe2,0xe1,0x00,0xe7,0xe3,0xe1,0x00, + 0xe9,0xe4,0xe3,0x00,0xea,0xe5,0xe3,0x00,0xeb,0xe6,0xe4,0x00,0xec,0xe7,0xe4,0x00,0xee,0xe9,0xe6,0x00,0xef,0xe9,0xe7,0x00,0xf0,0xeb,0xe8,0x00,0xf1,0xeb,0xe9,0x00, + 0xf2,0xed,0xea,0x00,0xf3,0xee,0xeb,0x00,0xf4,0xef,0xed,0x00,0xf5,0xf0,0xee,0x00,0xf7,0xf1,0xef,0x00,0xf8,0xf2,0xf0,0x00,0xf9,0xf3,0xf1,0x00,0xfb,0xf5,0xf2,0x00, + 0xfb,0xf6,0xf4,0x00,0xfc,0xf7,0xf5,0x00,0xfe,0xf8,0xf6,0x00,0xff,0xf9,0xf7,0x00,0xff,0xfa,0xf8,0x00,0xff,0xfc,0xf9,0x00,0xff,0xfc,0xfb,0x00,0xff,0xfd,0xfb,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x17,0x16,0x00,0x17,0x18,0x16,0x00,0x18,0x19,0x17,0x00,0x1a,0x1a,0x19,0x00, + 0x1c,0x1c,0x1a,0x00,0x1d,0x1d,0x1b,0x00,0x1e,0x1e,0x1c,0x00,0x1f,0x1f,0x1d,0x00,0x20,0x20,0x1e,0x00,0x20,0x21,0x1f,0x00,0x22,0x22,0x20,0x00,0x23,0x23,0x21,0x00, + 0x24,0x24,0x23,0x00,0x26,0x25,0x24,0x00,0x27,0x26,0x25,0x00,0x28,0x28,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2d,0x2c,0x2b,0x00, + 0x2d,0x2c,0x2c,0x00,0x2e,0x2e,0x2d,0x00,0x2f,0x2f,0x2e,0x00,0x31,0x30,0x30,0x00,0x31,0x32,0x30,0x00,0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x36,0x35,0x34,0x00, + 0x37,0x37,0x35,0x00,0x39,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3b,0x00,0x3e,0x3d,0x3c,0x00,0x40,0x3f,0x3d,0x00, + 0x41,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x46,0x45,0x00,0x48,0x47,0x46,0x00, + 0x49,0x48,0x47,0x00,0x4a,0x4a,0x48,0x00,0x4c,0x4b,0x4a,0x00,0x4c,0x4c,0x4a,0x00,0x4d,0x4d,0x4b,0x00,0x4e,0x4e,0x4d,0x00,0x50,0x4f,0x4e,0x00,0x51,0x50,0x4f,0x00, + 0x52,0x51,0x50,0x00,0x53,0x52,0x51,0x00,0x54,0x53,0x52,0x00,0x55,0x55,0x53,0x00,0x57,0x56,0x54,0x00,0x58,0x57,0x55,0x00,0x59,0x59,0x57,0x00,0x5b,0x5a,0x58,0x00, + 0x5c,0x5b,0x59,0x00,0x5d,0x5c,0x5b,0x00,0x5f,0x5e,0x5c,0x00,0x60,0x60,0x5e,0x00,0x62,0x61,0x5f,0x00,0x63,0x63,0x60,0x00,0x64,0x64,0x62,0x00,0x66,0x65,0x63,0x00, + 0x68,0x67,0x65,0x00,0x68,0x68,0x65,0x00,0x69,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00,0x6c,0x6b,0x69,0x00,0x6d,0x6c,0x6a,0x00,0x6e,0x6d,0x6b,0x00,0x6f,0x6e,0x6c,0x00, + 0x70,0x6f,0x6d,0x00,0x71,0x70,0x6e,0x00,0x72,0x72,0x6f,0x00,0x73,0x73,0x70,0x00,0x75,0x74,0x72,0x00,0x76,0x74,0x73,0x00,0x76,0x76,0x74,0x00,0x78,0x77,0x75,0x00, + 0x79,0x78,0x76,0x00,0x7a,0x79,0x77,0x00,0x7b,0x7a,0x78,0x00,0x7c,0x7b,0x79,0x00,0x7e,0x7d,0x7b,0x00,0x7e,0x7d,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x81,0x80,0x7e,0x00, + 0x82,0x80,0x7f,0x00,0x83,0x82,0x81,0x00,0x84,0x83,0x81,0x00,0x85,0x84,0x83,0x00,0x87,0x85,0x84,0x00,0x87,0x86,0x85,0x00,0x89,0x87,0x86,0x00,0x8a,0x88,0x87,0x00, + 0x8b,0x89,0x88,0x00,0x8c,0x8b,0x89,0x00,0x8d,0x8c,0x8b,0x00,0x8e,0x8d,0x8b,0x00,0x90,0x8e,0x8c,0x00,0x91,0x8f,0x8d,0x00,0x92,0x90,0x8f,0x00,0x93,0x91,0x90,0x00, + 0x95,0x93,0x91,0x00,0x95,0x94,0x92,0x00,0x97,0x95,0x93,0x00,0x97,0x96,0x94,0x00,0x98,0x97,0x96,0x00,0x9a,0x98,0x96,0x00,0x9b,0x9a,0x98,0x00,0x9d,0x9b,0x99,0x00, + 0x9f,0x9c,0x9a,0x00,0x9f,0x9d,0x9b,0x00,0xa0,0x9e,0x9c,0x00,0xa2,0x9f,0x9d,0x00,0xa3,0xa0,0x9f,0x00,0xa3,0xa1,0xa0,0x00,0xa4,0xa3,0xa2,0x00,0xa5,0xa4,0xa3,0x00, + 0xa7,0xa5,0xa4,0x00,0xa8,0xa6,0xa5,0x00,0xa9,0xa7,0xa6,0x00,0xaa,0xa9,0xa8,0x00,0xac,0xaa,0xa9,0x00,0xad,0xab,0xaa,0x00,0xaf,0xac,0xab,0x00,0xb0,0xae,0xac,0x00, + 0xb1,0xaf,0xad,0x00,0xb2,0xb0,0xae,0x00,0xb3,0xb1,0xb0,0x00,0xb5,0xb2,0xb0,0x00,0xb6,0xb3,0xb2,0x00,0xb6,0xb4,0xb3,0x00,0xb8,0xb5,0xb4,0x00,0xb8,0xb6,0xb5,0x00, + 0xbb,0xb8,0xb6,0x00,0xbc,0xb8,0xb7,0x00,0xbd,0xba,0xb8,0x00,0xbe,0xbb,0xba,0x00,0xbf,0xbc,0xba,0x00,0xc0,0xbd,0xbb,0x00,0xc1,0xbf,0xbc,0x00,0xc2,0xbf,0xbe,0x00, + 0xc4,0xc0,0xbf,0x00,0xc5,0xc2,0xc0,0x00,0xc6,0xc3,0xc1,0x00,0xc7,0xc4,0xc2,0x00,0xc8,0xc5,0xc3,0x00,0xc9,0xc6,0xc4,0x00,0xca,0xc7,0xc6,0x00,0xcb,0xc8,0xc7,0x00, + 0xcd,0xca,0xc8,0x00,0xcd,0xca,0xc9,0x00,0xcf,0xcb,0xca,0x00,0xd0,0xcc,0xcb,0x00,0xd1,0xcd,0xcc,0x00,0xd2,0xcf,0xcd,0x00,0xd3,0xd0,0xcf,0x00,0xd5,0xd1,0xcf,0x00, + 0xd6,0xd2,0xd0,0x00,0xd7,0xd4,0xd1,0x00,0xd8,0xd4,0xd3,0x00,0xd9,0xd5,0xd4,0x00,0xda,0xd7,0xd6,0x00,0xdb,0xd8,0xd6,0x00,0xdd,0xd9,0xd7,0x00,0xde,0xda,0xd8,0x00, + 0xdf,0xdb,0xd9,0x00,0xe0,0xdc,0xdb,0x00,0xe1,0xde,0xdc,0x00,0xe3,0xdf,0xdd,0x00,0xe4,0xe0,0xde,0x00,0xe5,0xe0,0xde,0x00,0xe6,0xe2,0xe0,0x00,0xe7,0xe3,0xe1,0x00, + 0xe9,0xe4,0xe2,0x00,0xe9,0xe4,0xe3,0x00,0xeb,0xe6,0xe4,0x00,0xec,0xe7,0xe4,0x00,0xee,0xe8,0xe6,0x00,0xee,0xe9,0xe7,0x00,0xef,0xeb,0xe8,0x00,0xf0,0xeb,0xe9,0x00, + 0xf2,0xec,0xeb,0x00,0xf3,0xee,0xeb,0x00,0xf4,0xef,0xec,0x00,0xf5,0xf0,0xed,0x00,0xf6,0xf1,0xef,0x00,0xf7,0xf2,0xf0,0x00,0xf8,0xf3,0xf1,0x00,0xf9,0xf5,0xf3,0x00, + 0xfb,0xf5,0xf4,0x00,0xfc,0xf7,0xf5,0x00,0xfd,0xf8,0xf6,0x00,0xfe,0xf9,0xf7,0x00,0xff,0xfa,0xf9,0x00,0xff,0xfb,0xfa,0x00,0xff,0xfc,0xfa,0x00,0xff,0xfd,0xfb,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x16,0x17,0x15,0x00,0x17,0x18,0x16,0x00,0x18,0x19,0x17,0x00,0x19,0x1a,0x18,0x00, + 0x1b,0x1b,0x19,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x20,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x22,0x22,0x20,0x00,0x22,0x22,0x21,0x00, + 0x24,0x24,0x22,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x25,0x00,0x28,0x28,0x26,0x00,0x28,0x28,0x27,0x00,0x2b,0x2a,0x29,0x00,0x2b,0x2b,0x29,0x00,0x2c,0x2c,0x2b,0x00, + 0x2c,0x2c,0x2b,0x00,0x2f,0x2f,0x2e,0x00,0x2f,0x2f,0x2e,0x00,0x30,0x30,0x2f,0x00,0x32,0x32,0x31,0x00,0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x34,0x00, + 0x37,0x37,0x36,0x00,0x38,0x37,0x36,0x00,0x39,0x38,0x37,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3b,0x00,0x3e,0x3d,0x3c,0x00,0x40,0x3e,0x3d,0x00, + 0x41,0x40,0x3e,0x00,0x41,0x41,0x3f,0x00,0x42,0x41,0x40,0x00,0x44,0x43,0x41,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x46,0x45,0x00,0x47,0x47,0x46,0x00, + 0x49,0x48,0x47,0x00,0x4a,0x49,0x48,0x00,0x4b,0x4b,0x49,0x00,0x4c,0x4b,0x4a,0x00,0x4d,0x4c,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4f,0x4d,0x00,0x51,0x50,0x4e,0x00, + 0x52,0x51,0x4f,0x00,0x52,0x52,0x51,0x00,0x54,0x53,0x52,0x00,0x55,0x55,0x53,0x00,0x56,0x56,0x54,0x00,0x57,0x57,0x55,0x00,0x59,0x58,0x56,0x00,0x5a,0x5a,0x57,0x00, + 0x5c,0x5b,0x59,0x00,0x5d,0x5d,0x5a,0x00,0x5e,0x5e,0x5c,0x00,0x60,0x5f,0x5d,0x00,0x61,0x60,0x5f,0x00,0x62,0x62,0x60,0x00,0x64,0x64,0x61,0x00,0x65,0x65,0x63,0x00, + 0x66,0x67,0x64,0x00,0x68,0x67,0x65,0x00,0x69,0x68,0x66,0x00,0x6a,0x6a,0x67,0x00,0x6b,0x6a,0x68,0x00,0x6c,0x6c,0x69,0x00,0x6d,0x6d,0x6b,0x00,0x6e,0x6e,0x6c,0x00, + 0x70,0x6f,0x6c,0x00,0x71,0x70,0x6e,0x00,0x72,0x71,0x6f,0x00,0x73,0x72,0x70,0x00,0x74,0x73,0x71,0x00,0x75,0x74,0x72,0x00,0x76,0x76,0x73,0x00,0x77,0x76,0x74,0x00, + 0x78,0x78,0x75,0x00,0x7a,0x79,0x77,0x00,0x7b,0x7a,0x78,0x00,0x7c,0x7b,0x79,0x00,0x7d,0x7c,0x7a,0x00,0x7e,0x7d,0x7b,0x00,0x7f,0x7e,0x7c,0x00,0x80,0x7f,0x7d,0x00, + 0x81,0x80,0x7f,0x00,0x82,0x81,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x86,0x85,0x83,0x00,0x87,0x86,0x84,0x00,0x89,0x87,0x86,0x00,0x8a,0x88,0x87,0x00, + 0x8b,0x89,0x88,0x00,0x8b,0x8a,0x89,0x00,0x8d,0x8b,0x8a,0x00,0x8e,0x8c,0x8b,0x00,0x8f,0x8e,0x8c,0x00,0x91,0x8f,0x8d,0x00,0x91,0x90,0x8e,0x00,0x92,0x91,0x8f,0x00, + 0x94,0x93,0x90,0x00,0x95,0x94,0x91,0x00,0x96,0x95,0x92,0x00,0x97,0x96,0x93,0x00,0x98,0x97,0x95,0x00,0x99,0x98,0x96,0x00,0x9b,0x99,0x97,0x00,0x9c,0x9a,0x98,0x00, + 0x9e,0x9c,0x9a,0x00,0x9f,0x9d,0x9b,0x00,0xa0,0x9e,0x9d,0x00,0xa1,0x9f,0x9e,0x00,0xa2,0xa0,0x9f,0x00,0xa2,0xa1,0x9f,0x00,0xa4,0xa3,0xa0,0x00,0xa5,0xa4,0xa1,0x00, + 0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa4,0x00,0xa9,0xa7,0xa5,0x00,0xaa,0xa8,0xa6,0x00,0xac,0xaa,0xa7,0x00,0xac,0xaa,0xa9,0x00,0xae,0xac,0xaa,0x00,0xaf,0xad,0xab,0x00, + 0xb0,0xae,0xad,0x00,0xb1,0xb0,0xad,0x00,0xb3,0xb0,0xaf,0x00,0xb4,0xb2,0xb0,0x00,0xb5,0xb3,0xb1,0x00,0xb5,0xb4,0xb1,0x00,0xb7,0xb5,0xb3,0x00,0xb8,0xb5,0xb3,0x00, + 0xba,0xb7,0xb5,0x00,0xbb,0xb8,0xb6,0x00,0xbc,0xba,0xb7,0x00,0xbe,0xba,0xb9,0x00,0xbe,0xbc,0xba,0x00,0xbf,0xbc,0xbb,0x00,0xc1,0xbe,0xbc,0x00,0xc1,0xbf,0xbd,0x00, + 0xc3,0xc0,0xbe,0x00,0xc4,0xc1,0xbf,0x00,0xc5,0xc2,0xc1,0x00,0xc6,0xc3,0xc2,0x00,0xc7,0xc4,0xc3,0x00,0xc8,0xc6,0xc4,0x00,0xc9,0xc7,0xc5,0x00,0xcb,0xc8,0xc6,0x00, + 0xcc,0xc9,0xc7,0x00,0xcd,0xca,0xc8,0x00,0xce,0xcb,0xc9,0x00,0xcf,0xcc,0xca,0x00,0xd0,0xce,0xcc,0x00,0xd2,0xce,0xcc,0x00,0xd3,0xd0,0xce,0x00,0xd4,0xd1,0xcf,0x00, + 0xd5,0xd2,0xd0,0x00,0xd6,0xd3,0xd1,0x00,0xd7,0xd4,0xd2,0x00,0xd8,0xd6,0xd3,0x00,0xda,0xd6,0xd4,0x00,0xdb,0xd7,0xd5,0x00,0xdc,0xd9,0xd7,0x00,0xdd,0xd9,0xd8,0x00, + 0xde,0xdb,0xd8,0x00,0xdf,0xdc,0xda,0x00,0xe1,0xdd,0xdb,0x00,0xe2,0xde,0xdc,0x00,0xe3,0xdf,0xdd,0x00,0xe4,0xe0,0xde,0x00,0xe4,0xe1,0xdf,0x00,0xe6,0xe2,0xe0,0x00, + 0xe6,0xe4,0xe1,0x00,0xe8,0xe4,0xe2,0x00,0xe9,0xe5,0xe3,0x00,0xeb,0xe6,0xe4,0x00,0xec,0xe8,0xe5,0x00,0xec,0xe9,0xe6,0x00,0xee,0xea,0xe7,0x00,0xef,0xeb,0xe8,0x00, + 0xf0,0xec,0xe9,0x00,0xf1,0xee,0xea,0x00,0xf2,0xee,0xec,0x00,0xf3,0xef,0xed,0x00,0xf4,0xf0,0xed,0x00,0xf5,0xf2,0xee,0x00,0xf7,0xf3,0xf0,0x00,0xf9,0xf4,0xf3,0x00, + 0xfa,0xf5,0xf3,0x00,0xfb,0xf6,0xf4,0x00,0xfc,0xf7,0xf5,0x00,0xfd,0xf8,0xf6,0x00,0xfe,0xf9,0xf8,0x00,0xff,0xfb,0xf9,0x00,0xff,0xfc,0xf9,0x00,0xff,0xfd,0xfb,0x00, + 0xff,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x16,0x15,0x00,0x17,0x18,0x16,0x00,0x18,0x19,0x17,0x00,0x1a,0x1a,0x18,0x00, + 0x1b,0x1b,0x19,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00, + 0x24,0x23,0x22,0x00,0x25,0x25,0x23,0x00,0x25,0x26,0x25,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x2a,0x2a,0x29,0x00,0x2a,0x2a,0x29,0x00,0x2c,0x2c,0x2b,0x00, + 0x2c,0x2c,0x2b,0x00,0x2e,0x2e,0x2d,0x00,0x2f,0x2f,0x2d,0x00,0x30,0x30,0x2f,0x00,0x32,0x32,0x30,0x00,0x33,0x33,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x35,0x33,0x00, + 0x37,0x36,0x36,0x00,0x38,0x37,0x36,0x00,0x39,0x38,0x37,0x00,0x3b,0x3a,0x38,0x00,0x3b,0x3b,0x39,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3f,0x3e,0x3d,0x00, + 0x40,0x3f,0x3e,0x00,0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x44,0x42,0x00,0x45,0x45,0x43,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x45,0x00, + 0x48,0x48,0x46,0x00,0x4a,0x49,0x47,0x00,0x4b,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4e,0x4d,0x00,0x50,0x50,0x4e,0x00, + 0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x51,0x00,0x55,0x54,0x53,0x00,0x56,0x55,0x54,0x00,0x57,0x56,0x55,0x00,0x58,0x58,0x56,0x00,0x5a,0x59,0x57,0x00, + 0x5b,0x5b,0x58,0x00,0x5d,0x5c,0x5a,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x61,0x60,0x5e,0x00,0x62,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x65,0x64,0x62,0x00, + 0x66,0x66,0x64,0x00,0x67,0x67,0x64,0x00,0x68,0x68,0x66,0x00,0x69,0x69,0x67,0x00,0x6b,0x6a,0x68,0x00,0x6c,0x6b,0x69,0x00,0x6c,0x6c,0x6a,0x00,0x6e,0x6d,0x6b,0x00, + 0x6f,0x6f,0x6c,0x00,0x70,0x70,0x6d,0x00,0x71,0x71,0x6e,0x00,0x72,0x72,0x70,0x00,0x73,0x73,0x71,0x00,0x74,0x74,0x72,0x00,0x75,0x75,0x73,0x00,0x76,0x77,0x74,0x00, + 0x78,0x77,0x75,0x00,0x79,0x78,0x76,0x00,0x7a,0x7a,0x77,0x00,0x7b,0x7b,0x78,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7f,0x7e,0x7c,0x00,0x80,0x7f,0x7d,0x00, + 0x81,0x80,0x7e,0x00,0x82,0x81,0x7f,0x00,0x83,0x82,0x81,0x00,0x84,0x83,0x82,0x00,0x85,0x85,0x83,0x00,0x87,0x86,0x84,0x00,0x88,0x86,0x85,0x00,0x89,0x88,0x86,0x00, + 0x8a,0x89,0x87,0x00,0x8b,0x8a,0x88,0x00,0x8c,0x8b,0x89,0x00,0x8d,0x8c,0x8a,0x00,0x8f,0x8d,0x8c,0x00,0x90,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x92,0x91,0x8f,0x00, + 0x93,0x92,0x90,0x00,0x94,0x93,0x91,0x00,0x95,0x95,0x92,0x00,0x96,0x95,0x93,0x00,0x98,0x96,0x95,0x00,0x99,0x98,0x95,0x00,0x9a,0x99,0x97,0x00,0x9b,0x9a,0x98,0x00, + 0x9d,0x9b,0x99,0x00,0x9d,0x9c,0x9a,0x00,0x9f,0x9e,0x9b,0x00,0xa0,0x9f,0x9e,0x00,0xa1,0xa0,0x9f,0x00,0xa3,0xa1,0x9f,0x00,0xa4,0xa2,0xa0,0x00,0xa5,0xa3,0xa0,0x00, + 0xa7,0xa5,0xa2,0x00,0xa7,0xa5,0xa3,0x00,0xa9,0xa7,0xa4,0x00,0xaa,0xa8,0xa5,0x00,0xab,0xa9,0xa7,0x00,0xad,0xaa,0xa7,0x00,0xae,0xac,0xaa,0x00,0xaf,0xad,0xab,0x00, + 0xb0,0xae,0xad,0x00,0xb1,0xaf,0xad,0x00,0xb2,0xb0,0xae,0x00,0xb3,0xb1,0xaf,0x00,0xb5,0xb3,0xb1,0x00,0xb6,0xb3,0xb1,0x00,0xb7,0xb4,0xb2,0x00,0xb8,0xb5,0xb3,0x00, + 0xb9,0xb7,0xb5,0x00,0xba,0xb8,0xb6,0x00,0xbb,0xb9,0xb7,0x00,0xbc,0xba,0xb8,0x00,0xbe,0xbb,0xb9,0x00,0xbe,0xbc,0xbb,0x00,0xc0,0xbd,0xbc,0x00,0xc1,0xbf,0xbd,0x00, + 0xc2,0xc0,0xbe,0x00,0xc3,0xc1,0xbf,0x00,0xc5,0xc2,0xc0,0x00,0xc5,0xc3,0xc1,0x00,0xc7,0xc5,0xc2,0x00,0xc8,0xc5,0xc3,0x00,0xc9,0xc6,0xc5,0x00,0xca,0xc7,0xc6,0x00, + 0xcb,0xc9,0xc7,0x00,0xcc,0xca,0xc8,0x00,0xce,0xcb,0xc9,0x00,0xcf,0xcb,0xca,0x00,0xcf,0xcd,0xcb,0x00,0xd0,0xce,0xcc,0x00,0xd2,0xcf,0xcd,0x00,0xd3,0xd0,0xce,0x00, + 0xd4,0xd2,0xd0,0x00,0xd5,0xd2,0xd0,0x00,0xd7,0xd4,0xd2,0x00,0xd9,0xd5,0xd2,0x00,0xda,0xd6,0xd3,0x00,0xdb,0xd7,0xd4,0x00,0xdb,0xd8,0xd6,0x00,0xdc,0xd9,0xd7,0x00, + 0xde,0xdb,0xd8,0x00,0xdf,0xdb,0xd9,0x00,0xe0,0xdd,0xda,0x00,0xe1,0xdd,0xdb,0x00,0xe2,0xdf,0xdc,0x00,0xe3,0xdf,0xdd,0x00,0xe4,0xe1,0xdf,0x00,0xe5,0xe2,0xe0,0x00, + 0xe6,0xe3,0xe1,0x00,0xe7,0xe4,0xe1,0x00,0xe8,0xe5,0xe3,0x00,0xe9,0xe6,0xe3,0x00,0xeb,0xe8,0xe5,0x00,0xec,0xe8,0xe6,0x00,0xed,0xea,0xe7,0x00,0xee,0xeb,0xe7,0x00, + 0xef,0xec,0xe9,0x00,0xf0,0xec,0xea,0x00,0xf1,0xee,0xea,0x00,0xf3,0xef,0xec,0x00,0xf4,0xf0,0xed,0x00,0xf5,0xf2,0xee,0x00,0xf6,0xf2,0xef,0x00,0xf7,0xf3,0xf1,0x00, + 0xf8,0xf5,0xf2,0x00,0xfa,0xf6,0xf4,0x00,0xfb,0xf7,0xf5,0x00,0xfb,0xf8,0xf6,0x00,0xfd,0xf9,0xf7,0x00,0xfe,0xfb,0xf8,0x00,0xff,0xfb,0xf9,0x00,0xff,0xfc,0xfa,0x00, + 0xff,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x16,0x15,0x00,0x17,0x17,0x15,0x00,0x17,0x18,0x17,0x00,0x19,0x1a,0x18,0x00, + 0x1a,0x1a,0x19,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1b,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00,0x22,0x22,0x21,0x00, + 0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x27,0x27,0x26,0x00,0x28,0x28,0x27,0x00,0x2a,0x29,0x29,0x00,0x2a,0x2a,0x29,0x00,0x2c,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2b,0x00,0x2e,0x2d,0x2d,0x00,0x2e,0x2e,0x2d,0x00,0x2f,0x30,0x2f,0x00,0x32,0x31,0x30,0x00,0x33,0x32,0x32,0x00,0x33,0x33,0x32,0x00,0x35,0x34,0x33,0x00, + 0x37,0x36,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x3b,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3b,0x00,0x3f,0x3d,0x3d,0x00, + 0x40,0x3f,0x3d,0x00,0x41,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x44,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x46,0x44,0x00,0x47,0x46,0x45,0x00, + 0x48,0x47,0x46,0x00,0x49,0x49,0x47,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4e,0x4d,0x4c,0x00,0x4f,0x4e,0x4d,0x00,0x50,0x50,0x4e,0x00, + 0x51,0x50,0x4f,0x00,0x52,0x51,0x50,0x00,0x53,0x53,0x51,0x00,0x54,0x54,0x52,0x00,0x55,0x55,0x53,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x59,0x59,0x57,0x00, + 0x5b,0x5a,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5e,0x5d,0x5b,0x00,0x5f,0x5f,0x5c,0x00,0x60,0x60,0x5e,0x00,0x62,0x62,0x5f,0x00,0x63,0x63,0x61,0x00,0x64,0x64,0x62,0x00, + 0x66,0x66,0x64,0x00,0x67,0x66,0x64,0x00,0x68,0x68,0x65,0x00,0x69,0x68,0x66,0x00,0x6a,0x6a,0x67,0x00,0x6b,0x6b,0x68,0x00,0x6c,0x6c,0x69,0x00,0x6d,0x6d,0x6b,0x00, + 0x6f,0x6e,0x6c,0x00,0x6f,0x6f,0x6d,0x00,0x71,0x71,0x6e,0x00,0x72,0x71,0x6f,0x00,0x73,0x73,0x70,0x00,0x74,0x74,0x71,0x00,0x75,0x75,0x72,0x00,0x76,0x76,0x74,0x00, + 0x77,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x7a,0x7a,0x77,0x00,0x7b,0x7a,0x78,0x00,0x7c,0x7b,0x79,0x00,0x7d,0x7c,0x7a,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7c,0x00, + 0x80,0x80,0x7e,0x00,0x81,0x80,0x7e,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x86,0x00, + 0x89,0x88,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8a,0x89,0x00,0x8c,0x8b,0x8a,0x00,0x8e,0x8d,0x8b,0x00,0x8f,0x8e,0x8c,0x00,0x90,0x8f,0x8d,0x00,0x91,0x90,0x8e,0x00, + 0x93,0x92,0x8f,0x00,0x94,0x93,0x90,0x00,0x95,0x94,0x92,0x00,0x96,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x98,0x97,0x95,0x00,0x9a,0x98,0x96,0x00,0x9b,0x99,0x97,0x00, + 0x9c,0x9b,0x99,0x00,0x9e,0x9c,0x99,0x00,0x9f,0x9d,0x9b,0x00,0xa0,0x9e,0x9c,0x00,0xa1,0x9f,0x9d,0x00,0xa1,0xa0,0x9e,0x00,0xa3,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00, + 0xa5,0xa3,0xa3,0x00,0xa6,0xa5,0xa4,0x00,0xa8,0xa6,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xaa,0xa8,0xa6,0x00,0xab,0xa9,0xa7,0x00,0xad,0xab,0xa9,0x00,0xae,0xac,0xaa,0x00, + 0xb0,0xad,0xab,0x00,0xb0,0xae,0xac,0x00,0xb2,0xb0,0xae,0x00,0xb3,0xb1,0xae,0x00,0xb4,0xb2,0xb0,0x00,0xb5,0xb2,0xb0,0x00,0xb5,0xb4,0xb1,0x00,0xb6,0xb5,0xb2,0x00, + 0xb9,0xb6,0xb4,0x00,0xb9,0xb7,0xb5,0x00,0xbb,0xb8,0xb7,0x00,0xbb,0xb9,0xb8,0x00,0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00,0xbf,0xbd,0xbb,0x00,0xc0,0xbd,0xbd,0x00, + 0xc1,0xbf,0xbe,0x00,0xc3,0xc0,0xbe,0x00,0xc4,0xc1,0xbf,0x00,0xc5,0xc2,0xc0,0x00,0xc6,0xc3,0xc1,0x00,0xc7,0xc5,0xc2,0x00,0xc8,0xc6,0xc4,0x00,0xc9,0xc7,0xc5,0x00, + 0xcb,0xc8,0xc6,0x00,0xcc,0xc9,0xc7,0x00,0xcd,0xca,0xc9,0x00,0xce,0xcb,0xc9,0x00,0xcf,0xcc,0xca,0x00,0xd0,0xce,0xcb,0x00,0xd2,0xcf,0xcd,0x00,0xd2,0xd0,0xce,0x00, + 0xd4,0xd1,0xcf,0x00,0xd5,0xd2,0xcf,0x00,0xd6,0xd3,0xd1,0x00,0xd8,0xd4,0xd2,0x00,0xd9,0xd6,0xd3,0x00,0xda,0xd6,0xd4,0x00,0xdb,0xd7,0xd5,0x00,0xdc,0xd8,0xd6,0x00, + 0xdd,0xda,0xd7,0x00,0xde,0xdb,0xd8,0x00,0xdf,0xdc,0xd9,0x00,0xe0,0xdd,0xdb,0x00,0xe1,0xde,0xdc,0x00,0xe2,0xdf,0xdc,0x00,0xe4,0xe0,0xde,0x00,0xe4,0xe1,0xde,0x00, + 0xe5,0xe3,0xe0,0x00,0xe6,0xe3,0xe0,0x00,0xe7,0xe5,0xe2,0x00,0xe9,0xe5,0xe3,0x00,0xea,0xe7,0xe4,0x00,0xeb,0xe7,0xe5,0x00,0xed,0xe8,0xe7,0x00,0xee,0xea,0xe7,0x00, + 0xef,0xeb,0xe9,0x00,0xf1,0xec,0xea,0x00,0xf2,0xed,0xeb,0x00,0xf3,0xee,0xec,0x00,0xf4,0xef,0xed,0x00,0xf5,0xf1,0xee,0x00,0xf6,0xf2,0xf0,0x00,0xf7,0xf3,0xf1,0x00, + 0xf9,0xf4,0xf2,0x00,0xf9,0xf6,0xf3,0x00,0xfb,0xf7,0xf4,0x00,0xfc,0xf8,0xf5,0x00,0xfd,0xf9,0xf6,0x00,0xff,0xfa,0xf7,0x00,0xff,0xfb,0xf8,0x00,0xff,0xfc,0xfa,0x00, + 0xff,0xfd,0xfb,0x00,0xff,0xfd,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x16,0x15,0x00,0x16,0x17,0x15,0x00,0x17,0x18,0x17,0x00,0x1a,0x19,0x18,0x00, + 0x1b,0x1a,0x19,0x00,0x1c,0x1b,0x1a,0x00,0x1d,0x1c,0x1b,0x00,0x1e,0x1d,0x1d,0x00,0x1f,0x1e,0x1e,0x00,0x20,0x1f,0x1f,0x00,0x21,0x20,0x20,0x00,0x22,0x22,0x20,0x00, + 0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x27,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x28,0x00,0x2a,0x2a,0x29,0x00,0x2c,0x2b,0x2a,0x00, + 0x2c,0x2c,0x2b,0x00,0x2e,0x2d,0x2d,0x00,0x2e,0x2e,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x31,0x30,0x00,0x33,0x32,0x31,0x00,0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00, + 0x37,0x36,0x34,0x00,0x37,0x37,0x36,0x00,0x38,0x37,0x36,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3c,0x3b,0x00,0x3e,0x3d,0x3c,0x00, + 0x3f,0x3f,0x3d,0x00,0x40,0x3f,0x3e,0x00,0x41,0x41,0x3f,0x00,0x42,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x47,0x46,0x45,0x00, + 0x48,0x47,0x46,0x00,0x49,0x48,0x47,0x00,0x4a,0x4a,0x48,0x00,0x4b,0x4b,0x49,0x00,0x4c,0x4c,0x4a,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4f,0x4e,0x00, + 0x51,0x50,0x4f,0x00,0x52,0x51,0x50,0x00,0x53,0x52,0x51,0x00,0x54,0x54,0x52,0x00,0x55,0x55,0x53,0x00,0x56,0x56,0x54,0x00,0x58,0x57,0x55,0x00,0x59,0x59,0x56,0x00, + 0x5a,0x5a,0x58,0x00,0x5b,0x5c,0x59,0x00,0x5d,0x5d,0x5b,0x00,0x5f,0x5e,0x5c,0x00,0x60,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x63,0x63,0x60,0x00,0x64,0x64,0x62,0x00, + 0x65,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x69,0x68,0x66,0x00,0x6a,0x69,0x67,0x00,0x6b,0x6b,0x68,0x00,0x6c,0x6b,0x69,0x00,0x6d,0x6d,0x6a,0x00, + 0x6e,0x6e,0x6c,0x00,0x6f,0x6f,0x6d,0x00,0x70,0x70,0x6e,0x00,0x71,0x71,0x6f,0x00,0x73,0x72,0x70,0x00,0x74,0x73,0x71,0x00,0x75,0x74,0x72,0x00,0x76,0x76,0x73,0x00, + 0x77,0x77,0x75,0x00,0x78,0x78,0x75,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7c,0x7b,0x79,0x00,0x7d,0x7c,0x7a,0x00,0x7e,0x7d,0x7b,0x00,0x7f,0x7e,0x7c,0x00, + 0x80,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x7f,0x00,0x83,0x82,0x80,0x00,0x84,0x84,0x81,0x00,0x85,0x84,0x82,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00, + 0x88,0x88,0x86,0x00,0x89,0x89,0x86,0x00,0x8b,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8e,0x8d,0x8a,0x00,0x8f,0x8e,0x8b,0x00,0x90,0x8f,0x8c,0x00,0x91,0x90,0x8e,0x00, + 0x93,0x91,0x90,0x00,0x94,0x93,0x91,0x00,0x95,0x94,0x92,0x00,0x96,0x95,0x93,0x00,0x96,0x95,0x94,0x00,0x98,0x97,0x95,0x00,0x99,0x98,0x96,0x00,0x9a,0x99,0x97,0x00, + 0x9c,0x9b,0x98,0x00,0x9d,0x9b,0x99,0x00,0x9f,0x9d,0x9a,0x00,0xa0,0x9e,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa0,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa2,0xa0,0x00, + 0xa5,0xa4,0xa1,0x00,0xa6,0xa5,0xa2,0x00,0xa7,0xa6,0xa3,0x00,0xa8,0xa7,0xa4,0x00,0xaa,0xa8,0xa6,0x00,0xab,0xa9,0xa7,0x00,0xad,0xab,0xa9,0x00,0xae,0xac,0xaa,0x00, + 0xaf,0xad,0xab,0x00,0xb0,0xae,0xac,0x00,0xb1,0xaf,0xad,0x00,0xb2,0xb0,0xae,0x00,0xb4,0xb1,0xaf,0x00,0xb4,0xb2,0xb0,0x00,0xb5,0xb3,0xb1,0x00,0xb6,0xb5,0xb2,0x00, + 0xb8,0xb6,0xb4,0x00,0xb9,0xb7,0xb5,0x00,0xba,0xb9,0xb6,0x00,0xbb,0xb9,0xb7,0x00,0xbd,0xba,0xb8,0x00,0xbd,0xbb,0xb9,0x00,0xbf,0xbc,0xba,0x00,0xc0,0xbe,0xbc,0x00, + 0xc1,0xbf,0xbd,0x00,0xc2,0xc0,0xbe,0x00,0xc3,0xc1,0xbf,0x00,0xc4,0xc2,0xc0,0x00,0xc6,0xc4,0xc1,0x00,0xc7,0xc5,0xc2,0x00,0xc8,0xc6,0xc3,0x00,0xc9,0xc7,0xc5,0x00, + 0xcb,0xc8,0xc6,0x00,0xcb,0xc9,0xc7,0x00,0xcd,0xca,0xc8,0x00,0xcd,0xcb,0xc9,0x00,0xcf,0xcc,0xca,0x00,0xd0,0xcd,0xcb,0x00,0xd1,0xcf,0xcc,0x00,0xd2,0xd0,0xcd,0x00, + 0xd4,0xd1,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd6,0xd3,0xd1,0x00,0xd7,0xd5,0xd1,0x00,0xd9,0xd6,0xd3,0x00,0xd9,0xd7,0xd3,0x00,0xdb,0xd7,0xd5,0x00,0xdb,0xd8,0xd6,0x00, + 0xdd,0xda,0xd7,0x00,0xde,0xda,0xd8,0x00,0xdf,0xdc,0xd9,0x00,0xe0,0xdd,0xda,0x00,0xe1,0xde,0xdb,0x00,0xe2,0xe0,0xdc,0x00,0xe4,0xe0,0xde,0x00,0xe4,0xe1,0xde,0x00, + 0xe5,0xe3,0xe0,0x00,0xe6,0xe4,0xe0,0x00,0xe7,0xe5,0xe2,0x00,0xe9,0xe5,0xe3,0x00,0xe9,0xe7,0xe4,0x00,0xeb,0xe7,0xe5,0x00,0xec,0xe9,0xe6,0x00,0xed,0xea,0xe6,0x00, + 0xee,0xeb,0xe8,0x00,0xef,0xec,0xe9,0x00,0xf1,0xed,0xea,0x00,0xf2,0xee,0xeb,0x00,0xf3,0xef,0xec,0x00,0xf4,0xf1,0xed,0x00,0xf5,0xf2,0xef,0x00,0xf6,0xf3,0xef,0x00, + 0xf7,0xf4,0xf1,0x00,0xf8,0xf5,0xf2,0x00,0xfa,0xf6,0xf3,0x00,0xfb,0xf7,0xf3,0x00,0xfc,0xf9,0xf5,0x00,0xfd,0xfa,0xf6,0x00,0xff,0xfb,0xf8,0x00,0xff,0xfc,0xf8,0x00, + 0xff,0xfd,0xf9,0x00,0xff,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x18,0x16,0x00,0x19,0x19,0x18,0x00, + 0x1a,0x1a,0x19,0x00,0x1b,0x1b,0x1a,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1e,0x00,0x20,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00, + 0x23,0x22,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x28,0x00,0x29,0x29,0x29,0x00,0x2b,0x2b,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x2f,0x00,0x32,0x32,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x34,0x33,0x00, + 0x36,0x35,0x34,0x00,0x37,0x36,0x36,0x00,0x38,0x37,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3e,0x3d,0x3c,0x00, + 0x3f,0x3f,0x3d,0x00,0x40,0x3f,0x3e,0x00,0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x44,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x46,0x45,0x44,0x00,0x46,0x46,0x45,0x00, + 0x47,0x47,0x46,0x00,0x49,0x48,0x47,0x00,0x4a,0x4a,0x48,0x00,0x4b,0x4a,0x49,0x00,0x4c,0x4b,0x4a,0x00,0x4d,0x4d,0x4b,0x00,0x4e,0x4e,0x4c,0x00,0x4f,0x4f,0x4d,0x00, + 0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x54,0x53,0x52,0x00,0x55,0x55,0x53,0x00,0x56,0x56,0x54,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00, + 0x5a,0x5a,0x57,0x00,0x5b,0x5b,0x59,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x60,0x5f,0x5e,0x00,0x61,0x61,0x5f,0x00,0x63,0x63,0x60,0x00,0x64,0x64,0x61,0x00, + 0x66,0x65,0x63,0x00,0x66,0x66,0x63,0x00,0x67,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x69,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00,0x6c,0x6c,0x69,0x00,0x6d,0x6c,0x6a,0x00, + 0x6e,0x6e,0x6b,0x00,0x6f,0x6f,0x6c,0x00,0x70,0x70,0x6d,0x00,0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x73,0x71,0x00,0x74,0x74,0x72,0x00,0x76,0x75,0x73,0x00, + 0x76,0x76,0x74,0x00,0x78,0x77,0x75,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7e,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00, + 0x80,0x7f,0x7d,0x00,0x81,0x80,0x7e,0x00,0x82,0x81,0x80,0x00,0x83,0x82,0x81,0x00,0x85,0x84,0x82,0x00,0x85,0x84,0x83,0x00,0x87,0x85,0x84,0x00,0x88,0x87,0x85,0x00, + 0x89,0x88,0x86,0x00,0x8a,0x89,0x87,0x00,0x8b,0x8a,0x88,0x00,0x8c,0x8b,0x89,0x00,0x8d,0x8c,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x90,0x8f,0x8d,0x00,0x91,0x90,0x8e,0x00, + 0x92,0x91,0x8f,0x00,0x93,0x92,0x90,0x00,0x94,0x94,0x91,0x00,0x95,0x95,0x92,0x00,0x97,0x96,0x94,0x00,0x98,0x97,0x94,0x00,0x99,0x98,0x96,0x00,0x9a,0x99,0x97,0x00, + 0x9b,0x9b,0x98,0x00,0x9c,0x9b,0x99,0x00,0x9e,0x9d,0x9a,0x00,0x9e,0x9e,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa2,0xa0,0x9e,0x00,0xa2,0xa1,0xa0,0x00,0xa4,0xa2,0xa1,0x00, + 0xa5,0xa3,0xa2,0x00,0xa6,0xa4,0xa3,0x00,0xa8,0xa6,0xa4,0x00,0xa9,0xa7,0xa5,0x00,0xaa,0xa8,0xa7,0x00,0xab,0xa9,0xa8,0x00,0xac,0xab,0xa9,0x00,0xad,0xac,0xaa,0x00, + 0xaf,0xad,0xab,0x00,0xb0,0xae,0xac,0x00,0xb1,0xaf,0xad,0x00,0xb2,0xb0,0xae,0x00,0xb3,0xb2,0xb0,0x00,0xb5,0xb2,0xb1,0x00,0xb6,0xb3,0xb2,0x00,0xb7,0xb4,0xb3,0x00, + 0xb8,0xb6,0xb4,0x00,0xb9,0xb7,0xb5,0x00,0xba,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbc,0xba,0xb8,0x00,0xbd,0xbb,0xb9,0x00,0xbf,0xbc,0xba,0x00,0xc0,0xbe,0xbb,0x00, + 0xc1,0xbf,0xbc,0x00,0xc2,0xc0,0xbd,0x00,0xc3,0xc1,0xbf,0x00,0xc4,0xc2,0xc0,0x00,0xc5,0xc4,0xc2,0x00,0xc7,0xc4,0xc2,0x00,0xc8,0xc6,0xc4,0x00,0xc9,0xc6,0xc4,0x00, + 0xca,0xc8,0xc6,0x00,0xcb,0xc9,0xc6,0x00,0xcc,0xca,0xc8,0x00,0xcd,0xcb,0xc9,0x00,0xcf,0xcc,0xca,0x00,0xd0,0xce,0xcb,0x00,0xd1,0xcf,0xcd,0x00,0xd2,0xcf,0xcd,0x00, + 0xd3,0xd0,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd6,0xd3,0xd0,0x00,0xd7,0xd4,0xd2,0x00,0xd9,0xd5,0xd3,0x00,0xd9,0xd6,0xd4,0x00,0xda,0xd7,0xd5,0x00,0xdb,0xd8,0xd6,0x00, + 0xdc,0xd9,0xd7,0x00,0xdd,0xda,0xd8,0x00,0xdf,0xdc,0xd9,0x00,0xe0,0xdc,0xda,0x00,0xe1,0xde,0xdb,0x00,0xe2,0xde,0xdc,0x00,0xe3,0xe0,0xde,0x00,0xe4,0xe0,0xde,0x00, + 0xe5,0xe2,0xe0,0x00,0xe6,0xe3,0xe1,0x00,0xe7,0xe4,0xe2,0x00,0xe8,0xe5,0xe3,0x00,0xea,0xe6,0xe4,0x00,0xea,0xe7,0xe4,0x00,0xec,0xe9,0xe6,0x00,0xed,0xea,0xe7,0x00, + 0xee,0xeb,0xe8,0x00,0xef,0xeb,0xe9,0x00,0xf0,0xed,0xea,0x00,0xf1,0xee,0xeb,0x00,0xf2,0xef,0xec,0x00,0xf4,0xf1,0xed,0x00,0xf5,0xf1,0xef,0x00,0xf6,0xf3,0xef,0x00, + 0xf7,0xf4,0xf0,0x00,0xf9,0xf5,0xf1,0x00,0xf9,0xf6,0xf3,0x00,0xfb,0xf7,0xf4,0x00,0xfb,0xf8,0xf5,0x00,0xfd,0xf9,0xf6,0x00,0xfe,0xfa,0xf7,0x00,0xff,0xfb,0xf8,0x00, + 0xff,0xfd,0xfa,0x00,0xff,0xfe,0xfa,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x16,0x00,0x18,0x18,0x18,0x00, + 0x1a,0x1a,0x19,0x00,0x1b,0x1b,0x1a,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x20,0x1f,0x1e,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x20,0x00, + 0x22,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2b,0x2a,0x00, + 0x2c,0x2b,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x2f,0x00,0x31,0x31,0x30,0x00,0x32,0x32,0x32,0x00,0x34,0x33,0x33,0x00, + 0x35,0x35,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x36,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00, + 0x3f,0x3e,0x3d,0x00,0x40,0x3f,0x3e,0x00,0x41,0x40,0x3f,0x00,0x42,0x41,0x40,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00, + 0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x4a,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4d,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4f,0x4f,0x4e,0x00, + 0x50,0x50,0x4f,0x00,0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x52,0x00,0x55,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x57,0x57,0x55,0x00,0x58,0x58,0x56,0x00, + 0x59,0x59,0x57,0x00,0x5b,0x5b,0x58,0x00,0x5c,0x5c,0x5a,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x61,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x63,0x61,0x00, + 0x64,0x65,0x62,0x00,0x65,0x66,0x63,0x00,0x67,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x69,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00,0x6b,0x6b,0x69,0x00,0x6c,0x6c,0x6a,0x00, + 0x6d,0x6e,0x6b,0x00,0x6e,0x6e,0x6c,0x00,0x70,0x6f,0x6d,0x00,0x71,0x71,0x6e,0x00,0x72,0x72,0x70,0x00,0x73,0x72,0x71,0x00,0x74,0x74,0x72,0x00,0x75,0x75,0x73,0x00, + 0x76,0x77,0x74,0x00,0x77,0x77,0x75,0x00,0x79,0x79,0x76,0x00,0x7a,0x79,0x77,0x00,0x7b,0x7b,0x78,0x00,0x7c,0x7b,0x79,0x00,0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00, + 0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x82,0x81,0x7f,0x00,0x83,0x82,0x80,0x00,0x84,0x83,0x82,0x00,0x85,0x84,0x82,0x00,0x86,0x85,0x83,0x00,0x87,0x87,0x85,0x00, + 0x89,0x88,0x86,0x00,0x89,0x88,0x87,0x00,0x8b,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8d,0x8c,0x8a,0x00,0x8e,0x8d,0x8c,0x00,0x8f,0x8e,0x8c,0x00,0x90,0x8f,0x8e,0x00, + 0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x90,0x00,0x94,0x94,0x92,0x00,0x96,0x95,0x94,0x00,0x97,0x96,0x94,0x00,0x98,0x97,0x95,0x00,0x99,0x99,0x96,0x00, + 0x9b,0x9a,0x98,0x00,0x9c,0x9b,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9d,0x00,0xa1,0x9f,0x9e,0x00,0xa2,0xa1,0x9e,0x00,0xa3,0xa2,0xa0,0x00, + 0xa5,0xa3,0xa1,0x00,0xa6,0xa4,0xa3,0x00,0xa7,0xa5,0xa4,0x00,0xa8,0xa7,0xa5,0x00,0xaa,0xa8,0xa7,0x00,0xab,0xa9,0xa7,0x00,0xac,0xaa,0xa8,0x00,0xad,0xab,0xa9,0x00, + 0xae,0xad,0xab,0x00,0xaf,0xad,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb1,0xaf,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xb0,0x00,0xb4,0xb3,0xb2,0x00,0xb5,0xb4,0xb2,0x00, + 0xb7,0xb6,0xb4,0x00,0xb8,0xb6,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbc,0xba,0xb8,0x00,0xbd,0xbb,0xb9,0x00,0xbe,0xbc,0xba,0x00,0xbf,0xbd,0xbb,0x00, + 0xc0,0xbe,0xbb,0x00,0xc1,0xbf,0xbd,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xbf,0x00,0xc5,0xc2,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc7,0xc5,0xc3,0x00,0xc8,0xc6,0xc4,0x00, + 0xc9,0xc7,0xc6,0x00,0xca,0xc8,0xc6,0x00,0xcb,0xca,0xc7,0x00,0xcc,0xca,0xc8,0x00,0xce,0xcc,0xc9,0x00,0xcf,0xcd,0xcb,0x00,0xd0,0xce,0xcc,0x00,0xd1,0xcf,0xcd,0x00, + 0xd2,0xd0,0xce,0x00,0xd4,0xd1,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd5,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00,0xda,0xd7,0xd4,0x00,0xda,0xd8,0xd5,0x00, + 0xdc,0xd9,0xd6,0x00,0xdd,0xda,0xd7,0x00,0xde,0xdb,0xd8,0x00,0xdf,0xdc,0xda,0x00,0xe0,0xde,0xdb,0x00,0xe1,0xdf,0xdb,0x00,0xe2,0xdf,0xdd,0x00,0xe3,0xe0,0xdd,0x00, + 0xe5,0xe2,0xdf,0x00,0xe6,0xe3,0xe0,0x00,0xe7,0xe4,0xe2,0x00,0xe8,0xe5,0xe2,0x00,0xea,0xe6,0xe4,0x00,0xea,0xe7,0xe4,0x00,0xec,0xe9,0xe5,0x00,0xed,0xe9,0xe6,0x00, + 0xee,0xea,0xe7,0x00,0xef,0xeb,0xe8,0x00,0xf0,0xec,0xea,0x00,0xf2,0xee,0xeb,0x00,0xf3,0xef,0xec,0x00,0xf4,0xf0,0xed,0x00,0xf5,0xf1,0xee,0x00,0xf6,0xf2,0xef,0x00, + 0xf7,0xf3,0xf0,0x00,0xf9,0xf5,0xf1,0x00,0xf9,0xf6,0xf2,0x00,0xfa,0xf7,0xf3,0x00,0xfc,0xf8,0xf4,0x00,0xfd,0xf9,0xf6,0x00,0xfe,0xfa,0xf7,0x00,0xff,0xfb,0xf8,0x00, + 0xff,0xfc,0xf9,0x00,0xff,0xfd,0xfa,0x00,0xff,0xff,0xfa,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x15,0x14,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x16,0x00,0x19,0x18,0x18,0x00, + 0x1a,0x19,0x19,0x00,0x1b,0x1b,0x1a,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00, + 0x22,0x22,0x21,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x26,0x26,0x26,0x00,0x29,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2b,0x2b,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2c,0x00,0x2c,0x2d,0x2d,0x00,0x2f,0x2f,0x2e,0x00,0x30,0x30,0x2f,0x00,0x32,0x31,0x30,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x36,0x35,0x34,0x00,0x36,0x36,0x35,0x00,0x37,0x37,0x36,0x00,0x39,0x38,0x38,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x3a,0x00,0x3c,0x3b,0x3b,0x00,0x3d,0x3c,0x3c,0x00, + 0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x45,0x44,0x00,0x46,0x45,0x45,0x00, + 0x47,0x46,0x45,0x00,0x48,0x47,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00, + 0x50,0x50,0x4e,0x00,0x50,0x50,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x58,0x56,0x00, + 0x59,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5c,0x00,0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00,0x61,0x62,0x5f,0x00,0x63,0x63,0x61,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x69,0x66,0x00,0x69,0x6a,0x68,0x00,0x6b,0x6b,0x69,0x00,0x6c,0x6c,0x6a,0x00, + 0x6d,0x6d,0x6b,0x00,0x6e,0x6e,0x6c,0x00,0x6f,0x6f,0x6d,0x00,0x70,0x70,0x6e,0x00,0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x73,0x71,0x00,0x74,0x75,0x73,0x00, + 0x76,0x76,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7e,0x7b,0x00, + 0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7d,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00, + 0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x90,0x8f,0x8d,0x00, + 0x91,0x91,0x8e,0x00,0x93,0x92,0x8f,0x00,0x94,0x93,0x90,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x93,0x00,0x97,0x97,0x95,0x00,0x99,0x98,0x96,0x00, + 0x9a,0x9a,0x98,0x00,0x9b,0x9a,0x98,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0x9f,0x9d,0x00,0xa1,0xa0,0x9e,0x00,0xa2,0xa1,0xa0,0x00, + 0xa4,0xa3,0xa1,0x00,0xa5,0xa3,0xa2,0x00,0xa6,0xa5,0xa3,0x00,0xa7,0xa6,0xa5,0x00,0xa9,0xa7,0xa6,0x00,0xaa,0xa8,0xa7,0x00,0xab,0xaa,0xa8,0x00,0xac,0xab,0xa9,0x00, + 0xad,0xac,0xaa,0x00,0xae,0xae,0xab,0x00,0xb0,0xae,0xad,0x00,0xb0,0xb0,0xad,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xaf,0x00,0xb5,0xb2,0xb1,0x00,0xb5,0xb3,0xb2,0x00, + 0xb7,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb9,0xb8,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xbb,0xb9,0xb7,0x00,0xbb,0xba,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xba,0x00, + 0xc0,0xbe,0xbb,0x00,0xc0,0xbf,0xbc,0x00,0xc2,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc4,0xc2,0xc0,0x00,0xc5,0xc3,0xc1,0x00,0xc6,0xc4,0xc2,0x00,0xc7,0xc6,0xc3,0x00, + 0xc8,0xc7,0xc5,0x00,0xca,0xc8,0xc6,0x00,0xcb,0xc9,0xc7,0x00,0xcc,0xca,0xc8,0x00,0xcd,0xcb,0xc9,0x00,0xce,0xcc,0xca,0x00,0xcf,0xcd,0xcb,0x00,0xd1,0xce,0xcc,0x00, + 0xd2,0xd0,0xce,0x00,0xd3,0xd1,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd6,0xd3,0xd1,0x00,0xd7,0xd4,0xd3,0x00,0xd7,0xd5,0xd3,0x00,0xd9,0xd7,0xd4,0x00,0xd9,0xd7,0xd5,0x00, + 0xdb,0xd9,0xd6,0x00,0xdc,0xd9,0xd7,0x00,0xdd,0xda,0xd8,0x00,0xde,0xdb,0xd9,0x00,0xe0,0xdd,0xda,0x00,0xe0,0xde,0xdb,0x00,0xe2,0xdf,0xdd,0x00,0xe3,0xe0,0xdd,0x00, + 0xe4,0xe1,0xdf,0x00,0xe5,0xe1,0xdf,0x00,0xe6,0xe3,0xe1,0x00,0xe7,0xe4,0xe1,0x00,0xe8,0xe6,0xe3,0x00,0xe9,0xe6,0xe3,0x00,0xeb,0xe8,0xe5,0x00,0xec,0xe9,0xe5,0x00, + 0xed,0xea,0xe7,0x00,0xee,0xeb,0xe8,0x00,0xef,0xec,0xe9,0x00,0xf0,0xed,0xea,0x00,0xf2,0xee,0xeb,0x00,0xf3,0xef,0xec,0x00,0xf4,0xf0,0xed,0x00,0xf5,0xf2,0xee,0x00, + 0xf7,0xf3,0xf0,0x00,0xf8,0xf4,0xf0,0x00,0xf9,0xf5,0xf2,0x00,0xfa,0xf6,0xf2,0x00,0xfb,0xf7,0xf4,0x00,0xfc,0xf8,0xf5,0x00,0xfd,0xf9,0xf6,0x00,0xfe,0xfb,0xf7,0x00, + 0xff,0xfc,0xf9,0x00,0xff,0xfd,0xfa,0x00,0xff,0xfe,0xfa,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x16,0x00,0x18,0x18,0x17,0x00, + 0x19,0x19,0x18,0x00,0x1a,0x1a,0x19,0x00,0x1b,0x1b,0x1b,0x00,0x1d,0x1d,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00, + 0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x3a,0x39,0x38,0x00,0x3b,0x3a,0x39,0x00,0x3c,0x3b,0x3a,0x00,0x3d,0x3d,0x3c,0x00, + 0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x43,0x42,0x41,0x00,0x44,0x43,0x42,0x00,0x45,0x44,0x43,0x00,0x46,0x45,0x44,0x00, + 0x47,0x46,0x45,0x00,0x48,0x47,0x46,0x00,0x49,0x48,0x47,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4f,0x4d,0x00, + 0x50,0x50,0x4e,0x00,0x51,0x51,0x4f,0x00,0x52,0x52,0x50,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x58,0x56,0x00, + 0x58,0x59,0x57,0x00,0x59,0x5a,0x58,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00,0x61,0x61,0x60,0x00,0x63,0x63,0x61,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x69,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00,0x6b,0x6c,0x6a,0x00, + 0x6d,0x6d,0x6b,0x00,0x6e,0x6e,0x6c,0x00,0x6f,0x6f,0x6d,0x00,0x70,0x70,0x6e,0x00,0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x73,0x71,0x00,0x74,0x75,0x73,0x00, + 0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x82,0x00,0x83,0x84,0x83,0x00,0x84,0x85,0x84,0x00,0x86,0x86,0x85,0x00, + 0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8e,0x8d,0x8c,0x00,0x8f,0x8f,0x8d,0x00, + 0x91,0x90,0x8f,0x00,0x92,0x91,0x90,0x00,0x93,0x92,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00, + 0x9a,0x99,0x97,0x00,0x9b,0x9a,0x98,0x00,0x9c,0x9b,0x99,0x00,0x9d,0x9d,0x9b,0x00,0x9f,0x9e,0x9c,0x00,0xa0,0x9f,0x9d,0x00,0xa1,0xa0,0x9e,0x00,0xa2,0xa1,0x9f,0x00, + 0xa3,0xa2,0xa1,0x00,0xa4,0xa3,0xa2,0x00,0xa5,0xa4,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa8,0xa7,0xa6,0x00,0xa9,0xa8,0xa7,0x00,0xaa,0xa9,0xa8,0x00,0xab,0xab,0xa9,0x00, + 0xad,0xac,0xaa,0x00,0xae,0xad,0xab,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb2,0xb0,0xaf,0x00,0xb3,0xb1,0xb0,0x00,0xb4,0xb2,0xb1,0x00,0xb5,0xb4,0xb2,0x00, + 0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xbb,0xb9,0xb8,0x00,0xbc,0xba,0xb8,0x00,0xbd,0xbb,0xb9,0x00,0xbe,0xbc,0xba,0x00, + 0xbf,0xbe,0xbb,0x00,0xc0,0xbf,0xbc,0x00,0xc1,0xc0,0xbd,0x00,0xc2,0xc1,0xbf,0x00,0xc4,0xc2,0xc0,0x00,0xc5,0xc3,0xc1,0x00,0xc6,0xc4,0xc2,0x00,0xc7,0xc6,0xc3,0x00, + 0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcd,0xcb,0xc9,0x00,0xce,0xcc,0xca,0x00,0xcf,0xcd,0xcb,0x00,0xd0,0xce,0xcd,0x00, + 0xd1,0xcf,0xce,0x00,0xd2,0xd0,0xcf,0x00,0xd3,0xd1,0xd0,0x00,0xd4,0xd3,0xd1,0x00,0xd6,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00,0xd9,0xd7,0xd5,0x00, + 0xdb,0xd8,0xd7,0x00,0xdc,0xd9,0xd8,0x00,0xdd,0xda,0xd9,0x00,0xde,0xdb,0xda,0x00,0xdf,0xdc,0xdb,0x00,0xe0,0xdd,0xdc,0x00,0xe1,0xde,0xdd,0x00,0xe2,0xe0,0xde,0x00, + 0xe3,0xe1,0xdf,0x00,0xe4,0xe2,0xe0,0x00,0xe5,0xe3,0xe1,0x00,0xe6,0xe4,0xe2,0x00,0xe7,0xe5,0xe3,0x00,0xe9,0xe6,0xe4,0x00,0xea,0xe7,0xe5,0x00,0xeb,0xe9,0xe6,0x00, + 0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf1,0xee,0xeb,0x00,0xf2,0xef,0xec,0x00,0xf3,0xf0,0xed,0x00,0xf4,0xf1,0xee,0x00, + 0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xfa,0xf7,0xf4,0x00,0xfb,0xf8,0xf5,0x00,0xfc,0xf9,0xf6,0x00,0xfd,0xfa,0xf7,0x00, + 0xfe,0xfb,0xf9,0x00,0xfe,0xfc,0xfa,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x15,0x00,0x17,0x17,0x16,0x00,0x18,0x18,0x17,0x00, + 0x19,0x19,0x18,0x00,0x1a,0x1a,0x19,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1e,0x1e,0x1d,0x00,0x1f,0x1f,0x1e,0x00,0x20,0x20,0x1f,0x00,0x21,0x21,0x20,0x00, + 0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x29,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00, + 0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00, + 0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00, + 0x4f,0x50,0x4e,0x00,0x50,0x51,0x4f,0x00,0x51,0x52,0x50,0x00,0x52,0x53,0x51,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00, + 0x58,0x59,0x57,0x00,0x59,0x5a,0x58,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x62,0x62,0x61,0x00, + 0x64,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x69,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00,0x6b,0x6b,0x69,0x00, + 0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00, + 0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00, + 0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8e,0x8d,0x8c,0x00,0x8f,0x8e,0x8d,0x00, + 0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00, + 0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9c,0x9b,0x99,0x00,0x9d,0x9c,0x9a,0x00,0x9f,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00, + 0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa5,0xa4,0xa3,0x00,0xa6,0xa5,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xaa,0xa9,0xa7,0x00,0xab,0xaa,0xa8,0x00, + 0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xb0,0x00,0xb4,0xb3,0xb1,0x00, + 0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00, + 0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc1,0xbf,0xbd,0x00,0xc2,0xc0,0xbe,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00, + 0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xca,0xc9,0xc6,0x00,0xcb,0xca,0xc7,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00, + 0xd0,0xcf,0xce,0x00,0xd1,0xd0,0xcf,0x00,0xd3,0xd1,0xd0,0x00,0xd4,0xd2,0xd1,0x00,0xd6,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00,0xd9,0xd7,0xd5,0x00, + 0xda,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00,0xe1,0xdf,0xdd,0x00, + 0xe3,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe5,0xe3,0xe0,0x00,0xe6,0xe4,0xe1,0x00,0xe7,0xe5,0xe3,0x00,0xe8,0xe6,0xe4,0x00,0xe9,0xe7,0xe5,0x00,0xea,0xe8,0xe6,0x00, + 0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00, + 0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf7,0xf4,0xf1,0x00,0xf8,0xf5,0xf2,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00,0xfc,0xfa,0xf7,0x00, + 0xfe,0xfb,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xfe,0xfd,0xfa,0x00,0xff,0xfe,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x17,0x16,0x00,0x17,0x18,0x17,0x00, + 0x18,0x19,0x18,0x00,0x1a,0x1a,0x19,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x23,0x22,0x22,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00, + 0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x42,0x41,0x41,0x00,0x43,0x42,0x42,0x00,0x44,0x43,0x43,0x00,0x45,0x44,0x44,0x00, + 0x46,0x45,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4c,0x4a,0x00,0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00, + 0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x55,0x53,0x00,0x55,0x56,0x54,0x00,0x56,0x57,0x55,0x00, + 0x57,0x58,0x56,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00, + 0x6c,0x6c,0x6a,0x00,0x6d,0x6d,0x6b,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00, + 0x74,0x75,0x73,0x00,0x76,0x76,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00, + 0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x89,0x88,0x87,0x00,0x8a,0x89,0x88,0x00,0x8b,0x8a,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8d,0x00, + 0x90,0x8f,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00, + 0x99,0x99,0x96,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9d,0x9c,0x9a,0x00,0x9e,0x9d,0x9b,0x00,0x9f,0x9e,0x9c,0x00,0xa0,0x9f,0x9d,0x00,0xa1,0xa0,0x9e,0x00, + 0xa2,0xa1,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa7,0xa6,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00, + 0xac,0xab,0xa9,0x00,0xad,0xac,0xaa,0x00,0xae,0xad,0xab,0x00,0xaf,0xae,0xac,0x00,0xb1,0xaf,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xb0,0x00,0xb4,0xb3,0xb1,0x00, + 0xb5,0xb4,0xb2,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00, + 0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc3,0xc1,0xbf,0x00,0xc4,0xc3,0xc0,0x00,0xc5,0xc4,0xc1,0x00,0xc6,0xc5,0xc2,0x00, + 0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcc,0xca,0xc8,0x00,0xcd,0xcb,0xca,0x00,0xce,0xcc,0xcb,0x00,0xcf,0xcd,0xcc,0x00, + 0xd0,0xce,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd4,0xd2,0xd0,0x00,0xd5,0xd3,0xd1,0x00,0xd6,0xd4,0xd2,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00, + 0xda,0xd7,0xd6,0x00,0xdb,0xd8,0xd7,0x00,0xdc,0xd9,0xd8,0x00,0xdd,0xda,0xd9,0x00,0xde,0xdb,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00,0xe1,0xdf,0xdd,0x00, + 0xe2,0xe0,0xde,0x00,0xe3,0xe1,0xdf,0x00,0xe4,0xe2,0xe0,0x00,0xe5,0xe3,0xe1,0x00,0xe6,0xe4,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe5,0x00,0xea,0xe8,0xe6,0x00, + 0xeb,0xe9,0xe7,0x00,0xec,0xea,0xe8,0x00,0xed,0xeb,0xe9,0x00,0xee,0xec,0xea,0x00,0xf0,0xed,0xeb,0x00,0xf1,0xee,0xec,0x00,0xf2,0xef,0xed,0x00,0xf3,0xf0,0xee,0x00, + 0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf9,0xf6,0xf3,0x00,0xfa,0xf7,0xf4,0x00,0xfb,0xf8,0xf5,0x00,0xfc,0xf9,0xf6,0x00, + 0xfd,0xfa,0xf8,0x00,0xfd,0xfb,0xf9,0x00,0xfe,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x17,0x16,0x00,0x17,0x18,0x17,0x00, + 0x18,0x19,0x18,0x00,0x19,0x1a,0x19,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00, + 0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00, + 0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x56,0x54,0x00,0x56,0x57,0x55,0x00, + 0x57,0x58,0x56,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00, + 0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00, + 0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00, + 0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x77,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00, + 0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00, + 0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x89,0x88,0x86,0x00,0x8a,0x89,0x87,0x00,0x8b,0x8a,0x88,0x00,0x8c,0x8b,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8d,0x00, + 0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00, + 0x98,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x99,0x00,0x9d,0x9c,0x9a,0x00,0x9e,0x9d,0x9b,0x00,0x9f,0x9e,0x9c,0x00,0xa0,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xae,0xad,0xab,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00, + 0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbb,0xba,0x00, + 0xbd,0xbc,0xbb,0x00,0xbe,0xbd,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00, + 0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xcb,0x00,0xce,0xcd,0xcc,0x00, + 0xcf,0xce,0xcd,0x00,0xd1,0xcf,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd4,0xd2,0xcf,0x00,0xd5,0xd3,0xd0,0x00,0xd6,0xd4,0xd1,0x00,0xd7,0xd5,0xd3,0x00,0xd8,0xd6,0xd4,0x00, + 0xd9,0xd7,0xd5,0x00,0xda,0xd8,0xd6,0x00,0xdb,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xe0,0xde,0xdb,0x00,0xe1,0xdf,0xdc,0x00, + 0xe2,0xe0,0xdd,0x00,0xe3,0xe1,0xde,0x00,0xe4,0xe2,0xe0,0x00,0xe4,0xe3,0xe1,0x00,0xe5,0xe4,0xe2,0x00,0xe6,0xe5,0xe3,0x00,0xe8,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00, + 0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xed,0xeb,0xe9,0x00,0xee,0xec,0xea,0x00,0xef,0xed,0xeb,0x00,0xf0,0xee,0xec,0x00,0xf1,0xef,0xed,0x00,0xf2,0xf0,0xed,0x00, + 0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00, + 0xfc,0xfa,0xf7,0x00,0xfd,0xfb,0xf8,0x00,0xfe,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x18,0x17,0x00, + 0x18,0x19,0x18,0x00,0x19,0x1a,0x19,0x00,0x1b,0x1b,0x1a,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x33,0x32,0x00, + 0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3c,0x3c,0x3b,0x00, + 0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4e,0x4d,0x00, + 0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x57,0x55,0x00, + 0x57,0x58,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x61,0x62,0x60,0x00, + 0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x68,0x66,0x00,0x69,0x69,0x67,0x00,0x6a,0x6b,0x69,0x00, + 0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x73,0x74,0x72,0x00, + 0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x79,0x79,0x77,0x00,0x7a,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7b,0x00, + 0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x85,0x85,0x83,0x00, + 0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x8a,0x89,0x87,0x00,0x8b,0x8a,0x88,0x00,0x8c,0x8b,0x89,0x00,0x8d,0x8c,0x8b,0x00,0x8e,0x8e,0x8c,0x00, + 0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x97,0x97,0x95,0x00, + 0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x9a,0x00,0x9e,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xaa,0xaa,0xa7,0x00, + 0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xb0,0xaf,0xad,0x00,0xb1,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00,0xb3,0xb2,0xb1,0x00, + 0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00,0xbc,0xbb,0xb9,0x00, + 0xbd,0xbc,0xbb,0x00,0xbe,0xbd,0xbc,0x00,0xbf,0xbe,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc2,0xc1,0xbf,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc3,0xc1,0x00,0xc5,0xc5,0xc2,0x00, + 0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00, + 0xcf,0xce,0xcd,0x00,0xd0,0xcf,0xcd,0x00,0xd2,0xd0,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00,0xd5,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd4,0x00, + 0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdd,0xdb,0xd9,0x00,0xde,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xdf,0xdc,0x00, + 0xe2,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe2,0x00,0xe6,0xe5,0xe3,0x00,0xe7,0xe6,0xe4,0x00,0xe9,0xe7,0xe5,0x00, + 0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00, + 0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00, + 0xfc,0xfa,0xf7,0x00,0xfd,0xfb,0xf8,0x00,0xfd,0xfc,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x19,0x18,0x00,0x19,0x1a,0x19,0x00,0x1b,0x1b,0x1a,0x00,0x1c,0x1c,0x1b,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2c,0x00,0x2d,0x2e,0x2d,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x34,0x33,0x00,0x34,0x35,0x34,0x00,0x35,0x36,0x35,0x00,0x36,0x37,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00, + 0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00, + 0x57,0x58,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00, + 0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00, + 0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00, + 0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8b,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00, + 0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9c,0x9b,0x99,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00, + 0xb4,0xb3,0xb2,0x00,0xb5,0xb4,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00, + 0xbd,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00, + 0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd1,0xcf,0x00,0xd4,0xd3,0xd0,0x00,0xd5,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00, + 0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00,0xdf,0xdd,0xdb,0x00,0xe0,0xde,0xdc,0x00, + 0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe4,0x00,0xe8,0xe7,0xe5,0x00, + 0xea,0xe8,0xe6,0x00,0xeb,0xe9,0xe7,0x00,0xec,0xea,0xe8,0x00,0xed,0xeb,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00, + 0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00, + 0xfc,0xfa,0xf7,0x00,0xfc,0xfb,0xf8,0x00,0xfd,0xfc,0xf9,0x00,0xfe,0xfd,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1b,0x1a,0x1a,0x00,0x1c,0x1b,0x1b,0x00,0x1d,0x1c,0x1c,0x00,0x1e,0x1d,0x1d,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2c,0x00,0x2d,0x2e,0x2d,0x00,0x2e,0x2f,0x2e,0x00,0x2f,0x30,0x2f,0x00,0x30,0x31,0x30,0x00,0x31,0x32,0x31,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00, + 0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x48,0x46,0x00,0x48,0x49,0x47,0x00,0x49,0x4a,0x48,0x00,0x4a,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00, + 0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x54,0x52,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00, + 0x56,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00, + 0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x65,0x62,0x00,0x64,0x66,0x63,0x00,0x66,0x67,0x64,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00, + 0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00, + 0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x78,0x78,0x76,0x00,0x79,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00, + 0x85,0x85,0x83,0x00,0x87,0x86,0x84,0x00,0x88,0x87,0x86,0x00,0x89,0x88,0x87,0x00,0x8a,0x89,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8e,0x8b,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00, + 0x97,0x98,0x95,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9d,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00, + 0xa0,0xa0,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa7,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00, + 0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xaf,0xae,0xac,0x00,0xb0,0xaf,0xae,0x00,0xb1,0xb0,0xaf,0x00,0xb2,0xb1,0xb0,0x00, + 0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00, + 0xbc,0xbb,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00, + 0xce,0xcd,0xcc,0x00,0xcf,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd1,0x00,0xd5,0xd4,0xd2,0x00,0xd6,0xd5,0xd3,0x00, + 0xd7,0xd6,0xd4,0x00,0xd8,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdc,0xda,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00, + 0xe1,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00, + 0xe9,0xe8,0xe6,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00, + 0xf2,0xf0,0xed,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00, + 0xfb,0xfa,0xf6,0x00,0xfc,0xfb,0xf7,0x00,0xfd,0xfc,0xf8,0x00,0xfe,0xfd,0xf9,0x00,0xff,0xfe,0xfb,0x00,0xff,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1b,0x1a,0x1a,0x00,0x1c,0x1b,0x1b,0x00,0x1d,0x1c,0x1c,0x00,0x1e,0x1d,0x1d,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2c,0x00,0x2d,0x2e,0x2d,0x00,0x2e,0x2f,0x2e,0x00,0x2f,0x30,0x2f,0x00,0x30,0x31,0x30,0x00,0x31,0x32,0x31,0x00, + 0x32,0x33,0x32,0x00,0x33,0x34,0x33,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00, + 0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x48,0x46,0x00,0x48,0x49,0x47,0x00,0x49,0x4a,0x48,0x00,0x4a,0x4b,0x49,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00, + 0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00, + 0x56,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00, + 0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x65,0x62,0x00,0x64,0x66,0x63,0x00,0x65,0x67,0x64,0x00,0x66,0x68,0x65,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00, + 0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00, + 0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00, + 0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x88,0x87,0x86,0x00,0x89,0x88,0x87,0x00,0x8a,0x89,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8c,0x8e,0x8b,0x00, + 0x8d,0x8f,0x8c,0x00,0x8e,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00, + 0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00, + 0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa6,0x00, + 0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb1,0xb0,0xaf,0x00,0xb2,0xb1,0xb0,0x00, + 0xb3,0xb2,0xb1,0x00,0xb4,0xb3,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00, + 0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00, + 0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00, + 0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00, + 0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe6,0xe4,0x00, + 0xe9,0xe7,0xe5,0x00,0xea,0xe8,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe7,0x00,0xee,0xec,0xe8,0x00,0xef,0xed,0xe9,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00, + 0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00, + 0xfb,0xfa,0xf6,0x00,0xfc,0xfb,0xf7,0x00,0xfd,0xfc,0xf8,0x00,0xfe,0xfd,0xf9,0x00,0xff,0xfe,0xfa,0x00,0xff,0xfe,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1c,0x1b,0x1b,0x00,0x1d,0x1c,0x1c,0x00,0x1e,0x1d,0x1d,0x00,0x1f,0x1e,0x1e,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2e,0x2d,0x00,0x2e,0x2f,0x2e,0x00,0x2f,0x30,0x2f,0x00,0x30,0x31,0x30,0x00,0x31,0x32,0x31,0x00, + 0x32,0x33,0x32,0x00,0x33,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00, + 0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x49,0x47,0x00,0x49,0x4a,0x48,0x00,0x4a,0x4b,0x49,0x00,0x4b,0x4c,0x4a,0x00,0x4d,0x4d,0x4c,0x00, + 0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00, + 0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x60,0x61,0x5f,0x00, + 0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x66,0x63,0x00,0x65,0x67,0x64,0x00,0x66,0x68,0x65,0x00,0x67,0x69,0x66,0x00,0x69,0x6a,0x68,0x00, + 0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x72,0x73,0x71,0x00, + 0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x84,0x84,0x82,0x00, + 0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x89,0x88,0x87,0x00,0x8a,0x89,0x88,0x00,0x8b,0x8a,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8f,0x8c,0x00,0x8e,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x96,0x96,0x94,0x00, + 0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9e,0x00, + 0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa3,0xa2,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa9,0xa9,0xa6,0x00, + 0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb2,0xb1,0xaf,0x00, + 0xb3,0xb2,0xb1,0x00,0xb4,0xb3,0xb2,0x00,0xb5,0xb4,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xbb,0xba,0xb8,0x00, + 0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcd,0xcc,0xca,0x00, + 0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd3,0x00, + 0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00,0xdf,0xde,0xdb,0x00, + 0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe8,0xe6,0xe4,0x00, + 0xe9,0xe7,0xe5,0x00,0xea,0xe8,0xe6,0x00,0xeb,0xe9,0xe6,0x00,0xed,0xeb,0xe7,0x00,0xee,0xec,0xe8,0x00,0xef,0xed,0xe9,0x00,0xf0,0xee,0xea,0x00,0xf1,0xef,0xec,0x00, + 0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00, + 0xfb,0xfa,0xf6,0x00,0xfc,0xfb,0xf7,0x00,0xfd,0xfc,0xf8,0x00,0xfe,0xfd,0xf9,0x00,0xff,0xfe,0xfa,0x00,0xff,0xfe,0xfb,0x00,0xff,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00, + 0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1d,0x1c,0x1c,0x00,0x1e,0x1d,0x1d,0x00,0x1f,0x1e,0x1e,0x00,0x20,0x1f,0x1f,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2f,0x2e,0x00,0x2f,0x30,0x2f,0x00,0x30,0x31,0x30,0x00,0x31,0x32,0x31,0x00, + 0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x36,0x36,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00, + 0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x4a,0x48,0x00,0x4a,0x4b,0x49,0x00,0x4b,0x4c,0x4a,0x00,0x4c,0x4d,0x4b,0x00, + 0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00, + 0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00, + 0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x67,0x64,0x00,0x66,0x68,0x65,0x00,0x67,0x69,0x66,0x00,0x68,0x6a,0x67,0x00, + 0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00, + 0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x8a,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8f,0x8c,0x00,0x8e,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00, + 0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa3,0xa2,0xa1,0x00,0xa4,0xa3,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00, + 0xb3,0xb2,0xb0,0x00,0xb4,0xb3,0xb1,0x00,0xb5,0xb4,0xb2,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbc,0xbb,0xb9,0x00,0xbd,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00, + 0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd1,0xd0,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd9,0xd8,0xd6,0x00,0xda,0xd9,0xd7,0x00,0xdb,0xda,0xd8,0x00,0xdc,0xdb,0xd9,0x00,0xdd,0xdc,0xda,0x00,0xde,0xdd,0xdb,0x00, + 0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe9,0xe7,0xe5,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xee,0xec,0xe8,0x00,0xef,0xed,0xe9,0x00,0xf0,0xee,0xea,0x00,0xf1,0xef,0xeb,0x00, + 0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00, + 0xfb,0xf9,0xf6,0x00,0xfc,0xfa,0xf7,0x00,0xfd,0xfb,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xff,0xfe,0xfa,0x00,0xff,0xfe,0xfb,0x00,0xff,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x16,0x00, + 0x18,0x18,0x17,0x00,0x19,0x19,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x23,0x23,0x00,0x23,0x24,0x24,0x00,0x24,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2b,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x31,0x30,0x00,0x32,0x32,0x31,0x00, + 0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x36,0x36,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00, + 0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00, + 0x56,0x56,0x55,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00, + 0x61,0x61,0x5f,0x00,0x62,0x63,0x60,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00, + 0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00, + 0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00, + 0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00, + 0x96,0x96,0x94,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa3,0xa2,0xa1,0x00,0xa4,0xa3,0xa2,0x00,0xa5,0xa4,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xaf,0xae,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00, + 0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb5,0xb4,0xb2,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00, + 0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00, + 0xcd,0xcc,0xca,0x00,0xce,0xce,0xcb,0x00,0xd0,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00, + 0xdf,0xde,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe2,0xe1,0xdd,0x00,0xe3,0xe2,0xde,0x00,0xe4,0xe3,0xdf,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe8,0xe6,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe7,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00, + 0xf1,0xef,0xec,0x00,0xf2,0xf1,0xed,0x00,0xf3,0xf2,0xee,0x00,0xf4,0xf3,0xef,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00, + 0xfa,0xf9,0xf5,0x00,0xfb,0xfa,0xf6,0x00,0xfd,0xfb,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xff,0xfd,0xfa,0x00,0xff,0xfe,0xfb,0x00,0xff,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x16,0x00, + 0x18,0x18,0x17,0x00,0x19,0x19,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x23,0x23,0x00,0x23,0x24,0x24,0x00,0x24,0x25,0x25,0x00,0x25,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x31,0x30,0x00,0x32,0x32,0x31,0x00, + 0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x36,0x36,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00, + 0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x49,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00, + 0x56,0x56,0x55,0x00,0x57,0x58,0x56,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00, + 0x61,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00, + 0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00, + 0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00, + 0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00, + 0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa3,0xa2,0xa1,0x00,0xa4,0xa3,0xa2,0x00,0xa5,0xa4,0xa3,0x00,0xa6,0xa5,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00, + 0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb5,0xb4,0xb2,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00, + 0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xcb,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00, + 0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xd0,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00, + 0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe2,0xe1,0xdd,0x00,0xe3,0xe2,0xde,0x00,0xe4,0xe3,0xdf,0x00,0xe5,0xe4,0xe0,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe5,0xe3,0x00, + 0xe8,0xe6,0xe4,0x00,0xe9,0xe7,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe6,0x00,0xed,0xeb,0xe7,0x00,0xee,0xec,0xe8,0x00,0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00, + 0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf2,0xee,0x00,0xf4,0xf3,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf8,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00, + 0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00,0xfd,0xfb,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xff,0xfd,0xfa,0x00,0xff,0xfe,0xfb,0x00,0xff,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x13,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00,0x17,0x17,0x16,0x00, + 0x18,0x18,0x17,0x00,0x19,0x19,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x24,0x24,0x00,0x24,0x25,0x25,0x00,0x25,0x26,0x26,0x00,0x26,0x27,0x27,0x00,0x28,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2c,0x2b,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x32,0x32,0x31,0x00, + 0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x36,0x36,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x39,0x00,0x3b,0x3b,0x3a,0x00, + 0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x49,0x4a,0x49,0x00,0x4a,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00,0x55,0x55,0x54,0x00, + 0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x60,0x5e,0x00, + 0x61,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00, + 0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00, + 0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x84,0x81,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00, + 0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00, + 0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9f,0x9f,0x9c,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa4,0xa3,0xa1,0x00,0xa5,0xa4,0xa3,0x00,0xa6,0xa5,0xa4,0x00,0xa7,0xa6,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb1,0xb1,0xae,0x00, + 0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb6,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xba,0xb7,0x00, + 0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcc,0xcb,0xc9,0x00, + 0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00,0xd5,0xd4,0xd1,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00, + 0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe3,0xe1,0xde,0x00,0xe4,0xe3,0xdf,0x00,0xe5,0xe3,0xe0,0x00,0xe6,0xe4,0xe1,0x00,0xe7,0xe5,0xe2,0x00, + 0xe8,0xe6,0xe4,0x00,0xe9,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xea,0xe6,0x00,0xed,0xeb,0xe7,0x00,0xee,0xec,0xe8,0x00,0xef,0xed,0xe9,0x00,0xf0,0xee,0xeb,0x00, + 0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf3,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf3,0x00,0xf9,0xf7,0xf4,0x00, + 0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00,0xfc,0xfa,0xf7,0x00,0xfe,0xfc,0xf9,0x00,0xff,0xfd,0xfa,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfe,0xfc,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x18,0x18,0x17,0x00,0x19,0x19,0x18,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x25,0x25,0x00,0x25,0x26,0x26,0x00,0x26,0x27,0x27,0x00,0x27,0x28,0x28,0x00, + 0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2c,0x2b,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x32,0x31,0x31,0x00, + 0x33,0x33,0x32,0x00,0x34,0x34,0x33,0x00,0x35,0x35,0x34,0x00,0x36,0x36,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x49,0x48,0x00,0x49,0x4a,0x49,0x00,0x4a,0x4b,0x4a,0x00,0x4b,0x4c,0x4b,0x00, + 0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00, + 0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5c,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x60,0x5e,0x00, + 0x61,0x61,0x5f,0x00,0x62,0x62,0x60,0x00,0x63,0x63,0x61,0x00,0x64,0x64,0x62,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00, + 0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00, + 0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00, + 0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00, + 0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00, + 0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa5,0xa4,0xa2,0x00,0xa6,0xa5,0xa3,0x00,0xa7,0xa6,0xa4,0x00,0xa8,0xa7,0xa5,0x00, + 0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb5,0x00,0xb9,0xb8,0xb6,0x00,0xba,0xb9,0xb7,0x00, + 0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00, + 0xcd,0xcc,0xca,0x00,0xce,0xcd,0xcb,0x00,0xcf,0xce,0xcc,0x00,0xd0,0xcf,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00,0xd5,0xd4,0xd1,0x00, + 0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00, + 0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00, + 0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xeb,0xe7,0x00,0xed,0xec,0xe8,0x00,0xee,0xed,0xe9,0x00,0xef,0xee,0xea,0x00, + 0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf3,0x00,0xf8,0xf7,0xf4,0x00, + 0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00,0xfc,0xfa,0xf7,0x00,0xfd,0xfb,0xf8,0x00,0xff,0xfd,0xfa,0x00,0xff,0xfd,0xfb,0x00,0xff,0xfe,0xfc,0x00,0xff,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x27,0x26,0x00,0x27,0x28,0x27,0x00, + 0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2c,0x2b,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x32,0x31,0x31,0x00, + 0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4b,0x4a,0x00,0x4b,0x4c,0x4b,0x00, + 0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x54,0x52,0x00,0x54,0x55,0x53,0x00, + 0x55,0x56,0x54,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x60,0x5e,0x00, + 0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x68,0x66,0x00, + 0x69,0x69,0x67,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00, + 0x71,0x72,0x70,0x00,0x73,0x73,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00, + 0x7a,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x81,0x7e,0x00,0x81,0x82,0x7f,0x00,0x82,0x83,0x80,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x8a,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8c,0x8c,0x8a,0x00, + 0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00, + 0x9f,0x9f,0x9d,0x00,0xa1,0xa0,0x9e,0x00,0xa2,0xa1,0x9f,0x00,0xa3,0xa2,0xa0,0x00,0xa4,0xa3,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00, + 0xb1,0xb1,0xae,0x00,0xb3,0xb2,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00, + 0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbd,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xce,0xcd,0xca,0x00,0xcf,0xce,0xcb,0x00,0xd0,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00, + 0xd5,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00, + 0xde,0xdd,0xda,0x00,0xe0,0xde,0xdb,0x00,0xe1,0xdf,0xdc,0x00,0xe2,0xe0,0xdd,0x00,0xe3,0xe2,0xde,0x00,0xe4,0xe3,0xdf,0x00,0xe5,0xe4,0xe0,0x00,0xe6,0xe5,0xe1,0x00, + 0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00, + 0xf0,0xee,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf6,0xf3,0x00,0xf8,0xf7,0xf4,0x00, + 0xf9,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00,0xfc,0xfa,0xf7,0x00,0xfd,0xfb,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xfe,0xfd,0xfa,0x00,0xff,0xfe,0xfb,0x00,0xff,0xfe,0xfc,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x1a,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x27,0x26,0x00,0x27,0x28,0x27,0x00, + 0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2c,0x2b,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x32,0x31,0x31,0x00, + 0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4b,0x4a,0x00,0x4b,0x4c,0x4b,0x00, + 0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x54,0x52,0x00,0x54,0x55,0x53,0x00, + 0x55,0x56,0x54,0x00,0x57,0x57,0x55,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5c,0x00,0x5f,0x60,0x5e,0x00, + 0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x67,0x65,0x00,0x68,0x68,0x66,0x00, + 0x69,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00, + 0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00, + 0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x82,0x7f,0x00,0x82,0x83,0x80,0x00, + 0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x89,0x89,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8c,0x8c,0x8a,0x00, + 0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00, + 0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa2,0xa1,0x9f,0x00,0xa3,0xa2,0xa0,0x00,0xa4,0xa3,0xa1,0x00,0xa5,0xa4,0xa2,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00, + 0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00, + 0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbd,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xcf,0xce,0xcb,0x00,0xd0,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00, + 0xd5,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00, + 0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe1,0xdf,0xdc,0x00,0xe2,0xe0,0xdd,0x00,0xe3,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe5,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00, + 0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00,0xef,0xed,0xea,0x00, + 0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf6,0xf3,0x00,0xf8,0xf7,0xf4,0x00, + 0xf9,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfc,0xfa,0xf7,0x00,0xfd,0xfb,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xfe,0xfd,0xfa,0x00,0xff,0xfe,0xfb,0x00,0xff,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1b,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x28,0x27,0x00, + 0x28,0x29,0x28,0x00,0x29,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2d,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x32,0x31,0x31,0x00, + 0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4c,0x4b,0x00, + 0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x55,0x53,0x00, + 0x55,0x56,0x54,0x00,0x56,0x57,0x55,0x00,0x58,0x58,0x56,0x00,0x59,0x5a,0x58,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00,0x5f,0x5f,0x5d,0x00, + 0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x68,0x68,0x66,0x00, + 0x69,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00,0x6b,0x6b,0x69,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00, + 0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00, + 0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x83,0x80,0x00, + 0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8c,0x89,0x00, + 0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9e,0x9e,0x9b,0x00, + 0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0xa0,0x00,0xa4,0xa3,0xa1,0x00,0xa5,0xa4,0xa2,0x00,0xa6,0xa5,0xa3,0x00,0xa7,0xa7,0xa5,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00, + 0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00, + 0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xbb,0x00,0xbf,0xbe,0xbc,0x00,0xc0,0xbf,0xbd,0x00,0xc1,0xc0,0xbe,0x00,0xc2,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xd0,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00, + 0xd5,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00, + 0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe3,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe5,0xe1,0x00, + 0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe9,0xe8,0xe4,0x00,0xea,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xef,0xed,0xea,0x00, + 0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf2,0xef,0x00,0xf5,0xf3,0xf0,0x00,0xf6,0xf4,0xf1,0x00,0xf7,0xf5,0xf2,0x00,0xf8,0xf7,0xf3,0x00, + 0xf9,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xfa,0xf7,0x00,0xfd,0xfb,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xfe,0xfd,0xfa,0x00,0xfe,0xfd,0xfb,0x00,0xff,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x13,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1c,0x1c,0x00,0x1c,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x29,0x29,0x00,0x29,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00, + 0x33,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x39,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00, + 0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00, + 0x55,0x56,0x54,0x00,0x56,0x57,0x55,0x00,0x58,0x58,0x56,0x00,0x59,0x59,0x57,0x00,0x5b,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00, + 0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00, + 0x69,0x69,0x67,0x00,0x6a,0x6a,0x68,0x00,0x6b,0x6b,0x69,0x00,0x6c,0x6c,0x6a,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00, + 0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00, + 0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00, + 0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00, + 0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9e,0x00,0xa2,0xa2,0x9f,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00, + 0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00, + 0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd1,0xd0,0xcd,0x00,0xd2,0xd1,0xce,0x00,0xd3,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00, + 0xd5,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00, + 0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00, + 0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe9,0xe8,0xe4,0x00,0xea,0xe9,0xe5,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00, + 0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf1,0xee,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00,0xf7,0xf6,0xf3,0x00, + 0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00,0xfb,0xfa,0xf6,0x00,0xfc,0xfb,0xf7,0x00,0xfe,0xfc,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xfe,0xfd,0xfa,0x00,0xff,0xfe,0xfb,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x28,0x00, + 0x28,0x28,0x29,0x00,0x29,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00, + 0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x39,0x00, + 0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4f,0x4d,0x00,0x4f,0x50,0x4e,0x00,0x50,0x51,0x4f,0x00,0x51,0x52,0x50,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00, + 0x55,0x55,0x54,0x00,0x56,0x57,0x55,0x00,0x58,0x58,0x56,0x00,0x59,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5f,0x5d,0x00, + 0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x65,0x63,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00, + 0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6f,0x6f,0x6d,0x00,0x70,0x70,0x6e,0x00, + 0x71,0x71,0x6f,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x79,0x76,0x00,0x78,0x7a,0x77,0x00, + 0x79,0x7b,0x78,0x00,0x7b,0x7c,0x79,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x7f,0x00, + 0x83,0x83,0x80,0x00,0x84,0x84,0x81,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00, + 0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa3,0xa2,0xa0,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa9,0xa9,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xaf,0xab,0x00,0xaf,0xb0,0xac,0x00, + 0xb0,0xb1,0xad,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00, + 0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbe,0xbd,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00, + 0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc1,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcd,0xcc,0xc9,0x00,0xce,0xce,0xca,0x00,0xcf,0xcf,0xcb,0x00,0xd0,0xd0,0xcc,0x00,0xd1,0xd1,0xcd,0x00,0xd2,0xd2,0xce,0x00,0xd3,0xd3,0xcf,0x00, + 0xd4,0xd4,0xd0,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00, + 0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe2,0xe1,0xdd,0x00,0xe3,0xe2,0xde,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe9,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00, + 0xef,0xed,0xea,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf4,0xf2,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00, + 0xf8,0xf7,0xf4,0x00,0xfa,0xf8,0xf5,0x00,0xfb,0xf9,0xf6,0x00,0xfc,0xfa,0xf7,0x00,0xfd,0xfb,0xf8,0x00,0xfe,0xfc,0xf9,0x00,0xfe,0xfd,0xfa,0x00,0xff,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00, + 0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00, + 0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00,0x3a,0x3a,0x39,0x00, + 0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4f,0x4d,0x00,0x4f,0x50,0x4e,0x00,0x50,0x51,0x4f,0x00,0x51,0x52,0x50,0x00,0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00, + 0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x58,0x58,0x56,0x00,0x59,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5b,0x00,0x5e,0x5f,0x5d,0x00, + 0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00, + 0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6f,0x6f,0x6d,0x00,0x70,0x70,0x6e,0x00, + 0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x79,0x76,0x00,0x78,0x7a,0x77,0x00, + 0x79,0x7b,0x78,0x00,0x7a,0x7c,0x79,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x7f,0x00, + 0x83,0x83,0x80,0x00,0x84,0x84,0x81,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9c,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00, + 0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xaa,0xaa,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xaf,0xab,0x00,0xaf,0xb0,0xac,0x00, + 0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xae,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00, + 0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00, + 0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc5,0xc4,0xc2,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xce,0xce,0xca,0x00,0xcf,0xcf,0xcb,0x00,0xd0,0xd0,0xcc,0x00,0xd1,0xd1,0xcd,0x00,0xd2,0xd2,0xce,0x00,0xd3,0xd3,0xcf,0x00, + 0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00, + 0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe9,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00, + 0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00, + 0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfb,0xf9,0xf5,0x00,0xfc,0xfa,0xf6,0x00,0xfd,0xfb,0xf7,0x00,0xfe,0xfc,0xf8,0x00,0xfe,0xfd,0xfa,0x00,0xff,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1f,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x28,0x00, + 0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00, + 0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x39,0x00, + 0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x49,0x4a,0x49,0x00,0x4b,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x50,0x4e,0x00,0x50,0x51,0x4f,0x00,0x51,0x52,0x50,0x00,0x52,0x53,0x52,0x00,0x54,0x54,0x53,0x00, + 0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x59,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5e,0x5e,0x5d,0x00, + 0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x67,0x68,0x66,0x00, + 0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x70,0x70,0x6e,0x00, + 0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x73,0x71,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x7a,0x77,0x00, + 0x79,0x7b,0x78,0x00,0x7a,0x7c,0x79,0x00,0x7b,0x7d,0x7a,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7e,0x00,0x82,0x82,0x7f,0x00, + 0x83,0x83,0x80,0x00,0x84,0x84,0x81,0x00,0x85,0x85,0x82,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8b,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x92,0x00, + 0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9c,0x99,0x00,0x9d,0x9d,0x9a,0x00, + 0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa2,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xab,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xb0,0xac,0x00, + 0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xae,0x00,0xb2,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00, + 0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc1,0xc1,0xbe,0x00, + 0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc6,0xc5,0xc3,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xcf,0xcf,0xcb,0x00,0xd0,0xd0,0xcc,0x00,0xd1,0xd1,0xcd,0x00,0xd2,0xd2,0xce,0x00,0xd3,0xd3,0xcf,0x00, + 0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdc,0xd8,0x00, + 0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe4,0xe3,0xdf,0x00,0xe5,0xe4,0xe1,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xea,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00, + 0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf1,0xed,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf7,0xf6,0xf2,0x00, + 0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00,0xfb,0xfa,0xf6,0x00,0xfd,0xfb,0xf7,0x00,0xfd,0xfc,0xf8,0x00,0xfe,0xfd,0xf9,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00, + 0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00,0x42,0x42,0x41,0x00, + 0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x48,0x47,0x00,0x48,0x49,0x48,0x00,0x49,0x4a,0x49,0x00,0x4a,0x4b,0x4a,0x00, + 0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x51,0x4f,0x00,0x51,0x52,0x50,0x00,0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00, + 0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x58,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5d,0x00, + 0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00, + 0x71,0x71,0x6f,0x00,0x72,0x72,0x70,0x00,0x73,0x73,0x71,0x00,0x74,0x74,0x72,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7b,0x78,0x00,0x7a,0x7c,0x79,0x00,0x7b,0x7d,0x7a,0x00,0x7c,0x7e,0x7b,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7d,0x00,0x80,0x81,0x7e,0x00,0x81,0x82,0x7f,0x00, + 0x83,0x83,0x80,0x00,0x84,0x84,0x81,0x00,0x85,0x85,0x82,0x00,0x86,0x86,0x83,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00, + 0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9c,0x99,0x00,0x9c,0x9d,0x9a,0x00, + 0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00, + 0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00,0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00, + 0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xae,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00, + 0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc7,0xc6,0xc4,0x00,0xc8,0xc7,0xc5,0x00,0xc9,0xc8,0xc6,0x00,0xca,0xc9,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xd0,0xd0,0xcc,0x00,0xd1,0xd1,0xcd,0x00,0xd2,0xd2,0xce,0x00,0xd3,0xd3,0xcf,0x00, + 0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00, + 0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe4,0xe3,0xdf,0x00,0xe5,0xe4,0xe0,0x00, + 0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xeb,0xe9,0xe6,0x00,0xec,0xea,0xe7,0x00,0xed,0xeb,0xe8,0x00,0xee,0xec,0xe9,0x00, + 0xef,0xed,0xea,0x00,0xf0,0xee,0xeb,0x00,0xf1,0xef,0xec,0x00,0xf2,0xf0,0xed,0x00,0xf3,0xf2,0xee,0x00,0xf4,0xf3,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00, + 0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00,0xfb,0xfa,0xf6,0x00,0xfc,0xfb,0xf7,0x00,0xfd,0xfc,0xf8,0x00,0xfe,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x34,0x00,0x36,0x35,0x35,0x00,0x37,0x37,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x4a,0x49,0x00,0x4a,0x4b,0x4a,0x00, + 0x4b,0x4c,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00, + 0x54,0x54,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x59,0x5a,0x58,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5d,0x00, + 0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00, + 0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x77,0x74,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00, + 0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00, + 0x8b,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x93,0x90,0x00,0x92,0x94,0x91,0x00, + 0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x9a,0x9a,0x97,0x00,0x9b,0x9c,0x99,0x00,0x9c,0x9d,0x9a,0x00, + 0x9d,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00, + 0xa6,0xa7,0xa4,0x00,0xa8,0xa8,0xa5,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb4,0x00, + 0xb9,0xb8,0xb5,0x00,0xba,0xb9,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00, + 0xc1,0xc1,0xbe,0x00,0xc3,0xc2,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00, + 0xca,0xca,0xc7,0x00,0xcc,0xcc,0xc8,0x00,0xcd,0xcd,0xc9,0x00,0xce,0xce,0xca,0x00,0xcf,0xcf,0xcb,0x00,0xd0,0xd0,0xcc,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00, + 0xd3,0xd3,0xd0,0x00,0xd5,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00, + 0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe5,0xe3,0xe0,0x00, + 0xe6,0xe4,0xe1,0x00,0xe7,0xe5,0xe2,0x00,0xe8,0xe7,0xe3,0x00,0xe9,0xe8,0xe4,0x00,0xea,0xe9,0xe5,0x00,0xeb,0xea,0xe6,0x00,0xec,0xeb,0xe7,0x00,0xed,0xec,0xe8,0x00, + 0xee,0xed,0xe9,0x00,0xef,0xee,0xea,0x00,0xf0,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xee,0x00,0xf4,0xf3,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00, + 0xf7,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00,0xfc,0xfa,0xf6,0x00,0xfc,0xfb,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x34,0x00,0x36,0x35,0x35,0x00,0x37,0x36,0x36,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x4a,0x49,0x00,0x4a,0x4b,0x4a,0x00, + 0x4b,0x4c,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00, + 0x54,0x54,0x54,0x00,0x55,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5d,0x00, + 0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00, + 0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00, + 0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00, + 0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x93,0x90,0x00,0x92,0x94,0x91,0x00, + 0x93,0x95,0x92,0x00,0x94,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9b,0x9c,0x99,0x00,0x9c,0x9d,0x9a,0x00, + 0x9d,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00, + 0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb7,0xb6,0xb4,0x00,0xb8,0xb7,0xb4,0x00, + 0xb9,0xb8,0xb5,0x00,0xba,0xb9,0xb6,0x00,0xbb,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00, + 0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00, + 0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcd,0xcd,0xc9,0x00,0xce,0xce,0xca,0x00,0xcf,0xcf,0xcb,0x00,0xd0,0xd0,0xcc,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00, + 0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd6,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00, + 0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe4,0xe2,0xdf,0x00,0xe5,0xe3,0xe0,0x00, + 0xe6,0xe4,0xe1,0x00,0xe7,0xe5,0xe2,0x00,0xe8,0xe7,0xe3,0x00,0xe9,0xe8,0xe4,0x00,0xea,0xe9,0xe5,0x00,0xeb,0xea,0xe6,0x00,0xec,0xeb,0xe7,0x00,0xed,0xec,0xe8,0x00, + 0xee,0xed,0xe9,0x00,0xef,0xee,0xea,0x00,0xf0,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xed,0x00,0xf3,0xf2,0xee,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00, + 0xf7,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00,0xfb,0xfa,0xf6,0x00,0xfc,0xfb,0xf7,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x16,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x27,0x27,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x34,0x34,0x00,0x36,0x35,0x35,0x00,0x37,0x36,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4b,0x4a,0x00, + 0x4b,0x4c,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x53,0x00, + 0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5c,0x00, + 0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00, + 0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x78,0x79,0x77,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00, + 0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x86,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x8a,0x8a,0x88,0x00, + 0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x94,0x91,0x00, + 0x93,0x95,0x92,0x00,0x94,0x96,0x93,0x00,0x95,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9a,0x9b,0x98,0x00,0x9b,0x9d,0x9a,0x00, + 0x9d,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa3,0x00, + 0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00, + 0xb9,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00, + 0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00, + 0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xce,0xca,0x00,0xcf,0xcf,0xcb,0x00,0xd0,0xd0,0xcc,0x00,0xd1,0xd1,0xcd,0x00,0xd2,0xd2,0xcf,0x00, + 0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd7,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xdb,0xd7,0x00, + 0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00, + 0xe6,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xee,0xed,0xe9,0x00,0xef,0xee,0xea,0x00,0xf0,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xed,0x00,0xf3,0xf2,0xee,0x00,0xf4,0xf3,0xef,0x00,0xf5,0xf5,0xf1,0x00, + 0xf7,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00,0xfb,0xfa,0xf6,0x00,0xfc,0xfb,0xf7,0x00,0xfd,0xfd,0xf8,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00, + 0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00, + 0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x34,0x34,0x00,0x36,0x35,0x35,0x00,0x37,0x36,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x38,0x00, + 0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x45,0x44,0x00,0x45,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4c,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x5a,0x58,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5c,0x5b,0x00,0x5d,0x5e,0x5c,0x00, + 0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00, + 0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00, + 0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00, + 0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00, + 0x93,0x95,0x92,0x00,0x94,0x96,0x93,0x00,0x95,0x97,0x94,0x00,0x96,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9a,0x9b,0x98,0x00,0x9b,0x9c,0x99,0x00, + 0x9c,0x9e,0x9b,0x00,0x9d,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00, + 0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00, + 0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00, + 0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xcf,0xcb,0x00,0xcf,0xd0,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00, + 0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd8,0xd7,0xd4,0x00,0xd9,0xd8,0xd5,0x00,0xda,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00, + 0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00,0xe4,0xe3,0xe0,0x00, + 0xe5,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00,0xe8,0xe7,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf4,0xf3,0xef,0x00,0xf5,0xf4,0xf0,0x00, + 0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfd,0xfd,0xf8,0x00,0xfe,0xfe,0xf9,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x15,0x00, + 0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00, + 0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x38,0x00, + 0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x45,0x44,0x00,0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4e,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00,0x51,0x50,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x57,0x55,0x00,0x57,0x58,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00, + 0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x80,0x7d,0x00,0x80,0x81,0x7e,0x00, + 0x81,0x82,0x7f,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00, + 0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00, + 0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x9a,0x97,0x00,0x99,0x9b,0x98,0x00,0x9a,0x9c,0x99,0x00, + 0x9c,0x9d,0x9a,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa3,0xa4,0xa1,0x00,0xa4,0xa5,0xa2,0x00, + 0xa5,0xa6,0xa3,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00, + 0xae,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb3,0x00, + 0xb8,0xb8,0xb4,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00, + 0xc9,0xc9,0xc6,0x00,0xca,0xcb,0xc7,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00, + 0xd2,0xd2,0xcf,0x00,0xd4,0xd3,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00, + 0xdb,0xdb,0xd7,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00, + 0xe5,0xe3,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00, + 0xed,0xec,0xe8,0x00,0xee,0xed,0xe9,0x00,0xef,0xef,0xea,0x00,0xf0,0xf0,0xeb,0x00,0xf1,0xf1,0xec,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00, + 0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00,0xf8,0xf8,0xf3,0x00,0xf9,0xf9,0xf4,0x00,0xfa,0xfa,0xf5,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfd,0xf8,0x00,0xfe,0xfe,0xf9,0x00, + 0xff,0xff,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x15,0x00, + 0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00, + 0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00, + 0x31,0x30,0x30,0x00,0x32,0x31,0x31,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x37,0x00,0x39,0x39,0x38,0x00, + 0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x45,0x44,0x00,0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4e,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00,0x51,0x50,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x57,0x55,0x00,0x57,0x58,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5b,0x59,0x00,0x5c,0x5c,0x5a,0x00,0x5d,0x5e,0x5c,0x00, + 0x5f,0x5f,0x5d,0x00,0x60,0x60,0x5e,0x00,0x61,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7b,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7f,0x80,0x7d,0x00,0x7f,0x81,0x7e,0x00, + 0x80,0x82,0x7f,0x00,0x81,0x83,0x80,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x89,0x86,0x00,0x89,0x8a,0x87,0x00, + 0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00, + 0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9b,0x98,0x00,0x9a,0x9c,0x99,0x00, + 0x9b,0x9d,0x9a,0x00,0x9c,0x9e,0x9b,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa4,0xa1,0x00,0xa4,0xa5,0xa2,0x00, + 0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00, + 0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb3,0x00, + 0xb7,0xb8,0xb4,0x00,0xb8,0xb9,0xb5,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00, + 0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00, + 0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00, + 0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00, + 0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00, + 0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xef,0xea,0x00,0xef,0xf0,0xeb,0x00,0xf0,0xf1,0xec,0x00,0xf1,0xf2,0xed,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00, + 0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf8,0xf3,0x00,0xf8,0xf9,0xf4,0x00,0xf9,0xfa,0xf5,0x00,0xfb,0xfb,0xf6,0x00,0xfc,0xfd,0xf8,0x00,0xfe,0xfe,0xf9,0x00, + 0xff,0xff,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x15,0x00, + 0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x19,0x18,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x27,0x00, + 0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00, + 0x31,0x30,0x30,0x00,0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x38,0x00, + 0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x41,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x46,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00,0x51,0x50,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x58,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5c,0x00, + 0x5f,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x66,0x67,0x65,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7c,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7e,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x81,0x7e,0x00, + 0x80,0x82,0x7f,0x00,0x81,0x83,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x8a,0x87,0x00, + 0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x93,0x90,0x00, + 0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9c,0x99,0x00, + 0x9b,0x9d,0x9a,0x00,0x9c,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa2,0x00, + 0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xab,0x00, + 0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb7,0xb3,0x00, + 0xb7,0xb8,0xb4,0x00,0xb8,0xb9,0xb5,0x00,0xb9,0xba,0xb6,0x00,0xba,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00, + 0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00, + 0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00, + 0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00, + 0xe4,0xe3,0xe0,0x00,0xe5,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00, + 0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xf0,0xeb,0x00,0xf0,0xf1,0xec,0x00,0xf1,0xf2,0xed,0x00,0xf3,0xf3,0xee,0x00,0xf4,0xf4,0xf0,0x00, + 0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf9,0xf4,0x00,0xf9,0xfa,0xf5,0x00,0xfb,0xfb,0xf6,0x00,0xfc,0xfc,0xf7,0x00,0xfd,0xfe,0xf9,0x00, + 0xff,0xff,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x15,0x00, + 0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x31,0x30,0x30,0x00,0x32,0x31,0x31,0x00,0x33,0x32,0x32,0x00,0x34,0x33,0x33,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x3a,0x3a,0x39,0x00,0x3b,0x3b,0x3a,0x00,0x3c,0x3c,0x3b,0x00,0x3d,0x3d,0x3c,0x00,0x3e,0x3e,0x3d,0x00,0x3f,0x3f,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00, + 0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x47,0x46,0x00,0x47,0x48,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00,0x51,0x50,0x50,0x00,0x52,0x52,0x51,0x00,0x53,0x53,0x52,0x00, + 0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00,0x5d,0x5d,0x5c,0x00, + 0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00, + 0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00, + 0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x82,0x7f,0x00,0x81,0x83,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8e,0x00,0x91,0x91,0x8f,0x00,0x92,0x92,0x90,0x00, + 0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00, + 0x9b,0x9d,0x9a,0x00,0x9c,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00, + 0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00, + 0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00, + 0xb7,0xb8,0xb4,0x00,0xb8,0xb9,0xb5,0x00,0xb9,0xba,0xb6,0x00,0xba,0xbb,0xb7,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00, + 0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00, + 0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00, + 0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00, + 0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00,0xe3,0xe2,0xdf,0x00, + 0xe4,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00, + 0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf1,0xec,0x00,0xf1,0xf2,0xed,0x00,0xf3,0xf3,0xee,0x00,0xf4,0xf4,0xef,0x00, + 0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xfa,0xfa,0xf5,0x00,0xfb,0xfb,0xf6,0x00,0xfc,0xfc,0xf7,0x00,0xfd,0xfd,0xf8,0x00, + 0xff,0xff,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00, + 0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00, + 0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00, + 0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5c,0x00, + 0x5e,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x61,0x62,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00, + 0x77,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x87,0x84,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x91,0x91,0x8e,0x00,0x92,0x92,0x8f,0x00, + 0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00, + 0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa1,0xa2,0x9f,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00, + 0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00, + 0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xae,0x00,0xb2,0xb3,0xaf,0x00,0xb3,0xb4,0xb0,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00, + 0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00, + 0xc8,0xc8,0xc5,0x00,0xc9,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xcd,0x00, + 0xd1,0xd1,0xce,0x00,0xd3,0xd3,0xcf,0x00,0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00, + 0xda,0xda,0xd7,0x00,0xdc,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00, + 0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xea,0x00,0xf0,0xf0,0xeb,0x00,0xf1,0xf1,0xed,0x00,0xf3,0xf2,0xee,0x00,0xf4,0xf3,0xef,0x00, + 0xf5,0xf4,0xf0,0x00,0xf6,0xf6,0xf1,0x00,0xf7,0xf7,0xf2,0x00,0xf9,0xf8,0xf3,0x00,0xfa,0xf9,0xf4,0x00,0xfb,0xfb,0xf6,0x00,0xfc,0xfc,0xf7,0x00,0xfd,0xfd,0xf8,0x00, + 0xfe,0xfe,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x3f,0x00,0x41,0x41,0x40,0x00, + 0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x49,0x48,0x00,0x4a,0x4a,0x49,0x00, + 0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x52,0x51,0x00,0x52,0x53,0x52,0x00, + 0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00,0x5c,0x5d,0x5c,0x00, + 0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x61,0x62,0x61,0x00,0x62,0x63,0x62,0x00,0x64,0x65,0x63,0x00,0x65,0x66,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00, + 0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x91,0x91,0x8e,0x00,0x92,0x92,0x8f,0x00, + 0x93,0x93,0x90,0x00,0x94,0x94,0x91,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x99,0x00, + 0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa1,0xa2,0x9f,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00, + 0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xac,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00, + 0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xae,0x00,0xb2,0xb3,0xaf,0x00,0xb3,0xb4,0xb0,0x00,0xb5,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00, + 0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00, + 0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00, + 0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xcd,0x00, + 0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdd,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00, + 0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xea,0x00,0xf0,0xf0,0xeb,0x00,0xf1,0xf1,0xec,0x00,0xf3,0xf2,0xee,0x00,0xf4,0xf3,0xef,0x00, + 0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf8,0xf7,0xf2,0x00,0xf9,0xf8,0xf3,0x00,0xfa,0xf9,0xf4,0x00,0xfb,0xfa,0xf5,0x00,0xfc,0xfc,0xf7,0x00,0xfd,0xfd,0xf8,0x00, + 0xfe,0xfe,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x12,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1e,0x1e,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x29,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x40,0x00, + 0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x49,0x00, + 0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x53,0x52,0x00, + 0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5c,0x5c,0x5b,0x00, + 0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x61,0x62,0x61,0x00,0x62,0x63,0x62,0x00,0x63,0x64,0x63,0x00,0x65,0x66,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6e,0x6f,0x6d,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x76,0x00, + 0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x89,0x87,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00, + 0x93,0x93,0x90,0x00,0x94,0x94,0x91,0x00,0x95,0x95,0x92,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9b,0x99,0x00, + 0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa1,0xa2,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa4,0xa4,0xa2,0x00, + 0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xad,0xad,0xaa,0x00, + 0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb2,0xae,0x00,0xb2,0xb3,0xaf,0x00,0xb3,0xb4,0xb0,0x00,0xb4,0xb5,0xb1,0x00,0xb6,0xb6,0xb3,0x00, + 0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00, + 0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00, + 0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00, + 0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd6,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xde,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00, + 0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xef,0xef,0xea,0x00,0xf0,0xf0,0xeb,0x00,0xf1,0xf1,0xec,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00, + 0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00,0xf8,0xf8,0xf3,0x00,0xfa,0xf9,0xf4,0x00,0xfb,0xfa,0xf5,0x00,0xfc,0xfb,0xf6,0x00,0xfd,0xfd,0xf8,0x00, + 0xfe,0xfe,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x13,0x13,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00, + 0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x42,0x42,0x41,0x00,0x43,0x43,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4b,0x4b,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00, + 0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x61,0x62,0x61,0x00,0x62,0x63,0x62,0x00,0x63,0x64,0x63,0x00,0x64,0x65,0x64,0x00, + 0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00, + 0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00, + 0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00,0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00, + 0x92,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa1,0xa2,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa3,0xa4,0xa1,0x00, + 0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00, + 0xae,0xae,0xab,0x00,0xaf,0xaf,0xac,0x00,0xb0,0xb0,0xad,0x00,0xb1,0xb1,0xae,0x00,0xb2,0xb3,0xaf,0x00,0xb3,0xb4,0xb0,0x00,0xb4,0xb5,0xb1,0x00,0xb5,0xb6,0xb2,0x00, + 0xb7,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00, + 0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00, + 0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00, + 0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xdf,0xde,0xdb,0x00,0xe0,0xdf,0xdc,0x00,0xe1,0xe0,0xdd,0x00,0xe2,0xe1,0xde,0x00, + 0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00, + 0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf9,0xf4,0x00,0xfa,0xfa,0xf5,0x00,0xfb,0xfb,0xf6,0x00,0xfc,0xfc,0xf7,0x00, + 0xfe,0xfe,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x13,0x00,0x13,0x12,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x25,0x00,0x25,0x26,0x26,0x00, + 0x26,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2c,0x2c,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00, + 0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x63,0x00,0x64,0x65,0x64,0x00, + 0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x73,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7f,0x7d,0x00,0x7e,0x80,0x7e,0x00, + 0x7f,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00, + 0x89,0x89,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x92,0x92,0x90,0x00,0x93,0x93,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa3,0xa4,0xa1,0x00, + 0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00, + 0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00, + 0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xba,0x00, + 0xbf,0xbf,0xbb,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00, + 0xc7,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xdb,0xda,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00, + 0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe5,0xe6,0xe1,0x00,0xe6,0xe7,0xe2,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00, + 0xea,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00, + 0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xfa,0xf5,0x00,0xfb,0xfb,0xf6,0x00,0xfc,0xfc,0xf7,0x00, + 0xfd,0xfd,0xf8,0x00,0xfe,0xfe,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x13,0x00,0x13,0x12,0x14,0x00,0x14,0x14,0x15,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x25,0x25,0x25,0x00,0x25,0x26,0x26,0x00, + 0x26,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x2a,0x29,0x00,0x2b,0x2b,0x2a,0x00,0x2c,0x2c,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4d,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x51,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00, + 0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x63,0x00,0x64,0x65,0x64,0x00, + 0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7f,0x7d,0x00,0x7e,0x80,0x7e,0x00, + 0x7f,0x81,0x7f,0x00,0x80,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00, + 0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x95,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa2,0xa3,0xa0,0x00,0xa3,0xa4,0xa1,0x00, + 0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00, + 0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00, + 0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xba,0x00, + 0xbf,0xbf,0xbb,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00, + 0xc7,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00, + 0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe5,0xe6,0xe1,0x00,0xe6,0xe7,0xe2,0x00,0xe7,0xe8,0xe3,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00, + 0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfb,0xfb,0xf6,0x00,0xfc,0xfc,0xf7,0x00, + 0xfd,0xfd,0xf8,0x00,0xfe,0xfe,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x13,0x00,0x13,0x12,0x14,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x22,0x21,0x00,0x23,0x23,0x22,0x00,0x24,0x24,0x23,0x00,0x24,0x25,0x24,0x00,0x25,0x26,0x26,0x00, + 0x26,0x27,0x27,0x00,0x27,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2b,0x2a,0x00,0x2c,0x2c,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x38,0x38,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4e,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x52,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5b,0x00, + 0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x64,0x00, + 0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6e,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x76,0x77,0x75,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x80,0x7e,0x00, + 0x7f,0x81,0x7f,0x00,0x80,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x86,0x00, + 0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x96,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x98,0x00, + 0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa4,0xa1,0x00, + 0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00, + 0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb5,0xb5,0xb2,0x00, + 0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xba,0x00, + 0xbf,0xbf,0xbb,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc7,0xc4,0x00, + 0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcc,0xc8,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xde,0x00, + 0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe6,0xe1,0x00,0xe6,0xe7,0xe2,0x00,0xe7,0xe8,0xe3,0x00,0xe8,0xe9,0xe4,0x00,0xe9,0xea,0xe6,0x00, + 0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf3,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfc,0xfc,0xf7,0x00, + 0xfd,0xfd,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x13,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00,0x23,0x23,0x22,0x00,0x23,0x24,0x23,0x00,0x24,0x25,0x24,0x00,0x25,0x26,0x25,0x00, + 0x26,0x27,0x27,0x00,0x27,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2c,0x2b,0x00,0x2d,0x2d,0x2c,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00, + 0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x46,0x45,0x00,0x47,0x47,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4f,0x4e,0x00,0x4f,0x50,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00, + 0x53,0x53,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x58,0x57,0x00,0x58,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00, + 0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00, + 0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00, + 0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x81,0x7f,0x00,0x80,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00, + 0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00, + 0xa4,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00, + 0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00, + 0xb6,0xb6,0xb3,0x00,0xb7,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00, + 0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00, + 0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcd,0xcd,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00, + 0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe7,0xe2,0x00,0xe7,0xe8,0xe3,0x00,0xe8,0xe9,0xe4,0x00,0xe9,0xea,0xe5,0x00, + 0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00, + 0xfd,0xfd,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x28,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2e,0x2e,0x00,0x2e,0x2f,0x2f,0x00, + 0x2f,0x30,0x30,0x00,0x30,0x31,0x31,0x00,0x31,0x32,0x32,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00, + 0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00, + 0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x61,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00, + 0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00, + 0x9a,0x9a,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9e,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00, + 0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa7,0xa4,0x00,0xa6,0xa8,0xa5,0x00,0xa7,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00, + 0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb1,0x00, + 0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb4,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00, + 0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00, + 0xc7,0xc7,0xc4,0x00,0xc8,0xc9,0xc5,0x00,0xca,0xca,0xc6,0x00,0xcb,0xcb,0xc7,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00, + 0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00, + 0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00, + 0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00, + 0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf6,0x00, + 0xfc,0xfc,0xf7,0x00,0xfd,0xfd,0xf8,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x14,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2e,0x2e,0x00,0x2e,0x2f,0x2f,0x00, + 0x2f,0x30,0x30,0x00,0x30,0x31,0x31,0x00,0x31,0x32,0x32,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x51,0x50,0x00,0x51,0x52,0x51,0x00, + 0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x59,0x57,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5c,0x5a,0x00, + 0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x63,0x64,0x62,0x00,0x64,0x65,0x63,0x00, + 0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x98,0x99,0x97,0x00, + 0x99,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00, + 0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa7,0xa4,0x00,0xa6,0xa8,0xa5,0x00,0xa7,0xa9,0xa6,0x00,0xa8,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00, + 0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb1,0x00, + 0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb3,0x00,0xb8,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00, + 0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00, + 0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xca,0xca,0xc6,0x00,0xcb,0xcb,0xc7,0x00,0xcc,0xcc,0xc8,0x00,0xcd,0xcd,0xc9,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00, + 0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00, + 0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00, + 0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00, + 0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf6,0x00, + 0xfc,0xfc,0xf7,0x00,0xfd,0xfd,0xf8,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x15,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2f,0x2f,0x00, + 0x2f,0x30,0x30,0x00,0x30,0x31,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x40,0x40,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x47,0x47,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x52,0x51,0x00, + 0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00, + 0x5c,0x5d,0x5b,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x62,0x00,0x64,0x65,0x63,0x00, + 0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7f,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x88,0x86,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x90,0x91,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00, + 0x99,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa3,0xa1,0x00, + 0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa8,0xa5,0x00,0xa7,0xa9,0xa6,0x00,0xa8,0xaa,0xa7,0x00,0xa9,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00, + 0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb5,0xb1,0x00, + 0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb3,0x00,0xb7,0xb8,0xb5,0x00,0xb9,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00, + 0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00, + 0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xcb,0xc7,0x00,0xcc,0xcc,0xc8,0x00,0xcd,0xcd,0xc9,0x00,0xce,0xce,0xca,0x00,0xcf,0xcf,0xcc,0x00, + 0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd8,0xd8,0xd4,0x00, + 0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00, + 0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xee,0xed,0xe9,0x00,0xef,0xee,0xeb,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf2,0xee,0x00, + 0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf4,0x00,0xfa,0xfa,0xf5,0x00,0xfb,0xfb,0xf6,0x00, + 0xfc,0xfc,0xf7,0x00,0xfd,0xfd,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x30,0x30,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x47,0x47,0x00,0x49,0x48,0x48,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x53,0x52,0x00,0x53,0x54,0x53,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00, + 0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5c,0x00,0x5e,0x5f,0x5d,0x00,0x5f,0x60,0x5e,0x00,0x60,0x61,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x62,0x00,0x63,0x64,0x63,0x00, + 0x65,0x66,0x64,0x00,0x66,0x67,0x65,0x00,0x67,0x68,0x66,0x00,0x68,0x69,0x67,0x00,0x69,0x6a,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00, + 0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00, + 0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8f,0x00, + 0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00, + 0x9a,0x9a,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00, + 0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa9,0xa6,0x00,0xa8,0xaa,0xa7,0x00,0xa9,0xab,0xa8,0x00,0xaa,0xac,0xa9,0x00, + 0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xaf,0x00,0xb3,0xb3,0xb0,0x00,0xb4,0xb4,0xb1,0x00, + 0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb3,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00, + 0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00, + 0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcc,0xc8,0x00,0xcc,0xcd,0xc9,0x00,0xcd,0xce,0xca,0x00,0xce,0xcf,0xcb,0x00, + 0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00, + 0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00, + 0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xef,0xee,0xea,0x00,0xf0,0xef,0xeb,0x00,0xf1,0xf0,0xed,0x00,0xf2,0xf1,0xee,0x00, + 0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00,0xfb,0xfa,0xf6,0x00, + 0xfc,0xfc,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x47,0x47,0x00,0x49,0x48,0x48,0x00, + 0x4a,0x49,0x49,0x00,0x4b,0x4a,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x57,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5a,0x00, + 0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x62,0x60,0x00,0x62,0x63,0x62,0x00,0x63,0x64,0x63,0x00, + 0x64,0x65,0x64,0x00,0x65,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00, + 0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00, + 0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8f,0x00, + 0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x94,0x92,0x00,0x93,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x96,0x00, + 0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00, + 0xa2,0xa3,0xa1,0x00,0xa3,0xa5,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00, + 0xb4,0xb5,0xb2,0x00,0xb6,0xb6,0xb3,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00, + 0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc5,0xc1,0x00,0xc5,0xc6,0xc2,0x00, + 0xc6,0xc7,0xc3,0x00,0xc7,0xc8,0xc4,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00, + 0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd2,0xd2,0xce,0x00,0xd3,0xd3,0xcf,0x00,0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00, + 0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe8,0xe7,0xe3,0x00,0xe9,0xe8,0xe4,0x00, + 0xea,0xe9,0xe5,0x00,0xeb,0xea,0xe6,0x00,0xec,0xec,0xe7,0x00,0xed,0xed,0xe8,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xee,0x00, + 0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00, + 0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x47,0x47,0x00,0x49,0x48,0x48,0x00, + 0x4a,0x49,0x49,0x00,0x4b,0x4a,0x4a,0x00,0x4c,0x4c,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x55,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x5a,0x59,0x00,0x5b,0x5b,0x5b,0x00, + 0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x63,0x62,0x00,0x63,0x64,0x63,0x00, + 0x64,0x65,0x64,0x00,0x65,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6c,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x74,0x75,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00, + 0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00, + 0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8b,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8f,0x00, + 0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x94,0x92,0x00,0x93,0x95,0x93,0x00,0x94,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x96,0x00, + 0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9d,0x9d,0x9a,0x00,0x9e,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa1,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00, + 0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa6,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00, + 0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbc,0xb9,0x00, + 0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc5,0xc1,0x00,0xc5,0xc6,0xc2,0x00, + 0xc6,0xc7,0xc3,0x00,0xc7,0xc8,0xc4,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00, + 0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd2,0xd2,0xce,0x00,0xd3,0xd3,0xcf,0x00,0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00, + 0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe8,0xe7,0xe3,0x00,0xe9,0xe8,0xe4,0x00, + 0xea,0xe9,0xe5,0x00,0xeb,0xea,0xe6,0x00,0xec,0xec,0xe7,0x00,0xed,0xed,0xe8,0x00,0xee,0xee,0xe9,0x00,0xef,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xee,0x00, + 0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00, + 0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x37,0x37,0x37,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x49,0x48,0x48,0x00, + 0x4a,0x49,0x49,0x00,0x4b,0x4a,0x4a,0x00,0x4c,0x4b,0x4b,0x00,0x4d,0x4d,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x56,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x59,0x00,0x5a,0x5b,0x5a,0x00, + 0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x64,0x63,0x00, + 0x64,0x65,0x64,0x00,0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6d,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x75,0x76,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7e,0x7e,0x7d,0x00, + 0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x7f,0x00,0x82,0x83,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x84,0x00,0x87,0x87,0x85,0x00, + 0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8c,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00, + 0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x95,0x93,0x00,0x94,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00, + 0x9a,0x9a,0x97,0x00,0x9b,0x9b,0x98,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9e,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0xa0,0xa0,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00, + 0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00, + 0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00, + 0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc6,0xc2,0x00, + 0xc6,0xc7,0xc3,0x00,0xc7,0xc8,0xc4,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00, + 0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd3,0xd3,0xcf,0x00,0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00, + 0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xe0,0xe0,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00, + 0xea,0xe9,0xe5,0x00,0xeb,0xea,0xe6,0x00,0xec,0xeb,0xe7,0x00,0xed,0xed,0xe8,0x00,0xee,0xee,0xe9,0x00,0xef,0xef,0xea,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00, + 0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xef,0x00,0xf5,0xf4,0xf0,0x00,0xf6,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xfa,0xf6,0x00, + 0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00, + 0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x4a,0x49,0x49,0x00,0x4b,0x4a,0x4a,0x00,0x4c,0x4b,0x4b,0x00,0x4d,0x4c,0x4c,0x00,0x4e,0x4e,0x4d,0x00,0x4f,0x4f,0x4e,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x57,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x59,0x00,0x5a,0x5b,0x5a,0x00, + 0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x65,0x64,0x00,0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00, + 0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00, + 0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x84,0x81,0x00,0x84,0x85,0x82,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x88,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8b,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00, + 0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x94,0x00,0x97,0x98,0x95,0x00,0x98,0x99,0x96,0x00, + 0x99,0x9a,0x97,0x00,0x9a,0x9b,0x98,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9f,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00, + 0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00, + 0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb9,0xba,0xb7,0x00,0xba,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00, + 0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00, + 0xc6,0xc7,0xc3,0x00,0xc7,0xc8,0xc4,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00, + 0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd4,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00,0xd7,0xd7,0xd3,0x00, + 0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd7,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00, + 0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00, + 0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xee,0xee,0xe9,0x00,0xef,0xef,0xea,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00, + 0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf7,0xf6,0xf2,0x00,0xf8,0xf7,0xf3,0x00,0xf9,0xf8,0xf4,0x00,0xfa,0xf9,0xf5,0x00, + 0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x24,0x25,0x24,0x00, + 0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x45,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x59,0x00,0x5a,0x5b,0x5a,0x00, + 0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00, + 0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00, + 0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00, + 0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00, + 0x99,0x99,0x97,0x00,0x9a,0x9b,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00, + 0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb2,0xb3,0xaf,0x00,0xb3,0xb4,0xb0,0x00, + 0xb4,0xb5,0xb1,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00, + 0xbd,0xbc,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xce,0xce,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00, + 0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdd,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00, + 0xe9,0xe8,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00, + 0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xee,0x00,0xf4,0xf4,0xef,0x00,0xf5,0xf5,0xf0,0x00,0xf6,0xf6,0xf1,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00, + 0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x24,0x25,0x24,0x00, + 0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x29,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x58,0x57,0x00,0x59,0x59,0x59,0x00,0x5a,0x5b,0x5a,0x00, + 0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x67,0x66,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00, + 0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00, + 0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8f,0x8c,0x00,0x8f,0x90,0x8d,0x00, + 0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x93,0x93,0x91,0x00,0x94,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x97,0x98,0x96,0x00, + 0x98,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00, + 0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb2,0xb3,0xaf,0x00,0xb3,0xb4,0xb0,0x00, + 0xb4,0xb5,0xb1,0x00,0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbb,0xb9,0x00, + 0xbd,0xbc,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00, + 0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00, + 0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00, + 0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf4,0xf4,0xef,0x00,0xf5,0xf5,0xf0,0x00,0xf6,0xf6,0xf1,0x00,0xf7,0xf7,0xf2,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00, + 0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1d,0x1d,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x23,0x24,0x24,0x00,0x24,0x25,0x24,0x00, + 0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x59,0x58,0x00,0x5a,0x5a,0x5a,0x00, + 0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x61,0x62,0x61,0x00,0x63,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00, + 0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00, + 0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00,0x86,0x87,0x85,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x90,0x8d,0x00, + 0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00, + 0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9c,0x99,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa2,0xa0,0x00, + 0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xaa,0xab,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb3,0xb4,0xb0,0x00, + 0xb4,0xb5,0xb1,0x00,0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbb,0xb9,0x00, + 0xbd,0xbc,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd7,0xd3,0x00, + 0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00, + 0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00, + 0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf5,0xf5,0xf0,0x00,0xf6,0xf6,0xf1,0x00,0xf7,0xf7,0xf2,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00, + 0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfe,0xfe,0xfa,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x22,0x23,0x23,0x00,0x23,0x24,0x24,0x00,0x24,0x25,0x24,0x00, + 0x25,0x26,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x5a,0x00, + 0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x61,0x62,0x61,0x00,0x62,0x63,0x62,0x00, + 0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00, + 0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x71,0x00,0x73,0x74,0x72,0x00,0x74,0x75,0x73,0x00, + 0x75,0x76,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x90,0x8d,0x00, + 0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00, + 0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9c,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00, + 0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00, + 0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00, + 0xb4,0xb5,0xb1,0x00,0xb5,0xb6,0xb2,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00, + 0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00, + 0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00, + 0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00,0xde,0xdf,0xdb,0x00, + 0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00, + 0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00, + 0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf6,0xf6,0xf1,0x00,0xf7,0xf7,0xf2,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00, + 0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x57,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x5a,0x00, + 0x5a,0x5b,0x5b,0x00,0x5b,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x62,0x61,0x00,0x62,0x63,0x62,0x00, + 0x63,0x64,0x63,0x00,0x64,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00, + 0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x74,0x73,0x00, + 0x75,0x75,0x74,0x00,0x76,0x77,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x90,0x8d,0x00, + 0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x95,0x00, + 0x98,0x99,0x96,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9c,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9d,0x9e,0x9b,0x00,0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00, + 0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00, + 0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xad,0xae,0xaa,0x00,0xae,0xaf,0xab,0x00,0xaf,0xb0,0xac,0x00,0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00, + 0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xbb,0xb8,0x00,0xba,0xbc,0xb9,0x00, + 0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00, + 0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00, + 0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00,0xde,0xde,0xdb,0x00, + 0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00, + 0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00, + 0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00, + 0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x54,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x57,0x00,0x58,0x59,0x58,0x00,0x59,0x5a,0x5a,0x00, + 0x5a,0x5b,0x5b,0x00,0x5b,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x62,0x61,0x00,0x62,0x63,0x62,0x00, + 0x63,0x64,0x63,0x00,0x64,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6b,0x69,0x00,0x6b,0x6c,0x6a,0x00, + 0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x74,0x73,0x00, + 0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x78,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x80,0x82,0x80,0x00,0x81,0x83,0x81,0x00,0x82,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8d,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8f,0x90,0x8d,0x00, + 0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x91,0x00,0x92,0x94,0x92,0x00,0x93,0x95,0x93,0x00,0x94,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x95,0x00, + 0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9b,0x9c,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9d,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00, + 0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00, + 0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xad,0xae,0xaa,0x00,0xae,0xaf,0xab,0x00,0xaf,0xb0,0xac,0x00,0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00, + 0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xbb,0xb8,0x00,0xba,0xbc,0xb9,0x00, + 0xbb,0xbd,0xba,0x00,0xbc,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00, + 0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd5,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00, + 0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00,0xde,0xde,0xdb,0x00, + 0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00, + 0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xeb,0xea,0xe7,0x00,0xec,0xeb,0xe8,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00, + 0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00, + 0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x11,0x11,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2e,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x34,0x35,0x00,0x36,0x36,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3f,0x3f,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x48,0x48,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x55,0x55,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x5a,0x59,0x00, + 0x5a,0x5b,0x5b,0x00,0x5b,0x5c,0x5c,0x00,0x5c,0x5d,0x5c,0x00,0x5e,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x63,0x62,0x00, + 0x63,0x64,0x63,0x00,0x64,0x65,0x64,0x00,0x65,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6c,0x6a,0x00, + 0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x74,0x74,0x73,0x00, + 0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x79,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7d,0x7e,0x7c,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x80,0x82,0x80,0x00,0x81,0x83,0x81,0x00,0x82,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x91,0x00,0x92,0x94,0x92,0x00,0x93,0x95,0x93,0x00,0x94,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x95,0x00, + 0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9a,0x9b,0x99,0x00,0x9c,0x9d,0x9a,0x00,0x9d,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa1,0xa1,0x9f,0x00, + 0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xaa,0xa7,0x00, + 0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xae,0xaf,0xab,0x00,0xaf,0xb0,0xac,0x00,0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xae,0x00,0xb2,0xb3,0xb0,0x00, + 0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbc,0xb9,0x00, + 0xbb,0xbd,0xba,0x00,0xbc,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00, + 0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00,0xd6,0xd6,0xd2,0x00, + 0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00, + 0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00, + 0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xec,0xeb,0xe7,0x00,0xed,0xec,0xe9,0x00,0xee,0xed,0xea,0x00,0xef,0xee,0xeb,0x00,0xf0,0xf0,0xec,0x00, + 0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf9,0xf9,0xf5,0x00, + 0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00, + 0x16,0x15,0x16,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2f,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00, + 0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x5a,0x59,0x00, + 0x5a,0x5b,0x5b,0x00,0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5f,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x64,0x63,0x00,0x64,0x65,0x64,0x00,0x65,0x66,0x65,0x00,0x66,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00,0x6b,0x6b,0x6a,0x00, + 0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x90,0x91,0x8e,0x00,0x91,0x92,0x8f,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x95,0x00, + 0x98,0x99,0x96,0x00,0x99,0x9a,0x97,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9d,0x9e,0x9b,0x00,0x9e,0x9f,0x9c,0x00,0x9f,0xa0,0x9d,0x00,0xa0,0xa1,0x9e,0x00, + 0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00, + 0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xaf,0xb0,0xac,0x00,0xb0,0xb1,0xad,0x00,0xb1,0xb2,0xae,0x00,0xb2,0xb3,0xaf,0x00, + 0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00, + 0xbb,0xbd,0xba,0x00,0xbc,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00, + 0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00, + 0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00,0xd5,0xd6,0xd2,0x00, + 0xd7,0xd7,0xd3,0x00,0xd8,0xd8,0xd4,0x00,0xd9,0xd9,0xd5,0x00,0xda,0xda,0xd6,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00, + 0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00,0xe7,0xe7,0xe3,0x00, + 0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xed,0xec,0xe8,0x00,0xee,0xed,0xe9,0x00,0xef,0xee,0xea,0x00,0xf0,0xef,0xeb,0x00, + 0xf1,0xf1,0xec,0x00,0xf2,0xf2,0xed,0x00,0xf3,0xf3,0xee,0x00,0xf4,0xf4,0xef,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00, + 0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00, + 0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x42,0x42,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x5a,0x59,0x00, + 0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00, + 0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x96,0x97,0x95,0x00, + 0x97,0x98,0x96,0x00,0x99,0x9a,0x97,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00, + 0xa9,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00, + 0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00, + 0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xcf,0xcb,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00, + 0xde,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xef,0xee,0xea,0x00,0xf0,0xef,0xeb,0x00, + 0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xed,0x00,0xf3,0xf3,0xee,0x00,0xf3,0xf4,0xef,0x00,0xf4,0xf5,0xf0,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00, + 0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00, + 0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x42,0x42,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x57,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x5a,0x59,0x00, + 0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00, + 0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6e,0x6f,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x80,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x89,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x96,0x97,0x95,0x00, + 0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9b,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00, + 0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00, + 0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00, + 0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00, + 0xde,0xdf,0xdb,0x00,0xdf,0xe0,0xdc,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe6,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe6,0x00,0xec,0xec,0xe7,0x00,0xed,0xed,0xe8,0x00,0xef,0xee,0xe9,0x00,0xf0,0xef,0xea,0x00, + 0xf1,0xf0,0xeb,0x00,0xf2,0xf1,0xec,0x00,0xf3,0xf3,0xee,0x00,0xf3,0xf4,0xef,0x00,0xf4,0xf5,0xf0,0x00,0xf5,0xf6,0xf1,0x00,0xf7,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00, + 0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x36,0x35,0x36,0x00, + 0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x50,0x50,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00, + 0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x62,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6b,0x6a,0x00, + 0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6f,0x70,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7d,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x86,0x84,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x8a,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8f,0x8d,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x94,0x94,0x93,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00, + 0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00, + 0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xbb,0xb8,0x00, + 0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc4,0xc1,0x00, + 0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xde,0xda,0x00, + 0xde,0xdf,0xdb,0x00,0xdf,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe7,0xe6,0xe3,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe5,0x00,0xea,0xe9,0xe5,0x00,0xeb,0xeb,0xe6,0x00,0xec,0xec,0xe7,0x00,0xed,0xed,0xe8,0x00,0xee,0xee,0xe9,0x00,0xf0,0xef,0xea,0x00, + 0xf1,0xf0,0xeb,0x00,0xf2,0xf1,0xec,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf5,0xf0,0x00,0xf5,0xf6,0xf1,0x00,0xf6,0xf7,0xf3,0x00,0xf8,0xf8,0xf4,0x00, + 0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00, + 0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00, + 0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00, + 0x5a,0x5b,0x5a,0x00,0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00,0x61,0x62,0x61,0x00, + 0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00, + 0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x70,0x71,0x6f,0x00,0x71,0x72,0x70,0x00,0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00, + 0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00, + 0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x80,0x81,0x7f,0x00,0x82,0x82,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00,0x85,0x85,0x83,0x00, + 0x86,0x87,0x85,0x00,0x87,0x88,0x86,0x00,0x88,0x89,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x89,0x00,0x8c,0x8c,0x8a,0x00,0x8d,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00, + 0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00, + 0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00, + 0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00, + 0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00, + 0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00, + 0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00, + 0xde,0xdf,0xdb,0x00,0xdf,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00, + 0xe8,0xe7,0xe4,0x00,0xe9,0xe8,0xe4,0x00,0xea,0xe9,0xe5,0x00,0xeb,0xea,0xe6,0x00,0xec,0xec,0xe7,0x00,0xed,0xed,0xe8,0x00,0xee,0xee,0xe9,0x00,0xef,0xef,0xea,0x00, + 0xf1,0xf0,0xeb,0x00,0xf1,0xf1,0xec,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf7,0xf3,0x00,0xf7,0xf8,0xf4,0x00, + 0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00, + 0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3d,0x3e,0x00, + 0x3f,0x3e,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00, + 0x51,0x50,0x50,0x00,0x52,0x51,0x51,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00, + 0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00, + 0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00, + 0x6b,0x6b,0x6a,0x00,0x6c,0x6d,0x6b,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00, + 0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00, + 0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x92,0x8f,0x00,0x91,0x93,0x90,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x96,0x95,0x00, + 0x97,0x97,0x96,0x00,0x98,0x99,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00, + 0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00, + 0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00, + 0xcc,0xcc,0xca,0x00,0xcd,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00, + 0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00, + 0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00, + 0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xed,0xec,0xe8,0x00,0xee,0xed,0xe9,0x00,0xef,0xee,0xea,0x00, + 0xf0,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf8,0xf4,0x00, + 0xf8,0xf9,0xf5,0x00,0xf9,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x18,0x17,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00, + 0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3d,0x3e,0x00, + 0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00, + 0x51,0x50,0x50,0x00,0x52,0x51,0x51,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00, + 0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00, + 0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00, + 0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00, + 0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00, + 0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x92,0x8f,0x00,0x91,0x93,0x90,0x00,0x92,0x94,0x91,0x00,0x93,0x95,0x92,0x00,0x95,0x96,0x94,0x00,0x96,0x96,0x95,0x00, + 0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00, + 0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00,0xa8,0xa9,0xa6,0x00, + 0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc2,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00, + 0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd4,0xd0,0x00,0xd4,0xd5,0xd1,0x00, + 0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00, + 0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00, + 0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xee,0xed,0xe9,0x00,0xef,0xee,0xea,0x00, + 0xf0,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xee,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf5,0xf1,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf8,0xf4,0x00, + 0xf8,0xf9,0xf5,0x00,0xf9,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00,0x15,0x14,0x14,0x00, + 0x16,0x15,0x15,0x00,0x17,0x16,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1d,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2e,0x2d,0x2d,0x00, + 0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00, + 0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x47,0x47,0x47,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x50,0x4f,0x4f,0x00, + 0x51,0x50,0x50,0x00,0x52,0x51,0x51,0x00,0x53,0x52,0x52,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x59,0x59,0x59,0x00, + 0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00, + 0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00, + 0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x73,0x73,0x73,0x00, + 0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00, + 0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x85,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8e,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x93,0x90,0x00,0x92,0x94,0x91,0x00,0x93,0x95,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x95,0x00, + 0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0xa0,0x9e,0x00, + 0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa6,0x00, + 0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00, + 0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc3,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00, + 0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd5,0xd1,0x00, + 0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdd,0xdd,0xda,0x00, + 0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe0,0x00,0xe5,0xe5,0xe1,0x00,0xe6,0xe6,0xe2,0x00, + 0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00, + 0xf0,0xef,0xeb,0x00,0xf1,0xf0,0xec,0x00,0xf2,0xf1,0xed,0x00,0xf3,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf4,0x00, + 0xf8,0xf9,0xf5,0x00,0xf9,0xfa,0xf6,0x00,0xfa,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00, + 0x16,0x15,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00, + 0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2f,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00, + 0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x51,0x50,0x50,0x00,0x52,0x51,0x51,0x00,0x53,0x52,0x52,0x00,0x54,0x53,0x53,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00, + 0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00, + 0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00,0x6a,0x6a,0x69,0x00, + 0x6b,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00, + 0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00, + 0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00, + 0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x94,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00, + 0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00, + 0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa6,0x00, + 0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00, + 0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00, + 0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00, + 0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00, + 0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00, + 0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe3,0xe4,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe5,0xe6,0xe2,0x00, + 0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00, + 0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00, + 0xf8,0xf9,0xf5,0x00,0xf9,0xfa,0xf6,0x00,0xfa,0xfb,0xf7,0x00,0xfb,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00, + 0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x53,0x52,0x52,0x00,0x54,0x53,0x53,0x00,0x55,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00, + 0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00, + 0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x70,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00, + 0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8c,0x8d,0x8c,0x00, + 0x8d,0x8e,0x8d,0x00,0x8e,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00, + 0x97,0x97,0x95,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9d,0x00,0x9e,0x9f,0x9e,0x00, + 0x9f,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00, + 0xa8,0xa9,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00, + 0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00, + 0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc0,0xbd,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00, + 0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xcf,0xcb,0x00,0xcf,0xd0,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00, + 0xdd,0xde,0xda,0x00,0xdf,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00, + 0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00, + 0xef,0xee,0xea,0x00,0xf0,0xef,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf1,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00, + 0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1b,0x1b,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00, + 0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x53,0x52,0x52,0x00,0x54,0x53,0x53,0x00,0x55,0x54,0x54,0x00,0x56,0x55,0x55,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00, + 0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5c,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x60,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x69,0x68,0x00,0x69,0x6a,0x69,0x00, + 0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x72,0x71,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00, + 0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8c,0x8d,0x8c,0x00, + 0x8d,0x8e,0x8d,0x00,0x8e,0x8f,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x95,0x95,0x93,0x00,0x96,0x96,0x94,0x00, + 0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9e,0x9d,0x00,0x9e,0x9f,0x9e,0x00, + 0x9f,0xa0,0x9f,0x00,0xa0,0xa1,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00, + 0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00, + 0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb9,0xb6,0x00,0xb9,0xba,0xb7,0x00, + 0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00, + 0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xcf,0xcb,0x00,0xcf,0xd0,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00, + 0xdd,0xde,0xda,0x00,0xde,0xdf,0xdb,0x00,0xe0,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe4,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00, + 0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00, + 0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf6,0xf6,0xf2,0x00,0xf7,0xf7,0xf3,0x00, + 0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1c,0x1c,0x1c,0x00, + 0x1d,0x1d,0x1d,0x00,0x1e,0x1e,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00, + 0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x53,0x53,0x00,0x55,0x54,0x54,0x00,0x56,0x55,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x58,0x00, + 0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5d,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x61,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x6a,0x69,0x00, + 0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x73,0x72,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7c,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00, + 0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8c,0x8d,0x8c,0x00, + 0x8d,0x8e,0x8d,0x00,0x8e,0x8f,0x8e,0x00,0x8f,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x96,0x96,0x94,0x00, + 0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9e,0x00, + 0x9f,0xa0,0x9f,0x00,0xa0,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00, + 0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00, + 0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xba,0xb7,0x00, + 0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc2,0xc2,0xc0,0x00, + 0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xd0,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd4,0xd4,0xd1,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdd,0xd9,0x00, + 0xdd,0xde,0xda,0x00,0xde,0xdf,0xdb,0x00,0xdf,0xe0,0xdc,0x00,0xe1,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe3,0xe3,0xdf,0x00,0xe3,0xe4,0xe0,0x00,0xe4,0xe5,0xe2,0x00, + 0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00, + 0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf2,0x00,0xf7,0xf7,0xf3,0x00, + 0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1d,0x1d,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00, + 0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00, + 0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x55,0x54,0x54,0x00,0x56,0x55,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5e,0x5d,0x00,0x5e,0x5f,0x5e,0x00,0x5f,0x60,0x5f,0x00,0x60,0x61,0x60,0x00, + 0x62,0x62,0x61,0x00,0x63,0x63,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00, + 0x6a,0x6b,0x6a,0x00,0x6b,0x6c,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x72,0x71,0x00, + 0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00, + 0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7c,0x00,0x7e,0x7f,0x7d,0x00,0x7f,0x80,0x7e,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00, + 0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x8a,0x8a,0x89,0x00,0x8a,0x8b,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8c,0x8d,0x8c,0x00, + 0x8d,0x8e,0x8d,0x00,0x8e,0x8f,0x8e,0x00,0x8f,0x91,0x8f,0x00,0x90,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00, + 0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00, + 0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00, + 0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00, + 0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00, + 0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd1,0xcd,0x00,0xd1,0xd2,0xce,0x00,0xd2,0xd3,0xcf,0x00,0xd3,0xd4,0xd0,0x00, + 0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00, + 0xdd,0xde,0xda,0x00,0xde,0xdf,0xdb,0x00,0xdf,0xe0,0xdc,0x00,0xe0,0xe1,0xdd,0x00,0xe2,0xe2,0xde,0x00,0xe2,0xe3,0xdf,0x00,0xe3,0xe4,0xe0,0x00,0xe4,0xe5,0xe1,0x00, + 0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xea,0xea,0xe6,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00, + 0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf8,0xf8,0xf4,0x00,0xf9,0xf9,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x10,0x00,0x13,0x11,0x11,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x23,0x00, + 0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2d,0x00, + 0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4e,0x4d,0x4e,0x00,0x4f,0x4e,0x4f,0x00, + 0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00, + 0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x72,0x71,0x00, + 0x73,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00, + 0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00, + 0x85,0x85,0x83,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x91,0x8e,0x00,0x90,0x92,0x8f,0x00,0x91,0x93,0x90,0x00,0x93,0x94,0x91,0x00,0x94,0x95,0x93,0x00,0x95,0x95,0x94,0x00, + 0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x99,0x98,0x00,0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00, + 0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00, + 0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xca,0xc8,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcd,0xc9,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00, + 0xdc,0xdd,0xd9,0x00,0xde,0xde,0xda,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00, + 0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf4,0xf4,0xf0,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x10,0x00,0x13,0x11,0x11,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x23,0x00, + 0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00, + 0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4e,0x4d,0x4e,0x00,0x4f,0x4e,0x4f,0x00, + 0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x57,0x57,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x64,0x64,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00, + 0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6d,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x71,0x71,0x70,0x00,0x72,0x72,0x71,0x00, + 0x73,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00, + 0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x83,0x83,0x81,0x00,0x84,0x84,0x82,0x00, + 0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x91,0x8e,0x00,0x90,0x92,0x8f,0x00,0x91,0x93,0x90,0x00,0x92,0x94,0x91,0x00,0x94,0x95,0x93,0x00,0x95,0x95,0x94,0x00, + 0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x99,0x98,0x00,0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa6,0xa7,0xa4,0x00,0xa7,0xa8,0xa5,0x00, + 0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc1,0xbe,0x00,0xc1,0xc2,0xbf,0x00, + 0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xdb,0xd7,0x00,0xdb,0xdc,0xd8,0x00, + 0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00, + 0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x10,0x00,0x13,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x23,0x00, + 0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2d,0x00, + 0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x35,0x34,0x35,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4f,0x4e,0x4f,0x00, + 0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x58,0x58,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x65,0x65,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x69,0x00, + 0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6e,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x72,0x72,0x71,0x00, + 0x73,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00, + 0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x84,0x84,0x82,0x00, + 0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x92,0x8f,0x00,0x91,0x93,0x90,0x00,0x92,0x94,0x91,0x00,0x93,0x94,0x93,0x00,0x95,0x95,0x94,0x00, + 0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa7,0xa8,0xa5,0x00, + 0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb5,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb9,0xb9,0xb7,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc2,0xbf,0x00, + 0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00,0xd2,0xd2,0xcf,0x00,0xd3,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdc,0xd8,0x00, + 0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00,0xde,0xdf,0xdb,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00,0xed,0xed,0xe9,0x00, + 0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf6,0xf6,0xf3,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x12,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00, + 0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00, + 0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00, + 0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x59,0x59,0x58,0x00,0x5a,0x5a,0x59,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x66,0x66,0x65,0x00,0x67,0x67,0x66,0x00,0x68,0x68,0x67,0x00,0x69,0x69,0x68,0x00, + 0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6f,0x6e,0x00,0x6f,0x70,0x6f,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00, + 0x73,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00, + 0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x85,0x85,0x83,0x00,0x86,0x86,0x84,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x93,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x93,0x00,0x94,0x95,0x94,0x00, + 0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00, + 0xa0,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00, + 0xa8,0xa9,0xa6,0x00,0xa9,0xaa,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00, + 0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb6,0xb3,0x00,0xb6,0xb7,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00, + 0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00, + 0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc8,0xc5,0x00,0xc9,0xc9,0xc6,0x00,0xca,0xca,0xc7,0x00, + 0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00, + 0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00,0xde,0xdf,0xdb,0x00,0xdf,0xe0,0xdc,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00,0xec,0xed,0xe9,0x00, + 0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf5,0xf6,0xf2,0x00, + 0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00, + 0xff,0xff,0xfc,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00, + 0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00, + 0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00, + 0x3e,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00, + 0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00, + 0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x93,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x96,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00,0x99,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00, + 0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00, + 0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00, + 0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00, + 0xc1,0xc2,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00, + 0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00, + 0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xea,0x00, + 0xed,0xed,0xeb,0x00,0xee,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xfa,0xf7,0x00,0xfc,0xfb,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x10,0x10,0x10,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00, + 0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00, + 0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00, + 0x3e,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x68,0x67,0x00,0x68,0x69,0x68,0x00, + 0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x71,0x70,0x00,0x71,0x72,0x71,0x00, + 0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x7a,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x83,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x8a,0x00,0x8c,0x8d,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8f,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x93,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00,0x99,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00, + 0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xaa,0xab,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00, + 0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb7,0xb8,0xb5,0x00,0xb8,0xb9,0xb6,0x00, + 0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbc,0x00,0xc0,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00, + 0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00, + 0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00, + 0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00, + 0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xfa,0xf7,0x00,0xfc,0xfb,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x10,0x10,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00, + 0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2c,0x2c,0x00, + 0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x39,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00, + 0x3e,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x45,0x00,0x46,0x46,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x60,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x69,0x68,0x00, + 0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x70,0x00,0x71,0x72,0x71,0x00, + 0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7b,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x84,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8c,0x8c,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00,0x99,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9d,0x00, + 0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xac,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xae,0x00, + 0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb9,0xb6,0x00, + 0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbf,0x00, + 0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00, + 0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd3,0xd0,0x00, + 0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe4,0xe4,0xe1,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00, + 0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xfa,0xf7,0x00,0xfc,0xfb,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x23,0x00, + 0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00, + 0x3e,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x6a,0x69,0x00,0x6a,0x6b,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x73,0x72,0x00,0x73,0x74,0x73,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7c,0x7a,0x00,0x7c,0x7d,0x7b,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00, + 0x84,0x85,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8b,0x00, + 0x8d,0x8e,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00,0x94,0x95,0x93,0x00, + 0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xad,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00, + 0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xba,0xb7,0x00,0xba,0xbb,0xb8,0x00,0xbb,0xbc,0xb9,0x00,0xbc,0xbd,0xba,0x00,0xbd,0xbe,0xbb,0x00,0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00, + 0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00, + 0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xcd,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00, + 0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00, + 0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00, + 0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xed,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfb,0xfa,0xf7,0x00,0xfc,0xfb,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00, + 0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8b,0x00, + 0x8c,0x8d,0x8c,0x00,0x8d,0x8e,0x8d,0x00,0x8e,0x8f,0x8e,0x00,0x8f,0x90,0x8f,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00, + 0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00, + 0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00, + 0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00, + 0xd2,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00, + 0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00, + 0xec,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6c,0x6c,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00, + 0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x88,0x00,0x8a,0x8b,0x89,0x00,0x8b,0x8c,0x8b,0x00, + 0x8c,0x8d,0x8c,0x00,0x8d,0x8e,0x8d,0x00,0x8e,0x8f,0x8e,0x00,0x8f,0x90,0x8f,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00, + 0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xae,0xaf,0xac,0x00,0xaf,0xb0,0xad,0x00, + 0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbf,0xc0,0xbd,0x00,0xc0,0xc1,0xbe,0x00, + 0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00, + 0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00, + 0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00, + 0xec,0xed,0xe9,0x00,0xed,0xee,0xea,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfd,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x42,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x46,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x56,0x00,0x57,0x57,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6d,0x6d,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x71,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x82,0x81,0x00,0x83,0x83,0x82,0x00, + 0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x85,0x00,0x88,0x88,0x86,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8c,0x8a,0x00, + 0x8c,0x8d,0x8c,0x00,0x8d,0x8e,0x8d,0x00,0x8e,0x8f,0x8e,0x00,0x8f,0x90,0x8f,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00, + 0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x98,0x97,0x96,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9e,0x9e,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa7,0xa5,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xaf,0xb0,0xad,0x00, + 0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbe,0x00, + 0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xd0,0x00, + 0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xdb,0xdb,0xd8,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00, + 0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00, + 0xec,0xed,0xe9,0x00,0xed,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00,0xf5,0xf5,0xf2,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfd,0xf9,0x00,0xfe,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x42,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00, + 0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6e,0x6e,0x6d,0x00,0x6f,0x6f,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x70,0x00, + 0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x82,0x81,0x00,0x82,0x83,0x82,0x00, + 0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00, + 0x8c,0x8d,0x8c,0x00,0x8d,0x8e,0x8d,0x00,0x8e,0x8f,0x8e,0x00,0x8f,0x90,0x8f,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00, + 0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x98,0x97,0x96,0x00,0x99,0x98,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00, + 0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00,0xa6,0xa6,0xa4,0x00, + 0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00, + 0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xaf,0x00,0xb2,0xb3,0xb0,0x00,0xb3,0xb4,0xb1,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00, + 0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00, + 0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00, + 0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00, + 0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00, + 0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe9,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00,0xeb,0xec,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00, + 0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfd,0xf9,0x00,0xfd,0xfe,0xfa,0x00, + 0xff,0xff,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2b,0x00, + 0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00, + 0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x70,0x00, + 0x72,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x74,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00, + 0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00, + 0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x98,0x97,0x96,0x00,0x99,0x98,0x97,0x00,0x9a,0x99,0x98,0x00,0x9b,0x9b,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00, + 0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc6,0x00, + 0xc9,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00, + 0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00, + 0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00, + 0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00, + 0xf5,0xf6,0xf2,0x00,0xf6,0xf7,0xf3,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfd,0xf9,0x00,0xfd,0xfe,0xfa,0x00, + 0xfe,0xff,0xfb,0x00,0xfe,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x27,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2b,0x00, + 0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00, + 0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x70,0x70,0x6f,0x00,0x71,0x71,0x70,0x00, + 0x72,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x75,0x74,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x82,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00, + 0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00, + 0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x98,0x97,0x96,0x00,0x99,0x98,0x97,0x00,0x9a,0x99,0x98,0x00,0x9b,0x9a,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00, + 0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc6,0x00, + 0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00, + 0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd9,0xda,0xd6,0x00,0xda,0xdb,0xd7,0x00, + 0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00, + 0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00, + 0xf5,0xf6,0xf2,0x00,0xf6,0xf7,0xf3,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfd,0xf9,0x00,0xfd,0xfe,0xfa,0x00, + 0xfe,0xff,0xfb,0x00,0xfe,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1b,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x21,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x28,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00, + 0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x33,0x00,0x34,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4e,0x4e,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x57,0x00, + 0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x68,0x68,0x68,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x71,0x71,0x70,0x00, + 0x72,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x76,0x75,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x7a,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x83,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00, + 0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x8f,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x92,0x00,0x94,0x94,0x93,0x00, + 0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x99,0x98,0x97,0x00,0x9a,0x99,0x98,0x00,0x9b,0x9a,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb3,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb6,0x00, + 0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb8,0x00,0xbc,0xbc,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00, + 0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd2,0xcf,0x00, + 0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00,0xda,0xdb,0xd7,0x00, + 0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00, + 0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe3,0x00,0xe8,0xe8,0xe4,0x00,0xe9,0xe9,0xe5,0x00,0xea,0xea,0xe7,0x00,0xec,0xec,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf5,0xf1,0x00, + 0xf5,0xf6,0xf2,0x00,0xf6,0xf7,0xf3,0x00,0xf7,0xf8,0xf4,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfe,0xfa,0x00, + 0xfe,0xff,0xfb,0x00,0xfe,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x10,0x10,0x00,0x12,0x11,0x11,0x00,0x13,0x12,0x13,0x00,0x14,0x13,0x14,0x00, + 0x15,0x14,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00, + 0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x1f,0x00,0x20,0x20,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00, + 0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2d,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00, + 0x35,0x34,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00, + 0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x72,0x72,0x71,0x00,0x73,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x77,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00,0x79,0x7a,0x79,0x00, + 0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x84,0x82,0x00,0x84,0x85,0x83,0x00,0x85,0x86,0x84,0x00,0x86,0x87,0x85,0x00,0x88,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00, + 0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8e,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x93,0x00, + 0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x9a,0x99,0x98,0x00,0x9b,0x9a,0x99,0x00,0x9c,0x9c,0x9a,0x00,0x9d,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00, + 0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00, + 0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbd,0xbd,0xba,0x00,0xbe,0xbe,0xbb,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00, + 0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00, + 0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xdb,0xdc,0xd8,0x00,0xdc,0xdd,0xd9,0x00,0xdd,0xde,0xda,0x00,0xde,0xdf,0xdb,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00, + 0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xed,0xed,0xe9,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf6,0xf2,0x00,0xf6,0xf7,0xf3,0x00,0xf7,0xf8,0xf4,0x00,0xf8,0xf9,0xf5,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00, + 0xfe,0xff,0xfb,0x00,0xfe,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00, + 0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00, + 0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x22,0x00, + 0x24,0x23,0x23,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00, + 0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3b,0x3c,0x00, + 0x3d,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x73,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00, + 0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00, + 0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8f,0x8d,0x00,0x8f,0x90,0x8f,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x92,0x00, + 0x94,0x95,0x93,0x00,0x96,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00, + 0x9d,0x9e,0x9d,0x00,0x9e,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00, + 0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc5,0xc2,0x00,0xc4,0xc6,0xc3,0x00,0xc5,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00, + 0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe2,0xde,0x00,0xe2,0xe3,0xdf,0x00, + 0xe3,0xe4,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00, + 0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00, + 0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00, + 0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x22,0x00, + 0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00, + 0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00,0x3c,0x3b,0x3c,0x00, + 0x3d,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x74,0x74,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00, + 0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7d,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x8a,0x8a,0x89,0x00,0x8b,0x8b,0x8a,0x00, + 0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8f,0x8e,0x00,0x8f,0x90,0x8f,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x92,0x00, + 0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x97,0x97,0x95,0x00,0x98,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9c,0x00, + 0x9d,0x9e,0x9d,0x00,0x9e,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa9,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xae,0xab,0x00,0xae,0xaf,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00, + 0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc5,0xc2,0x00,0xc4,0xc6,0xc3,0x00,0xc5,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00, + 0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe2,0xde,0x00,0xe2,0xe3,0xdf,0x00, + 0xe3,0xe4,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfc,0xfc,0xf8,0x00,0xfd,0xfd,0xf9,0x00, + 0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00, + 0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00, + 0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x22,0x00, + 0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00, + 0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00, + 0x3d,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x44,0x00,0x45,0x45,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5f,0x5f,0x5f,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x75,0x75,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00, + 0x7a,0x7a,0x79,0x00,0x7b,0x7b,0x7a,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x8a,0x88,0x00,0x8b,0x8b,0x8a,0x00, + 0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x90,0x8f,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x91,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00, + 0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x99,0x99,0x97,0x00,0x9a,0x9a,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00, + 0x9d,0x9e,0x9d,0x00,0x9e,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xaa,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xaf,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbe,0x00, + 0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc6,0xc3,0x00,0xc5,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00, + 0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xcf,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd6,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe3,0xdf,0x00, + 0xe3,0xe4,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe5,0xe6,0xe2,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00,0xf4,0xf4,0xf1,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfd,0xfd,0xf9,0x00, + 0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00, + 0x15,0x13,0x15,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00, + 0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x22,0x00, + 0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00, + 0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00, + 0x3d,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00, + 0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00, + 0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6b,0x6b,0x00,0x6b,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x76,0x76,0x75,0x00,0x77,0x77,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x78,0x00, + 0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7f,0x7e,0x00,0x7f,0x80,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x86,0x86,0x85,0x00,0x87,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x91,0x90,0x00,0x91,0x92,0x90,0x00,0x92,0x93,0x91,0x00,0x93,0x94,0x92,0x00, + 0x94,0x95,0x93,0x00,0x95,0x96,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00, + 0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xb0,0xad,0x00,0xb0,0xb1,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb7,0xb5,0x00, + 0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00,0xc8,0xc9,0xc6,0x00, + 0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcc,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcc,0x00,0xd0,0xd0,0xcd,0x00,0xd1,0xd1,0xce,0x00, + 0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd7,0xd3,0x00,0xd7,0xd8,0xd4,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00, + 0xe3,0xe4,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe5,0xe6,0xe2,0x00,0xe6,0xe7,0xe3,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00, + 0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf1,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00,0xf3,0xf4,0xf0,0x00, + 0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfe,0xfe,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00, + 0x15,0x13,0x14,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00, + 0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00, + 0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00, + 0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00, + 0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00, + 0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x62,0x61,0x62,0x00,0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6b,0x6b,0x00,0x6b,0x6c,0x6c,0x00,0x6c,0x6d,0x6d,0x00,0x6d,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x78,0x78,0x77,0x00,0x79,0x79,0x79,0x00, + 0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x85,0x86,0x85,0x00,0x86,0x87,0x86,0x00,0x88,0x88,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00, + 0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x97,0x95,0x00,0x97,0x98,0x96,0x00,0x98,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb6,0xb5,0x00, + 0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00, + 0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00, + 0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00, + 0xeb,0xec,0xe8,0x00,0xec,0xed,0xe9,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf7,0xf6,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xfa,0xf6,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00, + 0x15,0x13,0x14,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00, + 0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00, + 0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00, + 0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00, + 0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00, + 0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x62,0x61,0x62,0x00,0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6b,0x6b,0x00,0x6b,0x6c,0x6c,0x00,0x6c,0x6d,0x6d,0x00,0x6d,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00, + 0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x81,0x81,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x85,0x85,0x84,0x00,0x85,0x86,0x85,0x00,0x86,0x87,0x86,0x00,0x87,0x88,0x87,0x00,0x89,0x8a,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00, + 0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x97,0x95,0x00,0x96,0x98,0x96,0x00,0x97,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9b,0x9c,0x9a,0x00,0x9c,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa4,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00,0xb6,0xb6,0xb5,0x00, + 0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc3,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00, + 0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd4,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00, + 0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xea,0xe6,0x00,0xea,0xeb,0xe7,0x00, + 0xeb,0xec,0xe8,0x00,0xec,0xed,0xe9,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf7,0xf6,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00, + 0x15,0x13,0x14,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1c,0x00, + 0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00, + 0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x34,0x00, + 0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00, + 0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x45,0x00, + 0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x56,0x56,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6c,0x6c,0x00,0x6c,0x6d,0x6d,0x00,0x6d,0x6e,0x6e,0x00,0x6e,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x77,0x00,0x79,0x79,0x79,0x00, + 0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x82,0x82,0x81,0x00, + 0x83,0x83,0x82,0x00,0x84,0x84,0x83,0x00,0x84,0x85,0x84,0x00,0x85,0x86,0x85,0x00,0x86,0x87,0x86,0x00,0x87,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8b,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00, + 0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x95,0x96,0x95,0x00,0x96,0x98,0x96,0x00,0x97,0x99,0x97,0x00,0x99,0x9a,0x98,0x00,0x9a,0x9b,0x9a,0x00,0x9c,0x9d,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa5,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xae,0xae,0xac,0x00, + 0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00, + 0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc4,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc6,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd1,0xce,0x00, + 0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd5,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xda,0xd7,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00, + 0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xeb,0xe7,0x00, + 0xeb,0xec,0xe8,0x00,0xec,0xed,0xe9,0x00,0xed,0xee,0xea,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf8,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf9,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00, + 0x15,0x13,0x14,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00, + 0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00, + 0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00, + 0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00, + 0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x59,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x64,0x63,0x64,0x00,0x65,0x64,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6d,0x6d,0x00,0x6d,0x6e,0x6e,0x00,0x6e,0x6f,0x6f,0x00,0x6f,0x70,0x70,0x00, + 0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00, + 0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00, + 0x83,0x83,0x82,0x00,0x83,0x84,0x83,0x00,0x84,0x85,0x84,0x00,0x85,0x86,0x85,0x00,0x86,0x87,0x86,0x00,0x87,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8c,0x8a,0x00,0x8c,0x8d,0x8b,0x00,0x8e,0x8e,0x8c,0x00,0x8f,0x8f,0x8d,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x92,0x00, + 0x94,0x94,0x93,0x00,0x94,0x95,0x94,0x00,0x95,0x96,0x95,0x00,0x96,0x97,0x96,0x00,0x97,0x99,0x98,0x00,0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00, + 0x9e,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa6,0xa6,0xa4,0x00,0xa7,0xa7,0xa5,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00, + 0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xaf,0x00,0xb2,0xb2,0xb0,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00, + 0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00, + 0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc5,0xc5,0xc2,0x00,0xc6,0xc6,0xc3,0x00,0xc7,0xc7,0xc4,0x00,0xc8,0xc8,0xc5,0x00, + 0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd6,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00, + 0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00, + 0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xec,0xe8,0x00,0xec,0xed,0xe9,0x00,0xed,0xee,0xea,0x00,0xee,0xef,0xeb,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf9,0xf8,0xf5,0x00,0xfa,0xf9,0xf6,0x00,0xfb,0xfb,0xf7,0x00,0xfc,0xfc,0xf8,0x00, + 0xfd,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00, + 0x15,0x13,0x14,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00, + 0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x32,0x00,0x32,0x33,0x33,0x00, + 0x33,0x34,0x34,0x00,0x34,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x49,0x4a,0x00,0x4b,0x4a,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00, + 0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6f,0x6f,0x00,0x6f,0x70,0x70,0x00, + 0x70,0x71,0x71,0x00,0x71,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00, + 0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00, + 0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x88,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8e,0x8d,0x8c,0x00,0x8f,0x8e,0x8d,0x00,0x90,0x8f,0x8e,0x00,0x91,0x90,0x8f,0x00,0x92,0x92,0x91,0x00,0x92,0x93,0x92,0x00, + 0x93,0x94,0x93,0x00,0x94,0x95,0x94,0x00,0x95,0x96,0x95,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9c,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00, + 0xae,0xae,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00, + 0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00, + 0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00, + 0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe6,0x00, + 0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe9,0x00,0xed,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfb,0xf7,0x00,0xfb,0xfc,0xf8,0x00, + 0xfc,0xfd,0xf9,0x00,0xfd,0xfe,0xfa,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00, + 0x15,0x13,0x14,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00, + 0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x32,0x32,0x00,0x32,0x33,0x33,0x00, + 0x33,0x34,0x34,0x00,0x34,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x49,0x4a,0x00,0x4b,0x4a,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00, + 0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5d,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6f,0x6f,0x00,0x6f,0x70,0x70,0x00, + 0x70,0x71,0x71,0x00,0x71,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x77,0x00,0x78,0x79,0x78,0x00, + 0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7c,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00, + 0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x89,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8e,0x8d,0x8c,0x00,0x8f,0x8e,0x8d,0x00,0x90,0x8f,0x8e,0x00,0x91,0x90,0x8f,0x00,0x92,0x92,0x91,0x00,0x92,0x93,0x92,0x00, + 0x93,0x94,0x93,0x00,0x94,0x95,0x94,0x00,0x95,0x96,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9c,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa4,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00, + 0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00, + 0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00, + 0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00, + 0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xcb,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe6,0x00, + 0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xee,0xee,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfb,0xf7,0x00,0xfb,0xfc,0xf8,0x00, + 0xfc,0xfd,0xf9,0x00,0xfd,0xfe,0xfa,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0f,0x0f,0x0f,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00, + 0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00, + 0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2b,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x33,0x33,0x00, + 0x33,0x34,0x34,0x00,0x34,0x35,0x35,0x00,0x35,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x49,0x4a,0x00,0x4b,0x4a,0x4b,0x00,0x4c,0x4b,0x4c,0x00,0x4d,0x4d,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x56,0x00, + 0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5e,0x5e,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x67,0x67,0x67,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x70,0x70,0x00, + 0x70,0x71,0x71,0x00,0x71,0x72,0x72,0x00,0x72,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x79,0x78,0x00, + 0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7d,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x81,0x00, + 0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x89,0x88,0x00,0x8a,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8f,0x8e,0x8d,0x00,0x90,0x8f,0x8e,0x00,0x91,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x93,0x92,0x00, + 0x93,0x94,0x93,0x00,0x94,0x95,0x94,0x00,0x95,0x96,0x95,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x99,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa5,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00, + 0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb6,0xb6,0xb4,0x00, + 0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00, + 0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc3,0xc4,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00, + 0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcc,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd9,0xd9,0xd6,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe2,0xdf,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe6,0x00, + 0xeb,0xeb,0xe7,0x00,0xec,0xec,0xe8,0x00,0xed,0xed,0xea,0x00,0xef,0xef,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xf0,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfc,0xf8,0x00, + 0xfc,0xfd,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00, + 0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00, + 0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00, + 0x33,0x34,0x34,0x00,0x34,0x35,0x35,0x00,0x35,0x36,0x36,0x00,0x36,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00,0x3b,0x3b,0x3b,0x00, + 0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x4a,0x49,0x4a,0x00,0x4b,0x4a,0x4b,0x00,0x4c,0x4b,0x4c,0x00,0x4d,0x4c,0x4d,0x00, + 0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x57,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00, + 0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x71,0x71,0x00,0x71,0x72,0x72,0x00,0x72,0x73,0x73,0x00,0x73,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00, + 0x79,0x7a,0x79,0x00,0x7a,0x7b,0x7a,0x00,0x7b,0x7c,0x7b,0x00,0x7c,0x7d,0x7c,0x00,0x7e,0x7e,0x7d,0x00,0x7f,0x7f,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x89,0x88,0x00,0x89,0x8a,0x89,0x00, + 0x8b,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x90,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x94,0x93,0x00,0x94,0x95,0x94,0x00,0x95,0x96,0x95,0x00,0x96,0x97,0x96,0x00,0x97,0x98,0x98,0x00,0x98,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00, + 0x9d,0x9d,0x9b,0x00,0x9e,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00, + 0xa5,0xa6,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00, + 0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00, + 0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc4,0xc5,0xc2,0x00,0xc5,0xc6,0xc3,0x00,0xc6,0xc7,0xc4,0x00,0xc7,0xc8,0xc5,0x00, + 0xc8,0xc9,0xc6,0x00,0xc9,0xca,0xc7,0x00,0xca,0xcb,0xc8,0x00,0xcb,0xcc,0xc9,0x00,0xcd,0xcd,0xca,0x00,0xce,0xce,0xcb,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00, + 0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xf0,0xf0,0xec,0x00,0xf1,0xf1,0xed,0x00,0xf2,0xf2,0xee,0x00,0xf3,0xf3,0xef,0x00, + 0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfd,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00, + 0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00, + 0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x55,0x55,0x00, + 0x57,0x56,0x56,0x00,0x58,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00, + 0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x76,0x75,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00, + 0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x89,0x88,0x00,0x89,0x8a,0x89,0x00, + 0x8a,0x8b,0x8a,0x00,0x8c,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00, + 0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00, + 0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00, + 0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00, + 0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00, + 0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe5,0xe6,0xe2,0x00,0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00, + 0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00, + 0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x55,0x54,0x54,0x00,0x56,0x55,0x55,0x00, + 0x57,0x56,0x56,0x00,0x58,0x57,0x57,0x00,0x59,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00, + 0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00, + 0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x80,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x89,0x88,0x00,0x89,0x8a,0x89,0x00, + 0x8a,0x8b,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9c,0x9a,0x00, + 0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9f,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00, + 0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00,0xad,0xad,0xab,0x00, + 0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00, + 0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00, + 0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe5,0xe1,0x00,0xe5,0xe6,0xe2,0x00,0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe9,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf2,0xee,0x00,0xf2,0xf3,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00, + 0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00, + 0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x43,0x43,0x00,0x44,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x56,0x55,0x55,0x00, + 0x57,0x56,0x56,0x00,0x58,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5e,0x00, + 0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x77,0x77,0x00,0x78,0x78,0x78,0x00, + 0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x81,0x81,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x8a,0x89,0x00, + 0x8a,0x8b,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0xa0,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00, + 0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xad,0xad,0xab,0x00, + 0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xd0,0xd0,0xce,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd9,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00, + 0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe6,0xe2,0x00,0xe6,0xe7,0xe3,0x00,0xe7,0xe8,0xe4,0x00,0xe8,0xe9,0xe6,0x00,0xea,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf3,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf5,0xf6,0xf2,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00, + 0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00, + 0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x57,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00, + 0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x77,0x77,0x00,0x77,0x78,0x78,0x00, + 0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x82,0x82,0x81,0x00,0x83,0x83,0x82,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8b,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9d,0x9b,0x00,0x9d,0x9e,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa1,0xa1,0x9f,0x00,0xa2,0xa2,0xa0,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00, + 0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00,0xac,0xad,0xab,0x00, + 0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00,0xb5,0xb6,0xb4,0x00, + 0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00,0xbe,0xbe,0xbc,0x00, + 0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00, + 0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00, + 0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00, + 0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf4,0xf0,0x00,0xf4,0xf5,0xf1,0x00,0xf5,0xf6,0xf2,0x00,0xf6,0xf7,0xf3,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00, + 0xfc,0xfc,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00, + 0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00, + 0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00, + 0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x52,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x77,0x77,0x00,0x77,0x78,0x78,0x00, + 0x78,0x79,0x79,0x00,0x79,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x86,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa2,0x00,0xa3,0xa4,0xa3,0x00, + 0xa4,0xa5,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xaf,0x00,0xb0,0xb1,0xb0,0x00,0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00, + 0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00, + 0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe6,0x00, + 0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xed,0xe9,0x00,0xed,0xee,0xea,0x00,0xee,0xef,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xfa,0xf6,0x00,0xfa,0xfb,0xf7,0x00, + 0xfb,0xfc,0xf8,0x00,0xfc,0xfd,0xf9,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00, + 0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00, + 0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x43,0x43,0x00,0x43,0x44,0x44,0x00, + 0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x52,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x77,0x77,0x00,0x77,0x78,0x78,0x00, + 0x78,0x79,0x79,0x00,0x79,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x86,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8d,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x9a,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9f,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa2,0x00,0xa3,0xa4,0xa3,0x00, + 0xa4,0xa5,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xb0,0xaf,0x00,0xb0,0xb1,0xb0,0x00,0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00, + 0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbb,0x00, + 0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc2,0xbf,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe6,0x00, + 0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xed,0xe9,0x00,0xed,0xee,0xea,0x00,0xee,0xef,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xfa,0xf6,0x00,0xfa,0xfb,0xf7,0x00, + 0xfb,0xfc,0xf8,0x00,0xfc,0xfd,0xf9,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00, + 0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x33,0x00, + 0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x44,0x44,0x00, + 0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x52,0x53,0x00,0x54,0x53,0x54,0x00,0x55,0x55,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x66,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x78,0x78,0x00, + 0x78,0x79,0x79,0x00,0x79,0x7a,0x7a,0x00,0x7a,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x86,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8c,0x8c,0x00,0x8e,0x8e,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9b,0x9b,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0xa0,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa3,0x00, + 0xa4,0xa5,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xb0,0x00,0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00, + 0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbb,0x00, + 0xbe,0xbf,0xbc,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc2,0xc3,0xc0,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00, + 0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd4,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe1,0xde,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00, + 0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xee,0xea,0x00,0xee,0xef,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfb,0xf7,0x00, + 0xfb,0xfc,0xf8,0x00,0xfc,0xfd,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x16,0x00,0x17,0x17,0x17,0x00,0x18,0x18,0x18,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00, + 0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00, + 0x44,0x45,0x45,0x00,0x45,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x52,0x53,0x00,0x54,0x53,0x54,0x00,0x55,0x54,0x55,0x00, + 0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00, + 0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x79,0x79,0x00,0x79,0x7a,0x7a,0x00,0x7a,0x7b,0x7b,0x00,0x7b,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x86,0x86,0x00,0x86,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8c,0x8c,0x00,0x8e,0x8d,0x8d,0x00,0x8f,0x8f,0x8e,0x00,0x90,0x90,0x8f,0x00,0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00, + 0x93,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00, + 0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa1,0x9f,0x00,0xa1,0xa2,0xa0,0x00,0xa2,0xa3,0xa1,0x00,0xa3,0xa4,0xa2,0x00, + 0xa4,0xa5,0xa4,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00, + 0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00,0xbd,0xbe,0xbc,0x00, + 0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc3,0xc0,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00, + 0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00, + 0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd5,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdc,0xdc,0xd9,0x00,0xdd,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe9,0xe6,0x00, + 0xea,0xea,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xef,0xeb,0x00,0xef,0xf0,0xec,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00, + 0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfc,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00, + 0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x41,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00, + 0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x49,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00, + 0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x54,0x53,0x54,0x00,0x55,0x54,0x54,0x00, + 0x56,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x58,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8c,0x8c,0x00,0x8e,0x8d,0x8d,0x00,0x8f,0x8e,0x8e,0x00,0x90,0x8f,0x8f,0x00,0x91,0x90,0x90,0x00,0x91,0x91,0x91,0x00, + 0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x95,0x94,0x00,0x95,0x96,0x95,0x00,0x96,0x97,0x96,0x00,0x98,0x98,0x97,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00, + 0x9b,0x9b,0x9b,0x00,0x9c,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00, + 0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc3,0xc0,0x00,0xc2,0xc4,0xc1,0x00,0xc3,0xc5,0xc2,0x00,0xc4,0xc6,0xc4,0x00,0xc5,0xc6,0xc5,0x00, + 0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe8,0xe6,0x00, + 0xea,0xe9,0xe7,0x00,0xeb,0xeb,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00, + 0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00, + 0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00, + 0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x49,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00, + 0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x54,0x53,0x54,0x00,0x55,0x54,0x54,0x00, + 0x56,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x58,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5c,0x5c,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8d,0x8c,0x8c,0x00,0x8e,0x8d,0x8d,0x00,0x8f,0x8e,0x8e,0x00,0x90,0x8f,0x8f,0x00,0x91,0x90,0x90,0x00,0x91,0x91,0x91,0x00, + 0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x95,0x94,0x00,0x95,0x96,0x95,0x00,0x96,0x97,0x96,0x00,0x97,0x98,0x97,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00, + 0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb4,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00, + 0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc3,0xc0,0x00,0xc2,0xc4,0xc1,0x00,0xc3,0xc5,0xc2,0x00,0xc4,0xc6,0xc4,0x00,0xc5,0xc6,0xc5,0x00, + 0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd7,0xd7,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xdb,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe8,0xe8,0xe5,0x00,0xe9,0xe8,0xe6,0x00, + 0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00, + 0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1b,0x00, + 0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x44,0x00, + 0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x49,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00, + 0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x54,0x53,0x53,0x00,0x55,0x54,0x54,0x00, + 0x56,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5d,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6f,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7e,0x7e,0x00,0x80,0x80,0x80,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x89,0x89,0x89,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8e,0x8d,0x8d,0x00,0x8f,0x8e,0x8e,0x00,0x90,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00, + 0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x96,0x95,0x00,0x96,0x97,0x96,0x00,0x97,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x9a,0x00, + 0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9e,0x9d,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xab,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb5,0xb5,0xb3,0x00, + 0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbc,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc4,0xc1,0x00,0xc3,0xc5,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc5,0x00, + 0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd8,0xd8,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xda,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe9,0xe8,0xe6,0x00, + 0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf2,0xef,0x00, + 0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00, + 0x14,0x13,0x14,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00,0x1a,0x19,0x1a,0x00, + 0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00, + 0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2c,0x2b,0x2c,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2e,0x2e,0x00,0x2f,0x2f,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00,0x32,0x32,0x32,0x00, + 0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00, + 0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x49,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00, + 0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x52,0x00,0x54,0x53,0x53,0x00,0x55,0x54,0x54,0x00, + 0x56,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00, + 0x5e,0x5e,0x5e,0x00,0x5f,0x5f,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7e,0x7e,0x00,0x80,0x7f,0x7f,0x00, + 0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8f,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00, + 0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x97,0x96,0x00,0x97,0x98,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9e,0x9d,0x9d,0x00,0x9f,0x9e,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00, + 0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00,0xb4,0xb5,0xb3,0x00, + 0xb6,0xb6,0xb4,0x00,0xb7,0xb7,0xb5,0x00,0xb8,0xb8,0xb6,0x00,0xb9,0xb9,0xb7,0x00,0xba,0xba,0xb8,0x00,0xbb,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00, + 0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc4,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00, + 0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00, + 0xd9,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00, + 0xea,0xe9,0xe7,0x00,0xeb,0xea,0xe8,0x00,0xec,0xec,0xe9,0x00,0xed,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00, + 0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x21,0x21,0x22,0x00, + 0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00, + 0x4c,0x4d,0x4d,0x00,0x4d,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x53,0x53,0x00,0x55,0x54,0x54,0x00, + 0x56,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x5a,0x5a,0x5a,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00, + 0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7e,0x7e,0x00,0x80,0x7f,0x7f,0x00, + 0x81,0x80,0x80,0x00,0x82,0x81,0x81,0x00,0x83,0x83,0x83,0x00,0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8b,0x8a,0x8a,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00, + 0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9e,0x9d,0x9c,0x00,0x9f,0x9e,0x9d,0x00,0xa0,0x9f,0x9e,0x00,0xa1,0xa0,0x9f,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00, + 0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00, + 0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00, + 0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00, + 0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00, + 0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00, + 0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1d,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x21,0x21,0x21,0x00, + 0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x42,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4b,0x4b,0x00,0x4b,0x4c,0x4c,0x00, + 0x4c,0x4d,0x4d,0x00,0x4d,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x53,0x53,0x00,0x55,0x54,0x54,0x00, + 0x56,0x55,0x55,0x00,0x57,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00, + 0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x60,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7f,0x7e,0x7e,0x00,0x80,0x7f,0x7f,0x00, + 0x81,0x80,0x80,0x00,0x82,0x81,0x81,0x00,0x83,0x83,0x83,0x00,0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00, + 0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x99,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9e,0x9d,0x9c,0x00,0x9f,0x9e,0x9d,0x00,0xa0,0x9f,0x9e,0x00,0xa1,0xa0,0x9f,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa7,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xab,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00, + 0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbc,0xbc,0xba,0x00,0xbd,0xbd,0xbb,0x00, + 0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xce,0xcb,0x00,0xce,0xcf,0xcc,0x00, + 0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00, + 0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00, + 0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00, + 0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf9,0xf9,0xf6,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1e,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00, + 0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x43,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4c,0x4c,0x00, + 0x4c,0x4d,0x4d,0x00,0x4d,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x55,0x54,0x54,0x00, + 0x56,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00, + 0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x61,0x61,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x76,0x00,0x77,0x77,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x7f,0x7f,0x00, + 0x81,0x80,0x80,0x00,0x82,0x81,0x81,0x00,0x83,0x82,0x82,0x00,0x83,0x84,0x84,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00, + 0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x99,0x98,0x00,0x9a,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9f,0x9e,0x9d,0x00,0xa0,0x9f,0x9e,0x00,0xa1,0xa0,0x9f,0x00,0xa2,0xa1,0xa1,0x00,0xa3,0xa3,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa8,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xac,0xac,0xaa,0x00, + 0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00, + 0xbe,0xbe,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xcf,0xcc,0x00, + 0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00, + 0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xe0,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe2,0x00,0xe6,0xe6,0xe3,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00, + 0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf1,0xf1,0xee,0x00, + 0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xfa,0xfa,0xf7,0x00, + 0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1f,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00, + 0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x42,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4d,0x4d,0x00,0x4d,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x56,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00, + 0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x62,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00,0x6e,0x6e,0x6e,0x00, + 0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x81,0x80,0x80,0x00,0x82,0x81,0x81,0x00,0x83,0x82,0x82,0x00,0x84,0x83,0x83,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00, + 0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x99,0x98,0x00,0x99,0x9a,0x99,0x00, + 0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0xa0,0x9f,0x9f,0x00,0xa1,0xa0,0xa0,0x00,0xa2,0xa1,0xa1,0x00,0xa3,0xa2,0xa2,0x00, + 0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa9,0xa7,0x00,0xa9,0xaa,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00, + 0xad,0xad,0xab,0x00,0xae,0xae,0xac,0x00,0xaf,0xaf,0xad,0x00,0xb0,0xb0,0xae,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xb9,0x00,0xbb,0xbc,0xba,0x00,0xbc,0xbd,0xbb,0x00, + 0xbd,0xbe,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00, + 0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00, + 0xcf,0xd0,0xcd,0x00,0xd0,0xd1,0xce,0x00,0xd1,0xd2,0xcf,0x00,0xd2,0xd3,0xd0,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00, + 0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00, + 0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xdf,0x00,0xe3,0xe3,0xe0,0x00,0xe4,0xe4,0xe1,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00, + 0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00, + 0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00, + 0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00, + 0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x42,0x43,0x00, + 0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4f,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00, + 0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x83,0x82,0x82,0x00,0x84,0x83,0x83,0x00,0x85,0x84,0x84,0x00,0x86,0x85,0x85,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x90,0x90,0x00,0x90,0x91,0x90,0x00, + 0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x99,0x98,0x00,0x99,0x9a,0x99,0x00, + 0x9a,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa5,0xa3,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00, + 0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xba,0x00, + 0xbd,0xbd,0xbb,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00, + 0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00, + 0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00, + 0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe5,0x00, + 0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xeb,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00, + 0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00, + 0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00, + 0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x29,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2d,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x39,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x41,0x42,0x00,0x43,0x42,0x43,0x00, + 0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4f,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00, + 0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x64,0x64,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x83,0x82,0x82,0x00,0x84,0x83,0x83,0x00,0x85,0x84,0x84,0x00,0x86,0x85,0x85,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x90,0x90,0x00,0x90,0x91,0x90,0x00, + 0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x94,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x99,0x98,0x00,0x99,0x9a,0x99,0x00, + 0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xaa,0xab,0xa9,0x00,0xab,0xac,0xaa,0x00, + 0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbb,0xbc,0xba,0x00, + 0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00, + 0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd6,0xd6,0xd4,0x00,0xd7,0xd7,0xd5,0x00, + 0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00, + 0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe5,0x00, + 0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00, + 0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00, + 0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0e,0x0e,0x0e,0x00,0x10,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00, + 0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x29,0x00,0x2a,0x2a,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x3a,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x42,0x43,0x00, + 0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4c,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x56,0x57,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5a,0x5b,0x00,0x5c,0x5c,0x5d,0x00, + 0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x65,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6e,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x77,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x84,0x83,0x83,0x00,0x85,0x84,0x84,0x00,0x86,0x85,0x85,0x00,0x87,0x86,0x86,0x00,0x88,0x88,0x88,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x91,0x90,0x00, + 0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x93,0x00,0x95,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x98,0x00,0x99,0x9a,0x99,0x00, + 0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xab,0xac,0xaa,0x00, + 0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb4,0xb4,0xb3,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbb,0xbc,0xba,0x00, + 0xbc,0xbd,0xbb,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xce,0xce,0xcc,0x00, + 0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd7,0xd7,0xd5,0x00, + 0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00, + 0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe5,0x00, + 0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf1,0xee,0x00, + 0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00, + 0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x10,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00, + 0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00, + 0x2b,0x2b,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3b,0x3b,0x3b,0x00,0x3c,0x3c,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00, + 0x55,0x55,0x55,0x00,0x55,0x56,0x56,0x00,0x56,0x57,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5a,0x5b,0x00,0x5c,0x5b,0x5c,0x00, + 0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00, + 0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x85,0x84,0x84,0x00,0x86,0x85,0x85,0x00,0x87,0x86,0x86,0x00,0x88,0x87,0x87,0x00, + 0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x92,0x91,0x00,0x92,0x93,0x92,0x00,0x93,0x94,0x93,0x00,0x94,0x95,0x94,0x00,0x96,0x96,0x95,0x00,0x97,0x97,0x96,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00, + 0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00, + 0xac,0xad,0xab,0x00,0xad,0xae,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb4,0xb2,0x00, + 0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbb,0xbc,0xbb,0x00, + 0xbc,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00, + 0xd8,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00, + 0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00, + 0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf4,0x00,0xf8,0xf8,0xf5,0x00,0xf9,0xf9,0xf6,0x00, + 0xfa,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xff,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00, + 0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x43,0x43,0x00, + 0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00, + 0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00,0x56,0x57,0x57,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5a,0x5b,0x00,0x5c,0x5b,0x5c,0x00, + 0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x97,0x96,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00, + 0xab,0xac,0xab,0x00,0xac,0xad,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbb,0xbc,0xbb,0x00, + 0xbc,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00, + 0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00, + 0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00, + 0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00,0xf7,0xf6,0xf3,0x00,0xf8,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00, + 0xf9,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xff,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00, + 0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3d,0x3d,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x42,0x42,0x00,0x42,0x43,0x43,0x00, + 0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00, + 0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00,0x56,0x57,0x57,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5b,0x5a,0x5b,0x00,0x5c,0x5b,0x5c,0x00, + 0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x71,0x70,0x71,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa6,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00, + 0xab,0xac,0xab,0x00,0xac,0xad,0xac,0x00,0xae,0xaf,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb3,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbb,0xbc,0xbb,0x00, + 0xbc,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcd,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd6,0xd3,0x00,0xd6,0xd7,0xd4,0x00, + 0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xde,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00, + 0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00, + 0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf4,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00,0xf7,0xf6,0xf3,0x00,0xf8,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00, + 0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xff,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00, + 0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x43,0x43,0x00, + 0x43,0x44,0x44,0x00,0x44,0x45,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x54,0x54,0x00, + 0x54,0x55,0x55,0x00,0x55,0x56,0x56,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5b,0x00,0x5c,0x5b,0x5c,0x00, + 0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x72,0x71,0x72,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x76,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7f,0x7f,0x7f,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8b,0x8a,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x99,0x99,0x99,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00, + 0xab,0xac,0xab,0x00,0xac,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xaf,0xb0,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb2,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xba,0xbb,0xba,0x00,0xbb,0xbc,0xbb,0x00, + 0xbc,0xbd,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xce,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd7,0xd4,0x00, + 0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xdf,0xdf,0xdc,0x00, + 0xe0,0xe0,0xdd,0x00,0xe1,0xe1,0xde,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe8,0xe6,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00, + 0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf5,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00,0xf7,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf9,0xf6,0x00, + 0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xff,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00, + 0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00, + 0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x3f,0x00,0x40,0x40,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x44,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x55,0x55,0x55,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00, + 0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x73,0x72,0x73,0x00,0x74,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00, + 0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00, + 0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8b,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00, + 0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa8,0xa7,0x00,0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xaa,0x00, + 0xab,0xac,0xab,0x00,0xac,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xb0,0xb1,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb9,0xb9,0xb8,0x00,0xb9,0xba,0xb9,0x00,0xba,0xbb,0xba,0x00,0xbb,0xbc,0xbb,0x00, + 0xbc,0xbd,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00, + 0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00, + 0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd2,0x00,0xd5,0xd5,0xd3,0x00,0xd6,0xd6,0xd4,0x00, + 0xd7,0xd8,0xd5,0x00,0xd8,0xd9,0xd6,0x00,0xd9,0xda,0xd7,0x00,0xda,0xdb,0xd8,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdc,0x00, + 0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00, + 0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xeb,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00, + 0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf6,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xff,0xfc,0x00,0xfe,0xff,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00, + 0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00, + 0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x40,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x53,0x53,0x00, + 0x55,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x59,0x59,0x59,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00, + 0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00, + 0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8b,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8c,0x8d,0x8c,0x00,0x8d,0x8e,0x8d,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00, + 0x99,0x9a,0x99,0x00,0x9b,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xad,0xab,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb0,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xba,0x00,0xbb,0xbb,0xbb,0x00, + 0xbc,0xbc,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00, + 0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xde,0xdb,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00, + 0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x29,0x00,0x29,0x29,0x2a,0x00, + 0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x30,0x30,0x00,0x31,0x31,0x31,0x00, + 0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x53,0x52,0x52,0x00,0x54,0x53,0x53,0x00, + 0x55,0x54,0x54,0x00,0x56,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x57,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00,0x63,0x63,0x63,0x00,0x64,0x64,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6c,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00, + 0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7e,0x7d,0x00,0x7e,0x7f,0x7e,0x00, + 0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8b,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8c,0x8d,0x8c,0x00,0x8d,0x8e,0x8d,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00, + 0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb0,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb7,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xbb,0xba,0x00,0xbb,0xbb,0xbb,0x00, + 0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc4,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00, + 0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xef,0xed,0x00,0xef,0xf0,0xed,0x00, + 0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x25,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x2a,0x00, + 0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x31,0x31,0x00, + 0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4b,0x4b,0x4b,0x00, + 0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x54,0x53,0x53,0x00, + 0x55,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00,0x63,0x62,0x63,0x00,0x64,0x64,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6d,0x6d,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x76,0x75,0x76,0x00, + 0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7f,0x7e,0x00, + 0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x81,0x82,0x81,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8c,0x8b,0x00,0x8c,0x8d,0x8c,0x00,0x8d,0x8e,0x8d,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00, + 0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0xa0,0x00,0xa2,0xa2,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb0,0xb1,0xb0,0x00,0xb1,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb8,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xba,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xbb,0x00, + 0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc5,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcc,0x00, + 0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xdf,0xdd,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe7,0xe7,0xe5,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xf0,0xed,0x00, + 0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x20,0x21,0x00, + 0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x26,0x26,0x00,0x27,0x27,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2b,0x2a,0x2b,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x32,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00, + 0x55,0x54,0x55,0x00,0x55,0x55,0x55,0x00,0x56,0x56,0x56,0x00,0x56,0x57,0x57,0x00,0x57,0x58,0x58,0x00,0x58,0x59,0x59,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00, + 0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00,0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00, + 0x65,0x65,0x65,0x00,0x66,0x66,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6e,0x6e,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x80,0x7f,0x00,0x80,0x81,0x80,0x00,0x81,0x82,0x81,0x00,0x82,0x83,0x82,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00, + 0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8d,0x8d,0x00,0x8d,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00, + 0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00, + 0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9c,0x9d,0x9c,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00, + 0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb0,0xb1,0xb0,0x00,0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00, + 0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb9,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00, + 0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xca,0xca,0xc8,0x00,0xcb,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00, + 0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00, + 0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00, + 0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00, + 0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x29,0x00, + 0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00, + 0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00, + 0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00, + 0x88,0x87,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00, + 0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00, + 0xb3,0xb4,0xb3,0x00,0xb4,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xba,0xbb,0xba,0x00, + 0xbb,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00, + 0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00, + 0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00, + 0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00, + 0xf8,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x29,0x28,0x28,0x00,0x2a,0x29,0x29,0x00, + 0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00, + 0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x63,0x62,0x63,0x00,0x64,0x63,0x64,0x00, + 0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x67,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00, + 0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x97,0x00,0x98,0x99,0x98,0x00, + 0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00,0x9e,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00, + 0xb3,0xb4,0xb3,0x00,0xb4,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xba,0xbb,0xba,0x00, + 0xbb,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00, + 0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcc,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe6,0xe3,0x00,0xe6,0xe7,0xe4,0x00, + 0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00, + 0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00, + 0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x21,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x2a,0x29,0x29,0x00, + 0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x3a,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x42,0x43,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x55,0x56,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5b,0x5a,0x5c,0x00, + 0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x64,0x63,0x64,0x00, + 0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x68,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x86,0x00,0x87,0x86,0x87,0x00, + 0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8e,0x00,0x90,0x90,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x99,0x98,0x00, + 0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9c,0x9d,0x9d,0x00,0x9d,0x9e,0x9e,0x00,0x9e,0x9f,0x9f,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb3,0xb2,0x00, + 0xb3,0xb4,0xb3,0x00,0xb4,0xb5,0xb4,0x00,0xb5,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xba,0xbb,0xba,0x00, + 0xbb,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc3,0x00, + 0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcd,0xcd,0xcb,0x00, + 0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe7,0xe4,0x00, + 0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00, + 0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf4,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf6,0x00, + 0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00, + 0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2b,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00, + 0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x34,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x37,0x00,0x38,0x38,0x38,0x00,0x39,0x39,0x39,0x00, + 0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00, + 0x43,0x43,0x44,0x00,0x44,0x44,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00, + 0x54,0x54,0x55,0x00,0x54,0x55,0x56,0x00,0x55,0x56,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00, + 0x65,0x64,0x65,0x00,0x66,0x65,0x66,0x00,0x67,0x66,0x67,0x00,0x68,0x67,0x68,0x00,0x69,0x69,0x69,0x00,0x6a,0x6a,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00, + 0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x91,0x91,0x90,0x00,0x92,0x92,0x91,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x99,0x9a,0x99,0x00,0x9a,0x9b,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9c,0x9d,0x9c,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa7,0xa7,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00,0xaa,0xaa,0xa9,0x00, + 0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00, + 0xb3,0xb4,0xb3,0x00,0xb4,0xb5,0xb4,0x00,0xb5,0xb6,0xb5,0x00,0xb6,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00,0xc4,0xc4,0xc2,0x00, + 0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xce,0xce,0xcc,0x00,0xcf,0xcf,0xcd,0x00,0xd0,0xd0,0xce,0x00,0xd1,0xd1,0xcf,0x00,0xd2,0xd2,0xd0,0x00,0xd3,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdc,0x00, + 0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe1,0x00,0xe4,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00, + 0xe7,0xe8,0xe5,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00, + 0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00, + 0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00, + 0x43,0x42,0x43,0x00,0x44,0x43,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x52,0x53,0x00,0x52,0x53,0x54,0x00, + 0x53,0x54,0x55,0x00,0x54,0x55,0x56,0x00,0x55,0x56,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x81,0x82,0x82,0x00,0x82,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00, + 0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8a,0x8b,0x8b,0x00,0x8b,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa9,0xa8,0xa8,0x00,0xaa,0xa9,0xa9,0x00, + 0xab,0xaa,0xaa,0x00,0xac,0xab,0xab,0x00,0xad,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb6,0xb5,0x00,0xb6,0xb7,0xb6,0x00,0xb7,0xb8,0xb7,0x00,0xb8,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00,0xc8,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdb,0x00, + 0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00, + 0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xec,0x00,0xef,0xee,0xed,0x00, + 0xf0,0xef,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x28,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2c,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x38,0x37,0x38,0x00,0x39,0x38,0x39,0x00, + 0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x40,0x41,0x00,0x42,0x41,0x42,0x00, + 0x43,0x42,0x43,0x00,0x44,0x43,0x44,0x00,0x45,0x45,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x52,0x53,0x00,0x52,0x53,0x54,0x00, + 0x53,0x54,0x55,0x00,0x54,0x55,0x56,0x00,0x55,0x56,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x74,0x74,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x81,0x82,0x82,0x00,0x82,0x83,0x83,0x00,0x83,0x84,0x84,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00, + 0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8a,0x8b,0x8b,0x00,0x8b,0x8c,0x8c,0x00,0x8c,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9c,0x9c,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa9,0xa8,0xa8,0x00,0xaa,0xa9,0xa9,0x00, + 0xab,0xaa,0xaa,0x00,0xac,0xab,0xab,0x00,0xad,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb6,0xb5,0x00,0xb6,0xb7,0xb6,0x00,0xb7,0xb8,0xb7,0x00,0xb8,0xb9,0xb8,0x00,0xba,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbf,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00,0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcc,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00,0xdd,0xde,0xdb,0x00, + 0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe5,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00, + 0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xec,0x00,0xef,0xee,0xed,0x00, + 0xf0,0xef,0xee,0x00,0xf1,0xf0,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfb,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfe,0xfe,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x1a,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x29,0x29,0x00, + 0x2a,0x2a,0x2a,0x00,0x2b,0x2b,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x38,0x39,0x00, + 0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x42,0x41,0x42,0x00, + 0x43,0x42,0x43,0x00,0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x46,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4b,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x53,0x54,0x00, + 0x53,0x54,0x55,0x00,0x54,0x55,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x57,0x00,0x58,0x58,0x58,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x63,0x64,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00,0x6c,0x6c,0x6d,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x75,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7e,0x7e,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x81,0x82,0x82,0x00,0x82,0x83,0x83,0x00,0x83,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x87,0x00, + 0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8b,0x8b,0x00,0x8b,0x8c,0x8c,0x00,0x8c,0x8d,0x8d,0x00,0x8d,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x97,0x97,0x00,0x98,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9d,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xaa,0xa9,0xa9,0x00, + 0xab,0xaa,0xaa,0x00,0xac,0xab,0xab,0x00,0xac,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb7,0xb6,0x00,0xb7,0xb8,0xb7,0x00,0xb8,0xb9,0xb8,0x00,0xb9,0xba,0xb9,0x00,0xbb,0xbb,0xba,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xc0,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc7,0x00,0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcd,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd5,0xd5,0xd4,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00, + 0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe6,0xe6,0xe4,0x00, + 0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xeb,0xec,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xec,0x00,0xef,0xee,0xed,0x00, + 0xf0,0xef,0xee,0x00,0xf1,0xf0,0xef,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf8,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfc,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00, + 0x14,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x19,0x18,0x19,0x00, + 0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1e,0x1e,0x20,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00, + 0x2b,0x2a,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x3a,0x39,0x3a,0x00,0x3b,0x3a,0x3b,0x00,0x3c,0x3b,0x3c,0x00,0x3d,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x43,0x42,0x43,0x00,0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x45,0x46,0x00,0x47,0x47,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x54,0x54,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00, + 0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00, + 0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00, + 0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00, + 0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8c,0x8c,0x00,0x8c,0x8d,0x8d,0x00,0x8d,0x8e,0x8e,0x00,0x8e,0x8f,0x8f,0x00, + 0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00, + 0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9c,0x9c,0x00,0x9e,0x9e,0x9d,0x00,0x9f,0x9f,0x9e,0x00,0xa0,0xa0,0x9f,0x00,0xa1,0xa1,0xa0,0x00, + 0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00, + 0xab,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb8,0xb7,0x00,0xb8,0xb9,0xb8,0x00,0xb9,0xba,0xb9,0x00,0xba,0xbb,0xba,0x00, + 0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc1,0xbf,0x00,0xc1,0xc2,0xc0,0x00,0xc2,0xc3,0xc1,0x00,0xc3,0xc4,0xc2,0x00, + 0xc4,0xc5,0xc3,0x00,0xc5,0xc6,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xce,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00, + 0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xd9,0x00,0xdc,0xdd,0xda,0x00,0xdd,0xde,0xdb,0x00, + 0xde,0xdf,0xdc,0x00,0xdf,0xe0,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00, + 0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xed,0x00, + 0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfb,0xfc,0xf9,0x00,0xfd,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x20,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x28,0x00,0x2a,0x28,0x29,0x00, + 0x2b,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3e,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x45,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x53,0x52,0x53,0x00, + 0x54,0x53,0x54,0x00,0x55,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00, + 0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00, + 0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00, + 0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00, + 0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x81,0x00,0x83,0x82,0x82,0x00,0x84,0x83,0x84,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8e,0x8e,0x00,0x8e,0x8f,0x8f,0x00, + 0x8f,0x90,0x90,0x00,0x90,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00, + 0x98,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9c,0x9c,0x00,0x9e,0x9d,0x9d,0x00,0x9f,0x9e,0x9e,0x00,0xa0,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00, + 0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa4,0xa3,0xa4,0x00,0xa5,0xa4,0xa5,0x00,0xa6,0xa5,0xa6,0x00,0xa7,0xa6,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00, + 0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00, + 0xbb,0xbb,0xbb,0x00,0xbc,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00, + 0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00, + 0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfb,0xfc,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x20,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x29,0x27,0x28,0x00,0x2a,0x28,0x29,0x00, + 0x2b,0x29,0x2a,0x00,0x2c,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x45,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x52,0x51,0x52,0x00,0x53,0x52,0x53,0x00, + 0x54,0x53,0x54,0x00,0x55,0x54,0x55,0x00,0x56,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00, + 0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00, + 0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00, + 0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00, + 0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x81,0x00,0x83,0x82,0x82,0x00,0x84,0x83,0x83,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8e,0x8e,0x00,0x8e,0x8f,0x8f,0x00, + 0x8f,0x90,0x90,0x00,0x90,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x97,0x97,0x00,0x97,0x98,0x98,0x00, + 0x98,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9c,0x9c,0x00,0x9e,0x9d,0x9d,0x00,0x9f,0x9e,0x9e,0x00,0xa0,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00, + 0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa4,0xa3,0xa4,0x00,0xa5,0xa4,0xa5,0x00,0xa6,0xa5,0xa6,0x00,0xa7,0xa6,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00, + 0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xad,0xac,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00, + 0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc7,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd4,0xd2,0x00,0xd4,0xd5,0xd3,0x00, + 0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd8,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00, + 0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf2,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfb,0xfc,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0d,0x0d,0x0d,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x2a,0x28,0x29,0x00, + 0x2b,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x46,0x45,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x53,0x52,0x53,0x00, + 0x54,0x53,0x54,0x00,0x55,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x63,0x62,0x64,0x00, + 0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6b,0x6c,0x00, + 0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00, + 0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00, + 0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x82,0x81,0x81,0x00,0x83,0x82,0x82,0x00,0x84,0x83,0x83,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8f,0x8f,0x00, + 0x8f,0x90,0x90,0x00,0x90,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x98,0x98,0x00, + 0x98,0x99,0x99,0x00,0x99,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9e,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00, + 0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa5,0xa4,0xa4,0x00,0xa6,0xa5,0xa6,0x00,0xa7,0xa6,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00, + 0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xae,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00, + 0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc8,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcc,0xcc,0xcb,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd5,0xd3,0x00, + 0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd9,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00, + 0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xeb,0x00,0xee,0xef,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf3,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfc,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x20,0x20,0x00, + 0x21,0x21,0x21,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2b,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00, + 0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x46,0x47,0x00,0x48,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00, + 0x54,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00, + 0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00, + 0x6d,0x6c,0x6d,0x00,0x6e,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00, + 0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00, + 0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x81,0x00,0x83,0x82,0x82,0x00,0x84,0x83,0x83,0x00,0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00, + 0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x90,0x90,0x00,0x90,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x99,0x99,0x00,0x99,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00, + 0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa6,0xa5,0xa5,0x00,0xa7,0xa6,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xaf,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00,0xb2,0xb2,0xb1,0x00, + 0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00, + 0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc9,0xc7,0x00,0xc9,0xca,0xc8,0x00,0xca,0xcb,0xc9,0x00,0xcb,0xcc,0xca,0x00, + 0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xda,0xda,0xd8,0x00,0xdb,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00, + 0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xf0,0xed,0x00,0xf0,0xf1,0xee,0x00,0xf1,0xf2,0xef,0x00,0xf2,0xf3,0xf0,0x00,0xf4,0xf4,0xf1,0x00,0xf5,0xf5,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2b,0x2c,0x00,0x2e,0x2c,0x2d,0x00,0x2f,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x56,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00, + 0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00, + 0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00, + 0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00, + 0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00, + 0x86,0x87,0x87,0x00,0x87,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x92,0x91,0x92,0x00,0x93,0x92,0x93,0x00,0x94,0x93,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb1,0xb0,0xb0,0x00,0xb2,0xb1,0xb1,0x00, + 0xb3,0xb2,0xb2,0x00,0xb4,0xb3,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xb9,0xba,0xba,0x00, + 0xba,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe3,0x00,0xe4,0xe6,0xe4,0x00, + 0xe5,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2b,0x2c,0x00,0x2e,0x2c,0x2d,0x00,0x2f,0x2d,0x2e,0x00,0x30,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x49,0x49,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00, + 0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00, + 0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6f,0x6f,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00, + 0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00, + 0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00, + 0x86,0x87,0x87,0x00,0x87,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x92,0x91,0x92,0x00,0x93,0x92,0x93,0x00,0x94,0x93,0x94,0x00,0x95,0x94,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa8,0xa8,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb1,0xb0,0xb0,0x00,0xb2,0xb1,0xb1,0x00, + 0xb3,0xb2,0xb2,0x00,0xb4,0xb3,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00,0xb9,0xba,0xba,0x00, + 0xba,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe1,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe4,0xe5,0xe3,0x00,0xe4,0xe6,0xe4,0x00, + 0xe5,0xe7,0xe5,0x00,0xe6,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x29,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2b,0x2c,0x00,0x2e,0x2c,0x2d,0x00,0x2f,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x3f,0x41,0x00,0x41,0x41,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x4a,0x4a,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x5a,0x59,0x5b,0x00, + 0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00, + 0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x70,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x75,0x00, + 0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7e,0x00, + 0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x86,0x86,0x00, + 0x86,0x87,0x87,0x00,0x87,0x88,0x88,0x00,0x88,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x92,0x00,0x93,0x92,0x93,0x00,0x94,0x93,0x94,0x00,0x95,0x94,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa4,0x00,0xa6,0xa6,0xa5,0x00,0xa7,0xa7,0xa7,0x00,0xa9,0xa9,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb2,0xb1,0xb1,0x00, + 0xb3,0xb2,0xb2,0x00,0xb4,0xb3,0xb3,0x00,0xb5,0xb4,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb8,0xb9,0xb8,0x00,0xb9,0xba,0xba,0x00, + 0xba,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd4,0xd4,0xd3,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe2,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe3,0xe4,0xe1,0x00,0xe3,0xe5,0xe2,0x00,0xe4,0xe6,0xe4,0x00, + 0xe5,0xe7,0xe5,0x00,0xe6,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf7,0xf7,0xf5,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfe,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x28,0x00, + 0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2b,0x2c,0x00,0x2e,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00, + 0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00, + 0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4c,0x00,0x4d,0x4d,0x4d,0x00,0x4e,0x4e,0x4e,0x00,0x4f,0x4f,0x4f,0x00,0x50,0x50,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00, + 0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x71,0x00,0x72,0x72,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00, + 0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00, + 0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x87,0x87,0x00,0x87,0x88,0x88,0x00,0x88,0x89,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x93,0x94,0x00,0x95,0x94,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa3,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xaa,0xaa,0xa9,0x00,0xab,0xab,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00, + 0xb3,0xb2,0xb2,0x00,0xb4,0xb3,0xb3,0x00,0xb5,0xb4,0xb4,0x00,0xb6,0xb5,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb7,0xb8,0xb7,0x00,0xb8,0xb9,0xb8,0x00,0xb9,0xba,0xb9,0x00, + 0xba,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00, + 0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00, + 0xde,0xde,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe3,0xe0,0x00,0xe2,0xe4,0xe1,0x00,0xe3,0xe5,0xe2,0x00,0xe4,0xe6,0xe3,0x00, + 0xe5,0xe7,0xe5,0x00,0xe6,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xec,0x00, + 0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x27,0x27,0x00,0x29,0x28,0x29,0x00, + 0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x38,0x00,0x38,0x37,0x39,0x00, + 0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00, + 0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4d,0x4c,0x4d,0x00,0x4e,0x4d,0x4e,0x00,0x4f,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00, + 0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00, + 0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7c,0x7c,0x00,0x7c,0x7d,0x7d,0x00, + 0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00, + 0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00, + 0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00, + 0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00, + 0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xeb,0x00, + 0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfb,0xfc,0xf9,0x00,0xfc,0xfd,0xfb,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00, + 0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x33,0x33,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x37,0x38,0x00,0x38,0x37,0x39,0x00, + 0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00, + 0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4d,0x4c,0x4d,0x00,0x4e,0x4d,0x4e,0x00,0x4f,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x51,0x51,0x00,0x52,0x52,0x52,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x55,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00, + 0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x73,0x73,0x73,0x00,0x74,0x74,0x74,0x00, + 0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7c,0x7c,0x00,0x7c,0x7d,0x7d,0x00, + 0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8d,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xac,0xac,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00, + 0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbf,0xbf,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00, + 0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xcf,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00, + 0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdc,0xda,0x00,0xdc,0xdd,0xdb,0x00, + 0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xed,0xed,0xeb,0x00,0xee,0xee,0xeb,0x00, + 0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf6,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfb,0xfc,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x26,0x27,0x00,0x29,0x28,0x29,0x00, + 0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x34,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x36,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x39,0x00, + 0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x41,0x40,0x42,0x00, + 0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4e,0x4d,0x4e,0x00,0x4f,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x52,0x52,0x00, + 0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x55,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6b,0x6c,0x00, + 0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x74,0x74,0x74,0x00, + 0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7d,0x7d,0x00, + 0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8e,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x97,0x97,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9e,0x00,0xa0,0xa0,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xad,0xad,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00, + 0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xc0,0xc0,0xbe,0x00,0xc1,0xc1,0xbf,0x00,0xc2,0xc2,0xc0,0x00,0xc3,0xc3,0xc1,0x00, + 0xc4,0xc4,0xc2,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xd0,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00, + 0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdd,0xdb,0x00, + 0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xed,0xea,0x00,0xee,0xee,0xeb,0x00, + 0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf7,0xf4,0x00, + 0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfb,0xfc,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00, + 0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x18,0x19,0x00, + 0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x26,0x27,0x00,0x29,0x27,0x28,0x00, + 0x2a,0x29,0x2a,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x34,0x33,0x34,0x00,0x35,0x35,0x35,0x00,0x36,0x35,0x36,0x00,0x37,0x36,0x37,0x00,0x38,0x37,0x38,0x00, + 0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4f,0x4e,0x4f,0x00,0x50,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x52,0x00, + 0x53,0x53,0x54,0x00,0x54,0x53,0x54,0x00,0x55,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00, + 0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x75,0x75,0x75,0x00,0x76,0x76,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00, + 0x7d,0x7e,0x7e,0x00,0x7e,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00, + 0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00, + 0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa1,0xa1,0xa0,0x00,0xa2,0xa2,0xa1,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xae,0xae,0xad,0x00,0xaf,0xaf,0xae,0x00,0xb0,0xb0,0xaf,0x00,0xb1,0xb1,0xb0,0x00, + 0xb2,0xb2,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00, + 0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc3,0x00,0xc6,0xc6,0xc4,0x00,0xc7,0xc7,0xc5,0x00,0xc8,0xc8,0xc6,0x00,0xc9,0xc9,0xc7,0x00,0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00, + 0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd1,0xcf,0x00,0xd1,0xd2,0xd0,0x00,0xd2,0xd3,0xd1,0x00,0xd3,0xd4,0xd2,0x00, + 0xd4,0xd5,0xd3,0x00,0xd5,0xd6,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00, + 0xef,0xef,0xec,0x00,0xf0,0xf0,0xed,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf6,0x00,0xf9,0xfa,0xf7,0x00,0xfa,0xfb,0xf8,0x00,0xfb,0xfc,0xf9,0x00,0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x17,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x51,0x50,0x51,0x00,0x52,0x51,0x53,0x00, + 0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00, + 0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00, + 0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00, + 0x8f,0x8e,0x8f,0x00,0x90,0x8f,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00, + 0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb0,0xb1,0xb0,0x00, + 0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00, + 0xba,0xba,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00, + 0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00, + 0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x18,0x17,0x18,0x00,0x18,0x17,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x33,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00, + 0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5d,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00, + 0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x77,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00, + 0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00, + 0x8f,0x8e,0x8f,0x00,0x90,0x8f,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00, + 0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xb0,0xaf,0x00,0xb0,0xb1,0xb0,0x00, + 0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00, + 0xba,0xba,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xca,0xc9,0x00,0xca,0xcb,0xca,0x00, + 0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xec,0xed,0xea,0x00,0xed,0xee,0xeb,0x00, + 0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x17,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x52,0x51,0x53,0x00, + 0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5e,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x62,0x63,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6b,0x6a,0x6c,0x00, + 0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x78,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00, + 0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00, + 0x8f,0x8e,0x8f,0x00,0x90,0x8f,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x97,0x00, + 0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb1,0xb0,0x00, + 0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00, + 0xba,0xba,0xb9,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xcb,0xca,0x00, + 0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe6,0x00,0xe9,0xea,0xe7,0x00,0xea,0xeb,0xe8,0x00,0xec,0xec,0xea,0x00,0xed,0xee,0xeb,0x00, + 0xee,0xef,0xec,0x00,0xef,0xf0,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x17,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00, + 0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x53,0x52,0x54,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5a,0x00, + 0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5f,0x5e,0x5f,0x00,0x60,0x5f,0x60,0x00,0x61,0x60,0x61,0x00,0x62,0x61,0x62,0x00, + 0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00, + 0x7e,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x84,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00, + 0x8f,0x8e,0x8f,0x00,0x90,0x8f,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00, + 0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb2,0xb1,0x00,0xb2,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbd,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00, + 0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00, + 0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00,0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00, + 0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xef,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf5,0xf3,0x00,0xf5,0xf6,0xf4,0x00, + 0xf7,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x17,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x54,0x56,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00, + 0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00, + 0x7e,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00, + 0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbd,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbe,0xbf,0xbe,0x00,0xbf,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00, + 0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00,0xd0,0xcf,0xcf,0x00,0xd1,0xd0,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00, + 0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xde,0xdf,0xde,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf3,0x00,0xf5,0xf6,0xf4,0x00, + 0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x17,0x18,0x00,0x18,0x17,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00, + 0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00,0x7d,0x7c,0x7c,0x00, + 0x7e,0x7d,0x7d,0x00,0x7f,0x7e,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x80,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x84,0x84,0x00,0x85,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa7,0xa6,0x00,0xa7,0xa8,0xa7,0x00, + 0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbd,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbe,0xbf,0xbe,0x00,0xbf,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00, + 0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00,0xd0,0xcf,0xcf,0x00,0xd1,0xd0,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd7,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xda,0x00,0xdb,0xdc,0xdb,0x00, + 0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xde,0xdf,0xde,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xec,0xec,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf3,0x00,0xf5,0xf6,0xf4,0x00, + 0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x15,0x16,0x00,0x16,0x16,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x4a,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x59,0x00,0x59,0x58,0x5a,0x00, + 0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7c,0x7c,0x00, + 0x7e,0x7d,0x7d,0x00,0x7e,0x7e,0x7e,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x80,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x85,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9f,0x9f,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa8,0xa7,0x00, + 0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb9,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbe,0xbd,0x00,0xbe,0xbf,0xbe,0x00,0xbf,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00, + 0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00,0xd0,0xcf,0xcf,0x00,0xd1,0xd0,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd8,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xdb,0x00, + 0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe0,0xe1,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xed,0xed,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf4,0x00, + 0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x0f,0x00,0x12,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x15,0x15,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00, + 0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00, + 0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00, + 0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00, + 0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7c,0x00, + 0x7e,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x89,0x00,0x8a,0x8a,0x8a,0x00,0x8b,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00, + 0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa9,0xa8,0x00,0xa9,0xaa,0xa9,0x00,0xaa,0xab,0xab,0x00,0xab,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb6,0x00,0xb8,0xb8,0xb7,0x00,0xb9,0xb9,0xb8,0x00, + 0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00,0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00, + 0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd9,0xd7,0x00,0xd9,0xda,0xd8,0x00,0xda,0xdb,0xd9,0x00,0xdb,0xdc,0xda,0x00, + 0xdc,0xdd,0xdc,0x00,0xdd,0xde,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xdf,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xee,0xee,0xec,0x00,0xef,0xef,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00, + 0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x0f,0x00,0x12,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x20,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x36,0x37,0x38,0x00, + 0x37,0x38,0x39,0x00,0x38,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00, + 0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00,0x7c,0x7b,0x7d,0x00, + 0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x82,0x82,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x88,0x88,0x00,0x88,0x89,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8a,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbe,0xbe,0x00,0xc0,0xbf,0xbf,0x00,0xc1,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00, + 0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x0f,0x00,0x12,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x20,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x36,0x37,0x38,0x00, + 0x37,0x38,0x39,0x00,0x38,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x48,0x48,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00, + 0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00, + 0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x88,0x88,0x00,0x88,0x89,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8a,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x95,0x95,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xbb,0xba,0xba,0x00,0xbc,0xbc,0xbc,0x00,0xbe,0xbd,0xbd,0x00,0xbf,0xbe,0xbe,0x00,0xc0,0xbf,0xbf,0x00,0xc1,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xdf,0xdf,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xf0,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf5,0xf2,0x00,0xf5,0xf6,0xf3,0x00, + 0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0c,0x0c,0x0c,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x35,0x36,0x37,0x00,0x36,0x37,0x38,0x00, + 0x37,0x38,0x39,0x00,0x38,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3e,0x40,0x00,0x40,0x40,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x49,0x49,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x5a,0x00, + 0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x61,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x73,0x73,0x74,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00, + 0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x89,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8a,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x96,0x96,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa2,0xa1,0xa1,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xb0,0xb0,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbe,0xbe,0x00,0xc0,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xca,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xe0,0xe0,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xf0,0xee,0x00,0xf1,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf6,0xf3,0x00, + 0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x10,0x0d,0x0e,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00, + 0x20,0x20,0x21,0x00,0x21,0x21,0x21,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00, + 0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x34,0x35,0x36,0x00,0x35,0x36,0x37,0x00,0x36,0x37,0x38,0x00, + 0x37,0x38,0x39,0x00,0x38,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00, + 0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x4a,0x4a,0x4a,0x00,0x4b,0x4b,0x4b,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00, + 0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x81,0x00,0x82,0x81,0x82,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x8a,0x8a,0x00,0x8a,0x8b,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00, + 0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa2,0xa1,0xa1,0x00,0xa3,0xa2,0xa2,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00, + 0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbf,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00,0xca,0xca,0xc9,0x00, + 0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00, + 0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe1,0xe1,0xdf,0x00,0xe2,0xe2,0xe0,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00, + 0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf2,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf7,0xf4,0x00,0xf7,0xf8,0xf5,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0d,0x0e,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00, + 0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00, + 0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00, + 0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa2,0xa1,0xa1,0x00,0xa3,0xa2,0xa2,0x00,0xa4,0xa3,0xa3,0x00,0xa5,0xa4,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc9,0xc8,0xc8,0x00,0xca,0xc9,0xc9,0x00, + 0xcb,0xca,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd6,0xd5,0xd5,0x00,0xd7,0xd6,0xd6,0x00,0xd8,0xd7,0xd7,0x00,0xd9,0xd8,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xd9,0x00, + 0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00, + 0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0d,0x0e,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x20,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00, + 0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00, + 0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x54,0x54,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00, + 0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8c,0x8c,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa2,0xa1,0xa1,0x00,0xa3,0xa2,0xa2,0x00,0xa4,0xa3,0xa3,0x00,0xa5,0xa4,0xa4,0x00,0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc9,0xc8,0xc8,0x00,0xca,0xc9,0xc9,0x00, + 0xcb,0xca,0xca,0x00,0xcc,0xcb,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd6,0xd5,0xd5,0x00,0xd7,0xd6,0xd6,0x00,0xd8,0xd7,0xd7,0x00,0xd9,0xd8,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xd9,0x00, + 0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00, + 0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0d,0x0e,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x25,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x38,0x00, + 0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x40,0x3f,0x41,0x00, + 0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x51,0x00, + 0x52,0x52,0x52,0x00,0x53,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x61,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x6a,0x6a,0x6b,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x76,0x76,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7b,0x7d,0x00, + 0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x83,0x83,0x00,0x84,0x84,0x85,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8d,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa3,0xa2,0xa2,0x00,0xa4,0xa3,0xa3,0x00,0xa5,0xa4,0xa4,0x00,0xa6,0xa5,0xa6,0x00,0xa7,0xa7,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xca,0xc9,0xc9,0x00, + 0xcb,0xca,0xca,0x00,0xcc,0xcb,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd7,0xd6,0xd6,0x00,0xd8,0xd7,0xd7,0x00,0xd9,0xd8,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xd9,0x00, + 0xdc,0xdc,0xda,0x00,0xdd,0xdd,0xdb,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe3,0x00, + 0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xeb,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf1,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf5,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0d,0x0e,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x10,0x11,0x00, + 0x13,0x11,0x12,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00, + 0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00, + 0x52,0x52,0x53,0x00,0x52,0x53,0x53,0x00,0x53,0x54,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00, + 0x59,0x59,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00, + 0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x76,0x76,0x00,0x76,0x77,0x77,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7d,0x7c,0x7e,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x83,0x83,0x00,0x83,0x84,0x84,0x00, + 0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa4,0xa3,0xa3,0x00,0xa5,0xa4,0xa4,0x00,0xa6,0xa5,0xa6,0x00,0xa7,0xa6,0xa7,0x00, + 0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00, + 0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd8,0xd7,0xd7,0x00,0xd9,0xd8,0xd8,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe9,0xe9,0xe7,0x00,0xea,0xea,0xe8,0x00,0xeb,0xeb,0xe9,0x00,0xec,0xec,0xea,0x00, + 0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf2,0xf3,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf4,0xf5,0xf3,0x00, + 0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf5,0x00,0xf8,0xf8,0xf6,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00,0xfd,0xfe,0xfc,0x00, + 0xff,0xff,0xfd,0x00,0xff,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0d,0x0e,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x0f,0x11,0x00, + 0x13,0x10,0x12,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x50,0x51,0x00,0x50,0x51,0x52,0x00, + 0x51,0x52,0x53,0x00,0x52,0x53,0x54,0x00,0x53,0x54,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00, + 0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x76,0x76,0x00,0x76,0x77,0x77,0x00,0x77,0x78,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x82,0x00,0x82,0x83,0x83,0x00,0x83,0x84,0x84,0x00, + 0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x96,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00, + 0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xaa,0x00,0xac,0xab,0xab,0x00,0xad,0xac,0xac,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xca,0xc9,0x00, + 0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00, + 0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf4,0xf5,0xf3,0x00, + 0xf5,0xf6,0xf4,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00, + 0xfe,0xff,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0d,0x0e,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00,0x12,0x0f,0x11,0x00, + 0x13,0x10,0x12,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x50,0x51,0x00,0x50,0x51,0x52,0x00, + 0x51,0x52,0x53,0x00,0x52,0x53,0x54,0x00,0x53,0x54,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00, + 0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x76,0x76,0x00,0x76,0x77,0x77,0x00,0x77,0x78,0x78,0x00,0x78,0x79,0x79,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x83,0x83,0x00,0x83,0x84,0x84,0x00, + 0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x90,0x90,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00, + 0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xaa,0x00,0xac,0xab,0xab,0x00,0xad,0xac,0xac,0x00,0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb3,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00, + 0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00, + 0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf4,0xf5,0xf3,0x00, + 0xf5,0xf6,0xf4,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfc,0xfd,0xfa,0x00,0xfd,0xfe,0xfb,0x00, + 0xfe,0xff,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0d,0x0e,0x00,0x10,0x0e,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00, + 0x13,0x10,0x12,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x28,0x27,0x28,0x00, + 0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00, + 0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x42,0x43,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x51,0x52,0x00, + 0x51,0x52,0x53,0x00,0x52,0x53,0x54,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x62,0x00, + 0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x77,0x77,0x00,0x77,0x78,0x78,0x00,0x78,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7c,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x7f,0x00,0x80,0x80,0x80,0x00,0x81,0x81,0x81,0x00,0x82,0x82,0x83,0x00,0x83,0x84,0x84,0x00, + 0x84,0x85,0x85,0x00,0x85,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x91,0x91,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x96,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9e,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa7,0x00, + 0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xab,0xaa,0xaa,0x00,0xac,0xab,0xab,0x00,0xad,0xac,0xac,0x00,0xae,0xad,0xae,0x00,0xaf,0xaf,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb4,0xb4,0xb3,0x00,0xb5,0xb5,0xb4,0x00,0xb6,0xb6,0xb5,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc1,0xc1,0xc1,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xca,0xc9,0x00, + 0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xdb,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00, + 0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf4,0xf5,0xf3,0x00, + 0xf5,0xf6,0xf4,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfd,0xfe,0xfb,0x00, + 0xfe,0xff,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0d,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00, + 0x13,0x10,0x12,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x17,0x18,0x00, + 0x18,0x18,0x19,0x00,0x19,0x19,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x27,0x26,0x28,0x00, + 0x29,0x28,0x29,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x42,0x43,0x00,0x44,0x43,0x44,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x52,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x57,0x59,0x00, + 0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x78,0x78,0x00,0x78,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00, + 0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x85,0x85,0x85,0x00,0x86,0x86,0x86,0x00,0x87,0x87,0x87,0x00,0x88,0x88,0x88,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00, + 0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x92,0x92,0x92,0x00,0x93,0x93,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00, + 0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00, + 0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00, + 0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00, + 0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xcb,0xca,0x00,0xcb,0xcc,0xcb,0x00,0xcc,0xcd,0xcc,0x00,0xcd,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00, + 0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00, + 0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00, + 0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xee,0x00,0xef,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf4,0xf5,0xf3,0x00, + 0xf5,0xf6,0xf4,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf9,0xf7,0x00,0xf9,0xfa,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00, + 0xfe,0xff,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00, + 0x13,0x10,0x12,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x42,0x43,0x00,0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x45,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00,0x84,0x83,0x84,0x00, + 0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00, + 0x8d,0x8c,0x8d,0x00,0x8e,0x8e,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00, + 0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00, + 0xaf,0xaf,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00, + 0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00, + 0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00, + 0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xde,0xdf,0xde,0x00,0xdf,0xe0,0xdf,0x00,0xe0,0xe1,0xe0,0x00,0xe1,0xe2,0xe1,0x00,0xe2,0xe3,0xe2,0x00, + 0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00, + 0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xee,0x00,0xef,0xf0,0xef,0x00,0xf0,0xf1,0xf0,0x00,0xf1,0xf2,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf4,0xf5,0xf3,0x00, + 0xf5,0xf6,0xf4,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00, + 0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00, + 0x13,0x10,0x12,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x1a,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x43,0x42,0x43,0x00,0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x45,0x46,0x00,0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x68,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00,0x7b,0x7b,0x7b,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x83,0x82,0x83,0x00,0x84,0x83,0x84,0x00, + 0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00, + 0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x94,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00, + 0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00, + 0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00, + 0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00, + 0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd1,0xd1,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00, + 0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xde,0xdd,0x00,0xde,0xdf,0xde,0x00,0xdf,0xe0,0xdf,0x00,0xe0,0xe1,0xe0,0x00,0xe1,0xe2,0xe1,0x00,0xe2,0xe3,0xe2,0x00, + 0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xea,0xeb,0xe9,0x00,0xeb,0xec,0xea,0x00, + 0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xee,0x00,0xef,0xf0,0xef,0x00,0xf0,0xf1,0xf0,0x00,0xf1,0xf2,0xf1,0x00,0xf3,0xf4,0xf2,0x00,0xf4,0xf5,0xf3,0x00, + 0xf5,0xf6,0xf4,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf8,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00, + 0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00, + 0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1b,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1d,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x44,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x45,0x46,0x00,0x47,0x46,0x48,0x00,0x48,0x48,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x72,0x72,0x73,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7b,0x7b,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x82,0x83,0x00,0x84,0x83,0x84,0x00, + 0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00, + 0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x93,0x94,0x00,0x95,0x95,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00, + 0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00, + 0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00, + 0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00, + 0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xd0,0x00,0xd2,0xd2,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xda,0x00, + 0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xdf,0xde,0x00,0xdf,0xe0,0xdf,0x00,0xe0,0xe1,0xe0,0x00,0xe1,0xe2,0xe1,0x00,0xe2,0xe3,0xe2,0x00, + 0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xec,0xea,0x00, + 0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xed,0x00,0xef,0xf0,0xef,0x00,0xf0,0xf1,0xf0,0x00,0xf1,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf5,0xf3,0x00, + 0xf5,0xf6,0xf4,0x00,0xf6,0xf7,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00, + 0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00, + 0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1c,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x45,0x44,0x45,0x00,0x46,0x45,0x46,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00, + 0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00,0x60,0x60,0x61,0x00, + 0x61,0x61,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00, + 0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00, + 0x7c,0x7c,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x85,0x84,0x85,0x00,0x86,0x85,0x86,0x00,0x87,0x86,0x87,0x00,0x88,0x87,0x88,0x00,0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00, + 0x8d,0x8c,0x8d,0x00,0x8e,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x93,0x94,0x00,0x95,0x94,0x95,0x00, + 0x96,0x96,0x96,0x00,0x97,0x97,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00, + 0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00,0xa6,0xa6,0xa6,0x00, + 0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00, + 0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00, + 0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00, + 0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00, + 0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd3,0x00,0xd5,0xd5,0xd4,0x00,0xd6,0xd6,0xd5,0x00,0xd7,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xe0,0xdf,0x00,0xe0,0xe1,0xe0,0x00,0xe1,0xe2,0xe1,0x00,0xe2,0xe3,0xe2,0x00, + 0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xed,0xeb,0x00,0xed,0xee,0xec,0x00,0xee,0xef,0xed,0x00,0xef,0xf0,0xee,0x00,0xf0,0xf1,0xf0,0x00,0xf1,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00, + 0xf5,0xf6,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfb,0x00, + 0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00, + 0x30,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00, + 0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x52,0x00, + 0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00, + 0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00, + 0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00, + 0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x93,0x94,0x00,0x95,0x94,0x95,0x00, + 0x96,0x95,0x96,0x00,0x97,0x96,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9d,0x00, + 0x9f,0x9e,0x9e,0x00,0xa0,0x9f,0x9f,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa2,0xa3,0x00,0xa4,0xa3,0xa4,0x00,0xa5,0xa4,0xa5,0x00,0xa6,0xa5,0xa6,0x00, + 0xa7,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xaf,0xae,0xae,0x00, + 0xb0,0xaf,0xaf,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00, + 0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00, + 0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf2,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00, + 0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfa,0x00, + 0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00, + 0x30,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x32,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00, + 0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00, + 0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00, + 0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00, + 0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6c,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00, + 0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x93,0x94,0x00,0x95,0x94,0x95,0x00, + 0x96,0x95,0x96,0x00,0x97,0x96,0x97,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9d,0x00, + 0x9f,0x9e,0x9e,0x00,0xa0,0x9f,0x9f,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa2,0xa3,0x00,0xa4,0xa3,0xa4,0x00,0xa5,0xa4,0xa5,0x00,0xa6,0xa5,0xa6,0x00, + 0xa7,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xae,0xad,0xad,0x00,0xaf,0xae,0xae,0x00, + 0xb0,0xaf,0xaf,0x00,0xb1,0xb0,0xb0,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xbb,0xbb,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc8,0xc8,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00, + 0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe2,0xe0,0x00,0xe2,0xe3,0xe1,0x00, + 0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf3,0xf3,0xf1,0x00,0xf4,0xf4,0xf2,0x00, + 0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfc,0xfa,0x00,0xfc,0xfd,0xfa,0x00, + 0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xff,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2a,0x00,0x2c,0x2b,0x2b,0x00,0x2d,0x2c,0x2c,0x00,0x2e,0x2d,0x2d,0x00,0x2f,0x2e,0x2e,0x00, + 0x30,0x2f,0x2f,0x00,0x31,0x30,0x30,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3f,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x48,0x00,0x48,0x47,0x49,0x00, + 0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x52,0x00, + 0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00, + 0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x69,0x00,0x69,0x68,0x6a,0x00, + 0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6d,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7b,0x00, + 0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x83,0x83,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x95,0x94,0x95,0x00, + 0x96,0x95,0x96,0x00,0x97,0x96,0x97,0x00,0x98,0x97,0x98,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9d,0x9d,0x00, + 0x9f,0x9e,0x9e,0x00,0xa0,0x9f,0x9f,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa2,0xa3,0x00,0xa4,0xa3,0xa4,0x00,0xa5,0xa4,0xa5,0x00,0xa6,0xa5,0xa6,0x00, + 0xa7,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xaf,0xae,0xae,0x00, + 0xb0,0xaf,0xaf,0x00,0xb1,0xb0,0xb0,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbc,0xbc,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc9,0xc9,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00, + 0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe3,0xe1,0x00, + 0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf4,0xf4,0xf2,0x00, + 0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfd,0xfa,0x00, + 0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x1f,0x00, + 0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00, + 0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00, + 0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00, + 0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00, + 0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00, + 0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00, + 0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00, + 0x7c,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00, + 0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00, + 0x96,0x95,0x96,0x00,0x97,0x96,0x97,0x00,0x98,0x97,0x98,0x00,0x99,0x98,0x99,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00, + 0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa2,0xa3,0x00,0xa4,0xa3,0xa4,0x00,0xa5,0xa4,0xa5,0x00,0xa6,0xa5,0xa6,0x00, + 0xa7,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xb0,0xaf,0xaf,0x00,0xb1,0xb0,0xb0,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbd,0xbd,0xbc,0x00,0xbe,0xbe,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xca,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00, + 0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe4,0xe2,0x00,0xe4,0xe5,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf5,0xf5,0xf3,0x00,0xf6,0xf6,0xf4,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00, + 0xfd,0xfe,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2d,0x2f,0x00, + 0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00, + 0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00, + 0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00, + 0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00, + 0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00, + 0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00, + 0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x98,0x97,0x98,0x00,0x99,0x98,0x99,0x00,0x9a,0x99,0x9a,0x00,0x9b,0x9a,0x9b,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00, + 0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcc,0xcb,0xcb,0x00,0xcd,0xcc,0xcc,0x00,0xce,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00, + 0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf7,0xf6,0x00,0xf7,0xf8,0xf7,0x00,0xf8,0xf9,0xf8,0x00,0xf9,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00, + 0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x17,0x16,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2d,0x2e,0x00,0x2e,0x2d,0x2f,0x00, + 0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00, + 0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00, + 0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00, + 0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x75,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x79,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7c,0x00, + 0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00, + 0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00, + 0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x98,0x97,0x98,0x00,0x99,0x98,0x99,0x00,0x9a,0x99,0x9a,0x00,0x9b,0x9a,0x9b,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00, + 0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbf,0xbf,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcc,0xcb,0xcb,0x00,0xcd,0xcc,0xcc,0x00,0xce,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00, + 0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe6,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf7,0xf6,0x00,0xf7,0xf8,0xf7,0x00,0xf8,0xf9,0xf8,0x00,0xf9,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00, + 0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0b,0x0b,0x0b,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x23,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2a,0x2a,0x2b,0x00,0x2b,0x2b,0x2c,0x00,0x2c,0x2c,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00, + 0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x34,0x36,0x00,0x36,0x36,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00, + 0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x49,0x00, + 0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x6a,0x00, + 0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x76,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00, + 0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x84,0x00, + 0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00, + 0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x99,0x98,0x99,0x00,0x9a,0x99,0x9a,0x00,0x9b,0x9a,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9e,0x00, + 0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa6,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00,0xb7,0xb7,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xc0,0xc0,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcd,0xcc,0xcc,0x00,0xce,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00, + 0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00,0xda,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe7,0xe5,0x00,0xe7,0xe8,0xe6,0x00,0xe8,0xe9,0xe7,0x00,0xe9,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf8,0xf7,0x00,0xf8,0xf9,0xf8,0x00,0xf9,0xfa,0xf9,0x00,0xfa,0xfb,0xfa,0x00,0xfc,0xfc,0xfa,0x00, + 0xfd,0xfd,0xfb,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00, + 0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x24,0x23,0x23,0x00,0x25,0x24,0x24,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00, + 0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00, + 0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00, + 0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00, + 0x51,0x51,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x56,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00, + 0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x76,0x77,0x00,0x78,0x77,0x78,0x00,0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00, + 0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x86,0x87,0x00,0x86,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00, + 0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x9a,0x99,0x9a,0x00,0x9b,0x9a,0x9b,0x00,0x9c,0x9c,0x9c,0x00,0x9d,0x9d,0x9d,0x00, + 0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00,0xb7,0xb6,0xb7,0x00, + 0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc1,0xc1,0xc0,0x00,0xc2,0xc2,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00,0xd0,0xd0,0xcf,0x00,0xd1,0xd1,0xd0,0x00, + 0xd2,0xd2,0xd1,0x00,0xd3,0xd3,0xd2,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00,0xd9,0xda,0xd9,0x00, + 0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xe9,0xea,0xe9,0x00,0xea,0xeb,0xea,0x00, + 0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf9,0xf8,0x00,0xf9,0xfa,0xf9,0x00,0xfa,0xfb,0xfa,0x00,0xfb,0xfc,0xfb,0x00, + 0xfd,0xfd,0xfc,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00, + 0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00, + 0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x56,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x86,0x87,0x00,0x86,0x87,0x88,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x93,0x93,0x00,0x93,0x94,0x94,0x00, + 0x94,0x95,0x95,0x00,0x96,0x96,0x96,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00, + 0x9d,0x9e,0x9e,0x00,0x9e,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc7,0xc8,0x00, + 0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00, + 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe5,0xe6,0xe6,0x00,0xe6,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xea,0xe9,0x00,0xea,0xeb,0xe9,0x00, + 0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfb,0xfa,0x00,0xfb,0xfc,0xfb,0x00, + 0xfc,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00, + 0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00, + 0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00,0x57,0x56,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x5a,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x67,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x79,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x86,0x87,0x00,0x86,0x87,0x88,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x93,0x93,0x00,0x93,0x94,0x94,0x00, + 0x94,0x95,0x95,0x00,0x95,0x96,0x96,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9c,0x9c,0x00,0x9c,0x9d,0x9d,0x00, + 0x9d,0x9e,0x9e,0x00,0x9e,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xad,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc3,0xc3,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc7,0xc8,0x00, + 0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xd0,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00, + 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe5,0x00,0xe5,0xe6,0xe6,0x00,0xe6,0xe7,0xe7,0x00,0xe7,0xe8,0xe8,0x00,0xe9,0xea,0xe9,0x00,0xea,0xeb,0xe9,0x00, + 0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfb,0xfa,0x00,0xfb,0xfc,0xfb,0x00, + 0xfc,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x13,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x22,0x00,0x23,0x23,0x23,0x00,0x24,0x24,0x24,0x00,0x25,0x25,0x26,0x00,0x27,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00, + 0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00, + 0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5b,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x68,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x71,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x7a,0x7a,0x00, + 0x7b,0x7b,0x7b,0x00,0x7c,0x7c,0x7c,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x87,0x88,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x94,0x94,0x00, + 0x94,0x95,0x95,0x00,0x95,0x96,0x96,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9d,0x9d,0x00, + 0x9d,0x9e,0x9e,0x00,0x9e,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xae,0xae,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc4,0xc4,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc7,0xc8,0x00, + 0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd1,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00, + 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe7,0x00,0xe7,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xeb,0xe9,0x00, + 0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfb,0x00, + 0xfc,0xfd,0xfc,0x00,0xfd,0xfe,0xfd,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x11,0x00, + 0x12,0x10,0x12,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1e,0x1f,0x00, + 0x1f,0x1f,0x20,0x00,0x20,0x20,0x21,0x00,0x21,0x21,0x22,0x00,0x22,0x22,0x23,0x00,0x23,0x23,0x24,0x00,0x24,0x24,0x25,0x00,0x25,0x25,0x26,0x00,0x26,0x26,0x27,0x00, + 0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00, + 0x2f,0x2e,0x30,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00, + 0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00, + 0x51,0x50,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00, + 0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5c,0x5d,0x00,0x5d,0x5d,0x5e,0x00,0x5e,0x5e,0x5f,0x00,0x5f,0x5f,0x60,0x00, + 0x60,0x60,0x61,0x00,0x61,0x61,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00, + 0x69,0x69,0x6a,0x00,0x6a,0x6a,0x6b,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00, + 0x72,0x72,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7a,0x00, + 0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x88,0x89,0x00,0x88,0x89,0x8a,0x00,0x89,0x8a,0x8b,0x00,0x8a,0x8b,0x8c,0x00, + 0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00, + 0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa1,0xa1,0xa1,0x00,0xa2,0xa2,0xa2,0x00,0xa3,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc5,0xc5,0xc4,0x00,0xc6,0xc6,0xc5,0x00,0xc7,0xc7,0xc6,0x00,0xc8,0xc8,0xc7,0x00, + 0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00, + 0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00,0xe2,0xe2,0xe1,0x00, + 0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xec,0xea,0x00,0xec,0xed,0xeb,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfd,0xfc,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x10,0x00, + 0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00, + 0x27,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00, + 0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00, + 0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x56,0x56,0x57,0x00, + 0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00, + 0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00, + 0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00, + 0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x79,0x00,0x7a,0x79,0x7b,0x00, + 0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x93,0x95,0x00, + 0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9c,0x00,0x9d,0x9c,0x9d,0x00, + 0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfd,0xfb,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x10,0x00, + 0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00, + 0x27,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00, + 0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00,0x46,0x46,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00, + 0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x56,0x56,0x57,0x00, + 0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00, + 0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00, + 0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00, + 0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00, + 0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00, + 0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9c,0x9b,0x9c,0x00,0x9d,0x9c,0x9d,0x00, + 0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0xa0,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa4,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc7,0xc6,0x00,0xc7,0xc8,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd8,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xee,0xed,0xed,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfb,0xf9,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfd,0xfb,0x00,0xfd,0xfe,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x10,0x00, + 0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00, + 0x27,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x40,0x00, + 0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x47,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x50,0x4f,0x51,0x00, + 0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x57,0x00, + 0x57,0x57,0x58,0x00,0x58,0x58,0x59,0x00,0x59,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00, + 0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x68,0x67,0x69,0x00, + 0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x71,0x70,0x72,0x00, + 0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00, + 0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x94,0x93,0x95,0x00, + 0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x97,0x00,0x98,0x98,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9d,0x9c,0x9d,0x00, + 0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa1,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa5,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbf,0xbf,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc8,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd9,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe6,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xef,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfc,0xfa,0x00, + 0xfc,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x10,0x00, + 0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00, + 0x28,0x26,0x28,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00, + 0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x51,0x50,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5c,0x5e,0x00,0x5e,0x5d,0x5f,0x00,0x5f,0x5e,0x60,0x00, + 0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00, + 0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00, + 0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x95,0x94,0x96,0x00,0x96,0x95,0x96,0x00,0x97,0x96,0x97,0x00,0x98,0x97,0x98,0x00,0x99,0x99,0x99,0x00,0x9a,0x9a,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00, + 0x9e,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa2,0xa2,0x00,0xa2,0xa3,0xa3,0x00,0xa3,0xa4,0xa4,0x00,0xa4,0xa5,0xa5,0x00, + 0xa6,0xa6,0xa6,0x00,0xa7,0xa7,0xa7,0x00,0xa8,0xa8,0xa8,0x00,0xa9,0xa9,0xa9,0x00,0xaa,0xaa,0xaa,0x00,0xab,0xab,0xab,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00, + 0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00, + 0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc9,0xc8,0x00,0xc9,0xca,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00, + 0xda,0xda,0xd9,0x00,0xdb,0xdb,0xda,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe4,0x00,0xe7,0xe7,0xe5,0x00,0xe8,0xe8,0xe6,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00, + 0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00, + 0xfc,0xfd,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x10,0x00, + 0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x23,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00, + 0x28,0x26,0x27,0x00,0x29,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x76,0x78,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00, + 0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x9a,0x99,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00, + 0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00, + 0xb7,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00, + 0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00, + 0xd9,0xda,0xd9,0x00,0xda,0xdb,0xda,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe4,0x00,0xe7,0xe6,0xe5,0x00,0xe8,0xe7,0xe6,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf2,0xf1,0x00,0xf2,0xf3,0xf2,0x00, + 0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00, + 0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00,0x11,0x0f,0x10,0x00, + 0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x12,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1d,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00, + 0x28,0x26,0x27,0x00,0x29,0x27,0x28,0x00,0x2a,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x62,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x76,0x78,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00, + 0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x81,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9b,0x9b,0x9b,0x00,0x9c,0x9c,0x9c,0x00, + 0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00, + 0xb7,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00, + 0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xcb,0xcb,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd8,0xd7,0x00,0xd8,0xd9,0xd8,0x00, + 0xd9,0xda,0xd9,0x00,0xda,0xdb,0xda,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe5,0xe4,0xe4,0x00,0xe6,0xe5,0xe4,0x00,0xe7,0xe6,0xe5,0x00,0xe8,0xe7,0xe6,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf2,0xf1,0x00,0xf2,0xf3,0xf2,0x00, + 0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xf9,0x00, + 0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00, + 0x12,0x10,0x11,0x00,0x13,0x11,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1c,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00, + 0x28,0x26,0x27,0x00,0x29,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x51,0x52,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x58,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x63,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x70,0x72,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x76,0x78,0x00,0x78,0x78,0x79,0x00,0x7a,0x79,0x7b,0x00, + 0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x82,0x00,0x82,0x82,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9c,0x9c,0x9c,0x00, + 0x9d,0x9d,0x9d,0x00,0x9e,0x9e,0x9e,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xae,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00, + 0xb7,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbf,0x00, + 0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcc,0xcc,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xd0,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd9,0xd8,0x00, + 0xd9,0xda,0xd9,0x00,0xda,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe4,0x00,0xe7,0xe6,0xe5,0x00,0xe8,0xe7,0xe6,0x00,0xe9,0xe8,0xe8,0x00,0xea,0xea,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf3,0xf2,0x00, + 0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00, + 0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x0f,0x00,0x11,0x0f,0x10,0x00, + 0x12,0x10,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00, + 0x28,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00, + 0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00, + 0x50,0x50,0x51,0x00,0x50,0x51,0x52,0x00,0x51,0x52,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x56,0x57,0x00, + 0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x64,0x65,0x00,0x65,0x65,0x66,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x76,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7c,0x00,0x7d,0x7c,0x7d,0x00,0x7e,0x7d,0x7e,0x00,0x7f,0x7e,0x7f,0x00,0x80,0x7f,0x80,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00, + 0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00, + 0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00, + 0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00, + 0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00,0xb5,0xb4,0xb5,0x00,0xb6,0xb5,0xb6,0x00, + 0xb7,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcd,0xcd,0xcc,0x00,0xce,0xce,0xcd,0x00,0xcf,0xcf,0xce,0x00,0xd0,0xd0,0xcf,0x00, + 0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xda,0xd9,0x00,0xda,0xdb,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00, + 0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xeb,0xeb,0xea,0x00,0xec,0xec,0xeb,0x00,0xed,0xed,0xec,0x00,0xee,0xee,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00, + 0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4e,0x4f,0x50,0x00, + 0x4f,0x50,0x51,0x00,0x50,0x51,0x52,0x00,0x51,0x52,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x55,0x57,0x00, + 0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x77,0x76,0x78,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00, + 0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00, + 0x93,0x94,0x95,0x00,0x94,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00, + 0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00, + 0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00, + 0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xed,0xec,0x00,0xed,0xee,0xed,0x00,0xee,0xef,0xee,0x00,0xef,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00, + 0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1f,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x26,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x34,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4e,0x4f,0x50,0x00, + 0x4f,0x50,0x51,0x00,0x50,0x51,0x52,0x00,0x51,0x52,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x55,0x57,0x00, + 0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00, + 0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x92,0x93,0x00,0x92,0x93,0x94,0x00, + 0x93,0x94,0x95,0x00,0x94,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xac,0xac,0x00,0xad,0xad,0xad,0x00, + 0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb9,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00,0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xcf,0xce,0x00,0xcf,0xd0,0xcf,0x00, + 0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdc,0xdc,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00, + 0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe4,0xe5,0xe5,0x00,0xe5,0xe6,0xe6,0x00,0xe6,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xed,0xec,0x00,0xed,0xee,0xed,0x00,0xee,0xef,0xee,0x00,0xef,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xfa,0xfa,0xf8,0x00,0xfb,0xfb,0xf9,0x00, + 0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x23,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x25,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x35,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3e,0x3e,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4e,0x4f,0x50,0x00, + 0x4f,0x50,0x51,0x00,0x50,0x51,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x55,0x57,0x00, + 0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x68,0x00,0x67,0x67,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x79,0x00,0x79,0x79,0x7a,0x00, + 0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x83,0x00, + 0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x93,0x00,0x92,0x93,0x94,0x00, + 0x93,0x94,0x95,0x00,0x94,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa2,0xa3,0x00,0xa4,0xa4,0xa5,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xad,0xad,0x00, + 0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc7,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xd0,0xcf,0x00, + 0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdd,0xdd,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00, + 0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe4,0xe5,0xe5,0x00,0xe5,0xe6,0xe6,0x00,0xe6,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xee,0xed,0x00,0xee,0xef,0xee,0x00,0xef,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfb,0xfb,0xf9,0x00, + 0xfc,0xfc,0xfa,0x00,0xfd,0xfd,0xfb,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x11,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x16,0x18,0x00, + 0x17,0x17,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x24,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x34,0x36,0x00, + 0x36,0x36,0x37,0x00,0x37,0x37,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3f,0x3f,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x56,0x55,0x57,0x00, + 0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5a,0x00,0x5a,0x59,0x5b,0x00,0x5b,0x5a,0x5c,0x00,0x5c,0x5b,0x5d,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00, + 0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8a,0x00, + 0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8c,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x93,0x00,0x92,0x92,0x94,0x00, + 0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa2,0xa3,0x00,0xa4,0xa3,0xa4,0x00, + 0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00, + 0xae,0xae,0xae,0x00,0xaf,0xaf,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00, + 0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd1,0xd0,0x00,0xd1,0xd2,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd5,0x00,0xd5,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xde,0xde,0xdd,0x00,0xdf,0xdf,0xde,0x00,0xe0,0xe0,0xdf,0x00,0xe1,0xe1,0xe0,0x00, + 0xe2,0xe2,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xef,0xee,0x00,0xef,0xf0,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfc,0xfc,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x11,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00, + 0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x34,0x36,0x00, + 0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00, + 0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x93,0x00,0x93,0x92,0x94,0x00, + 0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa6,0xa5,0xa6,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xfa,0x00, + 0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x11,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1e,0x00, + 0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x34,0x36,0x00, + 0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x38,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x55,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00, + 0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00, + 0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa3,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xb0,0xb0,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd3,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00, + 0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0a,0x0a,0x0a,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1e,0x00, + 0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x34,0x36,0x00, + 0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x39,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x48,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5e,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x69,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00, + 0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x74,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x79,0x78,0x7a,0x00, + 0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8e,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x93,0x92,0x94,0x00, + 0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9b,0x9d,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9f,0x00,0x9e,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb1,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb6,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbe,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd4,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd8,0xd8,0xd8,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe4,0xe3,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf2,0xf2,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xfa,0x00, + 0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0f,0x0b,0x0d,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x14,0x13,0x15,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1e,0x00, + 0x1f,0x1e,0x1f,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00,0x26,0x25,0x26,0x00, + 0x27,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x34,0x36,0x00, + 0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x3a,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00, + 0x50,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x55,0x55,0x57,0x00, + 0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00, + 0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x75,0x76,0x00,0x76,0x76,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00, + 0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8f,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x94,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00, + 0x9c,0x9c,0x9e,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00, + 0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd5,0xd4,0x00,0xd5,0xd6,0xd5,0x00,0xd6,0xd7,0xd6,0x00,0xd7,0xd8,0xd7,0x00, + 0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00, + 0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00, + 0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00, + 0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x55,0x55,0x56,0x00, + 0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00, + 0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00, + 0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00, + 0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00, + 0xbf,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x15,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00, + 0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x55,0x55,0x56,0x00, + 0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x67,0x00,0x67,0x66,0x68,0x00, + 0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x80,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00, + 0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00, + 0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb4,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00, + 0xbf,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x14,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1f,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x36,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00, + 0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x56,0x00, + 0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5e,0x5d,0x60,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x67,0x66,0x68,0x00, + 0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x81,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x8a,0x89,0x8b,0x00, + 0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00, + 0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa7,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00,0xac,0xac,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb4,0xb4,0x00,0xb5,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00, + 0xbf,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00,0xcf,0xcf,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe7,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x13,0x00,0x14,0x13,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1d,0x1d,0x1e,0x00, + 0x1e,0x1e,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00, + 0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00, + 0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x50,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x55,0x56,0x00, + 0x56,0x56,0x57,0x00,0x57,0x57,0x58,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00, + 0x68,0x67,0x69,0x00,0x69,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00, + 0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x79,0x00, + 0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00, + 0x82,0x82,0x83,0x00,0x83,0x83,0x84,0x00,0x84,0x84,0x85,0x00,0x85,0x85,0x86,0x00,0x86,0x86,0x87,0x00,0x87,0x87,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00, + 0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00, + 0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00, + 0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb4,0xb4,0x00,0xb4,0xb5,0xb5,0x00, + 0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb7,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00, + 0xbf,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00,0xcf,0xce,0xcf,0x00, + 0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00,0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00, + 0xea,0xea,0xe9,0x00,0xeb,0xeb,0xea,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xf9,0x00, + 0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00, + 0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x54,0x56,0x00, + 0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00, + 0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00, + 0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x77,0x77,0x78,0x00,0x78,0x78,0x7a,0x00, + 0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00, + 0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00, + 0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb4,0xb4,0x00,0xb4,0xb5,0xb5,0x00, + 0xb5,0xb6,0xb6,0x00,0xb6,0xb7,0xb7,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00, + 0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00, + 0xd0,0xcf,0xcf,0x00,0xd1,0xd0,0xd0,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xec,0xec,0x00,0xec,0xed,0xed,0x00,0xed,0xee,0xee,0x00,0xee,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf0,0x00, + 0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf9,0xf8,0x00,0xf9,0xfa,0xf9,0x00, + 0xfa,0xfb,0xfa,0x00,0xfb,0xfc,0xfb,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00, + 0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x45,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00,0x55,0x54,0x56,0x00, + 0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00, + 0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x6a,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6e,0x6f,0x00,0x6f,0x6f,0x70,0x00, + 0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x76,0x75,0x77,0x00,0x77,0x77,0x79,0x00,0x79,0x78,0x7a,0x00, + 0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00, + 0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x88,0x89,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x91,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xac,0x00,0xac,0xab,0xad,0x00, + 0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb4,0xb4,0x00,0xb4,0xb5,0xb5,0x00, + 0xb5,0xb6,0xb6,0x00,0xb6,0xb7,0xb7,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00, + 0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc5,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xce,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00, + 0xd0,0xcf,0xcf,0x00,0xd1,0xd0,0xd0,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xec,0xec,0x00,0xec,0xed,0xed,0x00,0xed,0xee,0xee,0x00,0xee,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf0,0x00, + 0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf9,0xf8,0x00,0xf9,0xfa,0xf9,0x00, + 0xfa,0xfb,0xfa,0x00,0xfb,0xfc,0xfb,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x26,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00, + 0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3d,0x3d,0x3f,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00,0x46,0x46,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x50,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x55,0x00,0x55,0x54,0x56,0x00, + 0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5d,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00, + 0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6f,0x70,0x00, + 0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x77,0x76,0x78,0x00,0x78,0x78,0x79,0x00, + 0x7a,0x79,0x7b,0x00,0x7a,0x7a,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00,0x81,0x80,0x82,0x00, + 0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x89,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00,0x92,0x92,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xad,0x00, + 0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb5,0xb5,0x00, + 0xb5,0xb6,0xb6,0x00,0xb6,0xb7,0xb7,0x00,0xb7,0xb8,0xb8,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00, + 0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc5,0xc5,0x00,0xc6,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xcf,0xce,0xce,0x00, + 0xd0,0xcf,0xcf,0x00,0xd1,0xd0,0xd0,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xed,0xed,0x00,0xed,0xee,0xee,0x00,0xee,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf0,0x00, + 0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xfa,0xf9,0x00, + 0xfa,0xfb,0xfa,0x00,0xfb,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x24,0x26,0x00, + 0x27,0x25,0x27,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00, + 0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x32,0x00,0x32,0x32,0x33,0x00,0x33,0x33,0x34,0x00,0x34,0x34,0x35,0x00, + 0x35,0x35,0x36,0x00,0x36,0x36,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x47,0x47,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x51,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x55,0x54,0x56,0x00, + 0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5e,0x60,0x00,0x5f,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00, + 0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x70,0x71,0x00,0x71,0x71,0x72,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00, + 0x79,0x79,0x7a,0x00,0x7a,0x7a,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00, + 0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8c,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00, + 0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa9,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00,0xac,0xab,0xac,0x00, + 0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb6,0xb6,0x00,0xb6,0xb7,0xb7,0x00,0xb7,0xb8,0xb8,0x00,0xb8,0xb9,0xb9,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00, + 0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc5,0xc5,0x00,0xc5,0xc6,0xc6,0x00, + 0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xd0,0xcf,0xcf,0x00,0xd1,0xd0,0xd0,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00,0xd7,0xd7,0xd7,0x00, + 0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00, + 0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xee,0xee,0x00,0xee,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfb,0xfa,0x00,0xfb,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2b,0x2d,0x00, + 0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x30,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00, + 0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00, + 0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00, + 0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00, + 0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x92,0x00, + 0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb2,0xb2,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb8,0xb8,0x00,0xb8,0xb9,0xb9,0x00,0xb9,0xba,0xba,0x00,0xba,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc5,0xc5,0x00,0xc5,0xc6,0xc6,0x00, + 0xc6,0xc7,0xc7,0x00,0xc7,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00, + 0xd7,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xdf,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x16,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1c,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00,0x2d,0x2b,0x2d,0x00, + 0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x30,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00, + 0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x51,0x51,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x65,0x67,0x00,0x66,0x66,0x68,0x00, + 0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x78,0x00, + 0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7b,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00, + 0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x92,0x00, + 0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb8,0xb8,0x00,0xb8,0xb9,0xb9,0x00,0xb9,0xba,0xba,0x00,0xba,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc5,0xc5,0x00,0xc5,0xc6,0xc6,0x00, + 0xc6,0xc7,0xc7,0x00,0xc7,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00, + 0xd7,0xd7,0xd8,0x00,0xd8,0xd8,0xd9,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xdf,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00, + 0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x30,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00, + 0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x50,0x51,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x66,0x68,0x00, + 0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6f,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x78,0x00, + 0x78,0x78,0x79,0x00,0x79,0x79,0x7a,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7c,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x82,0x00, + 0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x92,0x00, + 0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa3,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xb0,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb5,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb9,0xb9,0x00,0xb9,0xba,0xba,0x00,0xba,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc6,0xc6,0x00, + 0xc6,0xc7,0xc7,0x00,0xc7,0xc8,0xc8,0x00,0xc8,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00, + 0xd7,0xd7,0xd8,0x00,0xd8,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf1,0xf1,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x17,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x28,0x29,0x00,0x2a,0x29,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00, + 0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x30,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00, + 0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00, + 0x4f,0x4f,0x50,0x00,0x4f,0x50,0x51,0x00,0x50,0x51,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00, + 0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00, + 0x78,0x78,0x7a,0x00,0x79,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7d,0x7e,0x00,0x7e,0x7e,0x7f,0x00,0x7f,0x7f,0x80,0x00,0x80,0x80,0x81,0x00, + 0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00, + 0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa1,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb1,0xb0,0xb1,0x00,0xb2,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xba,0xba,0x00,0xbb,0xbb,0xbb,0x00,0xbc,0xbc,0xbc,0x00,0xbd,0xbd,0xbd,0x00, + 0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc7,0xc7,0x00,0xc7,0xc8,0xc8,0x00,0xc8,0xc9,0xc9,0x00,0xc9,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcc,0x00,0xcd,0xcd,0xcd,0x00,0xce,0xce,0xce,0x00, + 0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00, + 0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe3,0xe2,0x00,0xe3,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00, + 0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x30,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00, + 0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4d,0x4e,0x4f,0x00, + 0x4e,0x4f,0x50,0x00,0x4f,0x50,0x51,0x00,0x50,0x51,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00, + 0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00, + 0x78,0x78,0x7a,0x00,0x79,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x89,0x00, + 0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00, + 0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbc,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd7,0xd6,0xd6,0x00, + 0xd8,0xd7,0xd7,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe3,0xe2,0x00,0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0f,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00, + 0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x30,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00, + 0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3d,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x40,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4d,0x4e,0x00,0x4d,0x4e,0x4f,0x00, + 0x4e,0x4f,0x50,0x00,0x4f,0x50,0x51,0x00,0x50,0x51,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x54,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x65,0x64,0x66,0x00,0x66,0x65,0x67,0x00, + 0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00, + 0x78,0x78,0x7a,0x00,0x79,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x88,0x87,0x89,0x00,0x89,0x88,0x89,0x00, + 0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8c,0x8d,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x99,0x99,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb3,0xb3,0x00,0xb4,0xb4,0xb4,0x00, + 0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbc,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd6,0xd5,0xd5,0x00,0xd7,0xd6,0xd6,0x00, + 0xd8,0xd7,0xd7,0x00,0xd9,0xd8,0xd8,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe3,0xe2,0x00,0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x05,0x05,0x05,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x10,0x00, + 0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00, + 0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00, + 0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3e,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x41,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4e,0x4f,0x00, + 0x4e,0x4f,0x50,0x00,0x4f,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x53,0x54,0x00,0x54,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5d,0x5c,0x5f,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x61,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x66,0x65,0x67,0x00, + 0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00, + 0x78,0x78,0x7a,0x00,0x79,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x89,0x88,0x89,0x00, + 0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8d,0x8e,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x99,0x98,0x9a,0x00,0x9a,0x9a,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa3,0xa2,0xa4,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xab,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb4,0xb4,0x00, + 0xb5,0xb5,0xb5,0x00,0xb6,0xb6,0xb6,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc6,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd7,0xd6,0xd6,0x00, + 0xd8,0xd7,0xd7,0x00,0xd9,0xd8,0xd8,0x00,0xda,0xd9,0xd9,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe4,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe8,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf1,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf3,0xf2,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xf9,0x00,0xfb,0xfb,0xfa,0x00,0xfc,0xfc,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0b,0x0c,0x00,0x0f,0x0c,0x0d,0x00,0x10,0x0d,0x0e,0x00,0x11,0x0e,0x0f,0x00, + 0x12,0x0f,0x11,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2d,0x2b,0x2d,0x00, + 0x2e,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00, + 0x35,0x34,0x36,0x00,0x36,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x42,0x42,0x43,0x00,0x43,0x43,0x44,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4f,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x52,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x58,0x5a,0x00,0x59,0x59,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x62,0x64,0x00,0x63,0x63,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00, + 0x67,0x66,0x68,0x00,0x68,0x67,0x69,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00, + 0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7d,0x00,0x7d,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x89,0x00, + 0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8b,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00,0x91,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb4,0x00, + 0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00, + 0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd8,0xd7,0xd7,0x00,0xd9,0xd8,0xd8,0x00,0xda,0xd9,0xd9,0x00,0xdb,0xda,0xda,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe5,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00, + 0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf2,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00, + 0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x76,0x78,0x00,0x78,0x77,0x79,0x00, + 0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x89,0x00, + 0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x90,0x92,0x00,0x92,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb2,0xb3,0x00,0xb4,0xb3,0xb5,0x00, + 0xb5,0xb4,0xb6,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00, + 0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00, + 0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x09,0x09,0x09,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x27,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x37,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3b,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x44,0x46,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5b,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x64,0x66,0x00,0x65,0x65,0x67,0x00, + 0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6d,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00, + 0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x89,0x00, + 0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00, + 0xb5,0xb4,0xb6,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc4,0xc4,0x00,0xc5,0xc5,0xc5,0x00, + 0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xde,0xde,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe7,0xe7,0xe6,0x00,0xe8,0xe8,0xe7,0x00, + 0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x09,0x09,0x09,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x16,0x16,0x18,0x00,0x17,0x17,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3c,0x3d,0x00, + 0x3d,0x3d,0x3e,0x00,0x3e,0x3e,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x45,0x47,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5c,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x65,0x67,0x00, + 0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00,0x6e,0x6e,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x78,0x00,0x78,0x77,0x79,0x00, + 0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7a,0x7a,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x89,0x00, + 0x89,0x89,0x8a,0x00,0x8a,0x8a,0x8b,0x00,0x8b,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x90,0x91,0x00,0x92,0x91,0x93,0x00, + 0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb4,0xb3,0xb5,0x00, + 0xb5,0xb4,0xb6,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc1,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc5,0xc5,0x00, + 0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd2,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xde,0x00,0xdf,0xdf,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe8,0xe8,0xe7,0x00, + 0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf9,0x00, + 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x15,0x17,0x00, + 0x16,0x16,0x18,0x00,0x17,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x23,0x00,0x24,0x23,0x24,0x00,0x25,0x24,0x25,0x00, + 0x26,0x25,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x33,0x35,0x00, + 0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x39,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00, + 0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00, + 0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5d,0x5f,0x00,0x5e,0x5e,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x66,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00,0x6e,0x6d,0x70,0x00, + 0x6f,0x6f,0x71,0x00,0x70,0x70,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x78,0x00,0x77,0x76,0x79,0x00, + 0x79,0x78,0x7a,0x00,0x79,0x79,0x7b,0x00,0x7a,0x7a,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00, + 0x89,0x89,0x8b,0x00,0x8a,0x8a,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00, + 0x93,0x92,0x94,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00, + 0x9b,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00,0xa2,0xa2,0xa3,0x00, + 0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa8,0xaa,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb5,0xb4,0xb6,0x00,0xb6,0xb5,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbd,0x00, + 0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc2,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc6,0xc6,0x00,0xc7,0xc7,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xcd,0xcd,0xce,0x00, + 0xcf,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd3,0xd3,0x00,0xd4,0xd4,0xd4,0x00,0xd5,0xd5,0xd5,0x00,0xd6,0xd6,0xd6,0x00, + 0xd7,0xd7,0xd7,0x00,0xd8,0xd8,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xdf,0x00, + 0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe9,0xe9,0xe8,0x00,0xea,0xea,0xe9,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00, + 0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x14,0x17,0x00, + 0x16,0x15,0x18,0x00,0x17,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x20,0x20,0x22,0x00,0x21,0x21,0x23,0x00,0x22,0x22,0x24,0x00,0x24,0x23,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x28,0x00,0x2a,0x28,0x29,0x00,0x2b,0x29,0x2a,0x00,0x2c,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x32,0x35,0x00, + 0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3e,0x00, + 0x3d,0x3c,0x3f,0x00,0x3e,0x3d,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00, + 0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6f,0x00,0x6e,0x6d,0x70,0x00, + 0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x78,0x00,0x77,0x76,0x79,0x00, + 0x78,0x77,0x7a,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x89,0x00,0x88,0x87,0x8a,0x00, + 0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00, + 0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00, + 0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb7,0xb8,0x00,0xb7,0xb8,0xb9,0x00,0xb8,0xb9,0xba,0x00,0xb9,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbb,0xbc,0x00, + 0xbd,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcd,0x00,0xcd,0xcd,0xce,0x00, + 0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe2,0xe2,0x00,0xe2,0xe3,0xe3,0x00,0xe3,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xeb,0x00,0xeb,0xeb,0xec,0x00,0xec,0xec,0xed,0x00,0xed,0xed,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00,0xf9,0xf8,0xf8,0x00, + 0xfa,0xf9,0xf9,0x00,0xfb,0xfa,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00,0x16,0x14,0x17,0x00, + 0x16,0x15,0x18,0x00,0x17,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1e,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x20,0x20,0x22,0x00,0x21,0x21,0x23,0x00,0x22,0x22,0x24,0x00,0x24,0x23,0x25,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x28,0x00,0x2a,0x28,0x29,0x00,0x2b,0x29,0x2a,0x00,0x2c,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00,0x33,0x32,0x35,0x00, + 0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3a,0x3d,0x00,0x3c,0x3b,0x3e,0x00, + 0x3d,0x3c,0x3f,0x00,0x3e,0x3d,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00, + 0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x57,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6f,0x00,0x6e,0x6d,0x70,0x00, + 0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x71,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x76,0x75,0x78,0x00,0x77,0x76,0x79,0x00, + 0x78,0x77,0x7a,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7f,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x89,0x00,0x88,0x87,0x8a,0x00, + 0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x90,0x91,0x00,0x91,0x91,0x92,0x00, + 0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x9a,0x00,0x99,0x99,0x9b,0x00, + 0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xab,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb7,0xb8,0x00,0xb7,0xb8,0xb9,0x00,0xb8,0xb9,0xba,0x00,0xb9,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbb,0xbc,0x00, + 0xbd,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc8,0xc8,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcd,0x00,0xcd,0xcd,0xce,0x00, + 0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xda,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe2,0xe2,0x00,0xe2,0xe3,0xe3,0x00,0xe3,0xe4,0xe4,0x00,0xe4,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xeb,0x00,0xeb,0xeb,0xec,0x00,0xec,0xec,0xed,0x00,0xed,0xed,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf4,0xf3,0xf3,0x00,0xf5,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00,0xf9,0xf8,0xf8,0x00, + 0xfa,0xf9,0xf9,0x00,0xfb,0xfa,0xfa,0x00,0xfc,0xfc,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x13,0x16,0x00,0x16,0x14,0x17,0x00, + 0x16,0x15,0x18,0x00,0x17,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x20,0x20,0x22,0x00,0x21,0x21,0x23,0x00,0x22,0x22,0x24,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x28,0x00,0x2a,0x28,0x29,0x00,0x2b,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00,0x2c,0x2b,0x2c,0x00, + 0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x31,0x34,0x00,0x33,0x32,0x35,0x00, + 0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3e,0x00, + 0x3d,0x3c,0x3f,0x00,0x3e,0x3d,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00, + 0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x70,0x00, + 0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x72,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x77,0x76,0x79,0x00, + 0x78,0x77,0x7a,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x80,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x89,0x00,0x88,0x87,0x8a,0x00, + 0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x91,0x91,0x92,0x00, + 0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9b,0x00, + 0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9d,0x00,0x9c,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xac,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb8,0x00,0xb7,0xb8,0xb9,0x00,0xb8,0xb9,0xba,0x00,0xb9,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbb,0xbc,0x00, + 0xbd,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc9,0xc9,0x00,0xca,0xca,0xca,0x00,0xcb,0xcb,0xcb,0x00,0xcc,0xcc,0xcd,0x00,0xcd,0xcd,0xce,0x00, + 0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe2,0xe2,0x00,0xe2,0xe3,0xe3,0x00,0xe3,0xe4,0xe4,0x00,0xe4,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xec,0x00,0xec,0xec,0xed,0x00,0xed,0xed,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf6,0xf5,0xf5,0x00,0xf7,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00,0xf9,0xf8,0xf8,0x00, + 0xfa,0xf9,0xf9,0x00,0xfb,0xfa,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfd,0xfd,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x16,0x14,0x17,0x00, + 0x16,0x15,0x18,0x00,0x17,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1c,0x1e,0x00, + 0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2d,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00,0x33,0x32,0x35,0x00, + 0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00, + 0x3d,0x3c,0x3f,0x00,0x3e,0x3d,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00, + 0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00,0x4d,0x4d,0x4f,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x54,0x56,0x00, + 0x55,0x55,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x73,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00, + 0x78,0x77,0x7a,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00, + 0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x87,0x00,0x87,0x86,0x89,0x00,0x88,0x87,0x8a,0x00, + 0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00, + 0x92,0x92,0x93,0x00,0x93,0x93,0x94,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00, + 0x9a,0x9a,0x9c,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa0,0x00,0xa1,0xa0,0xa2,0x00,0xa2,0xa1,0xa3,0x00, + 0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00, + 0xac,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb8,0x00,0xb7,0xb7,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbc,0xbc,0xbc,0x00, + 0xbd,0xbd,0xbd,0x00,0xbe,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xcd,0xcd,0xce,0x00, + 0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xdf,0x00, + 0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe2,0xe2,0x00,0xe2,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00,0xe7,0xe7,0xe7,0x00, + 0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xed,0x00,0xed,0xed,0xee,0x00,0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00, + 0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xfa,0xf9,0xf9,0x00,0xfb,0xfa,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfe,0xfe,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x14,0x11,0x14,0x00,0x15,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x16,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1b,0x1e,0x00, + 0x1e,0x1c,0x1e,0x00,0x1f,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2c,0x2c,0x2e,0x00,0x2d,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x34,0x00,0x33,0x32,0x35,0x00, + 0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00, + 0x3d,0x3c,0x3e,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00, + 0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x53,0x55,0x00, + 0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x73,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00, + 0x77,0x77,0x79,0x00,0x78,0x78,0x7a,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00, + 0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x87,0x86,0x89,0x00,0x88,0x87,0x8a,0x00, + 0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00, + 0x91,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00, + 0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00, + 0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00, + 0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb8,0x00,0xb8,0xb7,0xb9,0x00,0xb9,0xb8,0xba,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbb,0xbc,0xbc,0x00, + 0xbc,0xbd,0xbd,0x00,0xbd,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xcd,0xcd,0xcd,0x00, + 0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xdf,0x00, + 0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe2,0xe2,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00, + 0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00, + 0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf4,0xf4,0xf3,0x00,0xf5,0xf5,0xf4,0x00,0xf6,0xf6,0xf5,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x13,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x14,0x11,0x14,0x00,0x15,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x16,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1f,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x24,0x00, + 0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2b,0x2b,0x2d,0x00, + 0x2c,0x2c,0x2e,0x00,0x2d,0x2d,0x2f,0x00,0x2e,0x2e,0x30,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x34,0x00,0x33,0x32,0x35,0x00, + 0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00, + 0x3d,0x3c,0x3e,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x44,0x43,0x45,0x00,0x45,0x44,0x46,0x00, + 0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x48,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x50,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00,0x54,0x53,0x55,0x00, + 0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x60,0x5f,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6d,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x73,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00, + 0x77,0x77,0x79,0x00,0x78,0x78,0x7a,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00, + 0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x87,0x86,0x89,0x00,0x88,0x87,0x8a,0x00, + 0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8b,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00, + 0x91,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x98,0x98,0x99,0x00,0x99,0x99,0x9a,0x00, + 0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa2,0x00,0xa1,0xa1,0xa3,0x00, + 0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xaa,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00, + 0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb7,0xb6,0xb8,0x00,0xb8,0xb7,0xb9,0x00,0xb9,0xb8,0xba,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xbb,0xbc,0x00,0xbb,0xbc,0xbc,0x00, + 0xbc,0xbd,0xbd,0x00,0xbd,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc4,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc9,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcc,0xcd,0x00,0xcd,0xcd,0xcd,0x00, + 0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd9,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xde,0x00,0xde,0xde,0xdf,0x00, + 0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00, + 0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xef,0xef,0xee,0x00,0xf0,0xf0,0xef,0x00, + 0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf3,0xf3,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfc,0xfb,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0c,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x14,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1f,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x24,0x00, + 0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x27,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2b,0x2b,0x2d,0x00, + 0x2c,0x2c,0x2e,0x00,0x2d,0x2d,0x2f,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x35,0x00, + 0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x35,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3c,0x3b,0x3d,0x00, + 0x3d,0x3c,0x3e,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x45,0x44,0x46,0x00, + 0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x49,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x50,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x52,0x55,0x00,0x54,0x53,0x55,0x00, + 0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x61,0x60,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6e,0x6d,0x6f,0x00, + 0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x73,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00, + 0x77,0x77,0x79,0x00,0x78,0x78,0x7a,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00, + 0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8a,0x8d,0x00,0x8c,0x8c,0x8e,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00, + 0x91,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x99,0x9a,0x00, + 0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa3,0x00, + 0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xab,0xaa,0xab,0x00, + 0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00,0xb3,0xb3,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb8,0xb7,0xb9,0x00,0xb9,0xb8,0xba,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xba,0xbb,0x00,0xbb,0xbc,0xbc,0x00, + 0xbc,0xbd,0xbd,0x00,0xbd,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc4,0x00,0xc5,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcd,0xcd,0x00, + 0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd6,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xda,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xdf,0x00, + 0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe1,0xe1,0x00,0xe3,0xe3,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00, + 0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xf0,0xf0,0xef,0x00, + 0xf1,0xf1,0xf0,0x00,0xf2,0xf2,0xf1,0x00,0xf2,0xf3,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfd,0xfc,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0d,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x14,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x19,0x18,0x1a,0x00,0x1a,0x19,0x1b,0x00,0x1b,0x1a,0x1c,0x00,0x1c,0x1b,0x1d,0x00,0x1d,0x1b,0x1d,0x00, + 0x1e,0x1c,0x1e,0x00,0x1f,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x27,0x26,0x28,0x00,0x28,0x27,0x29,0x00,0x29,0x28,0x2a,0x00,0x2a,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00,0x2c,0x2b,0x2d,0x00, + 0x2d,0x2c,0x2e,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x33,0x32,0x34,0x00, + 0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x35,0x38,0x00,0x37,0x36,0x39,0x00,0x38,0x38,0x3a,0x00,0x39,0x39,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3d,0x3c,0x3e,0x00,0x3e,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00,0x41,0x41,0x43,0x00,0x42,0x42,0x44,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x46,0x45,0x47,0x00,0x47,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x4a,0x4b,0x00,0x4b,0x4b,0x4c,0x00,0x4c,0x4c,0x4d,0x00,0x4d,0x4d,0x4e,0x00, + 0x4e,0x4e,0x50,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x55,0x00,0x54,0x53,0x55,0x00, + 0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x58,0x57,0x59,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x62,0x61,0x63,0x00,0x63,0x62,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6b,0x6b,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00, + 0x6f,0x6e,0x70,0x00,0x70,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x75,0x00,0x74,0x73,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00, + 0x77,0x77,0x7a,0x00,0x78,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00, + 0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8d,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x8f,0x8f,0x91,0x00,0x90,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x9a,0x9b,0x00,0x9b,0x9b,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa4,0x00,0xa3,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xac,0xab,0xac,0x00,0xad,0xac,0xad,0x00,0xae,0xad,0xae,0x00,0xaf,0xae,0xaf,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00,0xb3,0xb2,0xb4,0x00, + 0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xba,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbd,0xbd,0x00,0xbd,0xbe,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc7,0x00,0xc8,0xc7,0xc8,0x00,0xc9,0xc8,0xc9,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00,0xcd,0xcc,0xcd,0x00, + 0xce,0xce,0xce,0x00,0xcf,0xcf,0xcf,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00, + 0xd7,0xd6,0xd7,0x00,0xd8,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xdb,0xdb,0x00,0xdc,0xdc,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe4,0xe4,0xe3,0x00,0xe5,0xe5,0xe4,0x00,0xe6,0xe6,0xe5,0x00,0xe7,0xe7,0xe6,0x00, + 0xe8,0xe8,0xe7,0x00,0xe9,0xe9,0xe8,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf1,0xf1,0xf0,0x00,0xf1,0xf2,0xf1,0x00,0xf2,0xf3,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf5,0x00,0xf5,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfe,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0d,0x00,0x0f,0x0b,0x0e,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x13,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00, + 0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x27,0x26,0x28,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00, + 0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x36,0x35,0x38,0x00,0x37,0x36,0x39,0x00,0x38,0x37,0x3a,0x00,0x39,0x38,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4f,0x00, + 0x4e,0x4d,0x50,0x00,0x4f,0x4e,0x51,0x00,0x50,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x50,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x55,0x00,0x54,0x53,0x55,0x00, + 0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x78,0x00, + 0x77,0x77,0x7a,0x00,0x78,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00, + 0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x89,0x00, + 0x89,0x88,0x8a,0x00,0x8a,0x89,0x8b,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb3,0x00,0xb2,0xb2,0xb4,0x00, + 0xb3,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00, + 0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00, + 0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xe9,0xea,0xea,0x00,0xea,0xeb,0xeb,0x00,0xeb,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf3,0xf2,0x00,0xf3,0xf4,0xf4,0x00,0xf4,0xf5,0xf5,0x00,0xf5,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0d,0x00,0x0f,0x0b,0x0e,0x00,0x10,0x0c,0x0f,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x13,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1b,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00, + 0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x27,0x26,0x28,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00, + 0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2f,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x32,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x36,0x35,0x38,0x00,0x37,0x36,0x39,0x00,0x38,0x37,0x3a,0x00,0x39,0x38,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4e,0x00,0x4d,0x4c,0x4f,0x00, + 0x4e,0x4d,0x50,0x00,0x4f,0x4e,0x51,0x00,0x50,0x4f,0x52,0x00,0x50,0x4f,0x52,0x00,0x51,0x50,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x55,0x00,0x54,0x53,0x55,0x00, + 0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x57,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5b,0x5a,0x5d,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x64,0x63,0x66,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6c,0x6e,0x00,0x6d,0x6d,0x6f,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x76,0x00,0x75,0x75,0x77,0x00,0x76,0x76,0x79,0x00, + 0x77,0x77,0x7a,0x00,0x78,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7e,0x80,0x00,0x7f,0x7f,0x81,0x00, + 0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x87,0x86,0x88,0x00,0x88,0x87,0x88,0x00, + 0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x90,0x8f,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x98,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb3,0x00,0xb2,0xb2,0xb4,0x00, + 0xb3,0xb3,0xb5,0x00,0xb5,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb8,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc4,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00, + 0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdd,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe6,0xe5,0x00,0xe6,0xe7,0xe6,0x00, + 0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xe9,0xea,0xea,0x00,0xea,0xeb,0xeb,0x00,0xeb,0xec,0xec,0x00,0xec,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf3,0xf3,0x00,0xf3,0xf4,0xf4,0x00,0xf4,0xf5,0xf5,0x00,0xf5,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0d,0x00,0x0f,0x0b,0x0e,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x13,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x1a,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x24,0x00,0x24,0x23,0x25,0x00, + 0x25,0x24,0x26,0x00,0x26,0x25,0x27,0x00,0x27,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00, + 0x2d,0x2b,0x2d,0x00,0x2e,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x37,0x36,0x39,0x00,0x38,0x37,0x3a,0x00,0x39,0x38,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4f,0x00, + 0x4e,0x4d,0x50,0x00,0x4f,0x4e,0x51,0x00,0x50,0x4f,0x51,0x00,0x50,0x4f,0x52,0x00,0x51,0x50,0x53,0x00,0x52,0x51,0x54,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00, + 0x55,0x54,0x56,0x00,0x56,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5c,0x5b,0x5e,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x65,0x64,0x67,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6d,0x6f,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x77,0x00,0x76,0x76,0x78,0x00, + 0x77,0x77,0x7a,0x00,0x78,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7d,0x80,0x00,0x7f,0x7f,0x81,0x00, + 0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x88,0x87,0x88,0x00, + 0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x91,0x00,0x91,0x90,0x92,0x00, + 0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x99,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb3,0x00,0xb2,0xb2,0xb4,0x00, + 0xb3,0xb3,0xb5,0x00,0xb4,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc5,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00, + 0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xde,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe7,0xe6,0x00, + 0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xe9,0xea,0xea,0x00,0xea,0xeb,0xeb,0x00,0xeb,0xec,0xec,0x00,0xec,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf4,0xf4,0x00,0xf4,0xf5,0xf5,0x00,0xf5,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x0a,0x0d,0x00,0x0f,0x0b,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x13,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x18,0x1a,0x00,0x19,0x19,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x25,0x00, + 0x26,0x24,0x26,0x00,0x26,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2c,0x2a,0x2c,0x00, + 0x2d,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x30,0x32,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x38,0x37,0x3a,0x00,0x39,0x38,0x3b,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00, + 0x4e,0x4d,0x50,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00,0x50,0x4f,0x52,0x00,0x51,0x50,0x53,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x54,0x53,0x55,0x00, + 0x55,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6e,0x70,0x00,0x6f,0x6f,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x77,0x00,0x76,0x75,0x78,0x00, + 0x78,0x77,0x79,0x00,0x79,0x78,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7b,0x7a,0x7c,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7c,0x7f,0x00,0x7e,0x7d,0x80,0x00,0x7f,0x7e,0x81,0x00, + 0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x87,0x88,0x00, + 0x89,0x88,0x89,0x00,0x8a,0x89,0x8a,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x91,0x00,0x90,0x8f,0x92,0x00, + 0x92,0x91,0x93,0x00,0x92,0x92,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa6,0x00,0xa5,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb3,0x00,0xb2,0xb2,0xb4,0x00, + 0xb3,0xb3,0xb5,0x00,0xb4,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb9,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc2,0x00,0xc3,0xc3,0xc3,0x00,0xc4,0xc4,0xc4,0x00, + 0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00,0xd5,0xd5,0xd6,0x00, + 0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xdd,0xde,0x00, + 0xdf,0xdf,0xdf,0x00,0xe0,0xe0,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe8,0xe7,0x00,0xe8,0xe9,0xe8,0x00,0xe9,0xea,0xea,0x00,0xea,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf5,0x00,0xf5,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00,0xf8,0xf8,0xf8,0x00, + 0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x09,0x0c,0x00,0x0f,0x0a,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x13,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x24,0x00, + 0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x27,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00, + 0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00,0x50,0x4f,0x52,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x77,0x75,0x77,0x00, + 0x78,0x76,0x79,0x00,0x79,0x77,0x7a,0x00,0x7a,0x79,0x7b,0x00,0x7a,0x7a,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x91,0x00,0x90,0x8f,0x92,0x00, + 0x91,0x90,0x93,0x00,0x92,0x91,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa6,0x00,0xa5,0xa5,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa7,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb3,0x00,0xb2,0xb2,0xb4,0x00, + 0xb3,0xb3,0xb5,0x00,0xb4,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xdd,0xde,0x00, + 0xdf,0xde,0xdf,0x00,0xe0,0xdf,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xea,0x00,0xeb,0xea,0xeb,0x00,0xec,0xeb,0xec,0x00,0xed,0xec,0xed,0x00,0xee,0xed,0xee,0x00,0xef,0xee,0xef,0x00, + 0xf0,0xef,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x03,0x03,0x03,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x09,0x0c,0x00,0x0f,0x0a,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x13,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x16,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x24,0x00, + 0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x28,0x26,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x3a,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3f,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x43,0x45,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x48,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00, + 0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00,0x50,0x4f,0x51,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x5a,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x71,0x70,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x76,0x74,0x76,0x00,0x77,0x75,0x77,0x00, + 0x78,0x76,0x78,0x00,0x79,0x77,0x79,0x00,0x7a,0x79,0x7b,0x00,0x7a,0x7a,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7e,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8b,0x8a,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x91,0x00,0x90,0x8f,0x92,0x00, + 0x91,0x90,0x93,0x00,0x92,0x91,0x94,0x00,0x93,0x93,0x95,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9c,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa6,0x00,0xa5,0xa5,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa7,0xa7,0xa9,0x00,0xa9,0xa9,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb3,0x00,0xb2,0xb2,0xb4,0x00, + 0xb3,0xb3,0xb5,0x00,0xb4,0xb4,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc3,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xd0,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xdd,0xde,0x00, + 0xdf,0xde,0xdf,0x00,0xe0,0xdf,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xea,0xe9,0xea,0x00,0xeb,0xea,0xeb,0x00,0xec,0xeb,0xec,0x00,0xed,0xec,0xed,0x00,0xee,0xed,0xee,0x00,0xef,0xee,0xef,0x00, + 0xf0,0xef,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf4,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf7,0xf7,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xff,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x04,0x04,0x04,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x09,0x0c,0x00,0x0f,0x0a,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x13,0x11,0x14,0x00,0x14,0x12,0x15,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x24,0x00, + 0x26,0x24,0x25,0x00,0x27,0x25,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3b,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x40,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x44,0x46,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x49,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00, + 0x4e,0x4d,0x4f,0x00,0x4f,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5b,0x5d,0x00, + 0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x67,0x69,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x72,0x71,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x77,0x75,0x77,0x00, + 0x78,0x76,0x78,0x00,0x79,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x7a,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7f,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x85,0x88,0x00,0x87,0x86,0x88,0x00, + 0x88,0x87,0x89,0x00,0x89,0x88,0x8a,0x00,0x8a,0x89,0x8c,0x00,0x8c,0x8b,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x92,0x00, + 0x91,0x90,0x93,0x00,0x92,0x91,0x94,0x00,0x93,0x92,0x95,0x00,0x94,0x94,0x95,0x00,0x95,0x95,0x96,0x00,0x96,0x96,0x97,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9d,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa7,0x00,0xa6,0xa6,0xa8,0x00,0xa7,0xa7,0xa9,0x00,0xa8,0xa8,0xaa,0x00,0xaa,0xaa,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb4,0x00, + 0xb3,0xb3,0xb5,0x00,0xb4,0xb4,0xb6,0x00,0xb5,0xb5,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd1,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd8,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xdd,0xde,0x00, + 0xdf,0xde,0xdf,0x00,0xe0,0xdf,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xeb,0xea,0xeb,0x00,0xec,0xeb,0xec,0x00,0xed,0xec,0xed,0x00,0xee,0xed,0xee,0x00,0xef,0xee,0xef,0x00, + 0xf0,0xef,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf6,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf8,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfb,0xfa,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfd,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x09,0x0c,0x00,0x0f,0x0a,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x13,0x00,0x13,0x11,0x14,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x25,0x23,0x24,0x00, + 0x26,0x24,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x33,0x00,0x32,0x32,0x34,0x00, + 0x33,0x33,0x35,0x00,0x34,0x34,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3c,0x3e,0x00,0x3d,0x3d,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x41,0x40,0x42,0x00,0x42,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x45,0x47,0x00,0x46,0x46,0x48,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x4a,0x49,0x4b,0x00,0x4b,0x4a,0x4c,0x00,0x4c,0x4b,0x4d,0x00,0x4d,0x4c,0x4e,0x00, + 0x4e,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5c,0x5e,0x00,0x5d,0x5d,0x5f,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x73,0x72,0x74,0x00,0x74,0x73,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x78,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7b,0x7d,0x00,0x7c,0x7c,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x80,0x7f,0x81,0x00,0x81,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x84,0x86,0x00,0x85,0x84,0x87,0x00,0x86,0x85,0x88,0x00,0x87,0x86,0x89,0x00, + 0x88,0x87,0x8a,0x00,0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8a,0x8d,0x00,0x8d,0x8c,0x8e,0x00,0x8e,0x8d,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x93,0x00,0x92,0x91,0x94,0x00,0x93,0x92,0x95,0x00,0x94,0x93,0x96,0x00,0x95,0x95,0x97,0x00,0x96,0x96,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9e,0x9f,0x00,0x9f,0x9f,0xa0,0x00,0xa0,0xa0,0xa1,0x00,0xa1,0xa1,0xa2,0x00, + 0xa2,0xa2,0xa3,0x00,0xa3,0xa3,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa8,0x00,0xa7,0xa7,0xa9,0x00,0xa8,0xa8,0xaa,0x00,0xa9,0xa9,0xab,0x00, + 0xab,0xab,0xac,0x00,0xac,0xac,0xad,0x00,0xad,0xad,0xae,0x00,0xae,0xae,0xaf,0x00,0xaf,0xaf,0xb0,0x00,0xb0,0xb0,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb5,0x00,0xb4,0xb4,0xb6,0x00,0xb5,0xb5,0xb7,0x00,0xb6,0xb6,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xb9,0xb9,0xba,0x00,0xba,0xba,0xbb,0x00,0xbb,0xbb,0xbc,0x00, + 0xbc,0xbc,0xbd,0x00,0xbd,0xbd,0xbe,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc7,0xc6,0xc8,0x00,0xc8,0xc7,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xca,0xca,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd2,0xd1,0xd2,0x00,0xd3,0xd2,0xd3,0x00,0xd4,0xd3,0xd4,0x00,0xd5,0xd4,0xd5,0x00, + 0xd6,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd8,0xd8,0xd9,0x00,0xd9,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdb,0xdc,0x00,0xdd,0xdc,0xdd,0x00,0xde,0xdd,0xde,0x00, + 0xdf,0xde,0xdf,0x00,0xe0,0xdf,0xe0,0x00,0xe1,0xe1,0xe1,0x00,0xe2,0xe2,0xe2,0x00,0xe3,0xe3,0xe3,0x00,0xe4,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xec,0xeb,0xec,0x00,0xed,0xec,0xed,0x00,0xee,0xed,0xee,0x00,0xef,0xee,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf5,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf9,0xf8,0xf8,0x00,0xfa,0xf9,0xf9,0x00,0xfb,0xfa,0xfb,0x00,0xfc,0xfb,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfd,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x09,0x0c,0x00,0x0f,0x0a,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x74,0x72,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x88,0x00,0x86,0x86,0x89,0x00, + 0x87,0x87,0x8a,0x00,0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8a,0x8d,0x00,0x8c,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x95,0x00,0x94,0x93,0x96,0x00,0x95,0x94,0x97,0x00,0x96,0x95,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xaa,0x00,0xa9,0xa9,0xab,0x00, + 0xaa,0xaa,0xac,0x00,0xab,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb7,0x00,0xb6,0xb6,0xb8,0x00,0xb7,0xb7,0xb9,0x00,0xb8,0xb8,0xba,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xba,0xbb,0x00, + 0xbc,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc7,0xc6,0xc8,0x00,0xc8,0xc7,0xc9,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd7,0xd6,0xd7,0x00,0xd8,0xd8,0xd9,0x00,0xd9,0xd9,0xda,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe1,0xe1,0x00,0xe1,0xe2,0xe2,0x00,0xe2,0xe3,0xe3,0x00,0xe3,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xee,0xed,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfb,0xfa,0xfb,0x00,0xfc,0xfb,0xfc,0x00,0xfd,0xfc,0xfd,0x00,0xfe,0xfd,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x07,0x07,0x07,0x00,0x08,0x08,0x08,0x00,0x0e,0x09,0x0c,0x00,0x0f,0x0a,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x17,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x20,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x24,0x22,0x24,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x31,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3c,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x53,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x56,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x67,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x75,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x82,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x88,0x00,0x86,0x86,0x89,0x00, + 0x87,0x87,0x8a,0x00,0x88,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8a,0x8d,0x00,0x8c,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8f,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x95,0x00,0x94,0x93,0x96,0x00,0x95,0x94,0x97,0x00,0x96,0x95,0x98,0x00,0x97,0x97,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa4,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xaa,0x00,0xa9,0xa9,0xab,0x00, + 0xaa,0xaa,0xac,0x00,0xab,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb1,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb7,0x00,0xb6,0xb6,0xb8,0x00,0xb7,0xb7,0xb9,0x00,0xb8,0xb8,0xba,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xba,0xbb,0x00, + 0xbc,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbe,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc7,0xc6,0xc8,0x00,0xc8,0xc7,0xc9,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xcb,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00,0xd8,0xd8,0xd9,0x00,0xd9,0xd9,0xda,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe1,0xe1,0x00,0xe1,0xe2,0xe2,0x00,0xe2,0xe3,0xe3,0x00,0xe3,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xee,0xee,0xee,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfb,0xfa,0xfb,0x00,0xfc,0xfb,0xfc,0x00,0xfd,0xfc,0xfd,0x00,0xfe,0xfd,0xfe,0x00,0xfe,0xfe,0xfe,0x00,0xff,0xfe,0xff,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x08,0x08,0x08,0x00,0x0e,0x09,0x0c,0x00,0x0f,0x0a,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x16,0x18,0x00,0x18,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x21,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x23,0x21,0x23,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2e,0x2e,0x2f,0x00,0x2f,0x2f,0x30,0x00,0x30,0x30,0x31,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3d,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x52,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x55,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x68,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x83,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x88,0x00,0x86,0x86,0x89,0x00, + 0x87,0x87,0x8a,0x00,0x88,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8a,0x8d,0x00,0x8c,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x96,0x00,0x95,0x94,0x97,0x00,0x96,0x95,0x98,0x00,0x97,0x96,0x99,0x00,0x98,0x98,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9d,0x00,0x9e,0x9d,0x9e,0x00,0x9f,0x9e,0x9f,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa5,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xab,0x00, + 0xaa,0xaa,0xac,0x00,0xab,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb8,0x00,0xb7,0xb7,0xb9,0x00,0xb8,0xb8,0xba,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xba,0xbb,0x00, + 0xbc,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbd,0xbf,0x00,0xbf,0xbf,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc8,0xc7,0xc9,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcc,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd9,0xd9,0xda,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe2,0xe2,0x00,0xe2,0xe3,0xe3,0x00,0xe3,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xef,0xef,0xef,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfc,0xfb,0xfc,0x00,0xfd,0xfc,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x0e,0x09,0x0c,0x00,0x0f,0x0a,0x0d,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x14,0x16,0x00, + 0x16,0x15,0x17,0x00,0x17,0x15,0x18,0x00,0x18,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x22,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x30,0x2f,0x32,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00, + 0x3c,0x3b,0x3e,0x00,0x3d,0x3c,0x3f,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x4f,0x51,0x00,0x51,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x53,0x55,0x00, + 0x54,0x54,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x61,0x60,0x63,0x00,0x62,0x61,0x64,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x69,0x6b,0x00,0x6a,0x6a,0x6c,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x84,0x83,0x85,0x00,0x85,0x84,0x86,0x00,0x86,0x85,0x88,0x00,0x87,0x86,0x89,0x00, + 0x88,0x87,0x8a,0x00,0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8b,0x8a,0x8d,0x00,0x8c,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x97,0x00,0x96,0x95,0x98,0x00,0x97,0x96,0x99,0x00,0x98,0x97,0x9a,0x00, + 0x99,0x99,0x9b,0x00,0x9a,0x9a,0x9c,0x00,0x9c,0x9b,0x9d,0x00,0x9d,0x9c,0x9e,0x00,0x9e,0x9d,0x9f,0x00,0x9f,0x9e,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa1,0xa0,0xa2,0x00, + 0xa2,0xa1,0xa3,0x00,0xa3,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa6,0xa7,0x00,0xa7,0xa7,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00, + 0xaa,0xaa,0xac,0x00,0xab,0xab,0xad,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb9,0x00,0xb8,0xb8,0xba,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xba,0xbc,0x00, + 0xbc,0xbb,0xbd,0x00,0xbd,0xbc,0xbe,0x00,0xbe,0xbd,0xbf,0x00,0xbf,0xbe,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc9,0xc8,0xca,0x00,0xca,0xc9,0xcb,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcd,0xce,0x00,0xce,0xce,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd8,0xd8,0xd9,0x00,0xda,0xda,0xdb,0x00,0xdb,0xdb,0xdc,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe1,0xe2,0x00,0xe2,0xe3,0xe3,0x00,0xe3,0xe4,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf1,0x00,0xf2,0xf2,0xf2,0x00,0xf3,0xf3,0xf3,0x00,0xf4,0xf4,0xf4,0x00,0xf5,0xf5,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfd,0xfc,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x0e,0x09,0x0b,0x00,0x0f,0x0a,0x0c,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x13,0x16,0x00, + 0x16,0x14,0x17,0x00,0x17,0x15,0x18,0x00,0x18,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1a,0x1d,0x00, + 0x1d,0x1b,0x1e,0x00,0x1e,0x1c,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2d,0x30,0x00,0x30,0x2e,0x31,0x00,0x31,0x2f,0x32,0x00,0x31,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00, + 0x3c,0x3b,0x3d,0x00,0x3d,0x3c,0x3e,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00, + 0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x86,0x85,0x88,0x00,0x87,0x86,0x89,0x00, + 0x88,0x87,0x8a,0x00,0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8a,0x8a,0x8d,0x00,0x8b,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00, + 0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9c,0x9a,0x9d,0x00,0x9d,0x9b,0x9e,0x00,0x9e,0x9c,0x9f,0x00,0x9f,0x9d,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00, + 0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xba,0xbc,0x00, + 0xbc,0xbb,0xbd,0x00,0xbd,0xbc,0xbe,0x00,0xbe,0xbd,0xbf,0x00,0xbf,0xbe,0xc0,0x00,0xc0,0xbf,0xc1,0x00,0xc1,0xc0,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd8,0xd8,0xd9,0x00,0xd9,0xd9,0xda,0x00,0xda,0xda,0xdb,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe1,0xe2,0x00,0xe2,0xe2,0xe3,0x00,0xe3,0xe3,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf2,0x00,0xf2,0xf2,0xf3,0x00,0xf3,0xf3,0xf4,0x00,0xf4,0xf4,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00, + 0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x0e,0x09,0x0b,0x00,0x0f,0x0a,0x0c,0x00,0x10,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x13,0x16,0x00, + 0x16,0x14,0x17,0x00,0x17,0x15,0x18,0x00,0x18,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1a,0x1d,0x00, + 0x1d,0x1b,0x1e,0x00,0x1e,0x1c,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2d,0x30,0x00,0x30,0x2e,0x31,0x00,0x31,0x2f,0x32,0x00,0x32,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x35,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00, + 0x3c,0x3b,0x3d,0x00,0x3d,0x3c,0x3e,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x47,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x51,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6c,0x6b,0x6e,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00, + 0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x86,0x85,0x88,0x00,0x87,0x86,0x89,0x00, + 0x88,0x87,0x8a,0x00,0x89,0x88,0x8b,0x00,0x8a,0x89,0x8c,0x00,0x8a,0x8a,0x8d,0x00,0x8b,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00, + 0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9c,0x9a,0x9d,0x00,0x9d,0x9b,0x9e,0x00,0x9e,0x9c,0x9f,0x00,0x9f,0x9d,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00, + 0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xbb,0x00,0xbb,0xba,0xbc,0x00, + 0xbc,0xbb,0xbd,0x00,0xbd,0xbc,0xbe,0x00,0xbe,0xbd,0xbf,0x00,0xbf,0xbe,0xc0,0x00,0xc0,0xbf,0xc1,0x00,0xc1,0xc0,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcc,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xcf,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd8,0xd8,0xd9,0x00,0xd9,0xd9,0xda,0x00,0xda,0xda,0xdb,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe1,0xe2,0x00,0xe2,0xe2,0xe3,0x00,0xe3,0xe3,0xe4,0x00,0xe5,0xe5,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf2,0x00,0xf2,0xf2,0xf3,0x00,0xf3,0xf3,0xf4,0x00,0xf4,0xf4,0xf5,0x00,0xf6,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00, + 0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x0e,0x09,0x0b,0x00,0x0f,0x0a,0x0c,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x13,0x16,0x00, + 0x16,0x14,0x17,0x00,0x17,0x15,0x18,0x00,0x18,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1a,0x1d,0x00, + 0x1d,0x1b,0x1e,0x00,0x1e,0x1c,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x20,0x00,0x21,0x20,0x21,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2d,0x30,0x00,0x30,0x2e,0x31,0x00,0x31,0x2f,0x32,0x00,0x32,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x36,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00, + 0x3c,0x3b,0x3d,0x00,0x3d,0x3c,0x3e,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x49,0x00,0x48,0x48,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x50,0x00,0x4f,0x4f,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x5f,0x62,0x00,0x61,0x60,0x63,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6d,0x6c,0x6f,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00, + 0x76,0x76,0x78,0x00,0x77,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x87,0x86,0x89,0x00, + 0x88,0x87,0x8a,0x00,0x89,0x88,0x8b,0x00,0x89,0x89,0x8c,0x00,0x8a,0x8a,0x8d,0x00,0x8b,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00, + 0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9d,0x00,0x9d,0x9b,0x9e,0x00,0x9e,0x9c,0x9f,0x00,0x9f,0x9d,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00, + 0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb2,0xb4,0x00,0xb4,0xb3,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbc,0x00, + 0xbc,0xbb,0xbd,0x00,0xbd,0xbc,0xbe,0x00,0xbe,0xbd,0xbf,0x00,0xbf,0xbe,0xc0,0x00,0xc0,0xbf,0xc1,0x00,0xc1,0xc0,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc4,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcd,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xce,0xd0,0x00,0xd0,0xd0,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd8,0xd8,0xd9,0x00,0xd9,0xd9,0xda,0x00,0xda,0xda,0xdb,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe1,0xe2,0x00,0xe2,0xe2,0xe3,0x00,0xe3,0xe3,0xe4,0x00,0xe5,0xe4,0xe5,0x00,0xe6,0xe6,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf2,0x00,0xf2,0xf2,0xf3,0x00,0xf3,0xf3,0xf4,0x00,0xf4,0xf4,0xf5,0x00,0xf5,0xf6,0xf6,0x00,0xf7,0xf7,0xf6,0x00, + 0xf8,0xf8,0xf7,0x00,0xf9,0xf9,0xf8,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x0e,0x09,0x0c,0x00,0x0e,0x0a,0x0d,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x13,0x16,0x00, + 0x16,0x14,0x17,0x00,0x17,0x15,0x18,0x00,0x18,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x22,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x28,0x00,0x29,0x27,0x29,0x00,0x2a,0x28,0x2a,0x00,0x2b,0x29,0x2b,0x00,0x2b,0x2a,0x2c,0x00, + 0x2c,0x2b,0x2d,0x00,0x2d,0x2c,0x2e,0x00,0x2e,0x2d,0x2f,0x00,0x2f,0x2e,0x30,0x00,0x30,0x2f,0x31,0x00,0x31,0x2f,0x32,0x00,0x32,0x30,0x33,0x00,0x32,0x31,0x34,0x00, + 0x33,0x32,0x35,0x00,0x34,0x33,0x36,0x00,0x35,0x34,0x37,0x00,0x36,0x35,0x38,0x00,0x37,0x37,0x39,0x00,0x38,0x38,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00, + 0x3c,0x3b,0x3d,0x00,0x3d,0x3c,0x3e,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x49,0x00,0x48,0x47,0x4a,0x00,0x49,0x49,0x4b,0x00,0x4a,0x4a,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4e,0x00, + 0x4d,0x4d,0x4f,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x52,0x55,0x00, + 0x54,0x53,0x56,0x00,0x55,0x54,0x57,0x00,0x56,0x55,0x58,0x00,0x57,0x56,0x59,0x00,0x58,0x57,0x5a,0x00,0x59,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5e,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00, + 0x6e,0x6d,0x70,0x00,0x6f,0x6e,0x71,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x74,0x76,0x00,0x75,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00, + 0x88,0x87,0x8a,0x00,0x88,0x88,0x8b,0x00,0x89,0x89,0x8c,0x00,0x8a,0x8a,0x8d,0x00,0x8b,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x98,0x97,0x99,0x00, + 0x99,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9d,0x00,0x9d,0x9b,0x9e,0x00,0x9e,0x9c,0x9f,0x00,0x9f,0x9d,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00, + 0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb1,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00, + 0xbc,0xbb,0xbd,0x00,0xbd,0xbc,0xbe,0x00,0xbe,0xbd,0xbf,0x00,0xbf,0xbe,0xc0,0x00,0xc0,0xc0,0xc1,0x00,0xc1,0xc1,0xc2,0x00,0xc2,0xc2,0xc3,0x00,0xc3,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc5,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00, + 0xcd,0xcc,0xce,0x00,0xce,0xcd,0xcf,0x00,0xcf,0xce,0xd0,0x00,0xd0,0xcf,0xd1,0x00,0xd1,0xd1,0xd2,0x00,0xd2,0xd2,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd8,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe1,0xe2,0x00,0xe2,0xe2,0xe3,0x00,0xe3,0xe3,0xe4,0x00,0xe5,0xe4,0xe5,0x00,0xe6,0xe5,0xe6,0x00, + 0xe7,0xe7,0xe7,0x00,0xe8,0xe8,0xe8,0x00,0xe9,0xe9,0xe9,0x00,0xea,0xea,0xea,0x00,0xeb,0xeb,0xeb,0x00,0xec,0xec,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf2,0x00,0xf2,0xf2,0xf3,0x00,0xf3,0xf3,0xf4,0x00,0xf4,0xf4,0xf5,0x00,0xf5,0xf6,0xf6,0x00,0xf6,0xf7,0xf7,0x00, + 0xf8,0xf8,0xf8,0x00,0xf9,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x00,0x02,0x02,0x02,0x00,0x03,0x03,0x03,0x00, + 0x04,0x04,0x04,0x00,0x05,0x05,0x05,0x00,0x06,0x06,0x06,0x00,0x07,0x07,0x07,0x00,0x0d,0x09,0x0c,0x00,0x0e,0x0a,0x0d,0x00,0x0f,0x0c,0x0e,0x00,0x10,0x0d,0x0f,0x00, + 0x11,0x0e,0x10,0x00,0x12,0x0f,0x11,0x00,0x12,0x10,0x12,0x00,0x13,0x10,0x12,0x00,0x13,0x11,0x13,0x00,0x14,0x12,0x14,0x00,0x15,0x13,0x15,0x00,0x15,0x13,0x16,0x00, + 0x16,0x14,0x17,0x00,0x17,0x15,0x18,0x00,0x18,0x16,0x19,0x00,0x18,0x17,0x1a,0x00,0x19,0x18,0x1b,0x00,0x1a,0x19,0x1c,0x00,0x1b,0x1a,0x1d,0x00,0x1c,0x1b,0x1d,0x00, + 0x1d,0x1c,0x1e,0x00,0x1e,0x1d,0x1f,0x00,0x1f,0x1e,0x20,0x00,0x20,0x1f,0x21,0x00,0x21,0x20,0x22,0x00,0x22,0x21,0x23,0x00,0x23,0x22,0x23,0x00,0x24,0x22,0x24,0x00, + 0x25,0x23,0x25,0x00,0x26,0x24,0x26,0x00,0x27,0x25,0x27,0x00,0x28,0x26,0x27,0x00,0x29,0x27,0x28,0x00,0x2a,0x28,0x29,0x00,0x2b,0x29,0x2a,0x00,0x2b,0x2a,0x2b,0x00, + 0x2c,0x2b,0x2c,0x00,0x2d,0x2c,0x2d,0x00,0x2e,0x2d,0x2e,0x00,0x2f,0x2e,0x2f,0x00,0x30,0x2f,0x30,0x00,0x31,0x30,0x31,0x00,0x32,0x30,0x32,0x00,0x32,0x31,0x33,0x00, + 0x33,0x32,0x34,0x00,0x34,0x33,0x35,0x00,0x35,0x34,0x37,0x00,0x36,0x35,0x38,0x00,0x37,0x36,0x39,0x00,0x38,0x37,0x3a,0x00,0x3a,0x39,0x3b,0x00,0x3b,0x3a,0x3c,0x00, + 0x3c,0x3b,0x3d,0x00,0x3d,0x3c,0x3e,0x00,0x3e,0x3e,0x40,0x00,0x3f,0x3f,0x41,0x00,0x40,0x40,0x42,0x00,0x41,0x41,0x43,0x00,0x43,0x42,0x44,0x00,0x44,0x43,0x45,0x00, + 0x45,0x44,0x46,0x00,0x46,0x45,0x47,0x00,0x47,0x46,0x49,0x00,0x48,0x47,0x4a,0x00,0x49,0x48,0x4b,0x00,0x4a,0x49,0x4c,0x00,0x4b,0x4b,0x4d,0x00,0x4c,0x4c,0x4d,0x00, + 0x4d,0x4d,0x4e,0x00,0x4e,0x4e,0x4f,0x00,0x4f,0x4f,0x50,0x00,0x4f,0x4f,0x51,0x00,0x50,0x50,0x52,0x00,0x51,0x51,0x53,0x00,0x52,0x52,0x54,0x00,0x53,0x52,0x54,0x00, + 0x54,0x53,0x55,0x00,0x55,0x54,0x56,0x00,0x56,0x55,0x58,0x00,0x56,0x56,0x59,0x00,0x57,0x57,0x5a,0x00,0x58,0x58,0x5b,0x00,0x5a,0x59,0x5c,0x00,0x5b,0x5a,0x5d,0x00, + 0x5c,0x5b,0x5e,0x00,0x5d,0x5c,0x5f,0x00,0x5e,0x5d,0x60,0x00,0x5f,0x5f,0x61,0x00,0x60,0x60,0x62,0x00,0x61,0x61,0x63,0x00,0x63,0x62,0x65,0x00,0x64,0x63,0x66,0x00, + 0x65,0x64,0x67,0x00,0x66,0x65,0x68,0x00,0x67,0x66,0x69,0x00,0x68,0x67,0x6a,0x00,0x69,0x68,0x6b,0x00,0x6a,0x69,0x6c,0x00,0x6b,0x6a,0x6d,0x00,0x6c,0x6b,0x6e,0x00, + 0x6d,0x6c,0x6f,0x00,0x6e,0x6d,0x70,0x00,0x70,0x6f,0x72,0x00,0x71,0x70,0x73,0x00,0x72,0x71,0x74,0x00,0x73,0x72,0x75,0x00,0x74,0x74,0x76,0x00,0x76,0x75,0x77,0x00, + 0x77,0x76,0x78,0x00,0x78,0x77,0x79,0x00,0x79,0x78,0x7b,0x00,0x7a,0x79,0x7c,0x00,0x7b,0x7a,0x7d,0x00,0x7c,0x7b,0x7e,0x00,0x7d,0x7d,0x7f,0x00,0x7e,0x7e,0x80,0x00, + 0x7f,0x7f,0x81,0x00,0x80,0x80,0x82,0x00,0x81,0x81,0x83,0x00,0x82,0x82,0x84,0x00,0x83,0x83,0x85,0x00,0x84,0x84,0x86,0x00,0x85,0x85,0x87,0x00,0x86,0x86,0x88,0x00, + 0x87,0x87,0x89,0x00,0x88,0x88,0x8a,0x00,0x89,0x89,0x8c,0x00,0x8a,0x8a,0x8d,0x00,0x8b,0x8b,0x8e,0x00,0x8d,0x8c,0x8f,0x00,0x8e,0x8e,0x90,0x00,0x90,0x8f,0x91,0x00, + 0x91,0x90,0x92,0x00,0x92,0x91,0x93,0x00,0x93,0x92,0x94,0x00,0x94,0x93,0x95,0x00,0x95,0x94,0x96,0x00,0x96,0x95,0x97,0x00,0x97,0x96,0x98,0x00,0x97,0x97,0x99,0x00, + 0x98,0x98,0x9a,0x00,0x9a,0x99,0x9b,0x00,0x9b,0x9a,0x9d,0x00,0x9d,0x9b,0x9e,0x00,0x9e,0x9c,0x9f,0x00,0x9f,0x9d,0xa0,0x00,0xa0,0x9f,0xa1,0x00,0xa0,0xa0,0xa2,0x00, + 0xa1,0xa1,0xa3,0x00,0xa2,0xa2,0xa4,0x00,0xa4,0xa3,0xa5,0x00,0xa5,0xa4,0xa6,0x00,0xa6,0xa5,0xa7,0x00,0xa7,0xa6,0xa8,0x00,0xa8,0xa8,0xa9,0x00,0xa9,0xa9,0xaa,0x00, + 0xaa,0xaa,0xab,0x00,0xab,0xab,0xac,0x00,0xad,0xac,0xae,0x00,0xae,0xad,0xaf,0x00,0xaf,0xae,0xb0,0x00,0xb0,0xaf,0xb1,0x00,0xb1,0xb0,0xb2,0x00,0xb2,0xb2,0xb3,0x00, + 0xb3,0xb3,0xb4,0x00,0xb4,0xb4,0xb5,0x00,0xb5,0xb5,0xb6,0x00,0xb6,0xb6,0xb7,0x00,0xb7,0xb7,0xb8,0x00,0xb8,0xb8,0xb9,0x00,0xba,0xb9,0xba,0x00,0xbb,0xba,0xbb,0x00, + 0xbc,0xbb,0xbc,0x00,0xbd,0xbc,0xbd,0x00,0xbe,0xbd,0xbe,0x00,0xbf,0xbf,0xbf,0x00,0xc0,0xc0,0xc0,0x00,0xc1,0xc1,0xc1,0x00,0xc2,0xc2,0xc3,0x00,0xc4,0xc3,0xc4,0x00, + 0xc5,0xc4,0xc5,0x00,0xc6,0xc5,0xc6,0x00,0xc6,0xc6,0xc7,0x00,0xc7,0xc7,0xc8,0x00,0xc8,0xc8,0xc9,0x00,0xc9,0xc9,0xca,0x00,0xcb,0xca,0xcb,0x00,0xcc,0xcb,0xcc,0x00, + 0xcd,0xcc,0xcd,0x00,0xce,0xcd,0xce,0x00,0xcf,0xce,0xd0,0x00,0xd0,0xcf,0xd1,0x00,0xd1,0xd0,0xd2,0x00,0xd2,0xd1,0xd3,0x00,0xd3,0xd3,0xd4,0x00,0xd4,0xd4,0xd5,0x00, + 0xd5,0xd5,0xd6,0x00,0xd6,0xd6,0xd7,0x00,0xd7,0xd7,0xd8,0x00,0xd9,0xd8,0xd9,0x00,0xda,0xd9,0xda,0x00,0xdb,0xda,0xdb,0x00,0xdc,0xdc,0xdd,0x00,0xdd,0xdd,0xde,0x00, + 0xde,0xde,0xdf,0x00,0xdf,0xdf,0xe0,0x00,0xe0,0xe0,0xe1,0x00,0xe1,0xe1,0xe2,0x00,0xe2,0xe2,0xe3,0x00,0xe3,0xe3,0xe4,0x00,0xe5,0xe4,0xe5,0x00,0xe6,0xe5,0xe6,0x00, + 0xe7,0xe6,0xe7,0x00,0xe8,0xe7,0xe8,0x00,0xe9,0xe8,0xe9,0x00,0xe9,0xe9,0xea,0x00,0xea,0xea,0xeb,0x00,0xeb,0xeb,0xec,0x00,0xed,0xed,0xed,0x00,0xee,0xee,0xee,0x00, + 0xef,0xef,0xef,0x00,0xf0,0xf0,0xf0,0x00,0xf1,0xf1,0xf2,0x00,0xf2,0xf2,0xf3,0x00,0xf3,0xf3,0xf4,0x00,0xf4,0xf4,0xf5,0x00,0xf5,0xf6,0xf6,0x00,0xf6,0xf7,0xf7,0x00, + 0xf7,0xf8,0xf8,0x00,0xf8,0xf9,0xf9,0x00,0xfa,0xfa,0xfa,0x00,0xfb,0xfb,0xfb,0x00,0xfc,0xfc,0xfc,0x00,0xfd,0xfd,0xfd,0x00,0xfd,0xfd,0xfd,0x00,0xfe,0xfe,0xfe,0x00 +}; diff --git a/LibOVR/Src/Displays/OVR_Display.cpp b/LibOVR/Src/Displays/OVR_Display.cpp old mode 100644 new mode 100755 index 55eb8a9..7c74eee --- a/LibOVR/Src/Displays/OVR_Display.cpp +++ b/LibOVR/Src/Displays/OVR_Display.cpp @@ -27,10 +27,262 @@ limitations under the License. #include "OVR_Display.h" + namespace OVR { // Place platform-independent code here +static bool DirectDisplayInitialized = false; + +bool Display::GetDirectDisplayInitialized() +{ + return DirectDisplayInitialized; +} + +void Display::SetDirectDisplayInitialized(bool initialized) +{ + DirectDisplayInitialized = initialized; +} + + +//----------------------------------------------------------------------------- +// EDID Parsing + +// FIXME: This can be done much more compactly without the bitfields. +#pragma pack(push, 1) + +#if defined(_MSC_VER) +#pragma warning(disable: 4201) // Nameless struct/union +#endif + +// All of our EDIDs use the Detailed timing descriptors, and not the +// older Standard timing info in the EDID. Conforming EDID v1.3+ displays +// always put their preferred resolution, refresh, and timing info into the +// first Detailed timing descriptor. + +#ifndef byte_t +typedef unsigned char byte_t; +#endif + +//static const uint32_t EDIDv13Size = 128; // Standard EDID v1.3 is 128 bytes. +static const uint32_t FirstDetailedTimingOffset = 54; // Detailed timing table starts here. +static const uint32_t DetailedTimingDescriptorCount = 4; +static const byte_t MonitorSerialNumberType = 0xFF; +static const byte_t MonitorNameType = 0xFC; + +// Expected signature of EDID +static const byte_t EDIDSignature[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; + +struct EDID_Header +{ + byte_t Signature[8]; + + byte_t VendorIDHigh; + byte_t VendorIDLow; + + uint16_t ProductCode; + uint32_t SerialNumber; + + // We don't currently use anything farther into the header + byte_t Unused[112]; +}; + +struct EDID_Detailed_Timing_Descriptor +{ + uint16_t PixelClock; // In 10Khz units + + byte_t HActivePixelsLSB; + byte_t HBlankingPixelsLSB; + + union + { + struct + { + byte_t HBlankingPixelsMSB : 4; + byte_t HActivePixelsMSB : 4; + } Values; + byte_t Value_; + } HSizeMSB; + + byte_t VActivePixelsLSB; + byte_t VBlankingPixelsLSB; + union + { + struct + { + byte_t VBlankingPixelsMSB : 4; + byte_t VActivePixelsMSB : 4; + } Values; + byte_t Value_; + } VSizeMSB; + + byte_t HSyncOffsetPixelsLSB; + byte_t HSyncPulseWidthPixelsLSB; + + union + { + struct + { + byte_t VSyncPulseWidthLSB : 4; + byte_t VSyncOffsetPixelsLSB : 4; + } Values; + byte_t Value_; + } VSync; + + union + { + struct + { + byte_t VSyncPulseWidthMSB : 2; + byte_t VSyncOffsetMSB : 2; + byte_t HSyncPulseWidthMSB : 2; + byte_t HSyncOffsetMSB : 2; + } Values; + byte_t Value_; + } SyncMSB; + + byte_t Unused[6]; // We don't use anything else in the header +}; + +struct EDID_Other_Descriptor +{ + byte_t Reserved[3]; + byte_t Type; + byte_t Reserved1; + char Data[13]; +}; + +#pragma pack(pop) + + +static void StripTrailingWhitespace(char* str) +{ + // Get initial string length + int mlen = (int)strlen(str); + + // While removing trailing characters, + while (mlen > 0) + { + // If trailing character should be stripped, + char trailing = str[mlen - 1]; + if (trailing == '\n' || trailing == ' ') + { + // Strip it and reduce string length. + str[mlen - 1] = '\0'; + --mlen; + } + else + { + // Stop here. + break; + } + } +} + +bool DisplayEDID::Parse(const unsigned char* edid) +{ + const EDID_Header* header = (const EDID_Header*)edid; + + if (memcmp(header->Signature, EDIDSignature, sizeof(EDIDSignature)) != 0) + { + OVR_ASSERT(false); + return false; + } + + memset(VendorName, 0, sizeof(VendorName)); + memset(MonitorName, 0, sizeof(MonitorName)); + memset(SerialNumber, 0, sizeof(SerialNumber)); + + // Extract the 5-bit chars for the Vendor ID (PNP code) + uint16_t char1 = (header->VendorIDHigh >> 2) & 0x1F; + uint16_t char2 = ((header->VendorIDHigh & 0x2) << 3) | (header->VendorIDLow >> 5); + uint16_t char3 = header->VendorIDLow & 0x1F; + VendorName[0] = (char)char1 - 1 + 'A'; + VendorName[1] = (char)char2 - 1 + 'A'; + VendorName[2] = (char)char3 - 1 + 'A'; + VendorName[3] = '\0'; + ModelNumber = header->ProductCode; + + const EDID_Detailed_Timing_Descriptor* detailedTiming = (const EDID_Detailed_Timing_Descriptor*)&edid[FirstDetailedTimingOffset]; + + // First Detailed timing info is always preferred mode: + uint32_t hActive = (detailedTiming->HSizeMSB.Values.HActivePixelsMSB << 8) | detailedTiming->HActivePixelsLSB; + uint32_t vActive = (detailedTiming->VSizeMSB.Values.VActivePixelsMSB << 8) | detailedTiming->VActivePixelsLSB; + uint32_t hBlanking = (detailedTiming->HSizeMSB.Values.HBlankingPixelsMSB << 8) | detailedTiming->HBlankingPixelsLSB; + uint32_t vBlanking = (detailedTiming->VSizeMSB.Values.VBlankingPixelsMSB << 8) | detailedTiming->VBlankingPixelsLSB; + + // Need to scale up the values, since they're in 10Khz, and we're using integer math without fractions + uint32_t denom = 1000; + uint32_t totalPixels = (hActive + hBlanking) * (vActive + vBlanking); + uint32_t vSyncNumerator = (uint32_t)(((uint64_t)detailedTiming->PixelClock * 10000 * denom) / totalPixels); + + Width = hActive; + Height = vActive; + + RefreshNumerator = vSyncNumerator; + RefreshDenominator = denom; + + // The remaining ones can hold extra info. Look for monitor name & serial number strings. + ++detailedTiming; + for (int i = 1; i < (int)DetailedTimingDescriptorCount; ++i, ++detailedTiming) + { + if (detailedTiming->PixelClock == 0) + { + // Not a timing info, use OtherDescriptor instead + const EDID_Other_Descriptor* other = (const EDID_Other_Descriptor*)detailedTiming; + switch (other->Type) + { + case MonitorNameType: + static_assert(sizeof(MonitorName) == sizeof(other->Data) + 1, "serial number field size is off"); + memcpy(MonitorName, other->Data, sizeof(MonitorName)); + MonitorName[sizeof(MonitorName) - 1] = '\0'; + StripTrailingWhitespace(MonitorName); + break; + + case MonitorSerialNumberType: + static_assert(sizeof(SerialNumber) == sizeof(other->Data) + 1, "serial number field size is off"); + memcpy(SerialNumber, other->Data, sizeof(SerialNumber)); + SerialNumber[sizeof(SerialNumber) - 1] = '\0'; + StripTrailingWhitespace(SerialNumber); + break; + + default: + break; + } + } + } + + return true; +} + +HmdTypeEnum HmdTypeFromModelNumber(int modelNumber) +{ + HmdTypeEnum deviceTypeGuess = HmdType_Unknown; + switch (modelNumber) + { + case 3: deviceTypeGuess = HmdType_DK2; break; + case 2: deviceTypeGuess = HmdType_DKHDProto; break; + case 1: deviceTypeGuess = HmdType_DK1; break; + default: break; + } + return deviceTypeGuess; +} + +bool Display::MatchDisplay(const Display* other) +{ + // Note this is not checking the DeviceName, which corresponds to which monitor the device is. + // This allows matching to match a display that has changed how it is plugged in. + // The rotation must match, which allows us to react properly by regenerating the HMD info. + bool displayMatch = + (DisplayID == other->DisplayID) && + (EdidSerialNumber == other->EdidSerialNumber) && + (NativeResolutionInPixels == other->NativeResolutionInPixels) && + (Rotation == other->Rotation) && + (ApplicationExclusive == other->ApplicationExclusive); + + return displayMatch; +} + } // namespace OVR diff --git a/LibOVR/Src/Displays/OVR_Display.h b/LibOVR/Src/Displays/OVR_Display.h index 46e9f13..7b4f1db 100644 --- a/LibOVR/Src/Displays/OVR_Display.h +++ b/LibOVR/Src/Displays/OVR_Display.h @@ -28,19 +28,63 @@ limitations under the License. #ifndef OVR_Display_h #define OVR_Display_h -#include "../Sensors/OVR_DeviceConstants.h" // Required for HmdTypeEnum +#include "Sensors/OVR_DeviceConstants.h" // Required for HmdTypeEnum -#include "../Kernel/OVR_Types.h" -#include "../Kernel/OVR_Atomic.h" -#include "../Kernel/OVR_RefCount.h" -#include "../Kernel/OVR_Array.h" -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_Math.h" +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_Atomic.h" +#include "Kernel/OVR_RefCount.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_String.h" +#include "Extras/OVR_Math.h" +#include // uint32_t namespace OVR { -class DisplaySearchHandle : virtual public RefCountBaseV + +//------------------------------------------------------------------------------------- +// DisplayEDID +// +// Parses binary EDID information for the pieces we need +struct DisplayEDID +{ + char VendorName[4]; + char MonitorName[14]; + char SerialNumber[14]; + uint16_t ModelNumber; + + uint32_t Width; + uint32_t Height; + + uint32_t RefreshNumerator; + uint32_t RefreshDenominator; + + bool Parse(const unsigned char* edid); +}; + +HmdTypeEnum HmdTypeFromModelNumber(int modelNumber); + + +//------------------------------------------------------------------------------------- +// DisplayDesc + +// Display information that is enumerable +struct DisplayDesc +{ + HmdTypeEnum DeviceTypeGuess; // This is a guess about what type of HMD it is connected to + char DisplayID[64]; // This is the device identifier string from MONITORINFO (for app usage) + char ModelName[14]; // This is a "DK2" type string + char EdidSerialNumber[14]; + Sizei ResolutionInPixels; + Vector2i DesktopDisplayOffset; + int Rotation; +}; + + +//----------------------------------------------------------------------------- +// Display Search Handle +// +class DisplaySearchHandle { public: DisplaySearchHandle() {} @@ -116,7 +160,8 @@ public: // any necessary shimming and function hooks. This should be one // of the very first things your application does when it // initializes LibOVR - static bool Initialize(); + static bool Initialize(); + static void Shutdown(); // Returns a count of the detected displays. These are Rift displays // attached directly to an active display port @@ -127,16 +172,7 @@ public: // Returns true if we are referencing the same display; useful for matching display // objects with the ones already detected. - bool MatchDisplay(const Display* other) - { - // Note this is not checking the DeviceName, which corresponds to which monitor the device is. - // This allows matching to match a display that has changed how it is plugged in. - return (DisplayID == other->DisplayID) && - (EdidSerialNumber == other->EdidSerialNumber) && - (NativeResolutionInPixels == other->NativeResolutionInPixels) && - (DesktopDisplayOffset == other->DesktopDisplayOffset) && - (ApplicationExclusive == other->ApplicationExclusive); - } + bool MatchDisplay(const Display* other); // ----- Device independent instance based Display functionality ----- @@ -187,9 +223,18 @@ public: return false; } - // Check if right now the current rendering application should be in compatibility mode + // Check if right now the current rendering application should be in monitor-extended mode. + // If displaySearch is true then this function attempts to discover extended mode devices. Otherwise this + // function modifies no data. static bool InCompatibilityMode( bool displaySearch = true ); + // Polls the computer's displays to see if any of them are extended mode Rift devices. + static bool ExtendedModeDevicesExist(); + + // Tracks the initialization state of direct mode. + static bool GetDirectDisplayInitialized(); + static void SetDirectDisplayInitialized(bool initialized); + // Get/set the mode for all applications static bool GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode); static bool SetDriverMode(bool compatMode, bool hideDK1Mode); diff --git a/LibOVR/Src/Displays/OVR_Linux_Display.cpp b/LibOVR/Src/Displays/OVR_Linux_Display.cpp old mode 100644 new mode 100755 index 4b840dd..f18dfac --- a/LibOVR/Src/Displays/OVR_Linux_Display.cpp +++ b/LibOVR/Src/Displays/OVR_Linux_Display.cpp @@ -7,16 +7,16 @@ Authors : James Hughes Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which otherwise accompanies this software in either electronic or hard copy form. You may obtain a copy of the License at -http://www.oculusvr.com/licenses/LICENSE-3.2 +http://www.oculusvr.com/licenses/LICENSE-3.2 -Unless required by applicable law or agreed to in writing, the Oculus VR SDK +Unless required by applicable law or agreed to in writing, the Oculus VR SDK distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and @@ -25,7 +25,7 @@ limitations under the License. *************************************************************************************/ #include "OVR_Linux_Display.h" -#include "../Kernel/OVR_Log.h" +#include "Kernel/OVR_Log.h" #include "../../../3rdParty/EDID/edid.h" @@ -34,10 +34,11 @@ limitations under the License. #include #include + //------------------------------------------------------------------------------------- // ***** Display enumeration Helpers -namespace OVR { +namespace OVR { static const uint8_t edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; @@ -185,7 +186,7 @@ static int parseEdid(uint8_t* edid, Linux::DisplayEDID& edidResult) // data OUT This pointer is modified to point to the output from // XRRGetOutputProperty. You *must* call XFree on this pointer. // dataLen OUT The length of the data returned in 'data'. -static int getXRRProperty(struct _XDisplay* display, RROutput output, Atom atom, +static int getXRRProperty(struct _XDisplay* X11Display, RROutput output, Atom atom, uint8_t** data, int* dataLen) { unsigned long nitems; @@ -193,7 +194,7 @@ static int getXRRProperty(struct _XDisplay* display, RROutput output, Atom atom, int actualFormat; Atom actualType; - int ret = XRRGetOutputProperty(display, output, atom, 0, 100, + int ret = XRRGetOutputProperty(X11Display, output, atom, 0, 100, False, False, AnyPropertyType, &actualType, &actualFormat, &nitems, &bytesAfter, data); @@ -222,28 +223,30 @@ static XRRModeInfo* findModeByXID(XRRScreenResources* screen, RRMode xid) return NULL; } -static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int inputArraySize, bool /*edidInfo*/) +static struct _XDisplay* X11Display = NULL; +static int BaseRREvent = 0; +static int BaseRRError = 0; + +static int discoverExtendedRifts(OVR::DisplayDesc* descriptorArray, int inputArraySize, bool /*edidInfo*/) { int result = 0; - struct _XDisplay* display = XOpenDisplay(NULL); - - if (display == NULL) + if (X11Display == NULL) { OVR::LogError("[Linux Display] Unable to open X Display!"); return 0; } - Atom EDIDAtom = XInternAtom(display, RR_PROPERTY_RANDR_EDID, False); - int numScreens = XScreenCount(display); + Atom EDIDAtom = XInternAtom(X11Display, RR_PROPERTY_RANDR_EDID, False); + int numScreens = XScreenCount(X11Display); for (int i = 0; i < numScreens; ++i) { - Window sr = XRootWindow(display, i); - XRRScreenResources* screen = XRRGetScreenResources(display, sr); + Window sr = XRootWindow(X11Display, i); + XRRScreenResources* screen = XRRGetScreenResources(X11Display, sr); for (int ii = 0; ii < screen->ncrtc; ++ii) { - XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(display, screen, screen->crtcs[ii]); + XRRCrtcInfo* crtcInfo = XRRGetCrtcInfo(X11Display, screen, screen->crtcs[ii]); if (0 == crtcInfo->noutput) { @@ -256,7 +259,7 @@ static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int i for (int k = 0; k < crtcInfo->noutput; ++k) { XRROutputInfo* outputInfo = - XRRGetOutputInfo(display, screen, crtcInfo->outputs[k]); + XRRGetOutputInfo(X11Display, screen, crtcInfo->outputs[k]); for (int kk = 0; kk < outputInfo->nmode; ++kk) { @@ -280,7 +283,7 @@ static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int i continue; } - XRROutputInfo* outputInfo = XRRGetOutputInfo(display, screen, output); + XRROutputInfo* outputInfo = XRRGetOutputInfo(X11Display, screen, output); if (RR_Connected != outputInfo->connection) { XRRFreeOutputInfo(outputInfo); @@ -291,7 +294,7 @@ static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int i // Read EDID associated with crtc. uint8_t* data = NULL; int dataLen = 0; - if (getXRRProperty(display, output, EDIDAtom, &data, &dataLen) != 0) + if (getXRRProperty(X11Display, output, EDIDAtom, &data, &dataLen) != 0) { // Identify rifts based on EDID. Linux::DisplayEDID edid; @@ -302,7 +305,7 @@ static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int i // TODO: Remove either this 3rdParty call to read EDID data // or remove our own parsing of the EDID. Probably opt // to remove our parsing. - MonitorInfo* mi = read_edid_data(display, output); + MonitorInfo* mi = read_edid_data(X11Display, output); if (mi == NULL) { XRRFreeOutputInfo(outputInfo); @@ -325,13 +328,6 @@ static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int i int width = modeInfo->width; int height = modeInfo->height; - if ( crtcInfo->rotation == RR_Rotate_90 - || crtcInfo->rotation == RR_Rotate_270 ) - { - width = modeInfo->height; - height = modeInfo->width; - } - int x = crtcInfo->x; int y = crtcInfo->y; @@ -341,12 +337,32 @@ static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int i mi->manufacturer_code, mi->product_code, screen->crtcs[ii]); - OVR::Linux::DisplayDesc& desc = descriptorArray[result++]; - desc.DisplayID = device_id; - desc.ModelName = edid.MonitorName; - desc.EdidSerialNumber = edid.SerialNumber; - desc.LogicalResolutionInPixels = Sizei(width, height); + OVR::DisplayDesc& desc = descriptorArray[result++]; + desc.ResolutionInPixels = Sizei(width, height); desc.DesktopDisplayOffset = Vector2i(x, y); + strncpy(desc.DisplayID, device_id, sizeof(desc.DisplayID)-1); + desc.DisplayID[sizeof(desc.DisplayID)-1] = 0; + strncpy(desc.ModelName, edid.MonitorName, sizeof(desc.ModelName)-1); + desc.ModelName[sizeof(desc.ModelName)-1] = 0; + strncpy(desc.EdidSerialNumber, edid.SerialNumber, sizeof(desc.EdidSerialNumber)-1); + desc.EdidSerialNumber[sizeof(desc.EdidSerialNumber)-1] = 0; + + bool tallScreen = (height > width); + switch (crtcInfo->rotation) + { + default: + desc.Rotation = tallScreen ? 270 : 0; + break; + case RR_Rotate_90: + desc.Rotation = tallScreen ? 0 : 90; + break; + case RR_Rotate_180: + desc.Rotation = tallScreen ? 90 : 180; + break; + case RR_Rotate_270: + desc.Rotation = tallScreen ? 180 : 270; + break; + } switch (mi->product_code) { @@ -363,19 +379,21 @@ static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int i if ( desc.DeviceTypeGuess == HmdType_DK2 || desc.DeviceTypeGuess == HmdType_DKHDProto) { - desc.LogicalResolutionInPixels = Sizei(1920, 1080); - desc.NativeResolutionInPixels = Sizei(1080, 1920); + desc.ResolutionInPixels = Sizei(1920, 1080); } else { - desc.LogicalResolutionInPixels = Sizei(width, height); - desc.NativeResolutionInPixels = Sizei(width, height); + desc.ResolutionInPixels = Sizei(width, height); } } delete mi; mi = NULL; } + else + { + XFree(data); + } XRRFreeOutputInfo(outputInfo); XRRFreeCrtcInfo(crtcInfo); @@ -384,21 +402,44 @@ static int discoverExtendedRifts(OVR::Linux::DisplayDesc* descriptorArray, int i XRRFreeScreenResources(screen); } - XCloseDisplay(display); - return result; } //------------------------------------------------------------------------------------- -// ***** Display +// ***** Display bool Display::Initialize() { - // Nothing to initialize. OS X only supports compatibility mode. + if (X11Display == NULL) + { + X11Display = XOpenDisplay(NULL); + } + + if (X11Display == NULL) + { + OVR::LogError("[Linux Display] Unable to open X display!"); + return false; + } + + if (!XRRQueryExtension(X11Display, &BaseRREvent, &BaseRRError)) + { + OVR::LogError("[Linux Display] Unable to query XRandR extension!"); + return false; + } + return true; } +void Display::Shutdown() +{ + if (X11Display != NULL) + { + XCloseDisplay(X11Display); + X11Display = NULL; + } +} + bool Display::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) { driverInstalled = false; @@ -417,9 +458,9 @@ DisplaySearchHandle* Display::GetDisplaySearchHandle() return new Linux::LinuxDisplaySearchHandle(); } -bool Display::InCompatibilityMode( bool displaySearch ) +bool Display::InCompatibilityMode( bool X11DisplaySearch ) { - OVR_UNUSED( displaySearch ); + OVR_UNUSED( X11DisplaySearch ); return true; } @@ -427,15 +468,42 @@ int Display::GetDisplayCount(DisplaySearchHandle* handle, bool extended, bool ap { OVR_UNUSED4(handle, extended, applicationOnly, edidInfo); - static int extendedCount = -1; + static int extendedCount = -1; + static int numScreens = -1; - Linux::LinuxDisplaySearchHandle* localHandle = (Linux::LinuxDisplaySearchHandle*)handle; + Linux::LinuxDisplaySearchHandle* localHandle = (Linux::LinuxDisplaySearchHandle*)handle; if (localHandle == NULL) { OVR::LogError("[Linux Display] No search handle passed into GetDisplayCount. Return 0 rifts."); return 0; } + if (X11Display == NULL) + { + OVR::LogError("[Linux Display] Unable to open X Display!"); + return 0; + } + + int screen_count = XScreenCount(X11Display); + if (screen_count != numScreens) + { + numScreens = screen_count; + extended = true; + for (int screen = 0; screen < numScreens; ++screen) + { + // Be sure we're subscribed to config changes on all screens. + XRRSelectInput(X11Display, XRootWindow(X11Display, screen), + RRScreenChangeNotifyMask | RRCrtcChangeNotifyMask | + RROutputChangeNotifyMask | RROutputPropertyNotifyMask); + } + } + + XEvent event_return = XEvent(); + if (XCheckTypedEvent(X11Display, BaseRREvent + RRScreenChangeNotify, &event_return)) + { + extended = true; + } + if (extendedCount == -1 || extended) { extendedCount = discoverExtendedRifts(localHandle->cachedDescriptorArray, Linux::LinuxDisplaySearchHandle::DescArraySize, edidInfo); @@ -445,7 +513,6 @@ int Display::GetDisplayCount(DisplaySearchHandle* handle, bool extended, bool ap localHandle->extendedDisplayCount = extendedCount; int totalCount = extendedCount; - /// FIXME: Implement application mode for OS X. localHandle->application = false; localHandle->applicationDisplayCount = 0; @@ -484,7 +551,7 @@ Ptr Display::GetDisplay( int index, DisplaySearchHandle* handle ) if (localHandle->application) { - OVR::LogError("[Linux Display] Mac does not support application displays."); + OVR::LogError("[Linux Display] Mac does not support application X11Displays."); } return result; diff --git a/LibOVR/Src/Displays/OVR_Linux_Display.h b/LibOVR/Src/Displays/OVR_Linux_Display.h index f685e6b..1ef1dab 100644 --- a/LibOVR/Src/Displays/OVR_Linux_Display.h +++ b/LibOVR/Src/Displays/OVR_Linux_Display.h @@ -32,23 +32,6 @@ limitations under the License. namespace OVR { namespace Linux { -//------------------------------------------------------------------------------------- -// DisplayDesc - -// Display information enumerable through OS . -// TBD: Should we just move this to public header, so it's a const member of Display? -struct DisplayDesc -{ - HmdTypeEnum DeviceTypeGuess; - String DisplayID; // This is the device identifier string from MONITORINFO (for app usage) - String ModelName; // This is a "DK2" type string - String EdidSerialNumber; - Sizei LogicalResolutionInPixels; - Sizei NativeResolutionInPixels; - Vector2i DesktopDisplayOffset; -}; - - //------------------------------------------------------------------------------------- // DisplayEDID @@ -82,7 +65,7 @@ public: static const int DescArraySize = 16; - Linux::DisplayDesc cachedDescriptorArray[DescArraySize]; + DisplayDesc cachedDescriptorArray[DescArraySize]; bool extended; bool application; int extendedDisplayCount; @@ -102,12 +85,12 @@ public: dd.DisplayID, dd.ModelName, dd.EdidSerialNumber, - dd.LogicalResolutionInPixels, - dd.NativeResolutionInPixels, + dd.ResolutionInPixels, + dd.ResolutionInPixels, dd.DesktopDisplayOffset, 0, - 0, - false) + dd.Rotation, + false) { } diff --git a/LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp b/LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp index 3d76f69..aa9acfc 100644 --- a/LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp +++ b/LibOVR/Src/Displays/OVR_Linux_SDKWindow.cpp @@ -25,8 +25,8 @@ limitations under the License. *******************************************************************************/ #include "OVR_Linux_SDKWindow.h" -#include "../Kernel/OVR_Log.h" -#include "../Kernel/OVR_Log.h" +#include "Kernel/OVR_Log.h" +#include "Kernel/OVR_Log.h" #include "../../../3rdParty/EDID/edid.h" namespace OVR { @@ -257,6 +257,7 @@ bool SDKWindow::getVisualFromDrawable(GLXDrawable drawable, XVisualInfo* vinfoOu XVisualInfo* chosen = glXGetVisualFromFBConfig(display, *config); *vinfoOut = *chosen; XFree(config); + XFree(chosen); return true; } return false; diff --git a/LibOVR/Src/Displays/OVR_Linux_SDKWindow.h b/LibOVR/Src/Displays/OVR_Linux_SDKWindow.h index 70b95dd..81c83b3 100644 --- a/LibOVR/Src/Displays/OVR_Linux_SDKWindow.h +++ b/LibOVR/Src/Displays/OVR_Linux_SDKWindow.h @@ -27,8 +27,8 @@ limitations under the License. #ifndef OVR_Linux_SDKWindow_h #define OVR_Linux_SDKWindow_h -#include "../OVR_CAPI.h" -#include "../CAPI/GL/CAPI_GL_Util.h" +#include "OVR_CAPI.h" +#include "CAPI/GL/CAPI_GL_Util.h" #include #include diff --git a/LibOVR/Src/Displays/OVR_OSX_Display.cpp b/LibOVR/Src/Displays/OVR_OSX_Display.cpp index 67df51d..5b88c49 100644 --- a/LibOVR/Src/Displays/OVR_OSX_Display.cpp +++ b/LibOVR/Src/Displays/OVR_OSX_Display.cpp @@ -25,7 +25,7 @@ limitations under the License. *************************************************************************************/ #include "OVR_OSX_Display.h" -#include "../Kernel/OVR_Log.h" +#include "Kernel/OVR_Log.h" #include #include @@ -197,15 +197,17 @@ static int discoverExtendedRifts(OVR::OSX::DisplayDesc* descriptorArray, int inp for (unsigned int i = 0; i < NDisplays; i++) { - io_service_t port = CGDisplayIOServicePort(Displays[i]); + CGDirectDisplayID dispId = Displays[i]; + + io_service_t port = CGDisplayIOServicePort(dispId); CFDictionaryRef DispInfo = IODisplayCreateInfoDictionary(port, kNilOptions); // Display[i] - uint32_t vendor = CGDisplayVendorNumber(Displays[i]); - uint32_t product = CGDisplayModelNumber(Displays[i]); + uint32_t vendor = CGDisplayVendorNumber(dispId); + uint32_t product = CGDisplayModelNumber(dispId); - CGRect desktop = CGDisplayBounds(Displays[i]); + CGRect desktop = CGDisplayBounds(dispId); Vector2i desktopOffset(desktop.origin.x, desktop.origin.y); if (vendor == 16082 && ( (product == 1)||(product == 2)||(product == 3) ) ) // 7" or HD @@ -216,7 +218,9 @@ static int discoverExtendedRifts(OVR::OSX::DisplayDesc* descriptorArray, int inp return result; } - Sizei monitorResolution(1280, 800); + int width = static_cast(CGDisplayPixelsWide(dispId)); + int height = static_cast(CGDisplayPixelsHigh(dispId)); + Sizei monitorResolution(width, height); // Obtain and parse EDID data. CFDataRef data = @@ -232,20 +236,46 @@ static int discoverExtendedRifts(OVR::OSX::DisplayDesc* descriptorArray, int inp parseEdid( edid, edidResult ); OVR::OSX::DisplayDesc& desc = descriptorArray[result++]; - desc.DisplayID = Displays[i]; - desc.ModelName = edidResult.MonitorName; // User friendly string. - desc.EdidSerialNumber = edidResult.SerialNumber; + desc.DisplayID = dispId; + desc.ModelName = edidResult.MonitorName; // User friendly string. + desc.EdidSerialNumber = edidResult.SerialNumber; desc.LogicalResolutionInPixels = monitorResolution; + desc.NativeResolutionInPixels = monitorResolution; desc.DesktopDisplayOffset = desktopOffset; + desc.Rotation = 0; + + auto roughEqual = [](double a, double b) -> bool + { + return fabs(a - b) < 1.0; + }; switch (product) { - case 3: desc.DeviceTypeGuess = HmdType_DK2; break; - case 2: desc.DeviceTypeGuess = HmdType_DKHDProto; break; - case 1: desc.DeviceTypeGuess = HmdType_DK1; break; + case 3: desc.DeviceTypeGuess = HmdType_DK2; break; + case 2: desc.DeviceTypeGuess = HmdType_DKHDProto; break; + case 1: desc.DeviceTypeGuess = HmdType_DK1; break; default: - case 0: desc.DeviceTypeGuess = HmdType_Unknown; break; + case 0: desc.DeviceTypeGuess = HmdType_Unknown; break; + } + + bool portraitDevice = (desc.DeviceTypeGuess == HmdType_DK2); + double rotation = fabs(CGDisplayRotation(dispId)); + if (roughEqual(rotation, 0)) + { + desc.Rotation = portraitDevice ? 270 : 0; + } + else if (roughEqual(rotation, 90)) + { + desc.Rotation = portraitDevice ? 0 : 90; + } + else if (roughEqual(rotation, 180)) + { + desc.Rotation = portraitDevice ? 90 : 180; + } + else if (roughEqual(rotation, 270)) + { + desc.Rotation = portraitDevice ? 180 : 270; } // Hard-coded defaults in case the device doesn't have the data itself. @@ -279,6 +309,10 @@ bool Display::Initialize() return true; } +void Display::Shutdown() +{ +} + bool Display::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) { diff --git a/LibOVR/Src/Displays/OVR_OSX_Display.h b/LibOVR/Src/Displays/OVR_OSX_Display.h index a69c955..d76e8db 100644 --- a/LibOVR/Src/Displays/OVR_OSX_Display.h +++ b/LibOVR/Src/Displays/OVR_OSX_Display.h @@ -53,6 +53,7 @@ struct DisplayDesc Sizei LogicalResolutionInPixels; Sizei NativeResolutionInPixels; Vector2i DesktopDisplayOffset; + int Rotation; }; @@ -112,8 +113,8 @@ public: dd.NativeResolutionInPixels, dd.DesktopDisplayOffset, 0, - 0, - false) + dd.Rotation, + false) { } diff --git a/LibOVR/Src/Displays/OVR_OSX_FocusObserver.h b/LibOVR/Src/Displays/OVR_OSX_FocusObserver.h deleted file mode 100644 index e2f28e3..0000000 --- a/LibOVR/Src/Displays/OVR_OSX_FocusObserver.h +++ /dev/null @@ -1,75 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_FocusObserver.h -Content : Observer for app focus on OSX -Created : August 5, 2014 -Authors : Jordan Tritell - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -OVR_PRIVATE_FILE - -#ifndef OVR_OSX_FocusObserver_h -#define OVR_OSX_FocusObserver_h - -#include "../Kernel/OVR_Threads.h" -#include "../Kernel/OVR_System.h" -#include "../Kernel/OVR_Lockless.h" - -#include "../Service/Service_NetServer.h" - -namespace OVR { namespace OSX{ - - struct FocusNotifierImpl; - -class AppFocusObserver : public SystemSingletonBase -{ - OVR_DECLARE_SINGLETON(AppFocusObserver); - -public: - Lock ListLock; - Array AppList; - Service::NetServerListener *listener; - FocusNotifierImpl* impl; - - void OnProcessFocus(pid_t pid); - void SetListener(Service::NetServerListener *_listener); - - pid_t LastProcessId; - pid_t ActiveProcessId; - void AddProcess(pid_t pid); - void nextProcess(); - void RemoveProcess(pid_t pid); - - -protected: - void onAppFocus(pid_t pid); - - pid_t LastAppFocus; - -}; - - - -}} // namespace OVR, OSX - - -#endif /* OVR_OSX_FocusObserver_h */ - diff --git a/LibOVR/Src/Displays/OVR_OSX_FocusObserver.mm b/LibOVR/Src/Displays/OVR_OSX_FocusObserver.mm deleted file mode 100644 index 3dd77a8..0000000 --- a/LibOVR/Src/Displays/OVR_OSX_FocusObserver.mm +++ /dev/null @@ -1,245 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_FocusObserver.mm -Content : Observer for app focus on OSX -Created : August 5, 2014 -Authors : Jordan Tritell - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -OVR_PRIVATE_FILE - -#include "OVR_OSX_FocusObserver.h" - -#include "../Service/Service_NetServer.h" -#include "OVR_DisplayEnumerator.h" - -#include - -OVR_DEFINE_SINGLETON(OVR::OSX::AppFocusObserver); - -extern bool ServiceRunningFlag; - -@interface FocusNotifier : NSObject { - NSWindow *window; -} - -- (void)start; - -@property (assign) IBOutlet NSWindow *window; - -@end - - -@implementation FocusNotifier - -@synthesize window; - -- (void) addActivationObserver -{ - //subscribe to focus notifications from the workspace - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self - selector:@selector(activated:) - name:NSWorkspaceDidActivateApplicationNotification - object:nil]; - - //subscribe to termination notifications from the workspace - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self - selector:@selector(terminated:) - name:NSWorkspaceDidTerminateApplicationNotification - object:nil]; -} - --(void) activated:(NSNotification *)notification -{ - NSRunningApplication *app = [[notification userInfo] objectForKey:@"NSWorkspaceApplicationKey"]; - pid_t pid = [app processIdentifier]; - OVR::OSX::AppFocusObserver::GetInstance()->OnProcessFocus(pid); - // NSLog(@"Activated: %@", [activatedApp bundleIdentifier]); -} - --(void) terminated:(NSNotification *)notification -{ - NSRunningApplication *app = [[notification userInfo] objectForKey:@"NSWorkspaceApplicationKey"]; - pid_t pid = [app processIdentifier]; - OVR::OSX::AppFocusObserver::GetInstance()->RemoveProcess(pid); - // NSLog(@"Activated: %@", [activatedApp bundleIdentifier]); -} - -- (void)start -{ - //initialize with relevant variables - [self addActivationObserver]; -} - -@end - - -namespace OVR { namespace OSX{ - -struct FocusNotifierImpl -{ - FocusNotifier* wrapped; -}; - -AppFocusObserver::AppFocusObserver(): - impl(new FocusNotifierImpl), - listener(NULL) -{ - //initialize with correct values - impl->wrapped = [[FocusNotifier alloc] init]; - [impl->wrapped start]; - ActiveProcessId = 0; -} - -AppFocusObserver::~AppFocusObserver() -{ - [impl->wrapped dealloc]; - delete impl; -} - -void AppFocusObserver::SetListener(Service::NetServerListener *_listener) -{ - listener = _listener; -} - -void AppFocusObserver::OnSystemDestroy() -{ -} - -void AppFocusObserver::OnProcessFocus(pid_t pid) -{ - // If the process changed, - if (pid != LastProcessId) - { - LastProcessId = pid; - - Lock::Locker locker(&ListLock); - - // Find the process id in the list - const int count = AppList.GetSizeI(); - for (int i = 0; i < count; ++i) - { - // If it is a rift process, - if (AppList[i] == pid) - { - onAppFocus(pid); - OVR_DEBUG_LOG(("[AppFocusObserver] Oculus Process getting focus: pid=%d", pid)); - return; - } - } - - OVR_DEBUG_LOG(("[AppFocusObserver] Focus change: %d (non-Oculus process)", pid)); - } -} - -void AppFocusObserver::AddProcess(pid_t pid) -{ - Lock::Locker locker(&ListLock); - - // If it already exists in the array, - const int count = AppList.GetSizeI(); - for (int i = 0; i < count; ++i) - { - // If we found it, - if (AppList[i] == pid) - { - return; - } - } - - // If the process being added is already in focus, - if (pid == LastProcessId) - { - // Set the active process - OVR_DEBUG_LOG(("[AppFocusObserver] AddProcess: Recognizing the newly added process as in-focus pid=%d", pid)); - } - - // Add it to the list - AppList.PushBack(pid); -} - -void AppFocusObserver::nextProcess() -{ - Lock::Locker locker(&ListLock); - - int count = AppList.GetSizeI(); - - // Pick the next available rift process - if (count > 0) - { - ActiveProcessId = AppList[0]; - OVR_DEBUG_LOG(("[AppFocusObserver] NextProcess: Switching active rift process to pid=%d", ActiveProcessId)); - onAppFocus(ActiveProcessId); - return; - } - - // No process to use - onAppFocus(ActiveProcessId); - OVR_DEBUG_LOG(("[AppFocusObserver] NextProcess: No remaining rift processes")); -} - - -void AppFocusObserver::onAppFocus(pid_t pid) -{ - // Note: This is not necessarily the same as the FocusState->ActiveProcessId. - - ActiveProcessId = pid; - - if (ActiveProcessId == 0) return; - - if (pid != LastAppFocus) - { - LastAppFocus = pid; - if(listener){ - listener->onFocusChange(pid); - } -// FocusSubject->Call(pid); - } -} - -void AppFocusObserver::RemoveProcess(pid_t pid) -{ - Lock::Locker locker(&ListLock); - - // Find the pid in the app list: - const int count = AppList.GetSizeI(); - for (int i = 0; i < count; ++i) - { - // If the app was found, - if (AppList[i] == pid) - { - // Remove from list here - AppList.RemoveAtUnordered(i); - - // If the removed process is the active one, - if (ActiveProcessId == pid) - { - OVR_DEBUG_LOG(("[AppFocusObserver] RemoveProcess: Active process going away")); - // Find a new active process - nextProcess(); - } - - break; - } - } -} -}} //namespace OVR::OSX - diff --git a/LibOVR/Src/Displays/OVR_OSX_FocusReader.h b/LibOVR/Src/Displays/OVR_OSX_FocusReader.h deleted file mode 100644 index dbfe9f6..0000000 --- a/LibOVR/Src/Displays/OVR_OSX_FocusReader.h +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_FocusReader.h -Content : Reader for current app with focus on OSX -Created : August 5, 2014 -Authors : Jordan Tritell - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -OVR_PRIVATE_FILE - -#ifndef OVR_OSX_FocusReader_h -#define OVR_OSX_FocusReader_h - -#import - -@interface FocusReader : NSObject { - NSWindow *window; -} - -- (void)start; - -@property (assign) IBOutlet NSWindow *window; - -@end - -#endif /* OVR_OSX_FocusReader_h */ - diff --git a/LibOVR/Src/Displays/OVR_OSX_FocusReader.mm b/LibOVR/Src/Displays/OVR_OSX_FocusReader.mm deleted file mode 100644 index bed95d6..0000000 --- a/LibOVR/Src/Displays/OVR_OSX_FocusReader.mm +++ /dev/null @@ -1,75 +0,0 @@ -/************************************************************************************ - -Filename : OVR_OSX_FocusReader.mm -Content : Reader for current app with focus on OSX -Created : August 5, 2014 -Authors : Jordan Tritell - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -OVR_PRIVATE_FILE - -#import "OVR_OSX_FocusReader.h" -#import "OVR_OSX_FocusObserver.h" - -@implementation FocusReader - -@synthesize window; - -- (void) addActivationObserver -{ - //subscribe to focus notifications from the workspace - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self - selector:@selector(activated:) - name:NSWorkspaceDidActivateApplicationNotification - object:nil]; - - //subscribe to focus notifications from the workspace - [[[NSWorkspace sharedWorkspace] notificationCenter] addObserver:self - selector:@selector(terminated:) - name:NSWorkspaceDidTerminateApplicationNotification - object:nil]; -} - --(void) activated:(NSNotification *)notification -{ - NSRunningApplication *app = [[notification userInfo] objectForKey:@"NSWorkspaceApplicationKey"]; - pid_t pid = [app processIdentifier]; - OVR::OSX::AppFocusObserver::GetInstance()->OnProcessFocus(pid); - // NSLog(@"Activated: %@", [activatedApp bundleIdentifier]); -} - --(void) terminated:(NSNotification *)notification -{ - NSRunningApplication *app = [[notification userInfo] objectForKey:@"NSWorkspaceApplicationKey"]; - pid_t pid = [app processIdentifier]; - OVR::OSX::AppFocusObserver::GetInstance()->RemoveProcess(pid); - // NSLog(@"Activated: %@", [activatedApp bundleIdentifier]); -} - -- (void)start -{ - //initialize with relevant variables - [self addActivationObserver]; -} - -@end - - diff --git a/LibOVR/Src/Displays/OVR_Win32_Display.cpp b/LibOVR/Src/Displays/OVR_Win32_Display.cpp index 677c619..f45dacc 100644 --- a/LibOVR/Src/Displays/OVR_Win32_Display.cpp +++ b/LibOVR/Src/Displays/OVR_Win32_Display.cpp @@ -1,1323 +1,720 @@ -/************************************************************************************ - -Filename : OVR_Win32_Display.cpp -Content : Win32 Display implementation -Created : May 6, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include - -#include "OVR_Win32_Display.h" -#include "OVR_Win32_Dxgi_Display.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef OVR_COMPAT_EDID_VIA_WMI -# pragma comment(lib, "wbemuuid.lib") -#include -#else // OVR_COMPAT_EDID_VIA_WMI -#include -#include -#endif // OVR_COMPAT_EDID_VIA_WMI - -// WIN32_LEAN_AND_MEAN included in OVR_Atomic.h may break 'byte' declaration. -#ifdef WIN32_LEAN_AND_MEAN - typedef unsigned char byte; -#endif - -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_Log.h" - -typedef struct -{ - HANDLE hDevice; - UINT ExpectedWidth; - UINT ExpectedHeight; - HWND hWindow; - bool CompatibilityMode; - bool HideDK1Mode; -} ContextStruct; - -static ContextStruct GlobalDisplayContext = {0}; - - -//------------------------------------------------------------------------------------- -// ***** Display enumeration Helpers - -// THere are two ways to enumerate display: through our driver (DeviceIoControl) -// and through Win32 EnumDisplayMonitors (compatibility mode). - - -namespace OVR { - -ULONG getRiftCount( HANDLE hDevice ) -{ - ULONG riftCount = 0; - DWORD bytesReturned = 0; - - BOOL result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GET_RIFT_COUNT, NULL, 0, - &riftCount, sizeof( ULONG ), &bytesReturned, NULL ); - - if( result ) - return riftCount; - else - return 0; -} - -ULONG getRift( HANDLE hDevice, int index ) -{ - ULONG riftCount = getRiftCount( hDevice ); - DWORD bytesReturned = 0; - BOOL result; - - if( riftCount >= (ULONG)index ) - { - RIFT_STATUS riftStatus[16] = {0}; - - result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GET_RIFT_ARRAY, riftStatus, - riftCount * sizeof( RIFT_STATUS ), &riftCount, - sizeof( ULONG ), &bytesReturned, NULL ); - if( result ) - { - PRIFT_STATUS tmpRift; - unsigned int i; - for( i = 0, tmpRift = riftStatus; i < riftCount; ++i, ++tmpRift ) - { - if( i == (unsigned int)index ) - return tmpRift->childUid; - } - } - else - { - printf("Failed to get array of rift devices\n"); - } - } - - return 0; -} - -#define EDID_LENGTH 0x80 - -#define EDID_HEADER 0x00 -#define EDID_HEADER_END 0x07 - -#define ID_MANUFACTURER_NAME 0x08 -#define ID_MANUFACTURER_NAME_END 0x09 - -#define EDID_STRUCT_VERSION 0x12 -#define EDID_STRUCT_REVISION 0x13 - -#define ESTABLISHED_TIMING_1 0x23 -#define ESTABLISHED_TIMING_2 0x24 -#define MANUFACTURERS_TIMINGS 0x25 - -#define DETAILED_TIMING_DESCRIPTIONS_START 0x36 -#define DETAILED_TIMING_DESCRIPTION_SIZE 18 -#define NO_DETAILED_TIMING_DESCRIPTIONS 4 - -#define DETAILED_TIMING_DESCRIPTION_1 0x36 -#define DETAILED_TIMING_DESCRIPTION_2 0x48 -#define DETAILED_TIMING_DESCRIPTION_3 0x5a -#define DETAILED_TIMING_DESCRIPTION_4 0x6c - -#define MONITOR_NAME 0xfc -#define MONITOR_LIMITS 0xfd -#define MONITOR_SERIAL 0xff - -#define UNKNOWN_DESCRIPTOR -1 -#define DETAILED_TIMING_BLOCK -2 - -#define DESCRIPTOR_DATA 5 - -const byte edid_v1_header[] = { 0x00, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0x00 }; - -const byte edid_v1_descriptor_flag[] = { 0x00, 0x00 }; - - -static int blockType( byte* block ) -{ - if ( !strncmp( (const char*)edid_v1_descriptor_flag, (const char*)block, 2 ) ) - { - // descriptor - if ( block[ 2 ] != 0 ) - return UNKNOWN_DESCRIPTOR; - return block[ 3 ]; - } - else - { - return DETAILED_TIMING_BLOCK; - } -} - -static char* getMonitorName( byte const* block ) -{ - static char name[ 13 ]; - unsigned i; - byte const* ptr = block + DESCRIPTOR_DATA; - - for( i = 0; i < 13; i++, ptr++ ) - { - if ( *ptr == 0xa ) - { - name[ i ] = 0; - return name; - } - - name[ i ] = *ptr; - } - - return name; -} - - -static bool parseEdid( byte* edid, OVR::Win32::DisplayEDID& edidResult ) -{ - unsigned i; - byte* block; - char* monitor_name = "Unknown"; - byte checksum = 0; - - for( i = 0; i < EDID_LENGTH; i++ ) - checksum += edid[ i ]; - - // Bad checksum, fail EDID - if ( checksum != 0 ) - return false; - - if ( strncmp( (const char*)edid+EDID_HEADER, (const char*)edid_v1_header, EDID_HEADER_END+1 ) ) - { - // First bytes don't match EDID version 1 header - return false; - } - - //printf( "\n# EDID version %d revision %d\n", (int)edid[EDID_STRUCT_VERSION],(int)edid[EDID_STRUCT_REVISION] ); - - // Monitor name and timings - - char serialNumber[14]; - memset( serialNumber, 0, 14 ); - - block = edid + DETAILED_TIMING_DESCRIPTIONS_START; - - for( i = 0; i < NO_DETAILED_TIMING_DESCRIPTIONS; i++, - block += DETAILED_TIMING_DESCRIPTION_SIZE ) - { - - if ( blockType( block ) == MONITOR_NAME ) - { - monitor_name = getMonitorName( block ); - } - - if( blockType( block ) == MONITOR_SERIAL ) - { - memcpy( serialNumber, block + 5, 13 ); - break; - } - } - - BYTE vendorString[4] = {0}; - - vendorString[0] = (edid[8] >> 2 & 31) + 64; - vendorString[1] = ((edid[8] & 3) << 3) | (edid[9] >> 5) + 64; - vendorString[2] = (edid[9] & 31) + 64; - - edidResult.ModelNumber = *(UINT16*)&edid[10]; - edidResult.MonitorName = OVR::String(monitor_name); - edidResult.VendorName = OVR::String((const char*)vendorString); - edidResult.SerialNumber = OVR::String(serialNumber); - -#if 0 - printf( "\tIdentifier \"%s\"\n", monitor_name ); - printf( "\tVendorName \"%s\"\n", vendorString ); - printf( "\tModelName \"%s\"\n", monitor_name ); - printf( "\tModelNumber %d\n", modelNumber ); - printf( "\tSerialNumber \"%x\"\n", *serialPointer ); -#endif - - // FIXME: Get timings as well, though they aren't very useful here - // except for the vertical refresh rate, presumably - - return true; -} - -static bool getEdid(HANDLE hDevice, ULONG uid, OVR::Win32::DisplayEDID& edidResult) -{ - ULONG riftCount = 0; - DWORD bytesReturned = 0; - RIFT_STATUS riftStatus[16] = {0}; - - BOOL result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GET_RIFT_COUNT, NULL, 0, - &riftCount, sizeof( ULONG ), &bytesReturned, NULL ); - - if (!result) - { - return false; - } - - result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GET_RIFT_ARRAY, &riftStatus, - riftCount * sizeof( RIFT_STATUS ), &riftCount, sizeof(ULONG), - &bytesReturned, NULL ); - if (!result) - { - return false; - } - - for (ULONG i = 0; i < riftCount; ++i) - { - ULONG riftUid = riftStatus[i].childUid; - if (riftUid == uid) - { - char edidBuffer[512]; - - result = DeviceIoControl(hDevice, IOCTL_RIFTMGR_GETEDID, &riftUid, sizeof(ULONG), - edidBuffer, 512, &bytesReturned, NULL); - - if (result) - { - if (parseEdid((byte*)edidBuffer, edidResult)) - { - return true; - } - else - { - OVR_DEBUG_LOG(("[Win32Display] WARNING: The driver was not able to return EDID for a display")); - } - } - - break; - } - } - - return false; -} - - -// Used to capture all the active monitor handles -struct MonitorSet -{ - enum { MaxMonitors = 8 }; - HMONITOR Monitors[MaxMonitors]; - int MonitorCount; - int PrimaryCount; -}; - -static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData) -{ - MonitorSet* monitorSet = (MonitorSet*)dwData; - if (monitorSet->MonitorCount >= MonitorSet::MaxMonitors) - return FALSE; - - monitorSet->Monitors[monitorSet->MonitorCount] = hMonitor; - monitorSet->MonitorCount++; - return TRUE; -}; - -#ifdef OVR_COMPAT_EDID_VIA_WMI - -static bool getCompatDisplayEDID( WCHAR* displayName, String& serialNumberStr, String& userFriendlyNameStr ) -{ - IWbemLocator *pLoc = NULL; - IWbemServices *pSvc = NULL; - HRESULT hres; - - static bool initialized = false; - static bool selfInitialized = true; - if (!initialized) - { - hres = CoInitializeEx(0, COINIT_MULTITHREADED); - if (FAILED(hres)) - { - - LogError("{ERR-082} [Display] WARNING: Failed to initialize COM library. Error code = 0x%x", hres); - OVR_ASSERT(false); - return false; - } - - hres = CoInitializeSecurity( - NULL, - -1, // COM authentication - NULL, // Authentication services - NULL, // Reserved - RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication - RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation - NULL, // Authentication info - EOAC_NONE, // Additional capabilities - NULL // Reserved - ); - - if (FAILED(hres)) - { - LogError("{ERR-083} [Display] WARNING: Failed to initialize security. Error code = 0x%x", hres); - OVR_ASSERT(false); - selfInitialized = false; - } - - initialized = true; - } - - hres = CoCreateInstance( - CLSID_WbemLocator, - 0, - CLSCTX_INPROC_SERVER, - IID_IWbemLocator, (LPVOID *)&pLoc); - - if (FAILED(hres)) - { - LogError("{ERR-084} [Display] WARNING: Failed to create IWbemLocator object.Err code = 0x%x", hres); - OVR_ASSERT(false); - return false; - } - - BSTR AbackB = SysAllocString(L"root\\WMI"); - // Connect to the root\cimv2 namespace with - // the current user and obtain pointer pSvc - // to make IWbemServices calls. - hres = pLoc->ConnectServer( - AbackB, // Object path of WMI namespace - NULL, // User name. NULL = current user - NULL, // User password. NULL = current - 0, // Locale. NULL indicates current - NULL, // Security flags. - 0, // Authority (e.g. Kerberos) - 0, // Context object - &pSvc // pointer to IWbemServices proxy - ); - SysFreeString(AbackB); - - if (FAILED(hres)) - { - LogError("{ERR-085} [Display] WARNING: Could not connect to root\\WMI. Error code = 0x%x", hres); - OVR_ASSERT(false); - pLoc->Release(); - return false; - } - - hres = CoSetProxyBlanket( - pSvc, // Indicates the proxy to set - RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx - RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx - NULL, // Server principal name - RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx - RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx - NULL, // client identity - EOAC_NONE // proxy capabilities - ); - - if (FAILED(hres)) - { - LogError("{ERR-086} [Display] WARNING: Could not set proxy blanket. Error code = 0x%x", hres); - OVR_ASSERT(false); - pSvc->Release(); - pLoc->Release(); - return false; - } - - - BSTR wql = SysAllocString(L"WQL"); - BSTR select = SysAllocString(L"SELECT * FROM WmiMonitorID"); - IEnumWbemClassObject* pEnumerator = NULL; - hres = pSvc->ExecQuery( - wql, - select, - WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, - NULL, - &pEnumerator); - SysFreeString(wql); - SysFreeString(select); - - if (FAILED(hres)) - { - LogError("{ERR-087} [Display] WARNING: Query for operating system name failed. Error code = 0x%x", hres); - OVR_ASSERT(false); - pSvc->Release(); - pLoc->Release(); - return false; - } - - int enumeratedCount = 0; - bool found = false; - - IWbemClassObject *pclsObj = 0; - while (pEnumerator) - { - ULONG uReturn = 0; - HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); - - if (FAILED(hr) || !uReturn) - { - break; - } - - ++enumeratedCount; - - VARIANT vtProp; - hr = pclsObj->Get(L"InstanceName", 0, &vtProp, 0, 0); - - WCHAR* instanceName = vtProp.bstrVal; - WCHAR* nextToken = NULL; - if (SUCCEEDED(hr) && - wcstok_s(instanceName, L"\\", &nextToken) != NULL) - { - WCHAR* aToken = wcstok_s(NULL, L"\\", &nextToken); - - if (aToken != NULL) - { - VariantClear(&vtProp); - - if (wcscmp(aToken, displayName) != 0) - { - pclsObj->Release(); - continue; - } - - // Read serial - - hr = pclsObj->Get(L"SerialNumberID", 0, &vtProp, 0, 0); - - if (SUCCEEDED(hr)) - { - if (vtProp.vt != VT_NULL && vtProp.parray != NULL) - { - static const int MaxSerialBytes = 14; - char serialNumber[MaxSerialBytes] = { 0 }; - - UINT32* serialArray = (UINT32*)vtProp.parray->pvData; - for (int i = 0; i < MaxSerialBytes; ++i) - { - serialNumber[i] = (BYTE)(serialArray[i] & 0xff); - } - - serialNumber[sizeof(serialNumber)-1] = '\0'; - serialNumberStr = serialNumber; - } - else - { - LogError("{ERR-088} [Display] WARNING: Wrong data format for SerialNumberID"); - } - - VariantClear(&vtProp); - } - else - { - LogError("{ERR-089} [Display] WARNING: Failure getting display SerialNumberID: %d", (int)hr); - } - - // Read length of name - - int userFriendlyNameLen = 0; - - hr = pclsObj->Get(L"UserFriendlyNameLength", 0, &vtProp, 0, 0); - - if (SUCCEEDED(hr)) - { - if (vtProp.vt != VT_NULL) - { - userFriendlyNameLen = vtProp.iVal; - - if (userFriendlyNameLen <= 0) - { - userFriendlyNameLen = 0; - - LogError("{ERR-090} [Display] WARNING: UserFriendlyNameLength = 0"); - } - } - else - { - LogError("{ERR-091} [Display] WARNING: Wrong data format for UserFriendlyNameLength"); - } - - VariantClear(&vtProp); - } - else - { - LogError("{ERR-092} [Display] WARNING: Failure getting display UserFriendlyNameLength: %d", (int)hr); - } - - // Read name - - hr = pclsObj->Get(L"UserFriendlyName", 0, &vtProp, 0, 0); - - if (SUCCEEDED(hr) && userFriendlyNameLen > 0) - { - if (vtProp.vt != VT_NULL && vtProp.parray != NULL) - { - static const int MaxNameBytes = 64; - char userFriendlyName[MaxNameBytes] = { 0 }; - - UINT32* nameArray = (UINT32*)vtProp.parray->pvData; - for (int i = 0; i < MaxNameBytes && i < userFriendlyNameLen; ++i) - { - userFriendlyName[i] = (BYTE)(nameArray[i] & 0xff); - } - - userFriendlyName[sizeof(userFriendlyName)-1] = '\0'; - userFriendlyNameStr = userFriendlyName; - } - else - { - // See: https://developer.oculusvr.com/forums/viewtopic.php?f=34&t=10961 - // This can happen if someone has an EDID override in the registry. - LogError("{ERR-093} [Display] WARNING: Wrong data format for UserFriendlyName"); - } - - VariantClear(&vtProp); - } - else - { - LogError("{ERR-094} [Display] WARNING: Failure getting display UserFriendlyName: %d", (int)hr); - } - } - - found = true; - pclsObj->Release(); - break; - } - - pclsObj->Release(); - } - - HMODULE hModule = GetModuleHandleA("wbemuuid"); - if (hModule) - { - DisableThreadLibraryCalls(hModule); - } - - pSvc->Release(); - pLoc->Release(); - pEnumerator->Release(); - - if (!found) - { - LogError("{ERR-095} [Display] WARNING: Unable to enumerate the rift via WMI (found %d monitors). This is not normally an issue. Running as a user with Administrator privileges has fixed this problem in the past.", enumeratedCount); - OVR_ASSERT(false); - } - - return found; -} - -#else // OVR_COMPAT_EDID_VIA_WMI - -#define NAME_SIZE 128 - -DEFINE_GUID(GUID_CLASS_MONITOR, - 0x4d36e96e, 0xe325, 0x11ce, 0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, - 0x03, 0x18); - -static void truncateNonalphanum(char* str, int len) -{ - for (int i = 0; i < len; ++i) - { - char ch = str[i]; - - if ((ch < 'A' || ch > 'Z') && - (ch < 'a' || ch > 'z') && - (ch < '0' || ch > '9') && - ch != ' ') - { - str[i] = '\0'; - break; - } - } -} - -static bool AccessDeviceRegistry(IN HDEVINFO devInfo, IN PSP_DEVINFO_DATA devInfoData, - const WCHAR* displayName, String& serialNumberStr, String& userFriendlyNameStr) -{ - // Match hardware id to display name - WCHAR hardwareId[128]; - if (!SetupDiGetDeviceRegistryProperty( - devInfo, - devInfoData, - SPDRP_HARDWAREID, - NULL, - (PBYTE)hardwareId, - sizeof(hardwareId), - NULL)) - { - LogError("{ERR-096} [Display] WARNING: SetupDiGetDeviceRegistryProperty for SPDRP_HARDWAREID failed. LastErr=%d", GetLastError()); - OVR_ASSERT(false); - return false; - } - hardwareId[127] = 0; - - // If the hardware id did not match, - if (!wcsstr(hardwareId, displayName)) - { - // Stop here - return false; - } - - // Grab hardware info registry key - HKEY hDevRegKey = SetupDiOpenDevRegKey( - devInfo, - devInfoData, - DICS_FLAG_GLOBAL, - 0, - DIREG_DEV, - KEY_READ); // Only read permissions so it can be run without Administrator privs - - if (hDevRegKey == INVALID_HANDLE_VALUE) - { - LogError("{ERR-097} [Display] WARNING: SetupDiOpenDevRegKey failed. LastErr=%d", GetLastError()); - OVR_ASSERT(false); - return false; - } - - // Enumerate keys in registry - bool found = false; - - // For each key, - for (int i = 0;; i++) - { - BYTE EDIDdata[1024]; - DWORD edidsize = sizeof(EDIDdata); - - DWORD dwType, ActualValueNameLength = NAME_SIZE; - CHAR valueName[NAME_SIZE]; - - // Read the key value data - LSTATUS retValue = RegEnumValueA( - hDevRegKey, - i, - &valueName[0], - &ActualValueNameLength, - NULL, - &dwType, - EDIDdata, - &edidsize); - - // If no more items in the enumeration, - if (retValue == ERROR_NO_MORE_ITEMS) - { - // Stop here - break; - } - - // If the request failed, - if (FAILED(retValue)) - { - LogError("{ERR-098} [Display] WARNING: RegEnumValueA failed to read a key. LastErr=%d", retValue); - OVR_ASSERT(false); - } - else if (0 == strcmp(valueName, "EDID")) // Value is EDID: - { - // Tested working for DK1 and DK2: - - char friendlyString[9]; - memcpy(friendlyString, EDIDdata + 77, 8); - truncateNonalphanum(friendlyString, 8); - friendlyString[8] = '\0'; - - char edidString[14]; - memcpy(edidString, EDIDdata + 95, 13); - truncateNonalphanum(edidString, 13); - edidString[13] = '\0'; - - serialNumberStr = edidString; - userFriendlyNameStr = friendlyString; - - found = true; - break; - } - } - - RegCloseKey(hDevRegKey); - - return found; -} - -static bool getCompatDisplayEDID(const WCHAR* displayName, String& serialNumberStr, String& userFriendlyNameStr) -{ - HDEVINFO devInfo = NULL; - - devInfo = SetupDiGetClassDevsEx( - &GUID_CLASS_MONITOR, //class GUID - NULL, //enumerator - NULL, //HWND - DIGCF_PRESENT, // Flags //DIGCF_ALLCLASSES| - NULL, // device info, create a new one. - NULL, // machine name, local machine - NULL);// reserved - - if (NULL == devInfo) - { - return false; - } - - DWORD lastError = 0; - - // For each display, - for (int i = 0;; i++) - { - SP_DEVINFO_DATA devInfoData = {}; - devInfoData.cbSize = sizeof(devInfoData); - - // Grab device info - if (SetupDiEnumDeviceInfo(devInfo, i, &devInfoData)) - { - // Access device info from registry - if (AccessDeviceRegistry(devInfo, &devInfoData, displayName, serialNumberStr, userFriendlyNameStr)) - { - return true; - } - } - else - { - lastError = GetLastError(); - - // If no more items found, - if (lastError != ERROR_NO_MORE_ITEMS) - { - LogError("{ERR-099} [Display] WARNING: SetupDiEnumDeviceInfo failed. LastErr=%d", lastError); - OVR_ASSERT(false); - } - - break; - } - } - - LogError("{ERR-100} [Display] WARNING: SetupDiEnumDeviceInfo did not return the rift display. LastErr=%d", lastError); - OVR_ASSERT(false); - - return false; -} - -#endif // OVR_COMPAT_EDID_VIA_WMI - -// This is function that's used -bool anyRiftsInExtendedMode() -{ - bool result = false; - - MonitorSet monitors; - monitors.MonitorCount = 0; - // Get all the monitor handles - EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors); - - DISPLAY_DEVICE dd, ddm; - UINT i, j; - - for( i = 0; - (ZeroMemory(&dd, sizeof(dd)), dd.cb = sizeof(dd), - EnumDisplayDevices(0, i, &dd, 0)) != 0; i++ ) - { - for( j = 0; - (ZeroMemory(&ddm, sizeof(ddm)), ddm.cb = sizeof(ddm), - EnumDisplayDevices(dd.DeviceName, j, &ddm, 0)) != 0; j++ ) - { - // Our monitor hardware has string "RTD2205" in it - // Nate's device "CVT0003" - if( wcsstr(ddm.DeviceID, L"RTD2205") || - wcsstr(ddm.DeviceID, L"CVT0003") || - wcsstr(ddm.DeviceID, L"MST0030") || - wcsstr(ddm.DeviceID, L"OVR00") ) // Part of Oculus EDID. - { - result = true; - } - } - } - - return result; -} - -static int discoverExtendedRifts(OVR::Win32::DisplayDesc* descriptorArray, int inputArraySize, bool includeEDID) -{ - static bool reportDiscovery = true; - - int result = 0; - - MonitorSet monitors; - monitors.MonitorCount = 0; - // Get all the monitor handles - EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, (LPARAM)&monitors); - - DISPLAY_DEVICE dd, ddm; - UINT i, j; - - for (i = 0; - (ZeroMemory(&dd, sizeof(dd)), dd.cb = sizeof(dd), - EnumDisplayDevices(0, i, &dd, 0)) != 0; i++) - { - for (j = 0; - (ZeroMemory(&ddm, sizeof(ddm)), ddm.cb = sizeof(ddm), - EnumDisplayDevices(dd.DeviceName, j, &ddm, 0)) != 0; j++) - { - if( result >= inputArraySize ) - return result; - - // Our monitor hardware has string "RTD2205" in it - // Nate's device "CVT0003" - if (wcsstr(ddm.DeviceID, L"RTD2205") || - wcsstr(ddm.DeviceID, L"CVT0003") || - wcsstr(ddm.DeviceID, L"MST0030") || - wcsstr(ddm.DeviceID, L"OVR00") ) // Part of Oculus EDID. - { - String deviceId(ddm.DeviceID); - String displayDeviceName(ddm.DeviceName); - Vector2i desktopOffset(0, 0); - Sizei monitorResolution(1280, 800); - - // Make a device type guess - HmdTypeEnum deviceTypeGuess = HmdType_Unknown; - if (wcsstr(ddm.DeviceID, L"OVR0003")) - { - // DK2 prototypes and variants - deviceTypeGuess = HmdType_DK2; - // Could also be: - // HmdType_CrystalCoveProto - } - else if (wcsstr(ddm.DeviceID, L"OVR0002")) - { // HD Prototypes - deviceTypeGuess = HmdType_DKHDProto; - // Could also be: - // HmdType_DKHD2Proto - // HmdType_DKHDProto566Mi - } - else if (wcsstr(ddm.DeviceID, L"OVR0001")) - { // DK1 - deviceTypeGuess = HmdType_DK1; - } - else if (wcsstr(ddm.DeviceID, L"OVR00")) - { // Future Oculus HMD devices - deviceTypeGuess = HmdType_Unknown; - } - else - { - deviceTypeGuess = HmdType_DKProto; - } - - // Find the matching MONITORINFOEX for this device so we can get the - // screen coordinates - MONITORINFOEX info; - for (int m=0; m < monitors.MonitorCount; m++) - { - info.cbSize = sizeof(MONITORINFOEX); - GetMonitorInfo(monitors.Monitors[m], &info); - if (_tcsstr(ddm.DeviceName, info.szDevice) == ddm.DeviceName) - { // If the device name starts with the monitor name - // then we found the matching DISPLAY_DEVICE and MONITORINFO - // so we can gather the monitor coordinates - desktopOffset = Vector2i(info.rcMonitor.left, info.rcMonitor.top); - break; - } - } - - WCHAR* instanceBuffer = (WCHAR*)calloc(wcslen(ddm.DeviceID) + 1, sizeof(WCHAR)); - wcscpy_s(instanceBuffer, wcslen(ddm.DeviceID) + 1, ddm.DeviceID); - WCHAR* instanceName = instanceBuffer; - WCHAR* nextToken = NULL; - if (wcstok_s(instanceName, L"\\", &nextToken)) - { - WCHAR* aToken = wcstok_s(NULL, L"\\", &nextToken); - - if (aToken) - { - String serialNumberStr, userFriendlyNameStr; - if (!includeEDID || getCompatDisplayEDID(aToken, serialNumberStr, userFriendlyNameStr)) - { - // Set descriptor - OVR::Win32::DisplayDesc& desc = descriptorArray[result++]; - - // If not including EDID, - if (!includeEDID) - { - // If DK2 id, - if (wcsstr(ddm.DeviceID, L"OVR0003")) - { - userFriendlyNameStr = "Rift DK2"; - } - else // Assume DK1 for now: - { - userFriendlyNameStr = "Rift DK1"; - } - } - - desc.DeviceTypeGuess = deviceTypeGuess; - desc.DisplayID = displayDeviceName; - desc.ModelName = userFriendlyNameStr; - desc.EdidSerialNumber = serialNumberStr; - desc.LogicalResolutionInPixels = monitorResolution; - desc.DesktopDisplayOffset = desktopOffset; - - // Hard-coded defaults in case the device doesn't have the data itself. - // DK2 prototypes (0003) or DK HD Prototypes (0002) - if (wcsstr(ddm.DeviceID, L"OVR0003") || wcsstr(ddm.DeviceID, L"OVR0002")) - { - desc.LogicalResolutionInPixels = Sizei(1920, 1080); - desc.NativeResolutionInPixels = Sizei(1080, 1920); - } - else - { - desc.LogicalResolutionInPixels = monitorResolution; - desc.NativeResolutionInPixels = monitorResolution; - } - } - } - } - - if (reportDiscovery) - { - // Only report once per run - OVR_DEBUG_LOG_TEXT(("Display Found %s - %s\n", - deviceId.ToCStr(), displayDeviceName.ToCStr())); - reportDiscovery = false; - } - - free(instanceBuffer); - - break; - } - } - } - - return result; -} - - -//------------------------------------------------------------------------------------- -// ***** Display - -bool Display::InCompatibilityMode( bool displaySearch ) -{ - bool result = false; - if( displaySearch ) - { - OVR::Win32::DisplayDesc displayArray[8]; - - int extendedRiftCount = discoverExtendedRifts(displayArray, 8, false); - if( extendedRiftCount ) - { - result = true; - } - else - { - result = GlobalDisplayContext.CompatibilityMode; - } - } - else - { - result = GlobalDisplayContext.CompatibilityMode; - } - - return result; -} - -#define OVR_FLAG_COMPATIBILITY_MODE 1 -#define OVR_FLAG_HIDE_DK1 2 - -bool Display::Initialize() -{ - HANDLE hDevice = INVALID_HANDLE_VALUE; - - if (GlobalDisplayContext.hDevice == 0) - { - hDevice = CreateFile( L"\\\\.\\ovr_video" , - GENERIC_READ | GENERIC_WRITE, NULL, - NULL, OPEN_EXISTING, NULL, NULL); - } - else - { // The device has already been created - hDevice = GlobalDisplayContext.hDevice; - } - - if (hDevice != NULL && hDevice != INVALID_HANDLE_VALUE) - { - GlobalDisplayContext.hDevice = hDevice; - GlobalDisplayContext.CompatibilityMode = false; - - DWORD bytesReturned = 0; - LONG compatiblityResult = OVR_STATUS_SUCCESS; - - BOOL result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GETCOMPATIBILITYMODE, NULL, 0, - &compatiblityResult, sizeof( LONG ), &bytesReturned, NULL ); - if (result) - { - GlobalDisplayContext.CompatibilityMode = (compatiblityResult & OVR_FLAG_COMPATIBILITY_MODE) != 0; - GlobalDisplayContext.HideDK1Mode = (compatiblityResult & OVR_FLAG_HIDE_DK1) != 0; - } - else - { - // If calling our driver fails in any way, assume compatibility mode as well - GlobalDisplayContext.CompatibilityMode = true; - } - - if (!GlobalDisplayContext.CompatibilityMode) - { - Ptr searchHandle = *Display::GetDisplaySearchHandle(); - - // If a display is actually connected, bring up the shim layers so we can actually use it - if (GetDisplayCount(searchHandle) > 0) - { - // FIXME: Initializing DX9 with landscape numbers rather than portrait - GlobalDisplayContext.ExpectedWidth = 1080; - GlobalDisplayContext.ExpectedHeight = 1920; - } - else - { - GlobalDisplayContext.CompatibilityMode = true; - } - - } - } - else - { - GlobalDisplayContext.CompatibilityMode = true; - } - - return true; -} - -bool Display::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) -{ - if (GlobalDisplayContext.hDevice == NULL) - { - driverInstalled = false; - compatMode = true; - hideDK1Mode = false; - } - else - { - driverInstalled = true; - compatMode = GlobalDisplayContext.CompatibilityMode; - hideDK1Mode = GlobalDisplayContext.HideDK1Mode; - } - - return true; -} - -bool Display::SetDriverMode(bool compatMode, bool hideDK1Mode) -{ - // If device is not initialized, - if (GlobalDisplayContext.hDevice == NULL) - { - OVR_ASSERT(false); - return false; - } - - // If no change, - if ((compatMode == GlobalDisplayContext.CompatibilityMode) && - (hideDK1Mode == GlobalDisplayContext.HideDK1Mode)) - { - return true; - } - - LONG mode_flags = 0; - if (compatMode) - { - mode_flags |= OVR_FLAG_COMPATIBILITY_MODE; - } - if (hideDK1Mode) - { - mode_flags |= OVR_FLAG_HIDE_DK1; - } - - DWORD bytesReturned = 0; - LONG err = 1; - - if (!DeviceIoControl(GlobalDisplayContext.hDevice, - IOCTL_RIFTMGR_SETCOMPATIBILITYMODE, - &mode_flags, - sizeof(LONG), - &err, - sizeof(LONG), - &bytesReturned, - NULL) || - (err != 0 && err != -3)) - { - LogError("{ERR-001w} [Win32Display] Unable to set device mode to (compat=%d dk1hide=%d): err=%d", - (int)compatMode, (int)hideDK1Mode, (int)err); - return false; - } - - OVR_DEBUG_LOG(("[Win32Display] Set device mode to (compat=%d dk1hide=%d)", - (int)compatMode, (int)hideDK1Mode)); - - GlobalDisplayContext.HideDK1Mode = hideDK1Mode; - GlobalDisplayContext.CompatibilityMode = compatMode; - return true; -} - -DisplaySearchHandle* Display::GetDisplaySearchHandle() -{ - return new Win32::Win32DisplaySearchHandle(); -} - -// FIXME: The handle parameter will be used to unify GetDisplayCount and GetDisplay calls -// The handle will be written to the 64-bit value pointed and will store the enumerated -// display list. This will allow the indexes to be meaningful between obtaining -// the count. With a single handle the count should be stable -int Display::GetDisplayCount(DisplaySearchHandle* handle, bool extended, bool applicationOnly, bool extendedEDIDSerials) -{ - static int extendedCount = -1; - static int applicationCount = -1; - - Win32::Win32DisplaySearchHandle* localHandle = (Win32::Win32DisplaySearchHandle*)handle; - - if( localHandle == NULL ) - return 0; - - if( extendedCount == -1 || extended ) - { - extendedCount = discoverExtendedRifts(localHandle->cachedDescriptorArray, 16, extendedEDIDSerials); - } - - localHandle->extended = true; - localHandle->extendedDisplayCount = extendedCount; - int totalCount = extendedCount; - - if( applicationCount == -1 || applicationOnly ) - { - applicationCount = getRiftCount(GlobalDisplayContext.hDevice); - localHandle->application = true; - } - - totalCount += applicationCount; - localHandle->applicationDisplayCount = applicationCount; - localHandle->displayCount = totalCount; - - return totalCount; -} - -Ptr Display::GetDisplay(int index, DisplaySearchHandle* handle) -{ - Ptr result; - - if( index < 0 ) - return result; - - Win32::Win32DisplaySearchHandle* localHandle = (Win32::Win32DisplaySearchHandle*)handle; - - if( localHandle == NULL ) - return NULL; - - if (localHandle->extended) - { - if (index >= 0 && index < (int)localHandle->extendedDisplayCount) - { - return *new Win32::Win32DisplayGeneric(localHandle->cachedDescriptorArray[index]); - } - - index -= localHandle->extendedDisplayCount; - } - - if(localHandle->application) - { - if (index >= 0 && index < (int)getRiftCount(GlobalDisplayContext.hDevice)) - { - ULONG riftChildId = getRift(GlobalDisplayContext.hDevice, index); - Win32::DisplayEDID dEdid; - - if (!getEdid(GlobalDisplayContext.hDevice, riftChildId, dEdid)) - { - return NULL; - } - - // FIXME: We have the EDID. Let's just use that instead. - uint32_t nativeWidth = 1080, nativeHeight = 1920; - uint32_t logicalWidth = 1920, logicalHeight = 1080; - uint32_t rotation = 0; - - switch (dEdid.ModelNumber) - { - case 0: - case 1: - nativeWidth = 1280; - nativeHeight = 800; - logicalWidth = nativeWidth; - logicalHeight = nativeHeight; - break; - case 2: - case 3: - default: - rotation = 90; - break; - } - - HmdTypeEnum deviceTypeGuess = HmdType_Unknown; - switch (dEdid.ModelNumber) - { - case 3: deviceTypeGuess = HmdType_DK2; break; - case 2: deviceTypeGuess = HmdType_DKHDProto; break; - case 1: deviceTypeGuess = HmdType_DK1; break; - default: break; - } - - result = *new Win32::Win32DisplayDriver( - deviceTypeGuess, - "", - dEdid.MonitorName, - dEdid.SerialNumber, - Sizei(logicalWidth, logicalHeight), - Sizei(nativeWidth, nativeHeight), - Vector2i(0), - dEdid, - GlobalDisplayContext.hDevice, - riftChildId, - rotation); - } - } - return result; -} - -Display::MirrorMode Win32::Win32DisplayDriver::SetMirrorMode( Display::MirrorMode newMode ) -{ - return newMode; -} - -static bool SetDisplayPower(HANDLE hDevice, ULONG childId, int mode) -{ - ULONG_PTR longArray[2]; - - longArray[0] = childId; - longArray[1] = mode; - - ULONG localResult = 0; - DWORD bytesReturned = 0; - - BOOL result = DeviceIoControl(hDevice, - IOCTL_RIFTMGR_DISPLAYPOWER, - longArray, - 2 * sizeof(ULONG_PTR), - &localResult, - sizeof(ULONG), - &bytesReturned, - NULL); - - // Note: bytesReturned does not seem to be set - return result != FALSE /* && bytesReturned == sizeof(ULONG) */ && mode == (int)localResult; -} - -bool Win32::Win32DisplayDriver::SetDisplaySleep(bool sleep) -{ - return SetDisplayPower(hDevice, ChildId, sleep ? 2 : 1); -} - - -} // namespace OVR +/************************************************************************************ + +Filename : OVR_Win32_Display.cpp +Content : Win32 Display implementation +Created : May 6, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Kernel/OVR_Win32_IncludeWindows.h" + +#include "OVR_Win32_Display.h" +#include "OVR_Win32_Dxgi_Display.h" +#include "OVR_Win32_ShimFunctions.h" +#include "Util/Util_Direct3D.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#pragma comment(lib, "setupapi.lib") // SetupDiGetDeviceRegistryProperty et al +#pragma comment(lib, "dxgi.lib") // D3D11 adapter/output enumeration + +// WIN32_LEAN_AND_MEAN included in OVR_Atomic.h may break 'byte' declaration. +#ifdef WIN32_LEAN_AND_MEAN + typedef unsigned char byte; +#endif + +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Log.h" + +typedef struct +{ + HANDLE hDevice; + UINT ExpectedWidth; + UINT ExpectedHeight; + HWND hWindow; + bool CompatibilityMode; + bool HideDK1Mode; +} ContextStruct; + +static ContextStruct GlobalDisplayContext = {}; + + +//------------------------------------------------------------------------------------- +// ***** Display enumeration Helpers + +// THere are two ways to enumerate display: through our driver (DeviceIoControl) +// and through Win32 EnumDisplayMonitors (compatibility mode). + + +namespace OVR { + + +//----------------------------------------------------------------------------- +// Direct Mode + +ULONG getRiftCount( HANDLE hDevice ) +{ + ULONG riftCount = 0; + DWORD bytesReturned = 0; + + BOOL result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GET_RIFT_COUNT, nullptr, 0, + &riftCount, sizeof( ULONG ), &bytesReturned, nullptr ); + + if( result ) + return riftCount; + else + return 0; +} + +ULONG getRift( HANDLE hDevice, int index ) +{ + ULONG riftCount = getRiftCount( hDevice ); + DWORD bytesReturned = 0; + BOOL result; + + if( riftCount >= (ULONG)index ) + { + RIFT_STATUS riftStatus[16] = {0}; + + result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GET_RIFT_ARRAY, riftStatus, + riftCount * sizeof( RIFT_STATUS ), &riftCount, + sizeof( ULONG ), &bytesReturned, nullptr ); + if( result ) + { + PRIFT_STATUS tmpRift; + unsigned int i; + for( i = 0, tmpRift = riftStatus; i < riftCount; ++i, ++tmpRift ) + { + if( i == (unsigned int)index ) + return tmpRift->childUid; + } + } + } + + return 0; +} + +static bool getEdid(HANDLE hDevice, ULONG uid, DisplayEDID& edid) +{ + ULONG riftCount = 0; + DWORD bytesReturned = 0; + RIFT_STATUS riftStatus[16] = {0}; + + BOOL result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GET_RIFT_COUNT, nullptr, 0, + &riftCount, sizeof( ULONG ), &bytesReturned, nullptr ); + + if (!result) + { + return false; + } + + result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GET_RIFT_ARRAY, &riftStatus, + riftCount * sizeof( RIFT_STATUS ), &riftCount, sizeof(ULONG), + &bytesReturned, nullptr ); + if (!result) + { + return false; + } + + for (ULONG i = 0; i < riftCount; ++i) + { + ULONG riftUid = riftStatus[i].childUid; + if (riftUid == uid) + { + char edidBuffer[512]; + + result = DeviceIoControl(hDevice, IOCTL_RIFTMGR_GETEDID, &riftUid, sizeof(ULONG), + edidBuffer, 512, &bytesReturned, nullptr); + + if (result) + { + if (edid.Parse((unsigned char*)edidBuffer)) + { + return true; + } + else + { + LogError(("[Win32Display] WARNING: The driver was not able to return EDID for a display")); + } + } + + break; + } + } + + return false; +} + + +//----------------------------------------------------------------------------- +// Rift Monitors + +static bool GetMonitorEDID(const wchar_t* deviceID, DisplayEDID& edid) +{ + // Find second slash and split there + const wchar_t* pSlash1 = wcschr(deviceID, L'\\'); + if (!pSlash1) + return false; + + // And the second one + const wchar_t* pSlash2 = wcschr(pSlash1 + 1, L'\\'); + if (!pSlash2) + return false; + + wchar_t hardwareID[128] = {}; + wcsncpy_s(hardwareID, pSlash1 + 1, (pSlash2 - pSlash1 - 1)); + + wchar_t driverID[128] = {}; + wcscpy_s(driverID, pSlash2 + 1); + + ScopedHKEY displayKey; + if (RegOpenKey(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Enum\\DISPLAY", + &displayKey.GetRawRef()) == 0) + { + wchar_t keyName[MAX_PATH] = {}; + DWORD iKey = 0; + while (RegEnumKey(displayKey.Get(), iKey++, keyName, _countof(keyName)) == 0) + { + if (_wcsicmp(keyName, hardwareID) == 0) + { + ScopedHKEY devKey; + if (RegOpenKey(displayKey.Get(), keyName, &devKey.GetRawRef()) == 0) + { + wchar_t nodeName[MAX_PATH] = {}; + DWORD iNode = 0; + while (RegEnumKey(devKey.Get(), iNode++, nodeName, _countof(nodeName)) == 0) + { + wchar_t devDriverID[MAX_PATH] = {}; + DWORD cbDriverID = sizeof(devDriverID); + if (RegGetValue(devKey.Get(), nodeName, L"Driver", RRF_RT_REG_SZ, nullptr, + devDriverID, &cbDriverID) == 0) + { + // Check if DriverID matches + if (_wcsicmp(devDriverID, driverID) == 0) + { + ScopedHKEY nodeKey; + if (RegOpenKey(devKey.Get(), nodeName, &nodeKey.GetRawRef()) == 0) + { + BYTE edidBytes[512] = {}; + DWORD cbEDID = sizeof(edidBytes); + if (RegGetValue(nodeKey.Get(), L"Device Parameters", L"EDID", RRF_RT_REG_BINARY, + nullptr, edidBytes, &cbEDID) == 0) + { + return edid.Parse(edidBytes); + } + } + } + } + } + } + } + } + } + + return true; +} + +static bool FillDisplayDesc(DXGI_OUTPUT_DESC const& outputDesc, DISPLAY_DEVICEW& dispDev, DisplayEDID const& edid, DisplayDesc& result) +{ + // EdidSerialNumber + static_assert(sizeof(result.EdidSerialNumber) == sizeof(edid.SerialNumber), "sizes need to match"); + memcpy(result.EdidSerialNumber, edid.SerialNumber, sizeof(result.EdidSerialNumber)); + + // DisplayID + size_t converted = 0; + if (0 != wcstombs_s(&converted, result.DisplayID, dispDev.DeviceName, _TRUNCATE)) + return false; + + // DesktopDisplayOffset + result.DesktopDisplayOffset = Vector2i(outputDesc.DesktopCoordinates.left, + outputDesc.DesktopCoordinates.top); + + // ModelName + static_assert(sizeof(result.ModelName) == sizeof(edid.MonitorName), "sizes need to match"); + memcpy(result.ModelName, edid.MonitorName, sizeof(result.ModelName)); + + // Resolution + result.ResolutionInPixels.w = edid.Width; + result.ResolutionInPixels.h = edid.Height; + + // DK2 Landscape = DXGI_MODE_ROTATION_IDENTITY -> DXGI_MODE_ROTATION_ROTATE90 + // DK2 Portrait = DXGI_MODE_ROTATION_ROTATE90 -> DXGI_MODE_ROTATION_IDENTITY + // DK2 Landscape(Flipped) = DXGI_MODE_ROTATION_ROTATE180 -> DXGI_MODE_ROTATION_ROTATE270 + // DK2 Portrait(Flipped) = DXGI_MODE_ROTATION_ROTATE270 -> DXGI_MODE_ROTATION_ROTATE180 + bool tallScreen = result.ResolutionInPixels.w < result.ResolutionInPixels.h; + + // Rotation + // This is the rotation from portrait mode, and the DK2 (for example) is naturally landscape, + // so we need to adjust the rotation value based on the HMD type. + switch (outputDesc.Rotation) + { + case DXGI_MODE_ROTATION_IDENTITY: + default: + result.Rotation = tallScreen ? 270 : 0; + break; + case DXGI_MODE_ROTATION_ROTATE90: + result.Rotation = tallScreen ? 0 : 90; + break; + case DXGI_MODE_ROTATION_ROTATE180: + result.Rotation = tallScreen ? 90 : 180; + break; + case DXGI_MODE_ROTATION_ROTATE270: + result.Rotation = tallScreen ? 180 : 270; + break; + } + + // DeviceTypeGuess + result.DeviceTypeGuess = HmdTypeFromModelNumber(edid.ModelNumber); + + return true; +} + +// Pass in 0 if only an existence check is requested. +static int DiscoverRiftMonitors(DisplayDesc* descriptorArray = nullptr, int inputArraySize = 0) +{ + int outputArraySize = 0; + + Ptr factory; + HRESULT hr = ::CreateDXGIFactory1(IID_PPV_ARGS(&factory.GetRawRef())); + OVR_D3D_CHECK_RET_FALSE(hr); + + Ptr adapter; + uint32_t iAdapter = 0; + while (adapter = nullptr, + SUCCEEDED(factory->EnumAdapters(iAdapter++, &adapter.GetRawRef()))) + { + Ptr adapter1; + hr = adapter->QueryInterface(IID_PPV_ARGS(&adapter1.GetRawRef())); + if (!OVR_D3D_CHECK(hr)) + continue; + + DXGI_ADAPTER_DESC1 adapterDesc = {}; + adapter1->GetDesc1(&adapterDesc); + + if (adapterDesc.Flags & DXGI_ADAPTER_FLAG_SOFTWARE) + { + // Don't bother with software adapters (WARP, BasicRender, etc...) + continue; + } + + Ptr output; + uint32_t iOutput = 0; + while (output = nullptr, + SUCCEEDED(adapter->EnumOutputs(iOutput++, &output.GetRawRef()))) + { + // Get DeviceName for each output + DXGI_OUTPUT_DESC outputDesc; + hr = output->GetDesc(&outputDesc); + if (!OVR_D3D_CHECK(hr)) + continue; + + // Get DeviceID from DeviceName + DISPLAY_DEVICEW dispDev = {}; + dispDev.cb = sizeof(dispDev); + if (!::EnumDisplayDevicesW(outputDesc.DeviceName, 0, &dispDev, 0)) + continue; + + // If it is a Rift monitor, + if (wcsstr(dispDev.DeviceID, L"RTD2205") || + wcsstr(dispDev.DeviceID, L"CVT0003") || + wcsstr(dispDev.DeviceID, L"MST0030") || + wcsstr(dispDev.DeviceID, L"OVR00")) // Part of Oculus EDID. + { + DisplayEDID edid = {}; + + // If monitor existence is the goal, + if (!descriptorArray || inputArraySize <= 0) + return 1; + + if (outputArraySize < inputArraySize) + { + if (GetMonitorEDID(dispDev.DeviceID, edid) && + FillDisplayDesc(outputDesc, dispDev, edid, descriptorArray[outputArraySize])) + { + outputArraySize++; + } + } + } + } + } + + return outputArraySize; +} + +bool Display::ExtendedModeDevicesExist() +{ + return DiscoverRiftMonitors() > 0; +} + + +//------------------------------------------------------------------------------------- +// ***** Display + +bool Display::InCompatibilityMode(bool displaySearch) +{ + return (displaySearch && ExtendedModeDevicesExist()) || + GlobalDisplayContext.CompatibilityMode; +} + +#define OVR_FLAG_COMPATIBILITY_MODE 1 +#define OVR_FLAG_HIDE_DK1 2 + + +void Display::Shutdown() +{ + Win32::DisplayShim::GetInstance().Shutdown(); + OVR::Display::SetDirectDisplayInitialized(false); +} + +bool Display::Initialize() +{ + // This function is re-entrant because it may be called again to + // patch-up comatibility mode by the Config Util (Hack in HMDView::SetupGraphics). + // For this reason, the GetDirectDisplayInitialized() check is only done for + // shim initialization below. + + HANDLE hDevice = INVALID_HANDLE_VALUE; + + if (GlobalDisplayContext.hDevice == 0) + { + hDevice = CreateFile(L"\\\\.\\ovr_video" , + GENERIC_READ | GENERIC_WRITE, 0, + nullptr, OPEN_EXISTING, 0, nullptr); + } + else + { // The device has already been created + hDevice = GlobalDisplayContext.hDevice; + } + + if (hDevice != nullptr && hDevice != INVALID_HANDLE_VALUE) + { + GlobalDisplayContext.hDevice = hDevice; + GlobalDisplayContext.CompatibilityMode = false; + + DWORD bytesReturned = 0; + LONG compatiblityResult = OVR_STATUS_SUCCESS; + + BOOL result = DeviceIoControl( hDevice, IOCTL_RIFTMGR_GETCOMPATIBILITYMODE, nullptr, 0, + &compatiblityResult, sizeof( LONG ), &bytesReturned, nullptr ); + if (result) + { + GlobalDisplayContext.CompatibilityMode = (compatiblityResult & OVR_FLAG_COMPATIBILITY_MODE) != 0; + GlobalDisplayContext.HideDK1Mode = (compatiblityResult & OVR_FLAG_HIDE_DK1) != 0; + } + else + { + // If calling our driver fails in any way, assume compatibility mode as well + GlobalDisplayContext.CompatibilityMode = true; + } + + if (!GlobalDisplayContext.CompatibilityMode) + { + // If a display is actually connected, bring up the shim layers so we can actually use it + // TBD: Do we care about extended mode displays? -cat + if (OVR::Display::ExtendedModeDevicesExist() || + getRiftCount(GlobalDisplayContext.hDevice) > 0) + { + // FIXME: Initializing DX9 with landscape numbers rather than portrait + GlobalDisplayContext.ExpectedWidth = 1080; + GlobalDisplayContext.ExpectedHeight = 1920; + } + else + { + GlobalDisplayContext.CompatibilityMode = true; + } + } + } + else + { + GlobalDisplayContext.CompatibilityMode = true; + } + + + + // Set up display code for Windows + Win32::DisplayShim::GetInstance(); + + // This code will look for the first display. If it's a display + // that's extending the desktop, the code will assume we're in + // compatibility mode. Compatibility mode prevents shim loading + // and renders only to extended Rifts. + // If we find a display and it's application exclusive, + // we load the shim so we can render to it. + // If no display is available, we revert to whatever the + // driver tells us we're in + + bool anyExtendedRifts = OVR::Display::ExtendedModeDevicesExist() || + GlobalDisplayContext.CompatibilityMode; + + if (!OVR::Display::GetDirectDisplayInitialized()) + { + OVR::Display::SetDirectDisplayInitialized( + Win32::DisplayShim::GetInstance().Initialize(anyExtendedRifts)); + } + + return true; +} + +bool Display::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) +{ + if (GlobalDisplayContext.hDevice == nullptr) + { + driverInstalled = false; + compatMode = true; + hideDK1Mode = false; + } + else + { + driverInstalled = true; + compatMode = GlobalDisplayContext.CompatibilityMode; + hideDK1Mode = GlobalDisplayContext.HideDK1Mode; + } + + return true; +} + +bool Display::SetDriverMode(bool compatMode, bool hideDK1Mode) +{ + // If device is not initialized, + if (GlobalDisplayContext.hDevice == nullptr) + { + OVR_ASSERT(false); + return false; + } + + // If no change, + if ((compatMode == GlobalDisplayContext.CompatibilityMode) && + (hideDK1Mode == GlobalDisplayContext.HideDK1Mode)) + { + return true; + } + + LONG mode_flags = 0; + if (compatMode) + { + mode_flags |= OVR_FLAG_COMPATIBILITY_MODE; + } + if (hideDK1Mode) + { + mode_flags |= OVR_FLAG_HIDE_DK1; + } + + DWORD bytesReturned = 0; + LONG err = 1; + + if (!DeviceIoControl(GlobalDisplayContext.hDevice, + IOCTL_RIFTMGR_SETCOMPATIBILITYMODE, + &mode_flags, + sizeof(LONG), + &err, + sizeof(LONG), + &bytesReturned, + nullptr) || + (err != 0 && err != -3)) + { + LogError("{ERR-001w} [Win32Display] Unable to set device mode to (compat=%d dk1hide=%d): err=%d", + (int)compatMode, (int)hideDK1Mode, (int)err); + return false; + } + + OVR_DEBUG_LOG(("[Win32Display] Set device mode to (compat=%d dk1hide=%d)", + (int)compatMode, (int)hideDK1Mode)); + + GlobalDisplayContext.HideDK1Mode = hideDK1Mode; + GlobalDisplayContext.CompatibilityMode = compatMode; + return true; +} + +DisplaySearchHandle* Display::GetDisplaySearchHandle() +{ + return new Win32::Win32DisplaySearchHandle(); +} + +// FIXME: The handle parameter will be used to unify GetDisplayCount and GetDisplay calls +// The handle will be written to the 64-bit value pointed and will store the enumerated +// display list. This will allow the indexes to be meaningful between obtaining +// the count. With a single handle the count should be stable +int Display::GetDisplayCount(DisplaySearchHandle* handle, bool extended, bool applicationOnly, bool extendedEDIDSerials) +{ + OVR_UNUSED(extendedEDIDSerials); + static int extendedCount = -1; + static int applicationCount = -1; + + Win32::Win32DisplaySearchHandle* localHandle = (Win32::Win32DisplaySearchHandle*)handle; + + if( localHandle == nullptr ) + return 0; + + if( extendedCount == -1 || extended ) + { + extendedCount = DiscoverRiftMonitors(localHandle->cachedDescriptorArray, 16); + } + + localHandle->extended = true; + localHandle->extendedDisplayCount = extendedCount; + int totalCount = extendedCount; + + if( applicationCount == -1 || applicationOnly ) + { + applicationCount = getRiftCount(GlobalDisplayContext.hDevice); + localHandle->application = true; + } + + totalCount += applicationCount; + localHandle->applicationDisplayCount = applicationCount; + localHandle->displayCount = totalCount; + + return totalCount; +} + +Ptr Display::GetDisplay(int index, DisplaySearchHandle* handle) +{ + Ptr result; + + if( index < 0 ) + return result; + + Win32::Win32DisplaySearchHandle* localHandle = (Win32::Win32DisplaySearchHandle*)handle; + + if( localHandle == nullptr ) + return nullptr; + + if (localHandle->extended) + { + if (index >= 0 && index < (int)localHandle->extendedDisplayCount) + { + return *new Win32::Win32DisplayGeneric(localHandle->cachedDescriptorArray[index]); + } + + index -= localHandle->extendedDisplayCount; + } + + if(localHandle->application) + { + if (index >= 0 && index < (int)getRiftCount(GlobalDisplayContext.hDevice)) + { + ULONG riftChildId = getRift(GlobalDisplayContext.hDevice, index); + DisplayEDID dEdid; + + if (!getEdid(GlobalDisplayContext.hDevice, riftChildId, dEdid)) + { + return nullptr; + } + + uint32_t nativeWidth = dEdid.Width, nativeHeight = dEdid.Height; + uint32_t rotation = (dEdid.ModelNumber == 2 || + dEdid.ModelNumber == 3) ? 90 : 0; + + uint32_t logicalWidth, logicalHeight; + if (rotation == 0) + { + logicalWidth = nativeWidth; + logicalHeight = nativeHeight; + } + else + { + logicalWidth = nativeHeight; + logicalHeight = nativeWidth; + } + + result = *new Win32::Win32DisplayDriver( + HmdTypeFromModelNumber(dEdid.ModelNumber), + "", + dEdid.MonitorName, + dEdid.SerialNumber, + Sizei(logicalWidth, logicalHeight), + Sizei(nativeWidth, nativeHeight), + Vector2i(0), + dEdid, + GlobalDisplayContext.hDevice, + riftChildId, + rotation); + } + } + return result; +} + +Display::MirrorMode Win32::Win32DisplayDriver::SetMirrorMode( Display::MirrorMode newMode ) +{ + return newMode; +} + +static bool SetDisplayPower(HANDLE hDevice, ULONG childId, int mode) +{ +#ifdef OVR_OS_WIN64 + BOOL is64BitOS = TRUE; +#else + BOOL is64BitOS = FALSE; + BOOL res = IsWow64Process(GetCurrentProcess(), &is64BitOS); + OVR_ASSERT_AND_UNUSED(res == TRUE,res); +#endif + ULONG localResult = 0; + DWORD bytesReturned = 0; + BOOL result; + if (is64BitOS) + { + ULONG64 longArray[2]; + longArray[0] = childId; + longArray[1] = mode; + result = DeviceIoControl(hDevice, + IOCTL_RIFTMGR_DISPLAYPOWER, + longArray, + 2 * sizeof(ULONG64), + &localResult, + sizeof(ULONG), + &bytesReturned, + nullptr); + } + else + { + ULONG32 longArray[2]; + longArray[0] = childId; + longArray[1] = mode; + result = DeviceIoControl(hDevice, + IOCTL_RIFTMGR_DISPLAYPOWER, + longArray, + 2 * sizeof(ULONG32), + &localResult, + sizeof(ULONG), + &bytesReturned, + nullptr); + } + + // Note: bytesReturned does not seem to be set + return result != FALSE /* && bytesReturned == sizeof(ULONG) */ && mode == (int)localResult; +} + +bool Win32::Win32DisplayDriver::SetDisplaySleep(bool sleep) +{ + return SetDisplayPower(hDevice, ChildId, sleep ? 2 : 1); +} + + +} // namespace OVR diff --git a/LibOVR/Src/Displays/OVR_Win32_Display.h b/LibOVR/Src/Displays/OVR_Win32_Display.h index 4517d44..5b30482 100644 --- a/LibOVR/Src/Displays/OVR_Win32_Display.h +++ b/LibOVR/Src/Displays/OVR_Win32_Display.h @@ -1,182 +1,153 @@ -/************************************************************************************ - -Filename : OVR_Win32_Display.h -Content : Win32-specific Display declarations -Created : May 6, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Win32_Display_h -#define OVR_Win32_Display_h - -#include "OVR_Display.h" - -OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized - -namespace OVR { namespace Win32 { - - -//------------------------------------------------------------------------------------- -// DisplayDesc - -// Display information enumerable through Win32. -// TBD: Should we just move this to public header, so it's a const member of Display? -struct DisplayDesc -{ - HmdTypeEnum DeviceTypeGuess; // This is a guess about what type of HMD it is connected to - String DisplayID; // This is the device identifier string from MONITORINFO (for app usage) - String ModelName; // This is a "DK2" type string - String EdidSerialNumber; - Sizei LogicalResolutionInPixels; - Sizei NativeResolutionInPixels; - Vector2i DesktopDisplayOffset; -}; - - -//------------------------------------------------------------------------------------- -// DisplayEDID - -// Describes EDID information as reported from our display driver. -struct DisplayEDID -{ - String MonitorName; - UINT16 ModelNumber; - String VendorName; - String SerialNumber; -}; - -class Win32DisplaySearchHandle : public DisplaySearchHandle -{ -public: - static const int ArraySize = 16; - - Win32::DisplayDesc cachedDescriptorArray[ArraySize]; - bool extended; - bool application; - int extendedDisplayCount; - int applicationDisplayCount; - int displayCount; - - Win32DisplaySearchHandle() - : cachedDescriptorArray(), - extended(), - application(false), - extendedDisplayCount(0), - applicationDisplayCount(0), - displayCount(0) - { - } - - virtual ~Win32DisplaySearchHandle() - { - } -}; - -//------------------------------------------------------------------------------------- -// Win32DisplayGeneric - -// Describes Win32 display in Compatibility mode, containing basic data -class Win32DisplayGeneric : public Display -{ -public: - Win32DisplayGeneric( const DisplayDesc& dd ) : - Display(dd.DeviceTypeGuess, - dd.DisplayID, - dd.ModelName, - dd.EdidSerialNumber, - dd.LogicalResolutionInPixels, - dd.NativeResolutionInPixels, - dd.DesktopDisplayOffset, - 0, - 0, - false) - { - } - - virtual ~Win32DisplayGeneric() - { - } - - // Generic displays are not capable of mirroring - virtual MirrorMode SetMirrorMode( MirrorMode newMode ) - { - OVR_UNUSED( newMode ); - return MirrorDisabled; - } -}; - - -//------------------------------------------------------------------------------------- -// Win32DisplayDriver - -// Oculus driver based display object. -class Win32DisplayDriver : public Display -{ - HANDLE hDevice; - ULONG ChildId; - DisplayEDID Edid; - -public: - Win32DisplayDriver(const HmdTypeEnum deviceTypeGuess, - const String& displayID, - const String& modelName, - const String& edidSerial, - const Sizei& logicalRes, - const Sizei& nativeRes, - const Vector2i& displayOffset, - const DisplayEDID& edid, - HANDLE hdevice, - ULONG child, - uint32_t rotation) : - Display(deviceTypeGuess, - displayID, - modelName, - edidSerial, - logicalRes, - nativeRes, - displayOffset, - child, - rotation, - true), - hDevice(hdevice), - ChildId(child), - Edid(edid) - { - } - - virtual ~Win32DisplayDriver() - { - } - - virtual MirrorMode SetMirrorMode( MirrorMode newMode ); - - // Support sleep/wake - virtual bool SetDisplaySleep(bool off); -}; - - -}} // namespace OVR::Win32 - - -OVR_RESTORE_MSVC_WARNING() - - -#endif // OVR_Win32_Display_h +/************************************************************************************ + +Filename : OVR_Win32_Display.h +Content : Win32-specific Display declarations +Created : May 6, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Win32_Display_h +#define OVR_Win32_Display_h + +#include "OVR_Display.h" + +OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized + +namespace OVR { namespace Win32 { + + +class Win32DisplaySearchHandle : public DisplaySearchHandle +{ +public: + static const int ArraySize = 16; + + DisplayDesc cachedDescriptorArray[ArraySize]; + bool extended; + bool application; + int extendedDisplayCount; + int applicationDisplayCount; + int displayCount; + + Win32DisplaySearchHandle() : + cachedDescriptorArray(), + extended(), + application(false), + extendedDisplayCount(0), + applicationDisplayCount(0), + displayCount(0) + { + } + + virtual ~Win32DisplaySearchHandle() + { + } +}; + +//------------------------------------------------------------------------------------- +// Win32DisplayGeneric + +// Describes Win32 display in Compatibility mode, containing basic data +class Win32DisplayGeneric : public Display +{ +public: + Win32DisplayGeneric( const DisplayDesc& dd ) : + Display(dd.DeviceTypeGuess, + dd.DisplayID, + dd.ModelName, + dd.EdidSerialNumber, + dd.ResolutionInPixels, + dd.ResolutionInPixels, + dd.DesktopDisplayOffset, + 0, + dd.Rotation, + false) + { + } + + virtual ~Win32DisplayGeneric() + { + } + + // Generic displays are not capable of mirroring + virtual MirrorMode SetMirrorMode( MirrorMode newMode ) + { + OVR_UNUSED( newMode ); + return MirrorDisabled; + } +}; + + +//------------------------------------------------------------------------------------- +// Win32DisplayDriver + +// Oculus driver based display object. +class Win32DisplayDriver : public Display +{ + HANDLE hDevice; + ULONG ChildId; + DisplayEDID Edid; + +public: + Win32DisplayDriver(const HmdTypeEnum deviceTypeGuess, + const String& displayID, + const String& modelName, + const String& edidSerial, + const Sizei& logicalRes, + const Sizei& nativeRes, + const Vector2i& displayOffset, + const DisplayEDID& edid, + HANDLE hdevice, + ULONG child, + uint32_t rotation) : + Display(deviceTypeGuess, + displayID, + modelName, + edidSerial, + logicalRes, + nativeRes, + displayOffset, + child, + rotation, + true), + hDevice(hdevice), + ChildId(child), + Edid(edid) + { + } + + virtual ~Win32DisplayDriver() + { + } + + virtual MirrorMode SetMirrorMode( MirrorMode newMode ); + + // Support sleep/wake + virtual bool SetDisplaySleep(bool off); +}; + + +}} // namespace OVR::Win32 + + +OVR_RESTORE_MSVC_WARNING() + + +#endif // OVR_Win32_Display_h diff --git a/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h b/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h index e801f4a..4ae110b 100644 --- a/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h +++ b/LibOVR/Src/Displays/OVR_Win32_Dxgi_Display.h @@ -1,429 +1,444 @@ -/************************************************************************************ - -PublicHeader: None -Filename : dxgi_ovr_filter.h -Content : Shared usermode/kernel mode definitions for IOCTL functionality. - Also used from LibOVR to access the driver. -Created : January 27, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2013 Oculus, LLC. All Rights reserved. - -Use of this software is subject to the terms of the Oculus LLC license -agreement provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -/************************************************************************************/ - -#ifndef OVR_dxgi_ovr_filter_h -#define OVR_dxgi_ovr_filter_h - -#include -#include - -#define USERMODE_TEST_ROTATION 1 - -#if USERMODE_TEST_ROTATION // Used only by the um test application -#define USERMODE_SURFACE_WIDTH 1920 -#define USERMODE_SURFACE_HEIGHT 1080 -#else -#define USERMODE_SURFACE_WIDTH 1080 -#define USERMODE_SURFACE_HEIGHT 1920 -#endif - -#define TEST_ROTATION 0 // Kernel-mode parameters - -#if TEST_ROTATION -#define SURFACE_WIDTH 1920 -#define SURFACE_HEIGHT 1080 -#else -#define SURFACE_WIDTH 1080 -#define SURFACE_HEIGHT 1920 -#endif - -// {46231713-49FD-4922-84E3-9FF907C06803} -DEFINE_GUID(GUID_DEVINTERFACE_OVRRIFTMGR, - 0x46231713, 0x49fd, 0x4922, 0x84, 0xe3, 0x9f, 0xf9, 0x7, 0xc0, 0x68, 0x3); - -#define QUERYADAPTER_MAGICSIZE 17836 -#define QUERYADAPTER_MAGICHEADER 0x4f565246 // OVRF -#define QUERYADAPTER_MAXPATH 2048 - -#define FUNCTION_INDEX 0xb800 - -#pragma pack(push,1) - -#define OVR_RIFT_MODE_OFF 0 // Disabled -#define OVR_RIFT_MODE_ENABLED 1 // Enabled -#define OVR_RIFT_MODE_EXTEND 2 // Extending 2D displays. Without this flag - // 2D displays are disabled when the Rift - // is active -#define OVR_RIFT_MODE_FRONTBUFFER 4 // Enable front buffer only for Rift -#define OVR_RIFT_MODE_LOCKMOUSE 8 // Prevent mouse from entering bounds - -#define OVR_ESCAPE_TYPE_HANDLE 1 // Escape to notify driver of our collected handles - -#define OVR_FlipImmediate 0x2 -#define OVR_FlipOnNextVSync 0x4 - -//----------------------------------------------------------------------------------- -// Structures for application to UM driver - -// Kernel32.dll functionality -typedef HMODULE (WINAPI *WinLoadLibraryA) ( LPCSTR ); -typedef HMODULE (WINAPI *WinLoadLibraryW) ( LPCWSTR ); -typedef HMODULE (WINAPI *WinLoadLibraryExA) ( LPCSTR, HANDLE, DWORD ); -typedef HMODULE (WINAPI *WinLoadLibraryExW) ( LPCWSTR, HANDLE, DWORD ); -typedef BOOL (WINAPI *WinGetModuleHandleExA)( DWORD, LPCSTR, HMODULE* ); -typedef BOOL (WINAPI *WinGetModuleHandleExW)( DWORD, LPCWSTR, HMODULE* ); - -// Overridden DirectX 9 entry points -typedef void* (WINAPI *WinDirect3DCreate9)(UINT SDKVersion); -typedef HRESULT (WINAPI *WinDirect3DCreate9Ex)(UINT SDKVersion, void** aDevice); - -// Overridden DXGI entry points -typedef HRESULT (WINAPI *WinCreateDXGIFactory)( - __in REFIID riid, - __out void **ppFactory - ); - -typedef HRESULT (WINAPI *WinCreateDXGIFactory1)( - __in REFIID riid, - __out void **ppFactory - ); - -typedef HRESULT (WINAPI *WinCreateDXGIFactory2)( - __in UINT flags, - __in const IID &riid, - __out void **ppFactory - ); - -// Application usermode callbacks from usermode driver. These -// functions are all provided by the calling application that uses -// the filter mode driver - -// IsInitializingDisplay is used at runtime to validate that -// the created resource (RT or bind_present) matches the resolution -// of our expected backbuffer. If the application returns true, -// our usermode driver will convert this to a primary -typedef BOOL (WINAPI *IsInitializingDisplay) ( PVOID, UINT, UINT ); -// RiftForContext is a function that will return the Rift device of -// the concerned context. This is for targeting a particular -// device instance with a particular Rift for rendering -typedef ULONG (WINAPI *RiftForContext)( PVOID, HANDLE ); -// CloseRiftForContext is a function that informs the application -// the created device is shutting down and the context -// can freedly disassociate with the particular -typedef BOOL (WINAPI *CloseRiftForContext)( PVOID, HANDLE, ULONG ); -typedef BOOL (WINAPI *WindowDisplayResolution)( PVOID, UINT*, UINT*, UINT*, UINT*, BOOL* ); -// IsCreatingBackBuffer is a function directed at the runtime shim -// to confirm that the runtime is actively creating the additional -// swapchain for rotation and display out to the rift. -// When creating the original swapchain this function should return false -// so the orignal swapchain isn't inadvertantly coopted. -typedef BOOL (WINAPI *IsCreatingBackBuffer)( PVOID ); -// Callback from the usermode driver to obtain the desire to see debug statements from -// the usermode drivers on the output console. Only called one per usermode driver shim -// and usermode runtime. -typedef BOOL (WINAPI *ShouldEnableDebug)( VOID ); -// Callback from the usermode driver to the runtime obtain the vsync status -typedef BOOL (WINAPI *ShouldVSync)( VOID ); -// Callback from usermode mode and runtime driver to obtain expected native width, -// height and degrees rotation of the rift -typedef BOOL (WINAPI *ExpectedResolution)( PVOID, UINT*, UINT*, UINT* ); -// Usermode callback that reports whether or not mirroring is enabled -typedef BOOL (WINAPI *MirroringEnabled)( PVOID ); -// Callback from the shim for Unity and other plugins used to -// report the swapchain that was created by the application -typedef void* (WINAPI *GetDX11SwapChain)( PVOID ); -// Callback to report the HWND associated with this context -typedef HWND (WINAPI* GetWindowForContext)( PVOID ); -// Should present Rift on context -typedef BOOL (WINAPI* PresentRiftOnContext)( PVOID ); -// Used by a pre-loaded shim (d3d9, dxgi, opengl32) to -// identify which api version we loaded -// 1 = OpenGL -// 9 = DirectX 9 -// 10 = DirectX 1X -typedef int (WINAPI* ActiveAPIVersion)( PVOID ); - -// Get the version of the runtime filter. -typedef ULONG (WINAPI* GetRTFilterVersion)(); - -#pragma warning(push) -#pragma warning(disable: 4201) - -typedef struct _LINK_APPLICATION_DRIVER -{ - UINT32 version; - PVOID context; - - union - { - struct - { - IsInitializingDisplay pfnInitializingDisplay; - RiftForContext pfnRiftForContext; - CloseRiftForContext pfnCloseRiftForContext; - WindowDisplayResolution pfnWindowDisplayResolution; - IsCreatingBackBuffer pfnIsCreatingBackBuffer; - ShouldEnableDebug pfnShouldEnableDebug; - ShouldVSync pfnShouldVSync; - ExpectedResolution pfnExpectedResolution; - MirroringEnabled pfnMirroringEnabled; - GetDX11SwapChain pfnGetDX11SwapChain; - GetWindowForContext pfnGetWindowForContext; - PresentRiftOnContext pfnPresentRiftOnContext; - ActiveAPIVersion pfnActiveAPIVersion; - }; - - PROC placeholders[128]; - }; - - - // Used by Runtime filter for linking with original libraries - WinDirect3DCreate9 pfnDirect3DCreate9; - WinDirect3DCreate9Ex pfnDirect3DCreate9Ex; - WinCreateDXGIFactory pfnCreateDXGIFactory; - WinCreateDXGIFactory1 pfnCreateDXGIFactory1; - WinCreateDXGIFactory2 pfnCreateDXGIFactory2; -} LINK_APPLICATION_DRIVER, *PLINK_APPLICATION_DRIVER; - -#pragma warning(pop) - - -// OVRDisplay.dll functionality -typedef HRESULT (WINAPI *PreloadLibraryFn) ( WinLoadLibraryA , LPCSTR, PLINK_APPLICATION_DRIVER appDriver ); -typedef HRESULT (WINAPI *PreloadLibraryRTFn) ( PLINK_APPLICATION_DRIVER appDriver ); - -//----------------------------------------------------------------------------------- -// Structures for UM driver to KM driver - -typedef struct _QUERY_KM_DRIVER -{ - UINT32 magic; // Friend or foe identifier for our filter driver - // See: QUERYADAPTER_MAGICHEADER - UINT32 maxVidPnSources; // Returns the maximum number of video present network sources -} QUERY_KM_DRIVER, *PQUERY_KM_DRIVER; - -#ifndef _D3DUKMDT_H_ -typedef UINT D3DKMT_HANDLE; -#endif - -typedef struct _HandleNotepad -{ - // These are assigned around CreateResource - HANDLE hUsermodeInResource; - HANDLE hUsermodeOutResource; - - // These are assigned within the kernel with - // DxgkDdiCreateAllocation and - // DxgkDdiOpenAllocation - D3DKMT_HANDLE hAllocation; - PVOID hDeviceSpecificHandle; - PVOID hKernelDriverHandle; - - // These are assigned around pfnAllocateCb - HANDLE hUsermodeSharedResource; - D3DKMT_HANDLE hKernelModeSharedResource; - - ULONG childUid; - - UINT pitch; - -} HandleNotepad, *PHandleNotepad; - - -typedef struct _ALLOC_PRIVATE_STRUCTURE -{ - UINT32 magic; // Friend or foe identifier for our filter driver - - PVOID originalPrivataDataPtr; // Location in usermode of the original private data structure - UINT originalPrivateSize; // Size of private data structure at the end of this header - - PVOID hAllocationHandle; // User-mode-assigned allocation handle for CreateAllocation - PVOID hDeviceSpecificHandle; // Assigned in kernal OpenAllocation - PVOID hInternalHandle; // Assigned in kernal CreateAllocation - UINT pitch; // Hinted surface pitch - - BYTE originalPrivateData[1]; // Variable length - - -} ALLOC_PRIVATE_STRUCTURE, *PALLOC_PRIVATE_STRUCTURE; - -typedef struct _ESCAPE_STRUCTURE -{ - UINT32 magic; // Friend or foe identifier for our filter driver - - UINT32 escapeType; // Specifier for individual type of escape message - // Type 1 for notepad - union { - HandleNotepad notepad; - }; -} ESCAPE_STRUCTURE, *PESCAPE_STRUCTURE; - -// Structures for internal operation of KM driver - -typedef struct _RIFT_SYNC -{ - ULONG childUid; // ChildUid as reported by RIFT_STATUS - ULONG vsync; // 1 for vsync, 0 for immediate -} RIFT_SYNC, *PRIFT_SYNC; - -typedef struct _RIFT_MODE -{ - ULONG childUid; // ChildUid as reported by RIFT_STATUS - ULONG mode; // Bitmap of mode values, defined by OVR_RIFT_HOME_* - HANDLE userModeHandle; // Handle of render target created in user mode - // that's usable as a primary -} RIFT_MODE, *PRIFT_MODE; - -typedef struct _RIFT_STATUS -{ - ULONG childUid; // Display driver assigned Uid for this display - ULONG mode; // Active rift mode, see OVR_RIFT_MODE_* - ULONG serialNumber; // Serial number as reported in the Rift's EDID - ULONG textureHandle; // Handle of shared render resource -- NULL if not shared -} RIFT_STATUS, *PRIFT_STATUS; - -typedef struct _RIFT_STATUS_ARRAY -{ - ULONG arraySize; // Size of pre-allocated RIFT_STATUS structures. - RIFT_STATUS status[1]; // Array of status blocks containing connection information on each Rift -} RIFT_STATUS_ARRAY, *PRIFT_STATUS_ARRAY; - -#pragma pack(pop) - -// IOCTL for UM application to KM driver - -#define OVR_STATUS_SUCCESS 0 -#define OVR_STATUS_FAIL -1 -#define OVR_STATUS_DRIVER_IN_USE -2 -#define OVR_STATUS_MODE_ALREADY_ACTIVE -3 -#define OVR_STATUS_RIFT_NOT_PRESENT -4 - -// -// Returns the number of Rift displays attached to the video adapter -// If 0, no Rift displays have been connected. -// If greater than 0, use this size to pre-allocate space for an array -// of rift statuses -// -// Input Buffer: Nothing -// Output Buffer: LONG - count of Rift displays attached to video adapter -// -#define IOCTL_RIFTMGR_GET_RIFT_COUNT CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS) - -// -// Fills out a pre-allocated array with information on the individually attached -// screens. -// -// On Input, specify the arraySize as the size of the allocation. -// -// On Output, the arraySize will be updated with the actual number of Rifts -// reported. Use IOCTL_RIFTMGR_GET_RIFT_COUNT to query the number of Rifts. -// If the count changes (added or removed) between calls, the function will either fail -// due to the buffer being too small, or the arraySize count will be updated -// with a new count of devices along with their respective parameters. -// -// Input Buffer: PRIFT_STATUS - Pointer to allocated status array -// Output Buffer: LONG - Count of Rift displays reported in the structure. -1 if out of -// memory -// -#define IOCTL_RIFTMGR_GET_RIFT_ARRAY CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 1, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Changes the mode of an attached Rift (DEPRECATED) -// Input Buffer: PRIFT_MODE - Pointer to a mode structure specifying the childUid and -// mode for a particular Rift -// Output Buffer: LONG - Non-zero on error, 0 on successful mode change -// -#define IOCTL_RIFTMGR_SET_RIFT_MODE CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 2, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Lock the primary of the rift and obtain an address -// Input Buffer: ULONG - ChildUid of a Rift as previously discovered -// Output Buffer: ULONG_PTR - Pointer to a usermode mapped address of the primary -#define IOCTL_RIFTMGR_GET_RIFT_PRIMARY CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 3, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Release Rift primary -// Input Buffer: PULONG_PTR - ChildUid of a Rift as previously discovered and virtual pointer -// Output Buffer: NOTHING -#define IOCTL_RIFTMGR_RELEASE_RIFT_PRIMARY CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 4, METHOD_NEITHER, FILE_ANY_ACCESS) - - -// Point the rift to another render target -// Input Buffer: PHANDLE - Array of handles, rift and the render target resource -// Output Buffer: NOTHING -#define IOCTL_RIFTMGR_SETRIFTBUFFER CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 5, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Enable or disable vsync on Rift present -// Input Buffer: PRIFT_SYNC - Pointer to a mode structure specifying the childUid and -// and sync -// Output Buffer: NOTHING -#define IOCTL_RIFTMGR_SETVSYNCMODE CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 6, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Get scan line -// Input Buffer: ULONG - ChildUid of a Rift as previously discovered -// Output Buffer: ULONG - 31st bit is set if in vertical blank, high 15 bits has per second -// frame number (0-74), low 16 bits has scanline (0-1919) -#define IOCTL_RIFTMGR_GETSCANLINE CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 7, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Enable or disable compatibility mode. Entering compatibility mode will fail if -// the Rift is already actively scanning out a surface -// Input Buffer: LONG - Bit assignments: -// LSB (bit 0) is a flag for compatibility mode itself. -// 1 means compatibility mode. -// 0 means application direct mode. -// Bit 1 means "Hide DK1's". -// 1 means operate DK1's in synchronous with the compatibility mode exactly. -// 0 means operate in DK1 legacy mode. -// Output Buffer: LONG - Result value (see OVR statuses) -// 0 = success -// -1 = general failure -// -2 = failure, rift scanning out -// -3 = already active -// -4 = rift not present -#define IOCTL_RIFTMGR_SETCOMPATIBILITYMODE CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 8, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Call to obtain the current status of compatibility mode -// Input Buffer: NOTHING -// Output Buffer: LONG - Bit assignments: -// LSB (bit 0) is a flag for compatibility mode itself. -// 1 means compatibility mode. -// 0 means application direct mode. -// Bit 1 means "Hide DK1's". -// 1 means operate DK1's in synchronous with the compatibility mode exactly. -// 0 means operate in DK1 legacy mode. -#define IOCTL_RIFTMGR_GETCOMPATIBILITYMODE CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 9, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Call to set the power mode of a particular Rift -// Input Buffer: PULONG_PTR - ChildUid of a Rift as previously discovered and ULONG value -// second ULONG has value of -// 0 to simply obtain the power status of the display -// 1 to set the display into a full power state (needs a primary to fully scan out) -// 2 to set the display into sleep mode -// 3 to set the display into full power off mode (WARNING: Will potentially trash primary) -// Output Buffer: LONG - Result value -// 0 = Failure to obtain power status -// 1 = Full power -// 2 = Sleep -// 3 = Power off -#define IOCTL_RIFTMGR_DISPLAYPOWER CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 10, METHOD_NEITHER, FILE_ANY_ACCESS) - -// Return the EDID of the display in the output buffer. The driver -// will copy as many bytes as possible to fill the buffer. -// Input Buffer: ULONG - ChildUid of a Rift as previously discovered -// Output Buffer: PCHAR - Preallocated buffer of a variable size to store the EDID from the display -#define IOCTL_RIFTMGR_GETEDID CTL_CODE(FILE_DEVICE_VIDEO, \ - FUNCTION_INDEX + 11, METHOD_NEITHER, FILE_ANY_ACCESS) - -#endif +/************************************************************************************ + +PublicHeader: None +Filename : dxgi_ovr_filter.h +Content : Shared usermode/kernel mode definitions for IOCTL functionality. + Also used from LibOVR to access the driver. +Created : January 27, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2013 Oculus, LLC. All Rights reserved. + +Use of this software is subject to the terms of the Oculus LLC license +agreement provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +/************************************************************************************/ + +#ifndef OVR_dxgi_ovr_filter_h +#define OVR_dxgi_ovr_filter_h + +#include +#include + +#define USERMODE_TEST_ROTATION 1 + +#if USERMODE_TEST_ROTATION // Used only by the um test application +#define USERMODE_SURFACE_WIDTH 1920 +#define USERMODE_SURFACE_HEIGHT 1080 +#else +#define USERMODE_SURFACE_WIDTH 1080 +#define USERMODE_SURFACE_HEIGHT 1920 +#endif + +#define TEST_ROTATION 0 // Kernel-mode parameters + +#if TEST_ROTATION +#define SURFACE_WIDTH 1920 +#define SURFACE_HEIGHT 1080 +#else +#define SURFACE_WIDTH 1080 +#define SURFACE_HEIGHT 1920 +#endif + +// {46231713-49FD-4922-84E3-9FF907C06803} +DEFINE_GUID(GUID_DEVINTERFACE_OVRRIFTMGR, + 0x46231713, 0x49fd, 0x4922, 0x84, 0xe3, 0x9f, 0xf9, 0x7, 0xc0, 0x68, 0x3); + +#define QUERYADAPTER_MAGICSIZE 17836 +#define QUERYADAPTER_MAGICHEADER 0x4f565246 // OVRF +#define QUERYADAPTER_MAXPATH 2048 + +#define FUNCTION_INDEX 0xb800 + +#pragma pack(push,1) + +#define OVR_RIFT_MODE_OFF 0 // Disabled +#define OVR_RIFT_MODE_ENABLED 1 // Enabled +#define OVR_RIFT_MODE_EXTEND 2 // Extending 2D displays. Without this flag + // 2D displays are disabled when the Rift + // is active +#define OVR_RIFT_MODE_FRONTBUFFER 4 // Enable front buffer only for Rift +#define OVR_RIFT_MODE_LOCKMOUSE 8 // Prevent mouse from entering bounds + +#define OVR_ESCAPE_TYPE_HANDLE 1 // Escape to notify driver of our collected handles + +#define OVR_FlipImmediate 0x2 +#define OVR_FlipOnNextVSync 0x4 + +//----------------------------------------------------------------------------------- +// Structures for application to UM driver + +// Kernel32.dll functionality +typedef HMODULE (WINAPI *WinLoadLibraryA) ( LPCSTR ); +typedef HMODULE (WINAPI *WinLoadLibraryW) ( LPCWSTR ); +typedef HMODULE (WINAPI *WinLoadLibraryExA) ( LPCSTR, HANDLE, DWORD ); +typedef HMODULE (WINAPI *WinLoadLibraryExW) ( LPCWSTR, HANDLE, DWORD ); +typedef BOOL (WINAPI *WinGetModuleHandleExA)( DWORD, LPCSTR, HMODULE* ); +typedef BOOL (WINAPI *WinGetModuleHandleExW)( DWORD, LPCWSTR, HMODULE* ); + +// Overridden DirectX 9 entry points +typedef void* (WINAPI *WinDirect3DCreate9)(UINT SDKVersion); +typedef HRESULT (WINAPI *WinDirect3DCreate9Ex)(UINT SDKVersion, void** aDevice); + +// Overridden DXGI entry points +typedef HRESULT (WINAPI *WinCreateDXGIFactory)( + __in REFIID riid, + __out void **ppFactory + ); + +typedef HRESULT (WINAPI *WinCreateDXGIFactory1)( + __in REFIID riid, + __out void **ppFactory + ); + +typedef HRESULT (WINAPI *WinCreateDXGIFactory2)( + __in UINT flags, + __in const IID &riid, + __out void **ppFactory + ); + +// Application usermode callbacks from usermode driver. These +// functions are all provided by the calling application that uses +// the filter mode driver + +// IsInitializingDisplay is used at runtime to validate that +// the created resource (RT or bind_present) matches the resolution +// of our expected backbuffer. If the application returns true, +// our usermode driver will convert this to a primary +typedef BOOL (WINAPI *IsInitializingDisplay) ( PVOID, UINT, UINT ); +// RiftForContext is a function that will return the Rift device of +// the concerned context. This is for targeting a particular +// device instance with a particular Rift for rendering +typedef ULONG (WINAPI *RiftForContext)( PVOID, HANDLE ); +// CloseRiftForContext is a function that informs the application +// the created device is shutting down and the context +// can freedly disassociate with the particular +typedef BOOL (WINAPI *CloseRiftForContext)( PVOID, HANDLE, ULONG ); +typedef BOOL (WINAPI *WindowDisplayResolution)( PVOID, UINT*, UINT*, UINT*, UINT*, BOOL* ); +// IsCreatingBackBuffer is a function directed at the runtime shim +// to confirm that the runtime is actively creating the additional +// swapchain for rotation and display out to the rift. +// When creating the original swapchain this function should return false +// so the orignal swapchain isn't inadvertantly coopted. +typedef BOOL (WINAPI *IsCreatingBackBuffer)( PVOID ); +// Callback from the usermode driver to obtain the desire to see debug statements from +// the usermode drivers on the output console. Only called one per usermode driver shim +// and usermode runtime. +typedef BOOL (WINAPI *ShouldEnableDebug)( VOID ); +// Callback from the usermode driver to the runtime obtain the vsync status +typedef BOOL (WINAPI *ShouldVSync)( VOID ); +// Callback from usermode mode and runtime driver to obtain expected native width, +// height and degrees rotation of the rift +typedef BOOL (WINAPI *ExpectedResolution)( PVOID, UINT*, UINT*, UINT* ); +// Usermode callback that reports whether or not mirroring is enabled +typedef BOOL (WINAPI *MirroringEnabled)( PVOID ); +// Callback from the shim for Unity and other plugins used to +// report the swapchain that was created by the application +typedef void* (WINAPI *GetDX11SwapChain)( PVOID ); +// Callback to report the HWND associated with this context +typedef HWND (WINAPI* GetWindowForContext)( PVOID ); +// Should present Rift on context +typedef BOOL (WINAPI* PresentRiftOnContext)( PVOID ); +// Used by a pre-loaded shim (d3d9, dxgi, opengl32) to +// identify which api version we loaded +// 1 = OpenGL +// 9 = DirectX 9 +// 10 = DirectX 1X +typedef int (WINAPI* ActiveAPIVersion)( PVOID ); + +// Get the version of the runtime filter. +typedef ULONG (WINAPI* GetRTFilterVersion)(); + +#pragma warning(push) +#pragma warning(disable: 4201) + +typedef struct _LINK_APPLICATION_DRIVER +{ + UINT32 version; + PVOID context; + + union + { + struct + { + IsInitializingDisplay pfnInitializingDisplay; + RiftForContext pfnRiftForContext; + CloseRiftForContext pfnCloseRiftForContext; + WindowDisplayResolution pfnWindowDisplayResolution; + IsCreatingBackBuffer pfnIsCreatingBackBuffer; + ShouldEnableDebug pfnShouldEnableDebug; + ShouldVSync pfnShouldVSync; + ExpectedResolution pfnExpectedResolution; + MirroringEnabled pfnMirroringEnabled; + GetDX11SwapChain pfnGetDX11SwapChain; + GetWindowForContext pfnGetWindowForContext; + PresentRiftOnContext pfnPresentRiftOnContext; + ActiveAPIVersion pfnActiveAPIVersion; + }; + + PROC placeholders[128]; + }; + + + // Used by Runtime filter for linking with original libraries + WinDirect3DCreate9 pfnDirect3DCreate9; + WinDirect3DCreate9Ex pfnDirect3DCreate9Ex; + WinCreateDXGIFactory pfnCreateDXGIFactory; + WinCreateDXGIFactory1 pfnCreateDXGIFactory1; + WinCreateDXGIFactory2 pfnCreateDXGIFactory2; +} LINK_APPLICATION_DRIVER, *PLINK_APPLICATION_DRIVER; + +#pragma warning(pop) + + +// OVRDisplay.dll functionality +typedef HRESULT (WINAPI *PreloadLibraryFn) ( WinLoadLibraryA , LPCSTR, PLINK_APPLICATION_DRIVER appDriver ); +typedef HRESULT (WINAPI *PreloadLibraryRTFn) ( PLINK_APPLICATION_DRIVER appDriver ); + +//----------------------------------------------------------------------------------- +// Structures for UM driver to KM driver + +typedef struct _QUERY_KM_DRIVER +{ + UINT32 magic; // Friend or foe identifier for our filter driver + // See: QUERYADAPTER_MAGICHEADER + UINT32 maxVidPnSources; // Returns the maximum number of video present network sources +} QUERY_KM_DRIVER, *PQUERY_KM_DRIVER; + +#ifndef _D3DUKMDT_H_ +typedef UINT D3DKMT_HANDLE; +#endif + +typedef struct _HandleNotepad +{ + // These are assigned around CreateResource + HANDLE hUsermodeInResource; + HANDLE hUsermodeOutResource; + + // These are assigned within the kernel with + // DxgkDdiCreateAllocation and + // DxgkDdiOpenAllocation + D3DKMT_HANDLE hAllocation; + PVOID hDeviceSpecificHandle; + PVOID hKernelDriverHandle; + + // These are assigned around pfnAllocateCb + HANDLE hUsermodeSharedResource; + D3DKMT_HANDLE hKernelModeSharedResource; + + ULONG childUid; + + UINT pitch; + +} HandleNotepad, *PHandleNotepad; + + +typedef struct _ALLOC_PRIVATE_STRUCTURE +{ + UINT32 magic; // Friend or foe identifier for our filter driver + + PVOID originalPrivataDataPtr; // Location in usermode of the original private data structure + UINT originalPrivateSize; // Size of private data structure at the end of this header + + PVOID hAllocationHandle; // User-mode-assigned allocation handle for CreateAllocation + PVOID hDeviceSpecificHandle; // Assigned in kernal OpenAllocation + PVOID hInternalHandle; // Assigned in kernal CreateAllocation + UINT pitch; // Hinted surface pitch + + BYTE originalPrivateData[1]; // Variable length + + +} ALLOC_PRIVATE_STRUCTURE, *PALLOC_PRIVATE_STRUCTURE; + +typedef struct _ESCAPE_STRUCTURE +{ + UINT32 magic; // Friend or foe identifier for our filter driver + + UINT32 escapeType; // Specifier for individual type of escape message + // Type 1 for notepad + union { + HandleNotepad notepad; + }; +} ESCAPE_STRUCTURE, *PESCAPE_STRUCTURE; + +// Structures for internal operation of KM driver + +typedef struct _RIFT_SYNC +{ + ULONG childUid; // ChildUid as reported by RIFT_STATUS + ULONG vsync; // 1 for vsync, 0 for immediate +} RIFT_SYNC, *PRIFT_SYNC; + +typedef struct _RIFT_MODE +{ + ULONG childUid; // ChildUid as reported by RIFT_STATUS + ULONG mode; // Bitmap of mode values, defined by OVR_RIFT_HOME_* + HANDLE userModeHandle; // Handle of render target created in user mode + // that's usable as a primary +} RIFT_MODE, *PRIFT_MODE; + +typedef struct _RIFT_STATUS +{ + ULONG childUid; // Display driver assigned Uid for this display + ULONG mode; // Active rift mode, see OVR_RIFT_MODE_* + ULONG serialNumber; // Serial number as reported in the Rift's EDID + ULONG textureHandle; // Handle of shared render resource -- NULL if not shared +} RIFT_STATUS, *PRIFT_STATUS; + +typedef struct _RIFT_STATUS_ARRAY +{ + ULONG arraySize; // Size of pre-allocated RIFT_STATUS structures. + RIFT_STATUS status[1]; // Array of status blocks containing connection information on each Rift +} RIFT_STATUS_ARRAY, *PRIFT_STATUS_ARRAY; + +#pragma pack(pop) + +// IOCTL for UM application to KM driver + +#define OVR_STATUS_SUCCESS 0 +#define OVR_STATUS_FAIL -1 +#define OVR_STATUS_DRIVER_IN_USE -2 +#define OVR_STATUS_MODE_ALREADY_ACTIVE -3 +#define OVR_STATUS_RIFT_NOT_PRESENT -4 + +// +// Returns the number of Rift displays attached to the video adapter +// If 0, no Rift displays have been connected. +// If greater than 0, use this size to pre-allocate space for an array +// of rift statuses +// +// Input Buffer: Nothing +// Output Buffer: LONG - count of Rift displays attached to video adapter +// +#define IOCTL_RIFTMGR_GET_RIFT_COUNT CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX, METHOD_BUFFERED, FILE_ANY_ACCESS) + +// +// Fills out a pre-allocated array with information on the individually attached +// screens. +// +// On Input, specify the arraySize as the size of the allocation. +// +// On Output, the arraySize will be updated with the actual number of Rifts +// reported. Use IOCTL_RIFTMGR_GET_RIFT_COUNT to query the number of Rifts. +// If the count changes (added or removed) between calls, the function will either fail +// due to the buffer being too small, or the arraySize count will be updated +// with a new count of devices along with their respective parameters. +// +// Input Buffer: PRIFT_STATUS - Pointer to allocated status array +// Output Buffer: LONG - Count of Rift displays reported in the structure. -1 if out of +// memory +// +#define IOCTL_RIFTMGR_GET_RIFT_ARRAY CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 1, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Changes the mode of an attached Rift (DEPRECATED) +// Input Buffer: PRIFT_MODE - Pointer to a mode structure specifying the childUid and +// mode for a particular Rift +// Output Buffer: LONG - Non-zero on error, 0 on successful mode change +// +#define IOCTL_RIFTMGR_SET_RIFT_MODE CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 2, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Lock the primary of the rift and obtain an address +// Input Buffer: ULONG - ChildUid of a Rift as previously discovered +// Output Buffer: ULONG_PTR - Pointer to a usermode mapped address of the primary +#define IOCTL_RIFTMGR_GET_RIFT_PRIMARY CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 3, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Release Rift primary +// Input Buffer: PULONG_PTR - ChildUid of a Rift as previously discovered and virtual pointer +// Output Buffer: NOTHING +#define IOCTL_RIFTMGR_RELEASE_RIFT_PRIMARY CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 4, METHOD_NEITHER, FILE_ANY_ACCESS) + + +// Point the rift to another render target +// Input Buffer: PHANDLE - Array of handles, rift and the render target resource +// Output Buffer: NOTHING +#define IOCTL_RIFTMGR_SETRIFTBUFFER CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 5, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Enable or disable vsync on Rift present +// Input Buffer: PRIFT_SYNC - Pointer to a mode structure specifying the childUid and +// and sync +// Output Buffer: NOTHING +#define IOCTL_RIFTMGR_SETVSYNCMODE CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 6, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Get scan line +// Input Buffer: ULONG - ChildUid of a Rift as previously discovered +// Output Buffer: ULONG - 31st bit is set if in vertical blank, high 15 bits has per second +// frame number (0-74), low 16 bits has scanline (0-1919) +#define IOCTL_RIFTMGR_GETSCANLINE CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 7, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Enable or disable compatibility mode. Entering compatibility mode will fail if +// the Rift is already actively scanning out a surface +// Input Buffer: LONG - Bit assignments: +// LSB (bit 0) is a flag for compatibility mode itself. +// 1 means compatibility mode. +// 0 means application direct mode. +// Bit 1 means "Hide DK1's". +// 1 means operate DK1's in synchronous with the compatibility mode exactly. +// 0 means operate in DK1 legacy mode. +// Output Buffer: LONG - Result value (see OVR statuses) +// 0 = success +// -1 = general failure +// -2 = failure, rift scanning out +// -3 = already active +// -4 = rift not present +#define IOCTL_RIFTMGR_SETCOMPATIBILITYMODE CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 8, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Call to obtain the current status of compatibility mode +// Input Buffer: NOTHING +// Output Buffer: LONG - Bit assignments: +// LSB (bit 0) is a flag for compatibility mode itself. +// 1 means compatibility mode. +// 0 means application direct mode. +// Bit 1 means "Hide DK1's". +// 1 means operate DK1's in synchronous with the compatibility mode exactly. +// 0 means operate in DK1 legacy mode. +#define IOCTL_RIFTMGR_GETCOMPATIBILITYMODE CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 9, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Call to set the power mode of a particular Rift +// Input Buffer: PULONG_PTR - ChildUid of a Rift as previously discovered and ULONG value +// second ULONG has value of +// 0 to simply obtain the power status of the display +// 1 to set the display into a full power state (needs a primary to fully scan out) +// 2 to set the display into sleep mode +// 3 to set the display into full power off mode (WARNING: Will potentially trash primary) +// Output Buffer: LONG - Result value +// 0 = Failure to obtain power status +// 1 = Full power +// 2 = Sleep +// 3 = Power off +#define IOCTL_RIFTMGR_DISPLAYPOWER CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 10, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Return the EDID of the display in the output buffer. The driver +// will copy as many bytes as possible to fill the buffer. +// Input Buffer: ULONG - ChildUid of a Rift as previously discovered +// Output Buffer: PCHAR - Preallocated buffer of a variable size to store the EDID from the display +#define IOCTL_RIFTMGR_GETEDID CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 11, METHOD_NEITHER, FILE_ANY_ACCESS) + +#define IOCTL_RIFTMGR_WAITFORVSYNC CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 12, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Return information about the currently scanned out frame to the rift +// Input Buffer: ULONG - ChildUid of a Rift as previously discovered +// Output Buffer: UINT64[2] - Preallocated buffer of 2 UINT64s to hold CurrentFrameIndex & QPC time of current scan out start +#define IOCTL_RIFTMGR_GETCURRENTFRAMEINFO CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 13, METHOD_NEITHER, FILE_ANY_ACCESS) + +// Return the kernel index of the adapter that the rift is connected to +// Input Buffer: ULONG - ChildUid of a Rift as previously discovered +// Output Buffer: ULONG - The kernel adapter index +#define IOCTL_RIFTMGR_GETRIFTADAPTERID CTL_CODE(FILE_DEVICE_VIDEO, \ + FUNCTION_INDEX + 14, METHOD_NEITHER, FILE_ANY_ACCESS) + +#endif diff --git a/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp b/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp index 7c3c7a3..e551657 100644 --- a/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp +++ b/LibOVR/Src/Displays/OVR_Win32_FocusReader.cpp @@ -1,79 +1,79 @@ -/************************************************************************************ - -Filename : OVR_Win32_FocusReader.cpp -Content : Reader for current app with focus on Windows -Created : July 2, 2014 -Authors : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "OVR_Win32_FocusReader.h" -#include "../Kernel/OVR_Log.h" -#include "../Service/Service_NetClient.h" - -OVR_DEFINE_SINGLETON(OVR::Win32::RenderFocusReader); - -namespace OVR { namespace Win32 { - - -HWND RenderFocusReader::ReadActiveWindow() -{ - const LocklessFocusState* focusState = Reader.Get(); - - if (!focusState || NoSharedMemory) - { - if (!Reader.Open(OVR_FOCUS_OBSERVER_SHARE_NAME)) - { - OVR_DEBUG_LOG(("[Win32ShimFunctions] Unable to open the shared memory space")); - // Note: This should only warn and not assert because it is normal behavior when the server is not running. - NoSharedMemory = true; - return 0; - } - - focusState = Reader.Get(); - if (!focusState) - { - OVR_DEBUG_LOG(("[Win32ShimFunctions] Unable to get the shared memory space")); - NoSharedMemory = true; - return 0; - } - } - - return (HWND)Ptr64ToPtr(focusState->ActiveWindowHandle); -} - -RenderFocusReader::RenderFocusReader() : - NoSharedMemory(false) -{ - // Must be at end of function - PushDestroyCallbacks(); -} - -RenderFocusReader::~RenderFocusReader() -{ -} - -void RenderFocusReader::OnSystemDestroy() -{ - delete this; -} - - -}} // namespace OVR::Win32 +/************************************************************************************ + +Filename : OVR_Win32_FocusReader.cpp +Content : Reader for current app with focus on Windows +Created : July 2, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "OVR_Win32_FocusReader.h" +#include "Kernel/OVR_Log.h" +#include "../Service/Service_NetClient.h" + +OVR_DEFINE_SINGLETON(OVR::Win32::RenderFocusReader); + +namespace OVR { namespace Win32 { + + +HWND RenderFocusReader::ReadActiveWindow() +{ + const LocklessFocusState* focusState = Reader.Get(); + + if (!focusState || NoSharedMemory) + { + if (!Reader.Open(OVR_FOCUS_OBSERVER_SHARE_NAME)) + { + OVR_DEBUG_LOG(("[Win32ShimFunctions] Unable to open the shared memory space")); + // Note: This should only warn and not assert because it is normal behavior when the server is not running. + NoSharedMemory = true; + return 0; + } + + focusState = Reader.Get(); + if (!focusState) + { + OVR_DEBUG_LOG(("[Win32ShimFunctions] Unable to get the shared memory space")); + NoSharedMemory = true; + return 0; + } + } + + return (HWND)Ptr64ToPtr(focusState->ActiveWindowHandle); +} + +RenderFocusReader::RenderFocusReader() : + NoSharedMemory(false) +{ + // Must be at end of function + PushDestroyCallbacks(); +} + +RenderFocusReader::~RenderFocusReader() +{ +} + +void RenderFocusReader::OnSystemDestroy() +{ + delete this; +} + + +}} // namespace OVR::Win32 diff --git a/LibOVR/Src/Displays/OVR_Win32_FocusReader.h b/LibOVR/Src/Displays/OVR_Win32_FocusReader.h index 358ab38..3805b1d 100644 --- a/LibOVR/Src/Displays/OVR_Win32_FocusReader.h +++ b/LibOVR/Src/Displays/OVR_Win32_FocusReader.h @@ -1,81 +1,81 @@ -/************************************************************************************ - -Filename : OVR_Win32_FocusReader.h -Content : Reader for current app with focus on Windows -Created : July 2, 2014 -Authors : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Win32_FocusReader_h -#define OVR_Win32_FocusReader_h - -#include "../Kernel/OVR_System.h" -#include "../Kernel/OVR_Lockless.h" -#include "../Kernel/OVR_Array.h" -#include "../Kernel/OVR_SharedMemory.h" - -namespace OVR { namespace Win32 { - - -#define OVR_FOCUS_OBSERVER_SHARE_NAME "OVRAppFocus" - -//----------------------------------------------------------------------------- -// LocklessFocusState - -#pragma pack(push, 8) - -// Focus state data -struct LocklessFocusState -{ - LocklessFocusState(DWORD pid = 0) : - ActiveProcessId(pid), - ActiveWindowHandle(NULL) - { - } - - DWORD ActiveProcessId; - void * POINTER_64 ActiveWindowHandle; -}; - -#pragma pack(pop) - -typedef SharedObjectWriter< LocklessFocusState > SharedFocusWriter; -typedef SharedObjectReader< LocklessFocusState > SharedFocusReader; - - -//----------------------------------------------------------------------------- -// RenderFocusReader - -class RenderFocusReader : public OVR::SystemSingletonBase, public NewOverrideBase -{ - OVR_DECLARE_SINGLETON(RenderFocusReader); - - SharedFocusReader Reader; // Shared memory reader - bool NoSharedMemory; // Flag reporting that no shared memory has been detected; - -public: - HWND ReadActiveWindow(); -}; - - -}} // namespace OVR::Win32 - -#endif // OVR_Win32_FocusReader_h +/************************************************************************************ + +Filename : OVR_Win32_FocusReader.h +Content : Reader for current app with focus on Windows +Created : July 2, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Win32_FocusReader_h +#define OVR_Win32_FocusReader_h + +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Lockless.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_SharedMemory.h" + +namespace OVR { namespace Win32 { + + +#define OVR_FOCUS_OBSERVER_SHARE_NAME "OVRAppFocus" + +//----------------------------------------------------------------------------- +// LocklessFocusState + +#pragma pack(push, 8) + +// Focus state data +struct LocklessFocusState +{ + LocklessFocusState(DWORD pid = 0) : + ActiveProcessId(pid), + ActiveWindowHandle(NULL) + { + } + + DWORD ActiveProcessId; + void * POINTER_64 ActiveWindowHandle; +}; + +#pragma pack(pop) + +typedef SharedObjectWriter< LocklessFocusState > SharedFocusWriter; +typedef SharedObjectReader< LocklessFocusState > SharedFocusReader; + + +//----------------------------------------------------------------------------- +// RenderFocusReader + +class RenderFocusReader : public OVR::SystemSingletonBase, public NewOverrideBase +{ + OVR_DECLARE_SINGLETON(RenderFocusReader); + + SharedFocusReader Reader; // Shared memory reader + bool NoSharedMemory; // Flag reporting that no shared memory has been detected; + +public: + HWND ReadActiveWindow(); +}; + + +}} // namespace OVR::Win32 + +#endif // OVR_Win32_FocusReader_h diff --git a/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp b/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp index a74ab75..48bcf2b 100644 --- a/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp +++ b/LibOVR/Src/Displays/OVR_Win32_RenderShim.cpp @@ -1,974 +1,991 @@ -/************************************************************************************ - -Filename : OVR_Win32_DisplayShim.cpp -Content : Shared static functions for inclusion that allow for an application - to inject the usermode driver into an application -Created : March 21, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Use of this software is subject to the terms of the Oculus Inc license -agreement provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -************************************************************************************/ - -#include "../../Include/OVR_Version.h" - -#ifndef AVOID_LIB_OVR -#include "../Kernel/OVR_Types.h" // Without this we can get warnings (due to VC++ bugs) about _malloca being redefined, and miss LibOVR overrides. -#endif - -#include -#include -#include - -#include "OVR_Win32_Dxgi_Display.h" -#include "OVR_Win32_ShimVersion.h" - -#if AVOID_LIB_OVR -#define IN_COMPATIBILITY_MODE() (0) -#else -#include "OVR_Win32_Display.h" -#define IN_COMPATIBILITY_MODE() OVR::Display::InCompatibilityMode() -#endif - -#pragma comment(lib, "DbgHelp.lib") - -#define WIDE_TO_MB(wideString) \ - int wideString ## _slen = (int)wcslen(wideString); \ - char* wideString ## _cstr = (char*)alloca(wideString ## _slen * 2); \ - int count = WideCharToMultiByte(GetACP(), 0, wideString, -1, wideString ## _cstr, wideString ## _slen * 2, NULL, NULL); \ - wideString ## _cstr[count] = '\0'; - -// Forward declarations -// These functions are implemented in OVR_Win32_DisplayDevice.cpp. - -BOOL WINAPI OVRIsInitializingDisplay( PVOID context, UINT width, UINT height ); -BOOL WINAPI OVRIsCreatingBackBuffer( PVOID context ); -BOOL WINAPI OVRShouldVSync( ); -ULONG WINAPI OVRRiftForContext( PVOID context, HANDLE driverHandle ); -BOOL WINAPI OVRCloseRiftForContext( PVOID context, HANDLE driverHandle, ULONG rift ); -BOOL WINAPI OVRWindowDisplayResolution( PVOID context, UINT* width, UINT* height, - UINT* titleHeight, UINT* borderWidth, - BOOL* vsyncEnabled ); -BOOL WINAPI OVRExpectedResolution( PVOID context, UINT* width, UINT* height, UINT* rotationInDegrees ); -BOOL WINAPI OVRShouldEnableDebug(); -BOOL WINAPI OVRMirroringEnabled( PVOID context ); -HWND WINAPI OVRGetWindowForContext(PVOID context); -BOOL WINAPI OVRShouldPresentOnContext(PVOID context); - -static const char* GFX_DRIVER_KEY_FMT = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\%04d"; -#ifdef _WIN64 -static const char* RTFilter = "OVRDisplayRT64.dll"; -static const char* UMFilter = "OVRDisplay64.dll"; -#else -static const char* RTFilter = "OVRDisplayRT32.dll"; -static const char* UMFilter = "OVRDisplay32.dll"; -#endif -static const char* OptimusDrivers = "nvumdshimx.dll nvumdshim.dll"; - -typedef enum OVRTargetAPI -{ - DirectX, - OpenGL -}; - -static PVOID lastContext = NULL; -LINK_APPLICATION_DRIVER appDriver = {0}; -static INT apiVersion = 10; - -static CHAR* ReadRegStr(HKEY keySub, const char* keyName, const char* valName) -{ - CHAR *val = NULL; - REGSAM access = KEY_READ; - HKEY hKey; - -TryAgainWOW64: - NTSTATUS res = RegOpenKeyExA( keySub, keyName, 0, access, &hKey ); - if ( res == ERROR_SUCCESS ) - { - DWORD valLen; - res = RegQueryValueExA( hKey, valName, NULL, NULL, NULL, &valLen ); - if( res == ERROR_SUCCESS ) { - val = (CHAR*)calloc( valLen + 1, sizeof(CHAR) ); - res = RegQueryValueExA( hKey, valName, NULL, NULL, (LPBYTE)val, &valLen ); - - if( res == ERROR_SUCCESS ) - { - CHAR* byte = val; - for( DWORD j = 0; j < valLen; ++j ) - { - if( byte[j] == 0 ) - byte[j] = ' '; - } - } - else - { - free( val ); - val = NULL; - } - } - RegCloseKey( hKey ); - } - - if( res == ERROR_FILE_NOT_FOUND && keySub == HKEY_LOCAL_MACHINE && access == KEY_READ ) { -#ifdef _WIN64 - access = KEY_READ | KEY_WOW64_32KEY; -#else - access = KEY_READ | KEY_WOW64_64KEY; -#endif - goto TryAgainWOW64; - } - return val; -} - -#define OLD_DATA_BACKUP_SIZE 16 - -static WinLoadLibraryA oldProcA = NULL; // Note: This is used to indicate that the shim is in place -static WinLoadLibraryExA oldProcExA = NULL; -static WinLoadLibraryW oldProcW = NULL; -static WinLoadLibraryExW oldProcExW = NULL; -static WinGetModuleHandleExA oldProcModExA = NULL; -static WinGetModuleHandleExW oldProcModExW = NULL; -static WinDirect3DCreate9 oldDirectX9Create = NULL; -static BYTE oldDirectX9CreateData[OLD_DATA_BACKUP_SIZE]; -static WinDirect3DCreate9Ex oldDirectX9ExCreate = NULL; -static BYTE oldDirectX9ExCreateData[OLD_DATA_BACKUP_SIZE]; -static WinCreateDXGIFactory oldCreateDXGIFactory = NULL; -static BYTE oldCreateDXGIFactoryData[OLD_DATA_BACKUP_SIZE]; -static WinCreateDXGIFactory1 oldCreateDXGIFactory1 = NULL; -static BYTE oldCreateDXGIFactory1Data[OLD_DATA_BACKUP_SIZE]; -static WinCreateDXGIFactory2 oldCreateDXGIFactory2 = NULL; -static BYTE oldCreateDXGIFactory2Data[OLD_DATA_BACKUP_SIZE]; - -#define NUM_LOADER_LIBS 4 - -static const char* loaderLibraryList[NUM_LOADER_LIBS] = { - "kernel32.dll", - "api-ms-win-core-libraryloader-l1-2-0.dll", - "api-ms-win-core-libraryloader-l1-1-0.dll", - "api-ms-win-core-libraryloader-l1-1-1.dll" -}; - -enum ShimedLibraries -{ - ShimLibDXGI = 0, - ShimLibD3D9 = 1, - ShimLibD3D11 = 2, - ShimLibDXGIDebug = 3, - ShimLibD3D10Core = 4, - ShimLibD3D10 = 5, - ShimLibGL = 6, - ShimCountMax = 7 -}; - -static const char* dllList[ShimCountMax] = { - "dxgi.dll", - "d3d9.dll", - "d3d11.dll", - "dxgidebug.dll", - "d3d10core.dll", - "d3d10.dll", - "opengl32.dll" -}; - -static HINSTANCE oldLoaderInstances[ShimCountMax] = { NULL }; -static PROC oldLoaderProcA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; -static PROC oldLoaderProcW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; -static PROC oldLoaderProcExA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; -static PROC oldLoaderProcExW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; -static PROC oldLoaderProcModExA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; -static PROC oldLoaderProcModExW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; - -static HMODULE rtFilterModule = NULL; - -static bool checkForOverride( LPCSTR libFileName, OVRTargetAPI& targetApi ) -{ - for (int i=0; ; i++) - { - CHAR keyString[256] = {0}; - - sprintf_s( keyString, 256, GFX_DRIVER_KEY_FMT, i ); - - CHAR* infSection = ReadRegStr( HKEY_LOCAL_MACHINE, keyString, "InfSection" ); - - // No provider name means we're out of display enumerations - if( infSection == NULL ) - break; - - free(infSection); - - // Check 64-bit driver names followed by 32-bit driver names - const char* driverKeys[] = {"UserModeDriverName", "UserModeDriverNameWoW", "OpenGLDriverName", "OpenGLDriverNameWoW", "InstalledDisplayDrivers" }; - for( int j = 0; j < 6; ++j ) - { - CHAR userModeList[4096] = {0}; - - switch(j) - { - case 5: - strcpy_s( userModeList, 4095, OptimusDrivers ); - break; - default: - { - CHAR* regString = ReadRegStr( HKEY_LOCAL_MACHINE, keyString, driverKeys[j] ); - if( regString ) - { - strcpy_s( userModeList, 4095, regString ); - free( regString ); - } - - } - break; - } - - char *nextToken = NULL; - - if( userModeList ) - { - char* first = strtok_s( userModeList, " ", &nextToken ); - while( first ) - { - if( strstr( libFileName, first ) != 0 ) - { - if( j < 2 ) - targetApi = DirectX; - else - targetApi = OpenGL; - - return true; - } - first = strtok_s( NULL, " ", &nextToken ); - } - } - } - } - - return false; -} - -static HMODULE createShim( LPCSTR lpLibFileName, OVRTargetAPI targetAPI ) -{ - //Sleep(10000); - if( IN_COMPATIBILITY_MODE() ) - { - return (*oldProcA)( lpLibFileName ); - } - - UNREFERENCED_PARAMETER( targetAPI ); - - HMODULE result = NULL; - - result = (*oldProcA)( UMFilter ); - - if( result ) - { - PreloadLibraryFn loadFunc = (PreloadLibraryFn)GetProcAddress( result, "PreloadLibrary" ); - if( loadFunc ) - { - HRESULT localRes = (*loadFunc)( oldProcA, lpLibFileName, &appDriver ); - if( localRes != S_OK ) - result = NULL; - } - } - - if( !result ) - { - MessageBox(nullptr, L"Unable to find the Rift Display Driver.", L"Configuration Error", MB_OK | MB_ICONERROR); - result = (*oldProcA)( lpLibFileName ); - } - return result; -} - -static HMODULE - WINAPI - OVRLoadLibraryA( - __in LPCSTR lpLibFileName - ) -{ - OVRTargetAPI targetAPI = DirectX; - bool needShim = checkForOverride( lpLibFileName, targetAPI ); - if( !needShim ) - return (*oldProcA)( lpLibFileName ); - - return createShim( lpLibFileName, targetAPI ); -} - -static HMODULE - WINAPI - OVRLoadLibraryW( - __in LPCWSTR lpLibFileName - ) -{ - WIDE_TO_MB(lpLibFileName); // Convert lpLibFileName -> lpLibFileName_cstr - - OVRTargetAPI targetAPI = DirectX; - - bool needShim = checkForOverride( lpLibFileName_cstr, targetAPI ); - if( !needShim ) - return (*oldProcW)( lpLibFileName ); - - return createShim( lpLibFileName_cstr, targetAPI ); -} - -static HMODULE - WINAPI - OVRLoadLibraryExA( - __in LPCSTR lpLibFileName, - __reserved HANDLE hFile, - __in DWORD dwFlags - - ) -{ - OVRTargetAPI targetAPI = DirectX; - - bool needShim = checkForOverride( lpLibFileName, targetAPI ); - if( !needShim ) - return (*oldProcExA)( lpLibFileName, hFile, dwFlags ); - - // FIXME: Don't throw away the flags parameter - return createShim( lpLibFileName, targetAPI ); -} - -static HMODULE - WINAPI - OVRLoadLibraryExW( - __in LPCWSTR lpLibFileName, - __reserved HANDLE hFile, - __in DWORD dwFlags - ) -{ - WIDE_TO_MB(lpLibFileName); // Convert lpLibFileName -> lpLibFileName_cstr - - OVRTargetAPI targetAPI = DirectX; - - bool needShim = checkForOverride( lpLibFileName_cstr, targetAPI ); - if( !needShim ) - return (*oldProcExW)( lpLibFileName, hFile, dwFlags ); - - // FIXME: Don't throw away the flags parameter - return createShim( lpLibFileName_cstr, targetAPI ); -} - -static BOOL WINAPI OVRGetModuleHandleExA( - __in DWORD dwFlags, - __in_opt LPCSTR lpModuleName, - __out HMODULE *phModule - ) -{ - OVRTargetAPI targetAPI = DirectX; - - bool needShim = checkForOverride( lpModuleName, targetAPI ); - if( !needShim ) - { - return (*oldProcModExA)( dwFlags, lpModuleName, phModule ); - } - - *phModule = createShim( lpModuleName, targetAPI ); - - return TRUE; -} - -static BOOL WINAPI OVRGetModuleHandleExW( - __in DWORD dwFlags, - __in_opt LPCWSTR lpModuleName, - __out HMODULE *phModule - ) -{ - WIDE_TO_MB(lpModuleName); // Convert lpModuleName -> lpModuleName_cstr - - OVRTargetAPI targetAPI = DirectX; - - bool needShim = checkForOverride( lpModuleName_cstr, targetAPI ); - if( !needShim ) - { - return (*oldProcModExW)( dwFlags, lpModuleName, phModule ); - } - - *phModule = createShim( lpModuleName_cstr, targetAPI ); - - return TRUE; -} - -#ifdef _AMD64_ -static void restoreFunction( PROC pfnHookAPIAddr, PBYTE oldData ) -{ - static const LONGLONG addressSize = sizeof(PROC); - static const LONGLONG jmpSize = addressSize + 6; - - DWORD oldProtect; - VirtualProtect((LPVOID)pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE, - PAGE_EXECUTE_READWRITE, &oldProtect); - - memcpy(pfnHookAPIAddr, oldData, OLD_DATA_BACKUP_SIZE); - - VirtualProtect((LPVOID)pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE, oldProtect, NULL); -} - -static void setFunction( PROC pfnHookAPIAddr, PROC replacementFunction, PBYTE oldData ) -{ - static const LONGLONG addressSize = sizeof(PROC); - static const LONGLONG jmpSize = addressSize + 6; - - INT_PTR jumpOffset = (INT_PTR)replacementFunction; - - DWORD oldProtect; - VirtualProtect((LPVOID)pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE, - PAGE_EXECUTE_READWRITE, &oldProtect); - - memcpy(oldData, pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE); - - PBYTE functionData = (PBYTE)pfnHookAPIAddr; - functionData[0] = 0xff; // JMP [RIP+0] - functionData[1] = 0x25; // - functionData[2] = 0x00; // - functionData[3] = 0x00; // - functionData[4] = 0x00; // - functionData[5] = 0x00; // - memcpy( functionData + 6, &jumpOffset, sizeof( INT_PTR ) ); - - VirtualProtect((LPVOID)pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE, oldProtect, NULL); -} -#else -static void restoreFunction( PROC pfnHookAPIAddr, PBYTE oldData ) -{ - static const LONGLONG addressSize = sizeof(PROC); - static const LONGLONG jmpSize = addressSize + 1; - - DWORD oldProtect; - VirtualProtect((LPVOID)pfnHookAPIAddr, jmpSize, - PAGE_EXECUTE_READWRITE, &oldProtect); - - memcpy(pfnHookAPIAddr, oldData, jmpSize); - - VirtualProtect((LPVOID)pfnHookAPIAddr, jmpSize, oldProtect, NULL); -} - -static void setFunction( PROC pfnHookAPIAddr, PROC replacementFunction, PBYTE oldData ) -{ - static const LONGLONG addressSize = sizeof(PROC); - static const LONGLONG jmpSize = addressSize + 1; - - INT_PTR jumpOffset = (INT_PTR)replacementFunction - (INT_PTR)pfnHookAPIAddr - jmpSize; - - DWORD oldProtect; - VirtualProtect((LPVOID)pfnHookAPIAddr, jmpSize, - PAGE_EXECUTE_READWRITE, &oldProtect); - - memcpy(oldData, pfnHookAPIAddr, jmpSize); - - PBYTE functionData = (PBYTE)pfnHookAPIAddr; - memcpy( oldData, functionData, jmpSize ); - functionData[0] = 0xe9; - memcpy( functionData + 1, &jumpOffset, sizeof( INT_PTR ) ); - - VirtualProtect((LPVOID)pfnHookAPIAddr, jmpSize, oldProtect, NULL); -} -#endif - -static BOOL WINAPI OVRLocalIsInitializingDisplay( PVOID context, UINT width, UINT height ) -{ - UINT expectedWidth, expectedHeight, rotation; - - OVRExpectedResolution( context, &expectedWidth, &expectedHeight, &rotation ); - - if( appDriver.pfnActiveAPIVersion ) - apiVersion = (*appDriver.pfnActiveAPIVersion)( context ); - - switch( apiVersion ) - { - case 1: // OpenGL - case 10: // DirectX 1X - if( width == expectedWidth && height == expectedHeight ) - return TRUE; - break; - case 9: // DirectX 9 - if( rotation == 90 || rotation == 270 ) - { - if( width == expectedHeight && height == expectedWidth ) - return TRUE; - } - else - { - if( width == expectedWidth && height == expectedHeight ) - return TRUE; - } - break; - default: - break; - } - - return FALSE; -} - - -HRESULT APIENTRY OVRDirect3DCreate9Ex(UINT SDKVersion, void** aDevice) -{ - apiVersion = 9; - - HRESULT result = S_OK; - - restoreFunction( (PROC)oldDirectX9ExCreate, oldDirectX9ExCreateData ); - - if (IN_COMPATIBILITY_MODE()) - { - result = (*oldDirectX9ExCreate)(SDKVersion, aDevice); - } - else - { - WinDirect3DCreate9Ex createFunction = (WinDirect3DCreate9Ex)GetProcAddress(rtFilterModule, "Direct3DCreate9Ex"); - result = (*createFunction)(SDKVersion, aDevice); - } - - setFunction( (PROC)oldDirectX9ExCreate, (PROC)OVRDirect3DCreate9Ex, oldDirectX9ExCreateData ); - - printf("%s result 0x%x\n", __FUNCTION__, result); - - return result; -} - -void* APIENTRY OVRDirect3DCreate9(UINT SDKVersion) -{ - void* result = NULL; - - OVRDirect3DCreate9Ex( SDKVersion, &result ); - - return result; -} - -HRESULT APIENTRY OVRCreateDXGIFactory( - __in REFIID riid, - __out void **ppFactory - ) -{ - HRESULT result = E_FAIL; - - restoreFunction( (PROC)oldCreateDXGIFactory, oldCreateDXGIFactoryData ); - - if (IN_COMPATIBILITY_MODE()) - { - result = (*oldCreateDXGIFactory)(riid, ppFactory); - } - else - { - WinCreateDXGIFactory createFunction = (WinCreateDXGIFactory)GetProcAddress(rtFilterModule, "CreateDXGIFactory"); - result = (*createFunction)(riid, ppFactory); - } - - setFunction( (PROC)oldCreateDXGIFactory, (PROC)OVRCreateDXGIFactory, oldCreateDXGIFactoryData ); - - printf("%s result 0x%x\n", __FUNCTION__, result); - - return result; -} - -HRESULT APIENTRY OVRCreateDXGIFactory1( - __in REFIID riid, - __out void **ppFactory - ) -{ - HRESULT result = E_FAIL; - - restoreFunction( (PROC)oldCreateDXGIFactory1, oldCreateDXGIFactory1Data ); - - if (IN_COMPATIBILITY_MODE()) - { - result = (*oldCreateDXGIFactory1)(riid, ppFactory); - } - else - { - WinCreateDXGIFactory1 createFunction = (WinCreateDXGIFactory1)GetProcAddress(rtFilterModule, "CreateDXGIFactory1"); - result = (*createFunction)(riid, ppFactory); - } - - setFunction( (PROC)oldCreateDXGIFactory1, (PROC)OVRCreateDXGIFactory1, oldCreateDXGIFactory1Data ); - - printf("%s result 0x%x\n", __FUNCTION__, result); - - return result; -} - -HRESULT APIENTRY OVRCreateDXGIFactory2( - __in UINT flags, - __in const IID &riid, - __out void **ppFactory - ) -{ - HRESULT result = E_FAIL; - - restoreFunction( (PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data ); - - if (IN_COMPATIBILITY_MODE()) - { - result = (*oldCreateDXGIFactory2)(flags, riid, ppFactory); - } - else - { - WinCreateDXGIFactory2 createFunction = (WinCreateDXGIFactory2)GetProcAddress(rtFilterModule, "CreateDXGIFactory2"); - result = (*createFunction)(flags, riid, ppFactory); - } - - setFunction( (PROC)oldCreateDXGIFactory2, (PROC)OVRCreateDXGIFactory2, oldCreateDXGIFactory2Data ); - - printf("%s result 0x%x\n", __FUNCTION__, result); - - return result; -} - -static PROC SetProcAddressDirect( - __in HINSTANCE hInstance, - __in LPCSTR lpProcName, - __in PROC newFunction, - __inout BYTE* oldData - ) -{ - static const LONGLONG addressSize = sizeof(PROC); - static const LONGLONG jmpSize = addressSize + 1; - - PROC result = NULL; - - PROC pfnHookAPIAddr = GetProcAddress( hInstance, lpProcName ); - - if( pfnHookAPIAddr ) - { - result = pfnHookAPIAddr; - - setFunction( pfnHookAPIAddr, newFunction, oldData ); - } - - return result; -} - -static PROC SetProcAddressA( - __in HINSTANCE targetModule, - __in LPCSTR lpLibFileName, - __in LPCSTR lpProcName, - __in PROC newFunction - ) -{ - HMODULE hModule = LoadLibraryA( lpLibFileName ); - if(hModule == NULL) - return NULL; - - // To do: call FreeLibrary(hModule) at the appropriate time. - PROC pfnHookAPIAddr = GetProcAddress(hModule, lpProcName ); - - HINSTANCE hInstance = targetModule; - - ULONG ulSize; - PIMAGE_IMPORT_DESCRIPTOR pImportDesc = - (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData( - hInstance, - TRUE, - IMAGE_DIRECTORY_ENTRY_IMPORT, - &ulSize - ); - - while (pImportDesc->Name) - { - PSTR pszModName = (PSTR)((PBYTE) hInstance + pImportDesc->Name); - if (_stricmp(pszModName, lpLibFileName) == 0) - break; - pImportDesc++; - } - - PIMAGE_THUNK_DATA pThunk = - (PIMAGE_THUNK_DATA)((PBYTE) hInstance + pImportDesc->FirstThunk); - - while (pThunk->u1.Function) - { - PROC* ppfn = (PROC*) &pThunk->u1.Function; - BOOL bFound = (*ppfn == pfnHookAPIAddr); - - if (bFound) - { - MEMORY_BASIC_INFORMATION mbi; - VirtualQuery( - ppfn, - &mbi, - sizeof(MEMORY_BASIC_INFORMATION) - ); - VirtualProtect( - mbi.BaseAddress, - mbi.RegionSize, - PAGE_READWRITE, - &mbi.Protect); - - *ppfn = *newFunction; - - DWORD dwOldProtect; - VirtualProtect( - mbi.BaseAddress, - mbi.RegionSize, - mbi.Protect, - &dwOldProtect - ); - break; - } - pThunk++; - } - - return pfnHookAPIAddr; -} - - -bool checkUMDriverOverrides(void* context) -{ - lastContext = context; - if (oldProcA != NULL) - return true; - - PreloadLibraryRTFn loadFunc = NULL; - for( int i = 0; i < ShimCountMax; ++i ) - { - HINSTANCE hInst = NULL; - try - { - hInst = LoadLibraryA(dllList[i]); - } - catch(...) - { - } - - oldLoaderInstances[i] = hInst; - - if (hInst == NULL) - continue; - - ShimedLibraries libCount = (ShimedLibraries)i; - switch( libCount ) - { - case ShimLibDXGI: - oldCreateDXGIFactory = (WinCreateDXGIFactory)SetProcAddressDirect( hInst, "CreateDXGIFactory", (PROC)OVRCreateDXGIFactory, oldCreateDXGIFactoryData ); - oldCreateDXGIFactory1 = (WinCreateDXGIFactory1)SetProcAddressDirect( hInst, "CreateDXGIFactory1", (PROC)OVRCreateDXGIFactory1, oldCreateDXGIFactory1Data ); - oldCreateDXGIFactory2 = (WinCreateDXGIFactory2)SetProcAddressDirect( hInst, "CreateDXGIFactory2", (PROC)OVRCreateDXGIFactory2, oldCreateDXGIFactory2Data ); - break; - case ShimLibD3D9: - oldDirectX9Create = (WinDirect3DCreate9)SetProcAddressDirect( hInst, "Direct3DCreate9", (PROC)OVRDirect3DCreate9, oldDirectX9CreateData ); - oldDirectX9ExCreate = (WinDirect3DCreate9Ex)SetProcAddressDirect( hInst, "Direct3DCreate9Ex", (PROC)OVRDirect3DCreate9Ex, oldDirectX9ExCreateData ); - break; - default: - break; - } - - for (int j = 0; j < NUM_LOADER_LIBS; ++j) - { - const char* loaderLibrary = loaderLibraryList[j]; - - PROC temp = NULL; - temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryA", (PROC)OVRLoadLibraryA); - if (!oldProcA) - { - oldProcA = (WinLoadLibraryA)temp; - } - oldLoaderProcA[i][j] = temp; - - temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryW", (PROC)OVRLoadLibraryW); - if (!oldProcW) - { - oldProcW = (WinLoadLibraryW)temp; - } - oldLoaderProcW[i][j] = temp; - - temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExA", (PROC)OVRLoadLibraryExA); - if (!oldProcExA) - { - oldProcExA = (WinLoadLibraryExA)temp; - } - oldLoaderProcExA[i][j] = temp; - - temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExW", (PROC)OVRLoadLibraryExW); - if (!oldProcExW) - { - oldProcExW = (WinLoadLibraryExW)temp; - } - oldLoaderProcExW[i][j] = temp; - - temp = SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExA", (PROC)OVRGetModuleHandleExA); - if (!oldProcModExA) - { - oldProcModExA = (WinGetModuleHandleExA)temp; - } - oldLoaderProcModExA[i][j] = temp; - - temp = SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExW", (PROC)OVRGetModuleHandleExW); - if (!oldProcModExW) - { - oldProcModExW = (WinGetModuleHandleExW)temp; - } - oldLoaderProcModExW[i][j] = temp; - } - - if (loadFunc == NULL) - { - loadFunc = (PreloadLibraryRTFn)GetProcAddress(hInst, "PreloadLibraryRT"); - } - } - - rtFilterModule = oldProcA ? (*oldProcA)(RTFilter) : NULL; - - IsCreatingBackBuffer backBufferFunc = NULL; - ShouldVSync shouldVSyncFunc = NULL; - GetRTFilterVersion getRTFilterVersionFunc = NULL; - - if (rtFilterModule != NULL) - { - loadFunc = (PreloadLibraryRTFn)GetProcAddress(rtFilterModule, "PreloadLibraryRT"); - backBufferFunc = (IsCreatingBackBuffer)GetProcAddress(rtFilterModule, "OVRIsCreatingBackBuffer"); - shouldVSyncFunc = (ShouldVSync)GetProcAddress(rtFilterModule, "OVRShouldVSync"); - getRTFilterVersionFunc = (GetRTFilterVersion)GetProcAddress(rtFilterModule, "OVRGetRTFilterVersion"); - } - - if (loadFunc == NULL) - { - MessageBox(nullptr, L"Unable to load the Oculus Display Driver. Please reinstall the Oculus Runtime.", L"Configuration Error", MB_OK | MB_ICONERROR); - return false; - } - - if (getRTFilterVersionFunc == NULL) - { - WCHAR message[1000] = {}; - swprintf_s(message, L"This app requires the %d.%d.%d version of the Oculus Runtime.", OVR_MAJOR_VERSION, OVR_MINOR_VERSION, OVR_BUILD_VERSION); - MessageBox(nullptr, message, L"Configuration Error", MB_OK | MB_ICONERROR); - return false; - } - - // Verify that we are running with the appropriate display driver - { - const ULONG rtFilterVersion = (*getRTFilterVersionFunc)(); - const ULONG rtFilterMajor = OVR_GET_VERSION_MAJOR(rtFilterVersion); - const ULONG rtFilterMinor = OVR_GET_VERSION_MINOR(rtFilterVersion); - - if ((rtFilterMajor != OVR_RTFILTER_VERSION_MAJOR) || (rtFilterMinor < OVR_RTFILTER_VERSION_MINOR)) - { - WCHAR message[1000] = {}; - swprintf_s(message, L"This app requires the %d.%d.%d version of the Oculus Runtime.", OVR_MAJOR_VERSION, OVR_MINOR_VERSION, OVR_BUILD_VERSION); - MessageBox(nullptr, message, L"Configuration Error", MB_OK | MB_ICONERROR); - return false; - } - } - - appDriver.version = OVR_RENDER_SHIM_VERSION_MAJOR; - appDriver.context = lastContext; - -// appDriver.pfnInitializingDisplay = OVRIsInitializingDisplay; - appDriver.pfnInitializingDisplay = OVRLocalIsInitializingDisplay; - appDriver.pfnRiftForContext = OVRRiftForContext; - appDriver.pfnCloseRiftForContext = OVRCloseRiftForContext; - appDriver.pfnWindowDisplayResolution = OVRWindowDisplayResolution; - appDriver.pfnShouldEnableDebug = OVRShouldEnableDebug; - appDriver.pfnIsCreatingBackBuffer = (backBufferFunc == NULL) ? OVRIsCreatingBackBuffer : backBufferFunc; - appDriver.pfnShouldVSync = (shouldVSyncFunc == NULL) ? OVRShouldVSync : shouldVSyncFunc; - appDriver.pfnExpectedResolution = OVRExpectedResolution; - appDriver.pfnMirroringEnabled = OVRMirroringEnabled; - appDriver.pfnGetWindowForContext = OVRGetWindowForContext; - appDriver.pfnPresentRiftOnContext = OVRShouldPresentOnContext; - - appDriver.pfnDirect3DCreate9 = oldDirectX9Create; - appDriver.pfnDirect3DCreate9Ex = oldDirectX9ExCreate; - appDriver.pfnCreateDXGIFactory = oldCreateDXGIFactory; - appDriver.pfnCreateDXGIFactory1 = oldCreateDXGIFactory1; - appDriver.pfnCreateDXGIFactory2 = oldCreateDXGIFactory2; - - (*loadFunc)( &appDriver ); - - return true; -} - -void clearUMDriverOverrides() -{ - if (oldProcA != NULL) - { - // Unpatch all the things. - - if (oldCreateDXGIFactory) - { - restoreFunction((PROC)oldCreateDXGIFactory, oldCreateDXGIFactoryData); - } - if (oldCreateDXGIFactory1) - { - restoreFunction((PROC)oldCreateDXGIFactory1, oldCreateDXGIFactory1Data); - } - if (oldCreateDXGIFactory2) - { - restoreFunction((PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data); - } - if (oldDirectX9Create) - { - restoreFunction((PROC)oldDirectX9Create, oldDirectX9CreateData); - } - if (oldDirectX9ExCreate) - { - restoreFunction((PROC)oldDirectX9ExCreate, oldDirectX9ExCreateData); - } - if (oldCreateDXGIFactory2) - { - restoreFunction((PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data); - } - - for (int i = 0; i < ShimCountMax; ++i) - { - HINSTANCE hInst = oldLoaderInstances[i]; - - if (hInst != NULL) - { - for (int j = 0; j < NUM_LOADER_LIBS; ++j) - { - const char* loaderLibrary = loaderLibraryList[j]; - - if (oldLoaderProcA[j]) - { - SetProcAddressA(hInst, loaderLibrary, "LoadLibraryA", oldLoaderProcA[i][j]); - } - if (oldLoaderProcW[j]) - { - SetProcAddressA(hInst, loaderLibrary, "LoadLibraryW", oldLoaderProcW[i][j]); - } - if (oldLoaderProcExA[j]) - { - SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExA", oldLoaderProcExA[i][j]); - } - if (oldLoaderProcExW[j]) - { - SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExW", oldLoaderProcExW[i][j]); - } - if (oldLoaderProcModExA[j]) - { - SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExA", oldLoaderProcModExA[i][j]); - } - if (oldLoaderProcModExW[j]) - { - SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExW", oldLoaderProcModExW[i][j]); - } - } - - FreeLibrary(hInst); - } - } - - if (rtFilterModule != NULL) - { - LPFNCANUNLOADNOW pfnCanUnloadNow = (LPFNCANUNLOADNOW)GetProcAddress(rtFilterModule, "DllCanUnloadNow"); - if (pfnCanUnloadNow && pfnCanUnloadNow() == S_OK) - { - FreeLibrary(rtFilterModule); - rtFilterModule = NULL; - } - } - - oldProcA = NULL; - oldProcExA = NULL; - oldProcW = NULL; - oldProcExW = NULL; - oldProcModExA = NULL; - oldProcModExW = NULL; - oldDirectX9Create = NULL; - oldDirectX9ExCreate = NULL; - oldCreateDXGIFactory = NULL; - oldCreateDXGIFactory1 = NULL; - oldCreateDXGIFactory2 = NULL; - lastContext = NULL; - } -} +/************************************************************************************ + +Filename : OVR_Win32_DisplayShim.cpp +Content : Shared static functions for inclusion that allow for an application + to inject the usermode driver into an application +Created : March 21, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Use of this software is subject to the terms of the Oculus Inc license +agreement provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +************************************************************************************/ + +#include "../../Include/OVR_Version.h" + +#ifndef AVOID_LIB_OVR +#include "Kernel/OVR_Types.h" // Without this we can get warnings (due to VC++ bugs) about _malloca being redefined, and miss LibOVR overrides. +#include "Kernel/OVR_Win32_IncludeWindows.h" +#else +#include +#ifndef NTSTATUS +#define NTSTATUS DWORD +#endif +#endif + +#include + +#include +#include "OVR_Win32_Dxgi_Display.h" +#include "OVR_Win32_ShimVersion.h" + +#if AVOID_LIB_OVR +#define IN_COMPATIBILITY_MODE() (0) +#else +#include "OVR_Win32_Display.h" +#define IN_COMPATIBILITY_MODE() OVR::Display::InCompatibilityMode() +#endif + +#pragma comment(lib, "DbgHelp.lib") + +#ifndef alloca +#include // alloca +#endif + +#define WIDE_TO_MB(wideString) \ + int wideString ## _slen = (int)wcslen(wideString); \ + char* wideString ## _cstr = (char*)alloca(wideString ## _slen * 2); \ + int count = WideCharToMultiByte(GetACP(), 0, wideString, -1, wideString ## _cstr, wideString ## _slen * 2, NULL, NULL); \ + wideString ## _cstr[count] = '\0'; + +// Forward declarations +// These functions are implemented in OVR_Win32_DisplayDevice.cpp. + +BOOL WINAPI OVRIsInitializingDisplay( PVOID context, UINT width, UINT height ); +BOOL WINAPI OVRIsCreatingBackBuffer( PVOID context ); +BOOL WINAPI OVRShouldVSync( ); +ULONG WINAPI OVRRiftForContext( PVOID context, HANDLE driverHandle ); +BOOL WINAPI OVRCloseRiftForContext( PVOID context, HANDLE driverHandle, ULONG rift ); +BOOL WINAPI OVRWindowDisplayResolution( PVOID context, UINT* width, UINT* height, + UINT* titleHeight, UINT* borderWidth, + BOOL* vsyncEnabled ); +BOOL WINAPI OVRExpectedResolution( PVOID context, UINT* width, UINT* height, UINT* rotationInDegrees ); +BOOL WINAPI OVRShouldEnableDebug(); +BOOL WINAPI OVRMirroringEnabled( PVOID context ); +HWND WINAPI OVRGetWindowForContext(PVOID context); +BOOL WINAPI OVRShouldPresentOnContext(PVOID context); + +static const char* GFX_DRIVER_KEY_FMT = "SYSTEM\\CurrentControlSet\\Control\\Class\\{4d36e968-e325-11ce-bfc1-08002be10318}\\%04d"; +#ifdef _WIN64 +static const char* RTFilter = "OVRDisplayRT64.dll"; +static const char* UMFilter = "OVRDisplay64.dll"; +#else +static const char* RTFilter = "OVRDisplayRT32.dll"; +static const char* UMFilter = "OVRDisplay32.dll"; +#endif +static const char* OptimusDrivers = "nvumdshimx.dll nvumdshim.dll"; + +typedef enum OVRTargetAPI +{ + DirectX, + OpenGL +}; + +static PVOID lastContext = NULL; +LINK_APPLICATION_DRIVER appDriver = {0}; +static INT apiVersion = 10; + +static CHAR* ReadRegStr(HKEY keySub, const char* keyName, const char* valName) +{ + CHAR *val = NULL; + REGSAM access = KEY_READ; + HKEY hKey; + +TryAgainWOW64: + NTSTATUS res = RegOpenKeyExA( keySub, keyName, 0, access, &hKey ); + if ( res == ERROR_SUCCESS ) + { + DWORD valLen; + res = RegQueryValueExA( hKey, valName, NULL, NULL, NULL, &valLen ); + if( res == ERROR_SUCCESS ) { + val = (CHAR*)calloc( valLen + 1, sizeof(CHAR) ); + res = RegQueryValueExA( hKey, valName, NULL, NULL, (LPBYTE)val, &valLen ); + + if( res == ERROR_SUCCESS ) + { + CHAR* byte = val; + for( DWORD j = 0; j < valLen; ++j ) + { + if( byte[j] == 0 ) + byte[j] = ' '; + } + } + else + { + free( val ); + val = NULL; + } + } + RegCloseKey( hKey ); + } + + if( res == ERROR_FILE_NOT_FOUND && keySub == HKEY_LOCAL_MACHINE && access == KEY_READ ) { +#ifdef _WIN64 + access = KEY_READ | KEY_WOW64_32KEY; +#else + access = KEY_READ | KEY_WOW64_64KEY; +#endif + goto TryAgainWOW64; + } + return val; +} + +#define OLD_DATA_BACKUP_SIZE 16 + +static WinLoadLibraryA oldProcA = NULL; // Note: This is used to indicate that the shim is in place +static WinLoadLibraryExA oldProcExA = NULL; +static WinLoadLibraryW oldProcW = NULL; +static WinLoadLibraryExW oldProcExW = NULL; +static WinGetModuleHandleExA oldProcModExA = NULL; +static WinGetModuleHandleExW oldProcModExW = NULL; +static WinDirect3DCreate9 oldDirectX9Create = NULL; +static BYTE oldDirectX9CreateData[OLD_DATA_BACKUP_SIZE]; +static WinDirect3DCreate9Ex oldDirectX9ExCreate = NULL; +static BYTE oldDirectX9ExCreateData[OLD_DATA_BACKUP_SIZE]; +static WinCreateDXGIFactory oldCreateDXGIFactory = NULL; +static BYTE oldCreateDXGIFactoryData[OLD_DATA_BACKUP_SIZE]; +static WinCreateDXGIFactory1 oldCreateDXGIFactory1 = NULL; +static BYTE oldCreateDXGIFactory1Data[OLD_DATA_BACKUP_SIZE]; +static WinCreateDXGIFactory2 oldCreateDXGIFactory2 = NULL; +static BYTE oldCreateDXGIFactory2Data[OLD_DATA_BACKUP_SIZE]; + +#define NUM_LOADER_LIBS 4 + +static const char* loaderLibraryList[NUM_LOADER_LIBS] = { + "kernel32.dll", + "api-ms-win-core-libraryloader-l1-2-0.dll", + "api-ms-win-core-libraryloader-l1-1-0.dll", + "api-ms-win-core-libraryloader-l1-1-1.dll" +}; + +enum ShimedLibraries +{ + ShimLibDXGI = 0, + ShimLibD3D9 = 1, + ShimLibD3D11 = 2, + ShimLibDXGIDebug = 3, + ShimLibD3D10Core = 4, + ShimLibD3D10 = 5, + ShimLibGL = 6, + ShimCountMax = 7 +}; + +static const char* dllList[ShimCountMax] = { + "dxgi.dll", + "d3d9.dll", + "d3d11.dll", + "dxgidebug.dll", + "d3d10core.dll", + "d3d10.dll", + "opengl32.dll" +}; + +static HINSTANCE oldLoaderInstances[ShimCountMax] = { NULL }; +static PROC oldLoaderProcA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcExA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcExW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcModExA[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; +static PROC oldLoaderProcModExW[ShimCountMax][NUM_LOADER_LIBS] = { { NULL } }; + +static HMODULE rtFilterModule = NULL; + +static bool checkForOverride( LPCSTR libFileName, OVRTargetAPI& targetApi ) +{ + for (int i=0; ; i++) + { + CHAR keyString[256] = {0}; + + sprintf_s( keyString, 256, GFX_DRIVER_KEY_FMT, i ); + + CHAR* infSection = ReadRegStr( HKEY_LOCAL_MACHINE, keyString, "InfSection" ); + + // No provider name means we're out of display enumerations + if( infSection == NULL ) + break; + + free(infSection); + + // Check 64-bit driver names followed by 32-bit driver names + const char* driverKeys[] = {"UserModeDriverName", "UserModeDriverNameWoW", "OpenGLDriverName", "OpenGLDriverNameWoW", "InstalledDisplayDrivers" }; + for( int j = 0; j < 6; ++j ) + { + CHAR userModeList[4096] = {0}; + + switch(j) + { + case 5: + strcpy_s( userModeList, 4095, OptimusDrivers ); + break; + default: + { + CHAR* regString = ReadRegStr( HKEY_LOCAL_MACHINE, keyString, driverKeys[j] ); + if( regString ) + { + strcpy_s( userModeList, 4095, regString ); + free( regString ); + } + + } + break; + } + + char *nextToken = NULL; + + if( userModeList ) + { + char* first = strtok_s( userModeList, " ", &nextToken ); + while( first ) + { + if( strstr( libFileName, first ) != 0 ) + { + if( j < 2 ) + targetApi = DirectX; + else + targetApi = OpenGL; + + return true; + } + first = strtok_s( NULL, " ", &nextToken ); + } + } + } + } + + return false; +} + +static HMODULE createShim( LPCSTR lpLibFileName, OVRTargetAPI targetAPI ) +{ + //Sleep(10000); + if( IN_COMPATIBILITY_MODE() ) + { + return (*oldProcA)( lpLibFileName ); + } + + UNREFERENCED_PARAMETER( targetAPI ); + + HMODULE result = NULL; + + result = (*oldProcA)( UMFilter ); + + if( result ) + { + PreloadLibraryFn loadFunc = (PreloadLibraryFn)GetProcAddress( result, "PreloadLibrary" ); + if( loadFunc ) + { + HRESULT localRes = (*loadFunc)( oldProcA, lpLibFileName, &appDriver ); + if( localRes != S_OK ) + result = NULL; + } + } + + if( !result ) + { + MessageBox(nullptr, L"Unable to find the Rift Display Driver.", L"Configuration Error", MB_OK | MB_ICONERROR); + result = (*oldProcA)( lpLibFileName ); + } + return result; +} + +static HMODULE + WINAPI + OVRLoadLibraryA( + __in LPCSTR lpLibFileName + ) +{ + OVRTargetAPI targetAPI = DirectX; + bool needShim = checkForOverride( lpLibFileName, targetAPI ); + if( !needShim ) + return (*oldProcA)( lpLibFileName ); + + return createShim( lpLibFileName, targetAPI ); +} + +static HMODULE + WINAPI + OVRLoadLibraryW( + __in LPCWSTR lpLibFileName + ) +{ + WIDE_TO_MB(lpLibFileName); // Convert lpLibFileName -> lpLibFileName_cstr + + OVRTargetAPI targetAPI = DirectX; + + bool needShim = checkForOverride( lpLibFileName_cstr, targetAPI ); + if( !needShim ) + return (*oldProcW)( lpLibFileName ); + + return createShim( lpLibFileName_cstr, targetAPI ); +} + +static HMODULE + WINAPI + OVRLoadLibraryExA( + __in LPCSTR lpLibFileName, + __reserved HANDLE hFile, + __in DWORD dwFlags + + ) +{ + OVRTargetAPI targetAPI = DirectX; + + bool needShim = checkForOverride( lpLibFileName, targetAPI ); + if( !needShim ) + return (*oldProcExA)( lpLibFileName, hFile, dwFlags ); + + // FIXME: Don't throw away the flags parameter + return createShim( lpLibFileName, targetAPI ); +} + +static HMODULE + WINAPI + OVRLoadLibraryExW( + __in LPCWSTR lpLibFileName, + __reserved HANDLE hFile, + __in DWORD dwFlags + ) +{ + WIDE_TO_MB(lpLibFileName); // Convert lpLibFileName -> lpLibFileName_cstr + + OVRTargetAPI targetAPI = DirectX; + + bool needShim = checkForOverride( lpLibFileName_cstr, targetAPI ); + if( !needShim ) + return (*oldProcExW)( lpLibFileName, hFile, dwFlags ); + + // FIXME: Don't throw away the flags parameter + return createShim( lpLibFileName_cstr, targetAPI ); +} + +static BOOL WINAPI OVRGetModuleHandleExA( + __in DWORD dwFlags, + __in_opt LPCSTR lpModuleName, + __out HMODULE *phModule + ) +{ + OVRTargetAPI targetAPI = DirectX; + + bool needShim = checkForOverride( lpModuleName, targetAPI ); + if( !needShim ) + { + return (*oldProcModExA)( dwFlags, lpModuleName, phModule ); + } + + *phModule = createShim( lpModuleName, targetAPI ); + + return TRUE; +} + +static BOOL WINAPI OVRGetModuleHandleExW( + __in DWORD dwFlags, + __in_opt LPCWSTR lpModuleName, + __out HMODULE *phModule + ) +{ + WIDE_TO_MB(lpModuleName); // Convert lpModuleName -> lpModuleName_cstr + + OVRTargetAPI targetAPI = DirectX; + + bool needShim = checkForOverride( lpModuleName_cstr, targetAPI ); + if( !needShim ) + { + return (*oldProcModExW)( dwFlags, lpModuleName, phModule ); + } + + *phModule = createShim( lpModuleName_cstr, targetAPI ); + + return TRUE; +} + +#ifdef _AMD64_ +static void restoreFunction( PROC pfnHookAPIAddr, PBYTE oldData ) +{ + static const LONGLONG addressSize = sizeof(PROC); + static const LONGLONG jmpSize = addressSize + 6; + + DWORD oldProtect; + VirtualProtect((LPVOID)pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE, + PAGE_EXECUTE_READWRITE, &oldProtect); + + memcpy(pfnHookAPIAddr, oldData, OLD_DATA_BACKUP_SIZE); + + VirtualProtect((LPVOID)pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE, oldProtect, NULL); +} + +static void setFunction( PROC pfnHookAPIAddr, PROC replacementFunction, PBYTE oldData ) +{ + static const LONGLONG addressSize = sizeof(PROC); + static const LONGLONG jmpSize = addressSize + 6; + + INT_PTR jumpOffset = (INT_PTR)replacementFunction; + + DWORD oldProtect; + VirtualProtect((LPVOID)pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE, + PAGE_EXECUTE_READWRITE, &oldProtect); + + memcpy(oldData, pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE); + + PBYTE functionData = (PBYTE)pfnHookAPIAddr; + functionData[0] = 0xff; // JMP [RIP+0] + functionData[1] = 0x25; // + functionData[2] = 0x00; // + functionData[3] = 0x00; // + functionData[4] = 0x00; // + functionData[5] = 0x00; // + memcpy( functionData + 6, &jumpOffset, sizeof( INT_PTR ) ); + + VirtualProtect((LPVOID)pfnHookAPIAddr, OLD_DATA_BACKUP_SIZE, oldProtect, NULL); +} +#else +static void restoreFunction( PROC pfnHookAPIAddr, PBYTE oldData ) +{ + static const LONGLONG addressSize = sizeof(PROC); + static const LONGLONG jmpSize = addressSize + 1; + + DWORD oldProtect; + VirtualProtect((LPVOID)pfnHookAPIAddr, jmpSize, + PAGE_EXECUTE_READWRITE, &oldProtect); + + memcpy(pfnHookAPIAddr, oldData, jmpSize); + + VirtualProtect((LPVOID)pfnHookAPIAddr, jmpSize, oldProtect, NULL); +} + +static void setFunction( PROC pfnHookAPIAddr, PROC replacementFunction, PBYTE oldData ) +{ + static const LONGLONG addressSize = sizeof(PROC); + static const LONGLONG jmpSize = addressSize + 1; + + INT_PTR jumpOffset = (INT_PTR)replacementFunction - (INT_PTR)pfnHookAPIAddr - jmpSize; + + DWORD oldProtect; + VirtualProtect((LPVOID)pfnHookAPIAddr, jmpSize, + PAGE_EXECUTE_READWRITE, &oldProtect); + + memcpy(oldData, pfnHookAPIAddr, jmpSize); + + PBYTE functionData = (PBYTE)pfnHookAPIAddr; + memcpy( oldData, functionData, jmpSize ); + functionData[0] = 0xe9; + memcpy( functionData + 1, &jumpOffset, sizeof( INT_PTR ) ); + + VirtualProtect((LPVOID)pfnHookAPIAddr, jmpSize, oldProtect, NULL); +} +#endif + +static BOOL WINAPI OVRLocalIsInitializingDisplay( PVOID context, UINT width, UINT height ) +{ + UINT expectedWidth, expectedHeight, rotation; + + OVRExpectedResolution( context, &expectedWidth, &expectedHeight, &rotation ); + + if( appDriver.pfnActiveAPIVersion ) + apiVersion = (*appDriver.pfnActiveAPIVersion)( context ); + + switch( apiVersion ) + { + case 1: // OpenGL + case 10: // DirectX 1X + if( width == expectedWidth && height == expectedHeight ) + return TRUE; + break; + case 9: // DirectX 9 + if( rotation == 90 || rotation == 270 ) + { + if( width == expectedHeight && height == expectedWidth ) + return TRUE; + } + else + { + if( width == expectedWidth && height == expectedHeight ) + return TRUE; + } + break; + default: + break; + } + + return FALSE; +} + + +HRESULT APIENTRY OVRDirect3DCreate9Ex(UINT SDKVersion, void** aDevice) +{ + apiVersion = 9; + + HRESULT result = S_OK; + + restoreFunction( (PROC)oldDirectX9ExCreate, oldDirectX9ExCreateData ); + + if (IN_COMPATIBILITY_MODE()) + { + result = (*oldDirectX9ExCreate)(SDKVersion, aDevice); + } + else + { + WinDirect3DCreate9Ex createFunction = (WinDirect3DCreate9Ex)GetProcAddress(rtFilterModule, "Direct3DCreate9Ex"); + result = (*createFunction)(SDKVersion, aDevice); + } + + setFunction( (PROC)oldDirectX9ExCreate, (PROC)OVRDirect3DCreate9Ex, oldDirectX9ExCreateData ); + + printf("%s result 0x%x\n", __FUNCTION__, result); + + return result; +} + +void* APIENTRY OVRDirect3DCreate9(UINT SDKVersion) +{ + void* result = NULL; + + OVRDirect3DCreate9Ex( SDKVersion, &result ); + + return result; +} + +HRESULT APIENTRY OVRCreateDXGIFactory( + __in REFIID riid, + __out void **ppFactory + ) +{ + HRESULT result = E_FAIL; + + restoreFunction( (PROC)oldCreateDXGIFactory, oldCreateDXGIFactoryData ); + + if (IN_COMPATIBILITY_MODE()) + { + result = (*oldCreateDXGIFactory)(riid, ppFactory); + } + else + { + WinCreateDXGIFactory createFunction = (WinCreateDXGIFactory)GetProcAddress(rtFilterModule, "CreateDXGIFactory"); + result = (*createFunction)(riid, ppFactory); + } + + setFunction( (PROC)oldCreateDXGIFactory, (PROC)OVRCreateDXGIFactory, oldCreateDXGIFactoryData ); + + printf("%s result 0x%x\n", __FUNCTION__, result); + + return result; +} + +HRESULT APIENTRY OVRCreateDXGIFactory1( + __in REFIID riid, + __out void **ppFactory + ) +{ + HRESULT result = E_FAIL; + + restoreFunction( (PROC)oldCreateDXGIFactory1, oldCreateDXGIFactory1Data ); + + if (IN_COMPATIBILITY_MODE()) + { + result = (*oldCreateDXGIFactory1)(riid, ppFactory); + } + else + { + WinCreateDXGIFactory1 createFunction = (WinCreateDXGIFactory1)GetProcAddress(rtFilterModule, "CreateDXGIFactory1"); + result = (*createFunction)(riid, ppFactory); + } + + setFunction( (PROC)oldCreateDXGIFactory1, (PROC)OVRCreateDXGIFactory1, oldCreateDXGIFactory1Data ); + + printf("%s result 0x%x\n", __FUNCTION__, result); + + return result; +} + +HRESULT APIENTRY OVRCreateDXGIFactory2( + __in UINT flags, + __in const IID &riid, + __out void **ppFactory + ) +{ + HRESULT result = E_FAIL; + + restoreFunction( (PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data ); + + if (IN_COMPATIBILITY_MODE()) + { + result = (*oldCreateDXGIFactory2)(flags, riid, ppFactory); + } + else + { + WinCreateDXGIFactory2 createFunction = (WinCreateDXGIFactory2)GetProcAddress(rtFilterModule, "CreateDXGIFactory2"); + result = (*createFunction)(flags, riid, ppFactory); + } + + setFunction( (PROC)oldCreateDXGIFactory2, (PROC)OVRCreateDXGIFactory2, oldCreateDXGIFactory2Data ); + + printf("%s result 0x%x\n", __FUNCTION__, result); + + return result; +} + +static PROC SetProcAddressDirect( + __in HINSTANCE hInstance, + __in LPCSTR lpProcName, + __in PROC newFunction, + __inout BYTE* oldData + ) +{ + static const LONGLONG addressSize = sizeof(PROC); + static const LONGLONG jmpSize = addressSize + 1; + + PROC result = NULL; + + PROC pfnHookAPIAddr = GetProcAddress( hInstance, lpProcName ); + + if( pfnHookAPIAddr ) + { + result = pfnHookAPIAddr; + + setFunction( pfnHookAPIAddr, newFunction, oldData ); + } + + return result; +} + +static PROC SetProcAddressA( + __in HINSTANCE targetModule, + __in LPCSTR lpLibFileName, + __in LPCSTR lpProcName, + __in PROC newFunction, + __in PROC origFunction = NULL + ) +{ + HMODULE hModule = LoadLibraryA( lpLibFileName ); + if(hModule == NULL) + return NULL; + + // To do: call FreeLibrary(hModule) at the appropriate time. + PROC pfnHookAPIAddr = (origFunction != NULL) ? origFunction : GetProcAddress(hModule, lpProcName ); + + HINSTANCE hInstance = targetModule; + + ULONG ulSize; + PIMAGE_IMPORT_DESCRIPTOR pImportDesc = + (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData( + hInstance, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &ulSize + ); + + while (pImportDesc->Name) + { + PSTR pszModName = (PSTR)((PBYTE) hInstance + pImportDesc->Name); + if (_stricmp(pszModName, lpLibFileName) == 0) + break; + pImportDesc++; + } + + PIMAGE_THUNK_DATA pThunk = + (PIMAGE_THUNK_DATA)((PBYTE) hInstance + pImportDesc->FirstThunk); + + while (pThunk->u1.Function) + { + PROC* ppfn = (PROC*) &pThunk->u1.Function; + BOOL bFound = (*ppfn == pfnHookAPIAddr); + + if (bFound) + { + MEMORY_BASIC_INFORMATION mbi; + VirtualQuery( + ppfn, + &mbi, + sizeof(MEMORY_BASIC_INFORMATION) + ); + VirtualProtect( + mbi.BaseAddress, + mbi.RegionSize, + PAGE_READWRITE, + &mbi.Protect); + + *ppfn = *newFunction; + + DWORD dwOldProtect; + VirtualProtect( + mbi.BaseAddress, + mbi.RegionSize, + mbi.Protect, + &dwOldProtect + ); + break; + } + pThunk++; + } + + return pfnHookAPIAddr; +} + +void clearUMDriverOverrides() +{ + if (lastContext != NULL) + { + // Unpatch all the things. + + if (oldCreateDXGIFactory) + { + restoreFunction((PROC)oldCreateDXGIFactory, oldCreateDXGIFactoryData); + } + if (oldCreateDXGIFactory1) + { + restoreFunction((PROC)oldCreateDXGIFactory1, oldCreateDXGIFactory1Data); + } + if (oldCreateDXGIFactory2) + { + restoreFunction((PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data); + } + if (oldDirectX9Create) + { + restoreFunction((PROC)oldDirectX9Create, oldDirectX9CreateData); + } + if (oldDirectX9ExCreate) + { + restoreFunction((PROC)oldDirectX9ExCreate, oldDirectX9ExCreateData); + } + if (oldCreateDXGIFactory2) + { + restoreFunction((PROC)oldCreateDXGIFactory2, oldCreateDXGIFactory2Data); + } + + for (int i = 0; i < ShimCountMax; ++i) + { + HINSTANCE hInst = oldLoaderInstances[i]; + + if (hInst != NULL) + { + for (int j = 0; j < NUM_LOADER_LIBS; ++j) + { + const char* loaderLibrary = loaderLibraryList[j]; + + if (oldLoaderProcA[j]) + { + SetProcAddressA(hInst, loaderLibrary, "LoadLibraryA", oldLoaderProcA[i][j], (PROC)OVRLoadLibraryA); + } + if (oldLoaderProcW[j]) + { + SetProcAddressA(hInst, loaderLibrary, "LoadLibraryW", oldLoaderProcW[i][j], (PROC)OVRLoadLibraryW); + } + if (oldLoaderProcExA[j]) + { + SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExA", oldLoaderProcExA[i][j], (PROC)OVRLoadLibraryExA); + } + if (oldLoaderProcExW[j]) + { + SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExW", oldLoaderProcExW[i][j], (PROC)OVRLoadLibraryExW); + } + if (oldLoaderProcModExA[j]) + { + SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExA", oldLoaderProcModExA[i][j], (PROC)OVRGetModuleHandleExA); + } + if (oldLoaderProcModExW[j]) + { + SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExW", oldLoaderProcModExW[i][j], (PROC)OVRGetModuleHandleExW); + } + } + + FreeLibrary(hInst); + } + } + + if (rtFilterModule != NULL) + { + LPFNCANUNLOADNOW pfnCanUnloadNow = (LPFNCANUNLOADNOW)GetProcAddress(rtFilterModule, "DllCanUnloadNow"); + if (pfnCanUnloadNow && pfnCanUnloadNow() == S_OK) + { + FreeLibrary(rtFilterModule); + rtFilterModule = NULL; + } + } + + // Do not set the following to NULL, because it's possible that we may be called after this function is executed. + // This is due to quirks in how third party DLLs implement their linking to these functions. In any case + // this module will be going away within a month or so of this writing. + //oldProcA = NULL; + //oldProcExA = NULL; + //oldProcW = NULL; + //oldProcExW = NULL; + //oldProcModExA = NULL; + //oldProcModExW = NULL; + + oldDirectX9Create = NULL; + oldDirectX9ExCreate = NULL; + oldCreateDXGIFactory = NULL; + oldCreateDXGIFactory1 = NULL; + oldCreateDXGIFactory2 = NULL; + + lastContext = NULL; + } +} + +bool checkUMDriverOverrides(void* context) +{ + lastContext = context; + if (oldCreateDXGIFactory != NULL) + return true; + + PreloadLibraryRTFn loadFunc = NULL; + for( int i = 0; i < ShimCountMax; ++i ) + { + HINSTANCE hInst = NULL; + try + { + hInst = LoadLibraryA(dllList[i]); + } + catch(...) + { + } + + oldLoaderInstances[i] = hInst; + + if (hInst == NULL) + continue; + + ShimedLibraries libCount = (ShimedLibraries)i; + switch( libCount ) + { + case ShimLibDXGI: + oldCreateDXGIFactory = (WinCreateDXGIFactory)SetProcAddressDirect( hInst, "CreateDXGIFactory", (PROC)OVRCreateDXGIFactory, oldCreateDXGIFactoryData ); + oldCreateDXGIFactory1 = (WinCreateDXGIFactory1)SetProcAddressDirect( hInst, "CreateDXGIFactory1", (PROC)OVRCreateDXGIFactory1, oldCreateDXGIFactory1Data ); + oldCreateDXGIFactory2 = (WinCreateDXGIFactory2)SetProcAddressDirect( hInst, "CreateDXGIFactory2", (PROC)OVRCreateDXGIFactory2, oldCreateDXGIFactory2Data ); + break; + case ShimLibD3D9: + oldDirectX9Create = (WinDirect3DCreate9)SetProcAddressDirect( hInst, "Direct3DCreate9", (PROC)OVRDirect3DCreate9, oldDirectX9CreateData ); + oldDirectX9ExCreate = (WinDirect3DCreate9Ex)SetProcAddressDirect( hInst, "Direct3DCreate9Ex", (PROC)OVRDirect3DCreate9Ex, oldDirectX9ExCreateData ); + break; + default: + break; + } + + for (int j = 0; j < NUM_LOADER_LIBS; ++j) + { + const char* loaderLibrary = loaderLibraryList[j]; + + PROC temp = NULL; + temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryA", (PROC)OVRLoadLibraryA); + if (!oldProcA) + { + oldProcA = (WinLoadLibraryA)temp; + } + oldLoaderProcA[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryW", (PROC)OVRLoadLibraryW); + if (!oldProcW) + { + oldProcW = (WinLoadLibraryW)temp; + } + oldLoaderProcW[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExA", (PROC)OVRLoadLibraryExA); + if (!oldProcExA) + { + oldProcExA = (WinLoadLibraryExA)temp; + } + oldLoaderProcExA[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "LoadLibraryExW", (PROC)OVRLoadLibraryExW); + if (!oldProcExW) + { + oldProcExW = (WinLoadLibraryExW)temp; + } + oldLoaderProcExW[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExA", (PROC)OVRGetModuleHandleExA); + if (!oldProcModExA) + { + oldProcModExA = (WinGetModuleHandleExA)temp; + } + oldLoaderProcModExA[i][j] = temp; + + temp = SetProcAddressA(hInst, loaderLibrary, "GetModuleHandleExW", (PROC)OVRGetModuleHandleExW); + if (!oldProcModExW) + { + oldProcModExW = (WinGetModuleHandleExW)temp; + } + oldLoaderProcModExW[i][j] = temp; + } + + if (loadFunc == NULL) + { + loadFunc = (PreloadLibraryRTFn)GetProcAddress(hInst, "PreloadLibraryRT"); + } + } + + rtFilterModule = oldProcA ? (*oldProcA)(RTFilter) : NULL; + + IsCreatingBackBuffer backBufferFunc = NULL; + ShouldVSync shouldVSyncFunc = NULL; + GetRTFilterVersion getRTFilterVersionFunc = NULL; + + if (rtFilterModule != NULL) + { + loadFunc = (PreloadLibraryRTFn)GetProcAddress(rtFilterModule, "PreloadLibraryRT"); + backBufferFunc = (IsCreatingBackBuffer)GetProcAddress(rtFilterModule, "OVRIsCreatingBackBuffer"); + shouldVSyncFunc = (ShouldVSync)GetProcAddress(rtFilterModule, "OVRShouldVSync"); + getRTFilterVersionFunc = (GetRTFilterVersion)GetProcAddress(rtFilterModule, "OVRGetRTFilterVersion"); + } + + if (loadFunc == NULL) + { + MessageBox(nullptr, L"Unable to load the Oculus Display Driver. Please reinstall the Oculus Runtime.", L"Configuration Error", MB_OK | MB_ICONERROR); + clearUMDriverOverrides(); + return false; + } + + if (getRTFilterVersionFunc == NULL) + { + WCHAR message[1000] = {}; + swprintf_s(message, L"This app requires the %d.%d.%d version of the Oculus Runtime.", OVR_MAJOR_VERSION, OVR_MINOR_VERSION, OVR_BUILD_NUMBER); + MessageBox(nullptr, message, L"Configuration Error", MB_OK | MB_ICONERROR); + clearUMDriverOverrides(); + return false; + } + + // Verify that we are running with the appropriate display driver + { + const ULONG rtFilterVersion = (*getRTFilterVersionFunc)(); + const ULONG rtFilterMajor = OVR_GET_VERSION_MAJOR(rtFilterVersion); + const ULONG rtFilterMinor = OVR_GET_VERSION_MINOR(rtFilterVersion); + + if ((rtFilterMajor != OVR_RTFILTER_VERSION_MAJOR) || (rtFilterMinor < OVR_RTFILTER_VERSION_MINOR)) + { + WCHAR message[1000] = {}; + swprintf_s(message, L"This app requires the %d.%d.%d version of the Oculus Runtime.", OVR_MAJOR_VERSION, OVR_MINOR_VERSION, OVR_BUILD_NUMBER); + MessageBox(nullptr, message, L"Configuration Error", MB_OK | MB_ICONERROR); + clearUMDriverOverrides(); + return false; + } + } + + appDriver.version = OVR_RENDER_SHIM_VERSION_MAJOR; + appDriver.context = lastContext; + +// appDriver.pfnInitializingDisplay = OVRIsInitializingDisplay; + appDriver.pfnInitializingDisplay = OVRLocalIsInitializingDisplay; + appDriver.pfnRiftForContext = OVRRiftForContext; + appDriver.pfnCloseRiftForContext = OVRCloseRiftForContext; + appDriver.pfnWindowDisplayResolution = OVRWindowDisplayResolution; + appDriver.pfnShouldEnableDebug = OVRShouldEnableDebug; + appDriver.pfnIsCreatingBackBuffer = (backBufferFunc == NULL) ? OVRIsCreatingBackBuffer : backBufferFunc; + appDriver.pfnShouldVSync = (shouldVSyncFunc == NULL) ? OVRShouldVSync : shouldVSyncFunc; + appDriver.pfnExpectedResolution = OVRExpectedResolution; + appDriver.pfnMirroringEnabled = OVRMirroringEnabled; + appDriver.pfnGetWindowForContext = OVRGetWindowForContext; + appDriver.pfnPresentRiftOnContext = OVRShouldPresentOnContext; + + appDriver.pfnDirect3DCreate9 = oldDirectX9Create; + appDriver.pfnDirect3DCreate9Ex = oldDirectX9ExCreate; + appDriver.pfnCreateDXGIFactory = oldCreateDXGIFactory; + appDriver.pfnCreateDXGIFactory1 = oldCreateDXGIFactory1; + appDriver.pfnCreateDXGIFactory2 = oldCreateDXGIFactory2; + + (*loadFunc)( &appDriver ); + + return true; +} diff --git a/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp index 602df98..e399863 100644 --- a/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp +++ b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.cpp @@ -1,234 +1,243 @@ -/************************************************************************************ - -Filename : OVR_Win32_ShimFunctions.cpp -Content : Client-side shim callbacks for usermode/rt hooks -Created : May 6, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "OVR_Win32_Display.h" -#include "OVR_Win32_ShimFunctions.h" -#include "OVR_Win32_Dxgi_Display.h" -#include "../OVR_Stereo.h" -#include "OVR_Win32_FocusReader.h" - -// Exported -extern bool checkUMDriverOverrides(void* context); -extern void clearUMDriverOverrides(); - -#include -#include -#include -#include -#include -#include -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include - - -//------------------------------------------------------------------------------------- -// ***** User-mode Callbacks -// -// See IsInitializingDisplay, etc in Dxgi_Display.h for details -// - -extern LINK_APPLICATION_DRIVER appDriver; - -BOOL WINAPI OVRIsInitializingDisplay(PVOID context, UINT width, UINT height) -{ - OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; - if (con->ExpectedWidth == (int)width && con->ExpectedHeight == (int)height) - return TRUE; - - return FALSE; -} - -BOOL WINAPI OVRExpectedResolution( PVOID context, UINT* width, UINT* height, UINT* rotationInDegrees ) -{ - OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; - - *width = con->ExpectedWidth; - *height = con->ExpectedHeight; - *rotationInDegrees = con->Rotation; - return TRUE; -} - -BOOL WINAPI OVRIsCreatingBackBuffer(PVOID context) -{ - OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; - if( con->ExpectedWidth != -1 && con->ExpectedHeight != -1 ) - return TRUE; - - return FALSE; -} - -BOOL WINAPI OVRShouldVSync( ) -{ - return FALSE; -} - - -ULONG WINAPI OVRRiftForContext(PVOID context, HANDLE driverHandle) -{ - OVR_UNUSED( driverHandle ); - OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; - - return con->ChildUid; -} - -HWND WINAPI OVRGetWindowForContext(PVOID context) -{ - OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; - - if( con->Active ) - { - return con->hWindow; - } - else - { - return 0; - } -} - -BOOL WINAPI OVRShouldPresentOnContext(PVOID context) -{ - OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; - - return con->Active && ( con->hWindow == OVR::Win32::RenderFocusReader::GetInstance()->ReadActiveWindow() ); -} - -BOOL WINAPI OVRCloseRiftForContext( PVOID context, HANDLE driverHandle, ULONG rift ) -{ - OVR_UNUSED( context ); OVR_UNUSED( driverHandle ); OVR_UNUSED( rift ); - // TODO - return TRUE; -} - -BOOL WINAPI OVRWindowDisplayResolution( PVOID context, UINT* width, UINT* height, - UINT* titleHeight, UINT* borderWidth, - BOOL* vsyncEnabled ) -{ - OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; - void* handle = con->hWindow; - - if( handle ) - { - RECT winRect = { 0 }; - GetWindowRect( (HWND)handle, &winRect ); - - RECT rect = {0}; - if( GetClientRect( (HWND)handle, &rect ) ) - { - LONG barHeight = (winRect.bottom - winRect.top) - (rect.bottom - rect.top); - LONG borderSize = (winRect.right - winRect.left) - (rect.right - rect.left); - - *titleHeight = barHeight - borderSize + (borderSize / 2 ); - *borderWidth = borderSize / 2; - *width = rect.right - rect.left + (borderSize / 2); - *height = rect.bottom - rect.top + *titleHeight; - } - else - { - return FALSE; - } - } - else - { - return FALSE; - } - - *vsyncEnabled = TRUE; - - return TRUE; -} - -BOOL WINAPI OVRShouldEnableDebug() -{ - return FALSE; -} - -BOOL WINAPI OVRMirroringEnabled( PVOID context ) -{ - OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; - - return con->UseMirroring; -} - -namespace OVR { namespace Win32 { - -DisplayShim::DisplayShim() : - ChildUid( 0 ), - ExpectedWidth( 1280 ), - ExpectedHeight( 800 ), - Rotation( 0 ), - hWindow( 0 ), - UseMirroring( true ), - Active( false ) -{ - -} - -DisplayShim::~DisplayShim() -{ - -} - -bool DisplayShim::Initialize( bool inCompatibility ) -{ - if (inCompatibility) - return false; - - return checkUMDriverOverrides( this ); -} - -bool DisplayShim::Shutdown() -{ - clearUMDriverOverrides(); - - return true; -} - -bool DisplayShim::Update(Win32ShimInfo* shimInfo) -{ - ChildUid = shimInfo->DeviceNumber; - ExpectedWidth = shimInfo->NativeWidth; - ExpectedHeight = shimInfo->NativeHeight; - Rotation = shimInfo->Rotation; - UseMirroring = shimInfo->UseMirroring != 0; - return true; -} - -void* DisplayShim::GetDX11SwapChain() -{ - if( appDriver.pfnGetDX11SwapChain ) - { - return (*appDriver.pfnGetDX11SwapChain)(this); - } - - return NULL; -} - - -} } // OVR::Win32 +/************************************************************************************ + +Filename : OVR_Win32_ShimFunctions.cpp +Content : Client-side shim callbacks for usermode/rt hooks +Created : May 6, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include +#include "OVR_Win32_Display.h" +#include "OVR_Win32_ShimFunctions.h" +#include "OVR_Win32_Dxgi_Display.h" +#include "../OVR_Stereo.h" +#include "OVR_Win32_FocusReader.h" + +// Exported +extern bool checkUMDriverOverrides(void* context); +extern void clearUMDriverOverrides(); + +#include +#include +#include +#include +#include +#include +#include +#include + + +//------------------------------------------------------------------------------------- +// ***** User-mode Callbacks +// +// See IsInitializingDisplay, etc in Dxgi_Display.h for details +// + +extern LINK_APPLICATION_DRIVER appDriver; + +BOOL WINAPI OVRIsInitializingDisplay(PVOID context, UINT width, UINT height) +{ + OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; + if (con->ExpectedWidth == (int)width && con->ExpectedHeight == (int)height) + return TRUE; + + return FALSE; +} + +BOOL WINAPI OVRExpectedResolution( PVOID context, UINT* width, UINT* height, UINT* rotationInDegrees ) +{ + OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; + + *width = con->ExpectedWidth; + *height = con->ExpectedHeight; + *rotationInDegrees = con->Rotation; + return TRUE; +} + +BOOL WINAPI OVRIsCreatingBackBuffer(PVOID context) +{ + OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; + if( con->ExpectedWidth != -1 && con->ExpectedHeight != -1 ) + return TRUE; + + return FALSE; +} + +BOOL WINAPI OVRShouldVSync( ) +{ + return FALSE; +} + + +ULONG WINAPI OVRRiftForContext(PVOID context, HANDLE driverHandle) +{ + OVR_UNUSED( driverHandle ); + OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; + + return con->ChildUid; +} + +HWND WINAPI OVRGetWindowForContext(PVOID context) +{ + OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; + + if( con->Active ) + { + return con->hWindow; + } + else + { + return 0; + } +} + +BOOL WINAPI OVRShouldPresentOnContext(PVOID context) +{ + OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; + + return con->Active && ( con->hWindow == OVR::Win32::RenderFocusReader::GetInstance()->ReadActiveWindow() ); +} + +BOOL WINAPI OVRCloseRiftForContext( PVOID context, HANDLE driverHandle, ULONG rift ) +{ + OVR_UNUSED( context ); OVR_UNUSED( driverHandle ); OVR_UNUSED( rift ); + // TODO + return TRUE; +} + +BOOL WINAPI OVRWindowDisplayResolution( PVOID context, UINT* width, UINT* height, + UINT* titleHeight, UINT* borderWidth, + BOOL* vsyncEnabled ) +{ + OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; + void* handle = con->hWindow; + + if( handle ) + { + RECT winRect = { 0 }; + GetWindowRect( (HWND)handle, &winRect ); + + RECT rect = {0}; + if( GetClientRect( (HWND)handle, &rect ) ) + { + LONG barHeight = (winRect.bottom - winRect.top) - (rect.bottom - rect.top); + LONG borderSize = (winRect.right - winRect.left) - (rect.right - rect.left); + + *titleHeight = barHeight - borderSize + (borderSize / 2 ); + *borderWidth = borderSize / 2; + *width = rect.right - rect.left + (borderSize / 2); + *height = rect.bottom - rect.top + *titleHeight; + } + else + { + return FALSE; + } + } + else + { + return FALSE; + } + + *vsyncEnabled = TRUE; + + return TRUE; +} + +BOOL WINAPI OVRShouldEnableDebug() +{ + return FALSE; +} + +BOOL WINAPI OVRMirroringEnabled( PVOID context ) +{ + OVR::Win32::DisplayShim* con = (OVR::Win32::DisplayShim*)context; + + return con->UseMirroring; +} + + +// This is a temporarily exported function for the purpose of aiding in the DLL transition for the Unity plugin. +// It is unsupported and will be removed in a future release. +extern "C" +{ + OVR_PUBLIC_FUNCTION(void*) ovr_GetDX11SwapChain() + { + return OVR::Win32::DisplayShim::GetInstance().GetDX11SwapChain(); + } +} + + +namespace OVR { namespace Win32 { + +DisplayShim::DisplayShim() : + ChildUid( 0 ), + ExpectedWidth( 1280 ), + ExpectedHeight( 800 ), + Rotation( 0 ), + hWindow( 0 ), + UseMirroring( true ), + Active( false ) +{ + +} + +DisplayShim::~DisplayShim() +{ + +} + +bool DisplayShim::Initialize( bool inCompatibility ) +{ + if (inCompatibility) + return false; + + return checkUMDriverOverrides( this ); +} + +bool DisplayShim::Shutdown() +{ + clearUMDriverOverrides(); + + return true; +} + +bool DisplayShim::Update(ExtraMonitorInfo* shimInfo) +{ + ChildUid = shimInfo->DeviceNumber; + ExpectedWidth = shimInfo->NativeWidth; + ExpectedHeight = shimInfo->NativeHeight; + Rotation = shimInfo->Rotation; + UseMirroring = shimInfo->UseMirroring != 0; + return true; +} + +void* DisplayShim::GetDX11SwapChain() +{ + if( appDriver.pfnGetDX11SwapChain ) + { + return (*appDriver.pfnGetDX11SwapChain)(this); + } + + return NULL; +} + + +} } // OVR::Win32 diff --git a/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h index 1339de4..08e384d 100644 --- a/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h +++ b/LibOVR/Src/Displays/OVR_Win32_ShimFunctions.h @@ -1,79 +1,79 @@ -/************************************************************************************ - -Filename : OVR_Win32_ShimFunctions.h -Content : Client-side shim callbacks for usermode/rt hooks -Created : May 6, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Win32_ShimFunctions_h -#define OVR_Win32_ShimFunctions_h - -#include "OVR_Win32_Display.h" - -namespace OVR { - -struct Win32ShimInfo; - -namespace Win32 { - - -class DisplayShim -{ -public: - -public: - static DisplayShim& GetInstance() - { - static DisplayShim instance; - return instance; - } - - bool Initialize( bool inCompatibility ); - bool Shutdown(); - - bool Update( Win32ShimInfo* shimInfo ); - - void* GetDX11SwapChain(); - - ULONG ChildUid; - int ExpectedWidth; - int ExpectedHeight; - int Rotation; - HWND hWindow; - bool UseMirroring; - bool Active; - -private: - - DisplayShim(); - - virtual ~DisplayShim(); - - DisplayShim(DisplayShim const&); // Don't Implement - void operator=(DisplayShim const&); // Don't implement - -}; - - -}} // namespace OVR::Win32 - -#endif +/************************************************************************************ + +Filename : OVR_Win32_ShimFunctions.h +Content : Client-side shim callbacks for usermode/rt hooks +Created : May 6, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Win32_ShimFunctions_h +#define OVR_Win32_ShimFunctions_h + +#include "OVR_Win32_Display.h" + +namespace OVR { + +struct ExtraMonitorInfo; + +namespace Win32 { + + +class DisplayShim +{ +public: + +public: + static DisplayShim& GetInstance() + { + static DisplayShim instance; + return instance; + } + + bool Initialize( bool inCompatibility ); + bool Shutdown(); + + bool Update( ExtraMonitorInfo* shimInfo ); + + void* GetDX11SwapChain(); + + ULONG ChildUid; + int ExpectedWidth; + int ExpectedHeight; + int Rotation; + HWND hWindow; + bool UseMirroring; + bool Active; + +private: + + DisplayShim(); + + virtual ~DisplayShim(); + + DisplayShim(DisplayShim const&); // Don't Implement + void operator=(DisplayShim const&); // Don't implement + +}; + + +}} // namespace OVR::Win32 + +#endif diff --git a/LibOVR/Src/Displays/OVR_Win32_ShimVersion.h b/LibOVR/Src/Displays/OVR_Win32_ShimVersion.h index f5eaa7c..2561ee5 100644 --- a/LibOVR/Src/Displays/OVR_Win32_ShimVersion.h +++ b/LibOVR/Src/Displays/OVR_Win32_ShimVersion.h @@ -1,47 +1,47 @@ -/************************************************************************************ - -Filename : OVR_Win32_ShimVersion.h -Content : Versioning info for our display shim -Created : Nov 4, 2014 -Authors : Scott Bassett - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#define STRINGIZE_(x) #x -#define STRINGIZE(x) STRINGIZE_(x) - -#define OVR_MAKE_VERSION(major, minor, patch) (ULONG)(((major) << 24) | ((minor) << 16) | patch) -#define OVR_GET_VERSION_MAJOR(x) (ULONG)(((x) >> 24) & 0x000000FF) -#define OVR_GET_VERSION_MINOR(x) (ULONG)(((x) >> 16) & 0x000000FF) -#define OVR_GET_VERSION_PATCH(x) (ULONG)((x) & 0x0000FFFF) - -#define OVR_RENDER_SHIM_VERSION_MAJOR 1 -#define OVR_RENDER_SHIM_VERSION_MINOR 0 -#define OVR_RENDER_SHIM_VERSION_PATCH 0 -#define OVR_RENDER_SHIM_VERSION OVR_MAKE_VERSION(OVR_RENDER_SHIM_VERSION_MAJOR, OVR_RENDER_SHIM_VERSION_MINOR, OVR_RENDER_SHIM_VERSION_PATCH) -#define OVR_RENDER_SHIM_VERSION_STRING (STRINGIZE(OVR_RENDER_SHIM_VERSION_MAJOR) "." STRINGIZE(OVR_RENDER_SHIM_VERSION_MINOR) "." STRINGIZE(OVR_RENDER_SHIM_VERSION_PATCH)) - -// IF YOU CHANGE ANY OF THESE NUMBERS YOU MUST UPDATE MULTIPLE FILES. -// PLEASE LOOK AT CHANGELIST 31947 TO SEE THE FULL LIST. -#define OVR_RTFILTER_VERSION_MAJOR 1 -#define OVR_RTFILTER_VERSION_MINOR 2 -#define OVR_RTFILTER_VERSION_PATCH 2 -#define OVR_RTFILTER_VERSION OVR_MAKE_VERSION(OVR_RTFILTER_VERSION_MAJOR, OVR_RTFILTER_VERSION_MINOR, OVR_RTFILTER_VERSION_PATCH) -#define OVR_RTFILTER_VERSION_STRING (STRINGIZE(OVR_RTFILTER_VERSION_MAJOR) "." STRINGIZE(OVR_RTFILTER_VERSION_MINOR) "." STRINGIZE(OVR_RTFILTER_VERSION_PATCH)) +/************************************************************************************ + +Filename : OVR_Win32_ShimVersion.h +Content : Versioning info for our display shim +Created : Nov 4, 2014 +Authors : Scott Bassett + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#define STRINGIZE_(x) #x +#define STRINGIZE(x) STRINGIZE_(x) + +#define OVR_MAKE_VERSION(major, minor, patch) (ULONG)(((major) << 24) | ((minor) << 16) | patch) +#define OVR_GET_VERSION_MAJOR(x) (ULONG)(((x) >> 24) & 0x000000FF) +#define OVR_GET_VERSION_MINOR(x) (ULONG)(((x) >> 16) & 0x000000FF) +#define OVR_GET_VERSION_PATCH(x) (ULONG)((x) & 0x0000FFFF) + +#define OVR_RENDER_SHIM_VERSION_MAJOR 1 +#define OVR_RENDER_SHIM_VERSION_MINOR 0 +#define OVR_RENDER_SHIM_VERSION_PATCH 0 +#define OVR_RENDER_SHIM_VERSION OVR_MAKE_VERSION(OVR_RENDER_SHIM_VERSION_MAJOR, OVR_RENDER_SHIM_VERSION_MINOR, OVR_RENDER_SHIM_VERSION_PATCH) +#define OVR_RENDER_SHIM_VERSION_STRING (STRINGIZE(OVR_RENDER_SHIM_VERSION_MAJOR) "." STRINGIZE(OVR_RENDER_SHIM_VERSION_MINOR) "." STRINGIZE(OVR_RENDER_SHIM_VERSION_PATCH)) + +// IF YOU CHANGE ANY OF THESE NUMBERS YOU MUST UPDATE MULTIPLE FILES. +// PLEASE LOOK AT CHANGELIST 31947 TO SEE THE FULL LIST. +#define OVR_RTFILTER_VERSION_MAJOR 1 +#define OVR_RTFILTER_VERSION_MINOR 2 +#define OVR_RTFILTER_VERSION_PATCH 4 +#define OVR_RTFILTER_VERSION OVR_MAKE_VERSION(OVR_RTFILTER_VERSION_MAJOR, OVR_RTFILTER_VERSION_MINOR, OVR_RTFILTER_VERSION_PATCH) +#define OVR_RTFILTER_VERSION_STRING (STRINGIZE(OVR_RTFILTER_VERSION_MAJOR) "." STRINGIZE(OVR_RTFILTER_VERSION_MINOR) "." STRINGIZE(OVR_RTFILTER_VERSION_PATCH)) diff --git a/LibOVR/Src/Kernel/OVR_Alg.cpp b/LibOVR/Src/Kernel/OVR_Alg.cpp deleted file mode 100644 index c087777..0000000 --- a/LibOVR/Src/Kernel/OVR_Alg.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Alg.cpp -Content : Static lookup tables for Alg functions -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Types.h" - -namespace OVR { namespace Alg { - -//------------------------------------------------------------------------ -extern const uint8_t UpperBitTable[256] = -{ - 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, - 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 -}; - -extern const uint8_t LowerBitTable[256] = -{ - 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, - 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 -}; - - -}} // OVE::Alg diff --git a/LibOVR/Src/Kernel/OVR_Alg.h b/LibOVR/Src/Kernel/OVR_Alg.h deleted file mode 100644 index f7f461f..0000000 --- a/LibOVR/Src/Kernel/OVR_Alg.h +++ /dev/null @@ -1,1062 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Alg.h -Content : Simple general purpose algorithms: Sort, Binary Search, etc. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Alg_h -#define OVR_Alg_h - -#include "OVR_Types.h" -#include - -namespace OVR { namespace Alg { - - -//----------------------------------------------------------------------------------- -// ***** Operator extensions - -template OVR_FORCE_INLINE void Swap(T &a, T &b) -{ T temp(a); a = b; b = temp; } - - -// ***** min/max are not implemented in Visual Studio 6 standard STL - -template OVR_FORCE_INLINE const T Min(const T a, const T b) -{ return (a < b) ? a : b; } - -template OVR_FORCE_INLINE const T Max(const T a, const T b) -{ return (b < a) ? a : b; } - -template OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal) -{ return Max(minVal, Min(v, maxVal)); } - -template OVR_FORCE_INLINE int Chop(T f) -{ return (int)f; } - -template OVR_FORCE_INLINE T Lerp(T a, T b, T f) -{ return (b - a) * f + a; } - - -// These functions stand to fix a stupid VC++ warning (with /Wp64 on): -// "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data" -// Use these functions instead of gmin/gmax if the argument has size -// of the pointer to avoid the warning. Though, functionally they are -// absolutelly the same as regular gmin/gmax. -template OVR_FORCE_INLINE const T PMin(const T a, const T b) -{ - OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); - return (a < b) ? a : b; -} -template OVR_FORCE_INLINE const T PMax(const T a, const T b) -{ - OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); - return (b < a) ? a : b; -} - - -template OVR_FORCE_INLINE const T Abs(const T v) -{ return (v>=0) ? v : -v; } - - -//----------------------------------------------------------------------------------- -// ***** OperatorLess -// -template struct OperatorLess -{ - static bool Compare(const T& a, const T& b) - { - return a < b; - } -}; - - -//----------------------------------------------------------------------------------- -// ***** QuickSortSliced -// -// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. -// The range is specified with start, end, where "end" is exclusive! -// The comparison predicate must be specified. -template -void QuickSortSliced(Array& arr, size_t start, size_t end, Less less) -{ - enum - { - Threshold = 9 - }; - - if(end - start < 2) return; - - intptr_t stack[80]; - intptr_t* top = stack; - intptr_t base = (intptr_t)start; - intptr_t limit = (intptr_t)end; - - for(;;) - { - intptr_t len = limit - base; - intptr_t i, j, pivot; - - if(len > Threshold) - { - // we use base + len/2 as the pivot - pivot = base + len / 2; - Swap(arr[base], arr[pivot]); - - i = base + 1; - j = limit - 1; - - // now ensure that *i <= *base <= *j - if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); - if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); - if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); - - for(;;) - { - do i++; while( less(arr[i], arr[base]) ); - do j--; while( less(arr[base], arr[j]) ); - - if( i > j ) - { - break; - } - - Swap(arr[i], arr[j]); - } - - Swap(arr[base], arr[j]); - - // now, push the largest sub-array - if(j - base > limit - i) - { - top[0] = base; - top[1] = j; - base = i; - } - else - { - top[0] = i; - top[1] = limit; - limit = j; - } - top += 2; - } - else - { - // the sub-array is small, perform insertion sort - j = base; - i = j + 1; - - for(; i < limit; j = i, i++) - { - for(; less(arr[j + 1], arr[j]); j--) - { - Swap(arr[j + 1], arr[j]); - if(j == base) - { - break; - } - } - } - if(top > stack) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - { - break; - } - } - } -} - - -//----------------------------------------------------------------------------------- -// ***** QuickSortSliced -// -// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. -// The range is specified with start, end, where "end" is exclusive! -// The data type must have a defined "<" operator. -template -void QuickSortSliced(Array& arr, size_t start, size_t end) -{ - typedef typename Array::ValueType ValueType; - QuickSortSliced(arr, start, end, OperatorLess::Compare); -} - -// Same as corresponding G_QuickSortSliced but with checking array limits to avoid -// crash in the case of wrong comparator functor. -template -bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end, Less less) -{ - enum - { - Threshold = 9 - }; - - if(end - start < 2) return true; - - intptr_t stack[80]; - intptr_t* top = stack; - intptr_t base = (intptr_t)start; - intptr_t limit = (intptr_t)end; - - for(;;) - { - intptr_t len = limit - base; - intptr_t i, j, pivot; - - if(len > Threshold) - { - // we use base + len/2 as the pivot - pivot = base + len / 2; - Swap(arr[base], arr[pivot]); - - i = base + 1; - j = limit - 1; - - // now ensure that *i <= *base <= *j - if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); - if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); - if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); - - for(;;) - { - do - { - i++; - if (i >= limit) - return false; - } while( less(arr[i], arr[base]) ); - do - { - j--; - if (j < 0) - return false; - } while( less(arr[base], arr[j]) ); - - if( i > j ) - { - break; - } - - Swap(arr[i], arr[j]); - } - - Swap(arr[base], arr[j]); - - // now, push the largest sub-array - if(j - base > limit - i) - { - top[0] = base; - top[1] = j; - base = i; - } - else - { - top[0] = i; - top[1] = limit; - limit = j; - } - top += 2; - } - else - { - // the sub-array is small, perform insertion sort - j = base; - i = j + 1; - - for(; i < limit; j = i, i++) - { - for(; less(arr[j + 1], arr[j]); j--) - { - Swap(arr[j + 1], arr[j]); - if(j == base) - { - break; - } - } - } - if(top > stack) - { - top -= 2; - base = top[0]; - limit = top[1]; - } - else - { - break; - } - } - } - return true; -} - -template -bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end) -{ - typedef typename Array::ValueType ValueType; - return QuickSortSlicedSafe(arr, start, end, OperatorLess::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** QuickSort -// -// Sort an array Array, ArrayPaged, ArrayUnsafe. -// The array must have GetSize() function. -// The comparison predicate must be specified. -template -void QuickSort(Array& arr, Less less) -{ - QuickSortSliced(arr, 0, arr.GetSize(), less); -} - -// checks for boundaries -template -bool QuickSortSafe(Array& arr, Less less) -{ - return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less); -} - - -//----------------------------------------------------------------------------------- -// ***** QuickSort -// -// Sort an array Array, ArrayPaged, ArrayUnsafe. -// The array must have GetSize() function. -// The data type must have a defined "<" operator. -template -void QuickSort(Array& arr) -{ - typedef typename Array::ValueType ValueType; - QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess::Compare); -} - -template -bool QuickSortSafe(Array& arr) -{ - typedef typename Array::ValueType ValueType; - return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** InsertionSortSliced -// -// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. -// The range is specified with start, end, where "end" is exclusive! -// The comparison predicate must be specified. -// Unlike Quick Sort, the Insertion Sort works much slower in average, -// but may be much faster on almost sorted arrays. Besides, it guarantees -// that the elements will not be swapped if not necessary. For example, -// an array with all equal elements will remain "untouched", while -// Quick Sort will considerably shuffle the elements in this case. -template -void InsertionSortSliced(Array& arr, size_t start, size_t end, Less less) -{ - size_t j = start; - size_t i = j + 1; - size_t limit = end; - - for(; i < limit; j = i, i++) - { - for(; less(arr[j + 1], arr[j]); j--) - { - Swap(arr[j + 1], arr[j]); - if(j <= start) - { - break; - } - } - } -} - - -//----------------------------------------------------------------------------------- -// ***** InsertionSortSliced -// -// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. -// The range is specified with start, end, where "end" is exclusive! -// The data type must have a defined "<" operator. -template -void InsertionSortSliced(Array& arr, size_t start, size_t end) -{ - typedef typename Array::ValueType ValueType; - InsertionSortSliced(arr, start, end, OperatorLess::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** InsertionSort -// -// Sort an array Array, ArrayPaged, ArrayUnsafe. -// The array must have GetSize() function. -// The comparison predicate must be specified. - -template -void InsertionSort(Array& arr, Less less) -{ - InsertionSortSliced(arr, 0, arr.GetSize(), less); -} - -//----------------------------------------------------------------------------------- -// ***** InsertionSort -// -// Sort an array Array, ArrayPaged, ArrayUnsafe. -// The array must have GetSize() function. -// The data type must have a defined "<" operator. -template -void InsertionSort(Array& arr) -{ - typedef typename Array::ValueType ValueType; - InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** Median -// Returns a median value of the input array. -// Caveats: partially sorts the array, returns a reference to the array element -// TBD: This needs to be optimized and generalized -// -template -typename Array::ValueType& Median(Array& arr) -{ - size_t count = arr.GetSize(); - size_t mid = (count - 1) / 2; - OVR_ASSERT(count > 0); - - for (size_t j = 0; j <= mid; j++) - { - size_t min = j; - for (size_t k = j + 1; k < count; k++) - if (arr[k] < arr[min]) - min = k; - Swap(arr[j], arr[min]); - } - return arr[mid]; -} - -//----------------------------------------------------------------------------------- -// ***** LowerBoundSliced -// -template -size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) -{ - intptr_t first = (intptr_t)start; - intptr_t len = (intptr_t)(end - start); - intptr_t half; - intptr_t middle; - - while(len > 0) - { - half = len >> 1; - middle = first + half; - if(less(arr[middle], val)) - { - first = middle + 1; - len = len - half - 1; - } - else - { - len = half; - } - } - return (size_t)first; -} - - -//----------------------------------------------------------------------------------- -// ***** LowerBoundSliced -// -template -size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) -{ - return LowerBoundSliced(arr, start, end, val, OperatorLess::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** LowerBoundSized -// -template -size_t LowerBoundSized(const Array& arr, size_t size, const Value& val) -{ - return LowerBoundSliced(arr, 0, size, val, OperatorLess::Compare); -} - -//----------------------------------------------------------------------------------- -// ***** LowerBound -// -template -size_t LowerBound(const Array& arr, const Value& val, Less less) -{ - return LowerBoundSliced(arr, 0, arr.GetSize(), val, less); -} - - -//----------------------------------------------------------------------------------- -// ***** LowerBound -// -template -size_t LowerBound(const Array& arr, const Value& val) -{ - return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess::Compare); -} - - - -//----------------------------------------------------------------------------------- -// ***** UpperBoundSliced -// -template -size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) -{ - intptr_t first = (intptr_t)start; - intptr_t len = (intptr_t)(end - start); - intptr_t half; - intptr_t middle; - - while(len > 0) - { - half = len >> 1; - middle = first + half; - if(less(val, arr[middle])) - { - len = half; - } - else - { - first = middle + 1; - len = len - half - 1; - } - } - return (size_t)first; -} - - -//----------------------------------------------------------------------------------- -// ***** UpperBoundSliced -// -template -size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) -{ - return UpperBoundSliced(arr, start, end, val, OperatorLess::Compare); -} - - -//----------------------------------------------------------------------------------- -// ***** UpperBoundSized -// -template -size_t UpperBoundSized(const Array& arr, size_t size, const Value& val) -{ - return UpperBoundSliced(arr, 0, size, val, OperatorLess::Compare); -} - - -//----------------------------------------------------------------------------------- -// ***** UpperBound -// -template -size_t UpperBound(const Array& arr, const Value& val, Less less) -{ - return UpperBoundSliced(arr, 0, arr.GetSize(), val, less); -} - - -//----------------------------------------------------------------------------------- -// ***** UpperBound -// -template -size_t UpperBound(const Array& arr, const Value& val) -{ - return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess::Compare); -} - - -//----------------------------------------------------------------------------------- -// ***** ReverseArray -// -template void ReverseArray(Array& arr) -{ - intptr_t from = 0; - intptr_t to = arr.GetSize() - 1; - while(from < to) - { - Swap(arr[from], arr[to]); - ++from; - --to; - } -} - - -// ***** AppendArray -// -template -void AppendArray(CDst& dst, const CSrc& src) -{ - size_t i; - for(i = 0; i < src.GetSize(); i++) - dst.PushBack(src[i]); -} - -//----------------------------------------------------------------------------------- -// ***** ArrayAdaptor -// -// A simple adapter that provides the GetSize() method and overloads -// operator []. Used to wrap plain arrays in QuickSort and such. -template class ArrayAdaptor -{ -public: - typedef T ValueType; - ArrayAdaptor() : Data(0), Size(0) {} - ArrayAdaptor(T* ptr, size_t size) : Data(ptr), Size(size) {} - size_t GetSize() const { return Size; } - int GetSizeI() const { return (int)GetSize(); } - const T& operator [] (size_t i) const { return Data[i]; } - T& operator [] (size_t i) { return Data[i]; } -private: - T* Data; - size_t Size; -}; - - -//----------------------------------------------------------------------------------- -// ***** GConstArrayAdaptor -// -// A simple const adapter that provides the GetSize() method and overloads -// operator []. Used to wrap plain arrays in LowerBound and such. -template class ConstArrayAdaptor -{ -public: - typedef T ValueType; - ConstArrayAdaptor() : Data(0), Size(0) {} - ConstArrayAdaptor(const T* ptr, size_t size) : Data(ptr), Size(size) {} - size_t GetSize() const { return Size; } - int GetSizeI() const { return (int)GetSize(); } - const T& operator [] (size_t i) const { return Data[i]; } -private: - const T* Data; - size_t Size; -}; - - - -//----------------------------------------------------------------------------------- -extern const uint8_t UpperBitTable[256]; -extern const uint8_t LowerBitTable[256]; - - - -//----------------------------------------------------------------------------------- -inline uint8_t UpperBit(size_t val) -{ -#ifndef OVR_64BIT_POINTERS - - if (val & 0xFFFF0000) - { - return (val & 0xFF000000) ? - UpperBitTable[(val >> 24) ] + 24: - UpperBitTable[(val >> 16) & 0xFF] + 16; - } - return (val & 0xFF00) ? - UpperBitTable[(val >> 8) & 0xFF] + 8: - UpperBitTable[(val ) & 0xFF]; - -#else - - if (val & 0xFFFFFFFF00000000) - { - if (val & 0xFFFF000000000000) - { - return (val & 0xFF00000000000000) ? - UpperBitTable[(val >> 56) ] + 56: - UpperBitTable[(val >> 48) & 0xFF] + 48; - } - return (val & 0xFF0000000000) ? - UpperBitTable[(val >> 40) & 0xFF] + 40: - UpperBitTable[(val >> 32) & 0xFF] + 32; - } - else - { - if (val & 0xFFFF0000) - { - return (val & 0xFF000000) ? - UpperBitTable[(val >> 24) ] + 24: - UpperBitTable[(val >> 16) & 0xFF] + 16; - } - return (val & 0xFF00) ? - UpperBitTable[(val >> 8) & 0xFF] + 8: - UpperBitTable[(val ) & 0xFF]; - } - -#endif -} - -//----------------------------------------------------------------------------------- -inline uint8_t LowerBit(size_t val) -{ -#ifndef OVR_64BIT_POINTERS - - if (val & 0xFFFF) - { - return (val & 0xFF) ? - LowerBitTable[ val & 0xFF]: - LowerBitTable[(val >> 8) & 0xFF] + 8; - } - return (val & 0xFF0000) ? - LowerBitTable[(val >> 16) & 0xFF] + 16: - LowerBitTable[(val >> 24) & 0xFF] + 24; - -#else - - if (val & 0xFFFFFFFF) - { - if (val & 0xFFFF) - { - return (val & 0xFF) ? - LowerBitTable[ val & 0xFF]: - LowerBitTable[(val >> 8) & 0xFF] + 8; - } - return (val & 0xFF0000) ? - LowerBitTable[(val >> 16) & 0xFF] + 16: - LowerBitTable[(val >> 24) & 0xFF] + 24; - } - else - { - if (val & 0xFFFF00000000) - { - return (val & 0xFF00000000) ? - LowerBitTable[(val >> 32) & 0xFF] + 32: - LowerBitTable[(val >> 40) & 0xFF] + 40; - } - return (val & 0xFF000000000000) ? - LowerBitTable[(val >> 48) & 0xFF] + 48: - LowerBitTable[(val >> 56) & 0xFF] + 56; - } - -#endif -} - - - -// ******* Special (optimized) memory routines -// Note: null (bad) pointer is not tested -class MemUtil -{ -public: - - // Memory compare - static int Cmp (const void* p1, const void* p2, size_t byteCount) { return memcmp(p1, p2, byteCount); } - static int Cmp16(const void* p1, const void* p2, size_t int16Count); - static int Cmp32(const void* p1, const void* p2, size_t int32Count); - static int Cmp64(const void* p1, const void* p2, size_t int64Count); -}; - -// ** Inline Implementation - -inline int MemUtil::Cmp16(const void* p1, const void* p2, size_t int16Count) -{ - int16_t* pa = (int16_t*)p1; - int16_t* pb = (int16_t*)p2; - unsigned ic = 0; - if (int16Count == 0) - return 0; - while (pa[ic] == pb[ic]) - if (++ic==int16Count) - return 0; - return pa[ic] > pb[ic] ? 1 : -1; -} -inline int MemUtil::Cmp32(const void* p1, const void* p2, size_t int32Count) -{ - int32_t* pa = (int32_t*)p1; - int32_t* pb = (int32_t*)p2; - unsigned ic = 0; - if (int32Count == 0) - return 0; - while (pa[ic] == pb[ic]) - if (++ic==int32Count) - return 0; - return pa[ic] > pb[ic] ? 1 : -1; -} -inline int MemUtil::Cmp64(const void* p1, const void* p2, size_t int64Count) -{ - int64_t* pa = (int64_t*)p1; - int64_t* pb = (int64_t*)p2; - unsigned ic = 0; - if (int64Count == 0) - return 0; - while (pa[ic] == pb[ic]) - if (++ic==int64Count) - return 0; - return pa[ic] > pb[ic] ? 1 : -1; -} - -// ** End Inline Implementation - - -//----------------------------------------------------------------------------------- -// ******* Byte Order Conversions -namespace ByteUtil { - - // *** Swap Byte Order - - // Swap the byte order of a byte array - inline void SwapOrder(void* pv, int size) - { - uint8_t* pb = (uint8_t*)pv; - uint8_t temp; - for (int i = 0; i < size>>1; i++) - { - temp = pb[size-1-i]; - pb[size-1-i] = pb[i]; - pb[i] = temp; - } - } - - // Swap the byte order of primitive types - inline uint8_t SwapOrder(uint8_t v) { return v; } - inline int8_t SwapOrder(int8_t v) { return v; } - inline uint16_t SwapOrder(uint16_t v) { return uint16_t(v>>8)|uint16_t(v<<8); } - inline int16_t SwapOrder(int16_t v) { return int16_t((uint16_t(v)>>8)|(v<<8)); } - inline uint32_t SwapOrder(uint32_t v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); } - inline int32_t SwapOrder(int32_t p) { return (int32_t)SwapOrder(uint32_t(p)); } - inline uint64_t SwapOrder(uint64_t v) - { - return (v>>56) | - ((v&uint64_t(0x00FF000000000000ULL))>>40) | - ((v&uint64_t(0x0000FF0000000000ULL))>>24) | - ((v&uint64_t(0x000000FF00000000ULL))>>8) | - ((v&uint64_t(0x00000000FF000000ULL))<<8) | - ((v&uint64_t(0x0000000000FF0000ULL))<<24) | - ((v&uint64_t(0x000000000000FF00ULL))<<40) | - (v<<56); - } - inline int64_t SwapOrder(int64_t v) { return (int64_t)SwapOrder(uint64_t(v)); } - inline float SwapOrder(float p) - { - union { - float p; - uint32_t v; - } u; - u.p = p; - u.v = SwapOrder(u.v); - return u.p; - } - - inline double SwapOrder(double p) - { - union { - double p; - uint64_t v; - } u; - u.p = p; - u.v = SwapOrder(u.v); - return u.p; - } - - // *** Byte-order conversion - -#if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN) - // Little Endian to System (LE) - inline uint8_t LEToSystem(uint8_t v) { return v; } - inline int8_t LEToSystem(int8_t v) { return v; } - inline uint16_t LEToSystem(uint16_t v) { return v; } - inline int16_t LEToSystem(int16_t v) { return v; } - inline uint32_t LEToSystem(uint32_t v) { return v; } - inline int32_t LEToSystem(int32_t v) { return v; } - inline uint64_t LEToSystem(uint64_t v) { return v; } - inline int64_t LEToSystem(int64_t v) { return v; } - inline float LEToSystem(float v) { return v; } - inline double LEToSystem(double v) { return v; } - - // Big Endian to System (LE) - inline uint8_t BEToSystem(uint8_t v) { return SwapOrder(v); } - inline int8_t BEToSystem(int8_t v) { return SwapOrder(v); } - inline uint16_t BEToSystem(uint16_t v) { return SwapOrder(v); } - inline int16_t BEToSystem(int16_t v) { return SwapOrder(v); } - inline uint32_t BEToSystem(uint32_t v) { return SwapOrder(v); } - inline int32_t BEToSystem(int32_t v) { return SwapOrder(v); } - inline uint64_t BEToSystem(uint64_t v) { return SwapOrder(v); } - inline int64_t BEToSystem(int64_t v) { return SwapOrder(v); } - inline float BEToSystem(float v) { return SwapOrder(v); } - inline double BEToSystem(double v) { return SwapOrder(v); } - - // System (LE) to Little Endian - inline uint8_t SystemToLE(uint8_t v) { return v; } - inline int8_t SystemToLE(int8_t v) { return v; } - inline uint16_t SystemToLE(uint16_t v) { return v; } - inline int16_t SystemToLE(int16_t v) { return v; } - inline uint32_t SystemToLE(uint32_t v) { return v; } - inline int32_t SystemToLE(int32_t v) { return v; } - inline uint64_t SystemToLE(uint64_t v) { return v; } - inline int64_t SystemToLE(int64_t v) { return v; } - inline float SystemToLE(float v) { return v; } - inline double SystemToLE(double v) { return v; } - - // System (LE) to Big Endian - inline uint8_t SystemToBE(uint8_t v) { return SwapOrder(v); } - inline int8_t SystemToBE(int8_t v) { return SwapOrder(v); } - inline uint16_t SystemToBE(uint16_t v) { return SwapOrder(v); } - inline int16_t SystemToBE(int16_t v) { return SwapOrder(v); } - inline uint32_t SystemToBE(uint32_t v) { return SwapOrder(v); } - inline int32_t SystemToBE(int32_t v) { return SwapOrder(v); } - inline uint64_t SystemToBE(uint64_t v) { return SwapOrder(v); } - inline int64_t SystemToBE(int64_t v) { return SwapOrder(v); } - inline float SystemToBE(float v) { return SwapOrder(v); } - inline double SystemToBE(double v) { return SwapOrder(v); } - -#elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN) - // Little Endian to System (BE) - inline uint8_t LEToSystem(uint8_t v) { return SwapOrder(v); } - inline int8_t LEToSystem(int8_t v) { return SwapOrder(v); } - inline uint16_t LEToSystem(uint16_t v) { return SwapOrder(v); } - inline int16_t LEToSystem(int16_t v) { return SwapOrder(v); } - inline uint32_t LEToSystem(uint32_t v) { return SwapOrder(v); } - inline int32_t LEToSystem(int32_t v) { return SwapOrder(v); } - inline uint64_t LEToSystem(uint64_t v) { return SwapOrder(v); } - inline int64_t LEToSystem(int64_t v) { return SwapOrder(v); } - inline float LEToSystem(float v) { return SwapOrder(v); } - inline double LEToSystem(double v) { return SwapOrder(v); } - - // Big Endian to System (BE) - inline uint8_t BEToSystem(uint8_t v) { return v; } - inline int8_t BEToSystem(int8_t v) { return v; } - inline uint16_t BEToSystem(uint16_t v) { return v; } - inline int16_t BEToSystem(int16_t v) { return v; } - inline uint32_t BEToSystem(uint32_t v) { return v; } - inline int32_t BEToSystem(int32_t v) { return v; } - inline uint64_t BEToSystem(uint64_t v) { return v; } - inline int64_t BEToSystem(int64_t v) { return v; } - inline float BEToSystem(float v) { return v; } - inline double BEToSystem(double v) { return v; } - - // System (BE) to Little Endian - inline uint8_t SystemToLE(uint8_t v) { return SwapOrder(v); } - inline int8_t SystemToLE(int8_t v) { return SwapOrder(v); } - inline uint16_t SystemToLE(uint16_t v) { return SwapOrder(v); } - inline int16_t SystemToLE(int16_t v) { return SwapOrder(v); } - inline uint32_t SystemToLE(uint32_t v) { return SwapOrder(v); } - inline int32_t SystemToLE(int32_t v) { return SwapOrder(v); } - inline uint64_t SystemToLE(uint64_t v) { return SwapOrder(v); } - inline int64_t SystemToLE(int64_t v) { return SwapOrder(v); } - inline float SystemToLE(float v) { return SwapOrder(v); } - inline double SystemToLE(double v) { return SwapOrder(v); } - - // System (BE) to Big Endian - inline uint8_t SystemToBE(uint8_t v) { return v; } - inline int8_t SystemToBE(int8_t v) { return v; } - inline uint16_t SystemToBE(uint16_t v) { return v; } - inline int16_t SystemToBE(int16_t v) { return v; } - inline uint32_t SystemToBE(uint32_t v) { return v; } - inline int32_t SystemToBE(int32_t v) { return v; } - inline uint64_t SystemToBE(uint64_t v) { return v; } - inline int64_t SystemToBE(int64_t v) { return v; } - inline float SystemToBE(float v) { return v; } - inline double SystemToBE(double v) { return v; } - -#else - #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN" -#endif - -} // namespace ByteUtil - - - -// Used primarily for hardware interfacing such as sensor reports, firmware, etc. -// Reported data is all little-endian. -inline uint16_t DecodeUInt16(const uint8_t* buffer) -{ - return ByteUtil::LEToSystem ( *(const uint16_t*)buffer ); -} - -inline int16_t DecodeSInt16(const uint8_t* buffer) -{ - return ByteUtil::LEToSystem ( *(const int16_t*)buffer ); -} - -inline uint32_t DecodeUInt32(const uint8_t* buffer) -{ - return ByteUtil::LEToSystem ( *(const uint32_t*)buffer ); -} - -inline int32_t DecodeSInt32(const uint8_t* buffer) -{ - return ByteUtil::LEToSystem ( *(const int32_t*)buffer ); -} - -inline float DecodeFloat(const uint8_t* buffer) -{ - union { - uint32_t U; - float F; - }; - - U = DecodeUInt32(buffer); - return F; -} - -inline void EncodeUInt16(uint8_t* buffer, uint16_t val) -{ - *(uint16_t*)buffer = ByteUtil::SystemToLE ( val ); -} - -inline void EncodeSInt16(uint8_t* buffer, int16_t val) -{ - *(int16_t*)buffer = ByteUtil::SystemToLE ( val ); -} - -inline void EncodeUInt32(uint8_t* buffer, uint32_t val) -{ - *(uint32_t*)buffer = ByteUtil::SystemToLE ( val ); -} - -inline void EncodeSInt32(uint8_t* buffer, int32_t val) -{ - *(int32_t*)buffer = ByteUtil::SystemToLE ( val ); -} - -inline void EncodeFloat(uint8_t* buffer, float val) -{ - union { - uint32_t U; - float F; - }; - - F = val; - EncodeUInt32(buffer, U); -} - -// Converts an 8-bit binary-coded decimal -inline int8_t DecodeBCD(uint8_t byte) -{ - uint8_t digit1 = (byte >> 4) & 0x0f; - uint8_t digit2 = byte & 0x0f; - int decimal = digit1 * 10 + digit2; // maximum value = 99 - return (int8_t)decimal; -} - - -}} // OVR::Alg - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Allocator.cpp b/LibOVR/Src/Kernel/OVR_Allocator.cpp deleted file mode 100644 index f963d08..0000000 --- a/LibOVR/Src/Kernel/OVR_Allocator.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Allocator.cpp -Content : Installable memory allocator implementation -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Allocator.h" -#ifdef OVR_OS_MAC - #include -#else - #include -#endif - -#if defined(OVR_OS_MS) - #include -#elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - #include - #include -#endif - - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Allocator - -Allocator* Allocator::pInstance = 0; - -// Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding. -void* Allocator::AllocAligned(size_t size, size_t align) -{ - OVR_ASSERT((align & (align-1)) == 0); - align = (align > sizeof(size_t)) ? align : sizeof(size_t); - size_t p = (size_t)Alloc(size+align); - size_t aligned = 0; - if (p) - { - aligned = (size_t(p) + align-1) & ~(align-1); - if (aligned == p) - aligned += align; - *(((size_t*)aligned)-1) = aligned-p; - } - return (void*)aligned; -} - -void Allocator::FreeAligned(void* p) -{ - size_t src = size_t(p) - *(((size_t*)p)-1); - Free((void*)src); -} - - -//------------------------------------------------------------------------ -// ***** Default Allocator - -// This allocator is created and used if no other allocator is installed. -// Default allocator delegates to system malloc. - -void* DefaultAllocator::Alloc(size_t size) -{ - return malloc(size); -} -void* DefaultAllocator::AllocDebug(size_t size, const char* file, unsigned line) -{ - OVR_UNUSED2(file, line); // should be here for debugopt config -#if defined(OVR_CC_MSVC) && defined(_CRTDBG_MAP_ALLOC) - return _malloc_dbg(size, _NORMAL_BLOCK, file, line); -#else - return malloc(size); -#endif -} - -void* DefaultAllocator::Realloc(void* p, size_t newSize) -{ - return realloc(p, newSize); -} -void DefaultAllocator::Free(void *p) -{ - return free(p); -} - - - - -void* MMapAlloc(size_t size) -{ - #if defined(OVR_OS_MS) - return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // size is rounded up to a page. // Returned memory is 0-filled. - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - #if !defined(MAP_FAILED) - #define MAP_FAILED ((void*)-1) - #endif - - void* result = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); // Returned memory is 0-filled. - if(result == MAP_FAILED) // mmap returns MAP_FAILED (-1) upon failure. - result = NULL; - return result; - #endif -} - - - - -void MMapFree(void* memory, size_t size) -{ - #if defined(OVR_OS_MS) - OVR_UNUSED(size); - VirtualFree(memory, 0, MEM_RELEASE); - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - size_t pageSize = getpagesize(); - size = (((size + (pageSize - 1)) / pageSize) * pageSize); - munmap(memory, size); // Must supply the size to munmap. - #endif -} - - - - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_Allocator.h b/LibOVR/Src/Kernel/OVR_Allocator.h deleted file mode 100644 index dcf097d..0000000 --- a/LibOVR/Src/Kernel/OVR_Allocator.h +++ /dev/null @@ -1,360 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Allocator.h -Content : Installable memory allocator -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Allocator_h -#define OVR_Allocator_h - -#include "OVR_Types.h" - -//----------------------------------------------------------------------------------- - -// ***** Disable template-unfriendly MS VC++ warnings -#if defined(OVR_CC_MSVC) -// Pragma to prevent long name warnings in in VC++ -#pragma warning(disable : 4503) -#pragma warning(disable : 4786) -// In MSVC 7.1, warning about placement new POD default initializer -#pragma warning(disable : 4345) -#endif - -// Un-define new so that placement constructors work -#undef new - - -//----------------------------------------------------------------------------------- -// ***** Placement new overrides - -// Calls constructor on own memory created with "new(ptr) type" -#ifndef __PLACEMENT_NEW_INLINE -#define __PLACEMENT_NEW_INLINE - -# if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU) -# include -# else - // Useful on MSVC - OVR_FORCE_INLINE void* operator new (size_t n, void *ptr) { OVR_UNUSED(n); return ptr; } - OVR_FORCE_INLINE void operator delete (void *, void *) { } -# endif - -#endif // __PLACEMENT_NEW_INLINE - - - -//------------------------------------------------------------------------ -// ***** Macros to redefine class new/delete operators - -// Types specifically declared to allow disambiguation of address in -// class member operator new. - -#define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \ - void* operator new(size_t sz) \ - { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; } \ - void* operator new(size_t sz, const char* file, int line) \ - { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; } \ - void operator delete(void *p) \ - { check_delete(class_name, p); OVR_FREE(p); } \ - void operator delete(void *p, const char*, int) \ - { check_delete(class_name, p); OVR_FREE(p); } - -#define OVR_MEMORY_DEFINE_PLACEMENT_NEW \ - void* operator new (size_t n, void *ptr) { OVR_UNUSED(n); return ptr; } \ - void operator delete (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); } - - -#define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p) - -// Redefined all delete/new operators in a class without custom memory initialization -#define OVR_MEMORY_REDEFINE_NEW(class_name) \ - OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE) - - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Construct / Destruct - -// Construct/Destruct functions are useful when new is redefined, as they can -// be called instead of placement new constructors. - - -template -OVR_FORCE_INLINE T* Construct(void *p) -{ - return ::new(p) T(); -} - -template -OVR_FORCE_INLINE T* Construct(void *p, const T& source) -{ - return ::new(p) T(source); -} - -// Same as above, but allows for a different type of constructor. -template -OVR_FORCE_INLINE T* ConstructAlt(void *p, const S& source) -{ - return ::new(p) T(source); -} - -template -OVR_FORCE_INLINE T* ConstructAlt(void *p, const S1& src1, const S2& src2) -{ - return ::new(p) T(src1, src2); -} - -template -OVR_FORCE_INLINE void ConstructArray(void *p, size_t count) -{ - uint8_t *pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - { - Construct(pdata); - } -} - -template -OVR_FORCE_INLINE void ConstructArray(void *p, size_t count, const T& source) -{ - uint8_t *pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - { - Construct(pdata, source); - } -} - -template -OVR_FORCE_INLINE void Destruct(T *pobj) -{ - pobj->~T(); - OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning. -} - -template -OVR_FORCE_INLINE void DestructArray(T *pobj, size_t count) -{ - for (size_t i=0; i~T(); -} - - -//----------------------------------------------------------------------------------- -// ***** Allocator - -// Allocator defines a memory allocation interface that developers can override -// to to provide memory for OVR; an instance of this class is typically created on -// application startup and passed into System or OVR::System constructor. -// -// -// Users implementing this interface must provide three functions: Alloc, Free, -// and Realloc. Implementations of these functions must honor the requested alignment. -// Although arbitrary alignment requests are possible, requested alignment will -// typically be small, such as 16 bytes or less. - -class Allocator -{ - friend class System; -public: - virtual ~Allocator(){} - - // *** Standard Alignment Alloc/Free - - // Allocate memory of specified size with default alignment. - // Alloc of size==0 will allocate a tiny block & return a valid pointer; - // this makes it suitable for new operator. - virtual void* Alloc(size_t size) = 0; - // Same as Alloc, but provides an option of passing debug data. - virtual void* AllocDebug(size_t size, const char* file, unsigned line) - { OVR_UNUSED2(file, line); return Alloc(size); } - - // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to - // new memory block, which may be the same as original pointer. Will return 0 if reallocation - // failed, in which case previous memory is still valid. - // Realloc to decrease size will never fail. - // Realloc of pointer == 0 is equivalent to Alloc - // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free(). - virtual void* Realloc(void* p, size_t newSize) = 0; - - // Frees memory allocated by Alloc/Realloc. - // Free of null pointer is valid and will do nothing. - virtual void Free(void *p) = 0; - - - // *** Standard Alignment Alloc/Free - - // Allocate memory of specified alignment. - // Memory allocated with AllocAligned MUST be freed with FreeAligned. - // Default implementation will delegate to Alloc/Free after doing rounding. - virtual void* AllocAligned(size_t size, size_t align); - // Frees memory allocated with AllocAligned. - virtual void FreeAligned(void* p); - - // Returns the pointer to the current globally installed Allocator instance. - // This pointer is used for most of the memory allocations. - static Allocator* GetInstance() { return pInstance; } - - -protected: - // onSystemShutdown is called on the allocator during System::Shutdown. - // At this point, all allocations should've been freed. - virtual void onSystemShutdown() { } - -public: - static void setInstance(Allocator* palloc) - { - OVR_ASSERT((pInstance == 0) || (palloc == 0)); - pInstance = palloc; - } - -private: - - static Allocator* pInstance; -}; - - - -//------------------------------------------------------------------------ -// ***** Allocator_SingletonSupport - -// Allocator_SingletonSupport is a Allocator wrapper class that implements -// the InitSystemSingleton static function, used to create a global singleton -// used for the OVR::System default argument initialization. -// -// End users implementing custom Allocator interface don't need to make use of this base -// class; they can just create an instance of their own class on stack and pass it to System. - -template -class Allocator_SingletonSupport : public Allocator -{ - struct AllocContainer - { - size_t Data[(sizeof(D) + sizeof(size_t)-1) / sizeof(size_t)]; - bool Initialized; - AllocContainer() : Initialized(0) { } - }; - - AllocContainer* pContainer; - -public: - Allocator_SingletonSupport() : pContainer(0) { } - - // Creates a singleton instance of this Allocator class used - // on OVR_DEFAULT_ALLOCATOR during System initialization. - static D* InitSystemSingleton() - { - static AllocContainer Container; - OVR_ASSERT(Container.Initialized == false); - - Allocator_SingletonSupport *presult = Construct((void*)Container.Data); - presult->pContainer = &Container; - Container.Initialized = true; - return (D*)presult; - } - -protected: - virtual void onSystemShutdown() - { - Allocator::onSystemShutdown(); - if (pContainer) - { - pContainer->Initialized = false; - Destruct((D*)this); - pContainer = 0; - } - } -}; - -//------------------------------------------------------------------------ -// ***** Default Allocator - -// This allocator is created and used if no other allocator is installed. -// Default allocator delegates to system malloc. - -class DefaultAllocator : public Allocator_SingletonSupport -{ -public: - virtual void* Alloc(size_t size); - virtual void* AllocDebug(size_t size, const char* file, unsigned line); - virtual void* Realloc(void* p, size_t newSize); - virtual void Free(void *p); -}; - - -//------------------------------------------------------------------------ -// ***** Memory Allocation Macros - -// These macros should be used for global allocation. In the future, these -// macros will allows allocation to be extended with debug file/line information -// if necessary. - -#define OVR_REALLOC(p,s) OVR::Allocator::GetInstance()->Realloc((p),(s)) -#define OVR_FREE(p) OVR::Allocator::GetInstance()->Free((p)) -#define OVR_ALLOC_ALIGNED(s,a) OVR::Allocator::GetInstance()->AllocAligned((s),(a)) -#define OVR_FREE_ALIGNED(p) OVR::Allocator::GetInstance()->FreeAligned((p)) - -#ifdef OVR_BUILD_DEBUG -#define OVR_ALLOC(s) OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__) -#define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->AllocDebug((s), f, l) -#else -#define OVR_ALLOC(s) OVR::Allocator::GetInstance()->Alloc((s)) -#define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->Alloc((s)) -#endif - -//------------------------------------------------------------------------ - -// Base class that overrides the new and delete operators. -// Deriving from this class, even as a multiple base, incurs no space overhead. -class NewOverrideBase -{ -public: - - // Redefine all new & delete operators. - OVR_MEMORY_REDEFINE_NEW(NewOverrideBase) -}; - - -//------------------------------------------------------------------------ -// ***** Mapped memory allocation -// -// Equates to VirtualAlloc/VirtualFree on Windows, mmap/munmap on Unix. -// These are useful for when you need system-supplied memory pages. -// These are also useful for when you need to allocate memory in a way -// that doesn't affect the application heap. - -void* MMapAlloc(size_t size); -void MMapFree(void* memory, size_t size); - - -} // OVR - - -// Redefine operator 'new' if necessary. -#if defined(OVR_DEFINE_NEW) -#define new OVR_DEFINE_NEW -#endif - - -#endif // OVR_Memory diff --git a/LibOVR/Src/Kernel/OVR_Array.h b/LibOVR/Src/Kernel/OVR_Array.h deleted file mode 100644 index 7855a5b..0000000 --- a/LibOVR/Src/Kernel/OVR_Array.h +++ /dev/null @@ -1,837 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Array.h -Content : Template implementation for Array -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Array_h -#define OVR_Array_h - -#include "OVR_ContainerAllocator.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** ArrayDefaultPolicy -// -// Default resize behavior. No minimal capacity, Granularity=4, -// Shrinking as needed. ArrayConstPolicy actually is the same as -// ArrayDefaultPolicy, but parametrized with constants. -// This struct is used only in order to reduce the template "matroska". -struct ArrayDefaultPolicy -{ - ArrayDefaultPolicy() : Capacity(0) {} - ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {} - - size_t GetMinCapacity() const { return 0; } - size_t GetGranularity() const { return 4; } - bool NeverShrinking() const { return 0; } - - size_t GetCapacity() const { return Capacity; } - void SetCapacity(size_t capacity) { Capacity = capacity; } -private: - size_t Capacity; -}; - - -//----------------------------------------------------------------------------------- -// ***** ArrayConstPolicy -// -// Statically parametrized resizing behavior: -// MinCapacity, Granularity, and Shrinking flag. -template -struct ArrayConstPolicy -{ - typedef ArrayConstPolicy SelfType; - - ArrayConstPolicy() : Capacity(0) {} - ArrayConstPolicy(const SelfType&) : Capacity(0) {} - - size_t GetMinCapacity() const { return MinCapacity; } - size_t GetGranularity() const { return Granularity; } - bool NeverShrinking() const { return NeverShrink; } - - size_t GetCapacity() const { return Capacity; } - void SetCapacity(size_t capacity) { Capacity = capacity; } -private: - size_t Capacity; -}; - -//----------------------------------------------------------------------------------- -// ***** ArrayDataBase -// -// Basic operations with array data: Reserve, Resize, Free, ArrayPolicy. -// For internal use only: ArrayData,ArrayDataCC and others. -template -struct ArrayDataBase -{ - typedef T ValueType; - typedef Allocator AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayDataBase SelfType; - - ArrayDataBase() - : Data(0), Size(0), Policy() {} - - ArrayDataBase(const SizePolicy& p) - : Data(0), Size(0), Policy(p) {} - - ~ArrayDataBase() - { - Allocator::DestructArray(Data, Size); - Allocator::Free(Data); - } - - size_t GetCapacity() const - { - return Policy.GetCapacity(); - } - - void ClearAndRelease() - { - Allocator::DestructArray(Data, Size); - Allocator::Free(Data); - Data = 0; - Size = 0; - Policy.SetCapacity(0); - } - - void Reserve(size_t newCapacity) - { - if (Policy.NeverShrinking() && newCapacity < GetCapacity()) - return; - - if (newCapacity < Policy.GetMinCapacity()) - newCapacity = Policy.GetMinCapacity(); - - // Resize the buffer. - if (newCapacity == 0) - { - if (Data) - { - Allocator::Free(Data); - Data = 0; - } - Policy.SetCapacity(0); - } - else - { - size_t gran = Policy.GetGranularity(); - newCapacity = (newCapacity + gran - 1) / gran * gran; - if (Data) - { - if (Allocator::IsMovable()) - { - Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity); - } - else - { - T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity); - size_t i, s; - s = (Size < newCapacity) ? Size : newCapacity; - for (i = 0; i < s; ++i) - { - Allocator::Construct(&newData[i], Data[i]); - Allocator::Destruct(&Data[i]); - } - for (i = s; i < Size; ++i) - { - Allocator::Destruct(&Data[i]); - } - Allocator::Free(Data); - Data = newData; - } - } - else - { - Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity); - //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this? - } - Policy.SetCapacity(newCapacity); - // OVR_ASSERT(Data); // need to throw (or something) on alloc failure! - } - } - - // This version of Resize DOES NOT construct the elements. - // It's done to optimize PushBack, which uses a copy constructor - // instead of the default constructor and assignment - void ResizeNoConstruct(size_t newSize) - { - size_t oldSize = Size; - - if (newSize < oldSize) - { - Allocator::DestructArray(Data + newSize, oldSize - newSize); - if (newSize < (Policy.GetCapacity() >> 1)) - { - Reserve(newSize); - } - } - else if(newSize >= Policy.GetCapacity()) - { - Reserve(newSize + (newSize >> 2)); - } - //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable - // array may use this array and may traverse it during Reserve (in the case, if - // collection occurs because of heap limit exceeded). - Size = newSize; - } - - ValueType* Data; - size_t Size; - SizePolicy Policy; -}; - - - -//----------------------------------------------------------------------------------- -// ***** ArrayData -// -// General purpose array data. -// For internal use only in Array, ArrayLH, ArrayPOD and so on. -template -struct ArrayData : ArrayDataBase -{ - typedef T ValueType; - typedef Allocator AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayDataBase BaseType; - typedef ArrayData SelfType; - - ArrayData() - : BaseType() { } - - ArrayData(size_t size) - : BaseType() { Resize(size); } - - ArrayData(const SelfType& a) - : BaseType(a.Policy) { Append(a.Data, a.Size); } - - - void Resize(size_t newSize) - { - size_t oldSize = this->Size; - BaseType::ResizeNoConstruct(newSize); - if(newSize > oldSize) - Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize); - } - - void PushBack(const ValueType& val) - { - BaseType::ResizeNoConstruct(this->Size + 1); - OVR_ASSERT(this->Data != NULL); - Allocator::Construct(this->Data + this->Size - 1, val); - } - - template - void PushBackAlt(const S& val) - { - BaseType::ResizeNoConstruct(this->Size + 1); - Allocator::ConstructAlt(this->Data + this->Size - 1, val); - } - - // Append the given data to the array. - void Append(const ValueType other[], size_t count) - { - if (count) - { - size_t oldSize = this->Size; - BaseType::ResizeNoConstruct(this->Size + count); - Allocator::ConstructArray(this->Data + oldSize, count, other); - } - } -}; - - - -//----------------------------------------------------------------------------------- -// ***** ArrayDataCC -// -// A modification of ArrayData that always copy-constructs new elements -// using a specified DefaultValue. For internal use only in ArrayCC. -template -struct ArrayDataCC : ArrayDataBase -{ - typedef T ValueType; - typedef Allocator AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayDataBase BaseType; - typedef ArrayDataCC SelfType; - - ArrayDataCC(const ValueType& defval) - : BaseType(), DefaultValue(defval) { } - - ArrayDataCC(const ValueType& defval, size_t size) - : BaseType(), DefaultValue(defval) { Resize(size); } - - ArrayDataCC(const SelfType& a) - : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); } - - - void Resize(size_t newSize) - { - size_t oldSize = this->Size; - BaseType::ResizeNoConstruct(newSize); - if(newSize > oldSize) - Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue); - } - - void PushBack(const ValueType& val) - { - BaseType::ResizeNoConstruct(this->Size + 1); - Allocator::Construct(this->Data + this->Size - 1, val); - } - - template - void PushBackAlt(const S& val) - { - BaseType::ResizeNoConstruct(this->Size + 1); - Allocator::ConstructAlt(this->Data + this->Size - 1, val); - } - - // Append the given data to the array. - void Append(const ValueType other[], size_t count) - { - if (count) - { - size_t oldSize = this->Size; - BaseType::ResizeNoConstruct(this->Size + count); - Allocator::ConstructArray(this->Data + oldSize, count, other); - } - } - - ValueType DefaultValue; -}; - - - - - -//----------------------------------------------------------------------------------- -// ***** ArrayBase -// -// Resizable array. The behavior can be POD (suffix _POD) and -// Movable (no suffix) depending on the allocator policy. -// In case of _POD the constructors and destructors are not called. -// -// Arrays can't handle non-movable objects! Don't put anything in here -// that can't be moved around by bitwise copy. -// -// The addresses of elements are not persistent! Don't keep the address -// of an element; the array contents will move around as it gets resized. -template -class ArrayBase -{ -public: - typedef typename ArrayData::ValueType ValueType; - typedef typename ArrayData::AllocatorType AllocatorType; - typedef typename ArrayData::SizePolicyType SizePolicyType; - typedef ArrayBase SelfType; - - -#undef new - OVR_MEMORY_REDEFINE_NEW(ArrayBase) -// Redefine operator 'new' if necessary. -#if defined(OVR_DEFINE_NEW) -#define new OVR_DEFINE_NEW -#endif - - - ArrayBase() - : Data() {} - ArrayBase(size_t size) - : Data(size) {} - ArrayBase(const SelfType& a) - : Data(a.Data) {} - - ArrayBase(const ValueType& defval) - : Data(defval) {} - ArrayBase(const ValueType& defval, size_t size) - : Data(defval, size) {} - - SizePolicyType* GetSizePolicy() const { return Data.Policy; } - void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; } - - bool NeverShrinking()const { return Data.Policy.NeverShrinking(); } - size_t GetSize() const { return Data.Size; } - int GetSizeI() const { return (int)Data.Size; } - bool IsEmpty() const { return Data.Size == 0; } - size_t GetCapacity() const { return Data.GetCapacity(); } - size_t GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); } - - void ClearAndRelease() { Data.ClearAndRelease(); } - void Clear() { Data.Resize(0); } - void Resize(size_t newSize) { Data.Resize(newSize); } - - // Reserve can only increase the capacity - void Reserve(size_t newCapacity) - { - if (newCapacity > Data.GetCapacity()) - Data.Reserve(newCapacity); - } - - // Basic access. - ValueType& At(size_t index) - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); // Asserting that Data.Data is valid helps static analysis tools. - return Data.Data[index]; - } - const ValueType& At(size_t index) const - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - return Data.Data[index]; - } - - ValueType ValueAt(size_t index) const - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - return Data.Data[index]; - } - - // Basic access. - ValueType& operator [] (size_t index) - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - return Data.Data[index]; - } - const ValueType& operator [] (size_t index) const - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - return Data.Data[index]; - } - - // Raw pointer to the data. Use with caution! - const ValueType* GetDataPtr() const { return Data.Data; } - ValueType* GetDataPtr() { return Data.Data; } - - // Insert the given element at the end of the array. - void PushBack(const ValueType& val) - { - // DO NOT pass elements of your own vector into - // push_back()! Since we're using references, - // resize() may munge the element storage! - // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]); - Data.PushBack(val); - } - - template - void PushBackAlt(const S& val) - { - Data.PushBackAlt(val); - } - - // Remove the last element. - void PopBack(size_t count = 1) - { - OVR_ASSERT(Data.Size >= count); - Data.Resize(Data.Size - count); - } - - ValueType& PushDefault() - { - Data.PushBack(ValueType()); - return Back(); - } - - ValueType Pop() - { - OVR_ASSERT((Data.Data) && (Data.Size > 0)); - ValueType t = Back(); - PopBack(); - return t; - } - - - // Access the first element. - ValueType& Front() { return At(0); } - const ValueType& Front() const { return At(0); } - - // Access the last element. - ValueType& Back() { return At(Data.Size - 1); } - const ValueType& Back() const { return At(Data.Size - 1); } - - // Array copy. Copies the contents of a into this array. - const SelfType& operator = (const SelfType& a) - { - Resize(a.GetSize()); - OVR_ASSERT((Data.Data != NULL) || (Data.Size == 0)); - for (size_t i = 0; i < Data.Size; i++) { - *(Data.Data + i) = a[i]; - } - return *this; - } - - // Removing multiple elements from the array. - void RemoveMultipleAt(size_t index, size_t num) - { - OVR_ASSERT(index + num <= Data.Size); - if (Data.Size == num) - { - Clear(); - } - else - { - AllocatorType::DestructArray(Data.Data + index, num); - AllocatorType::CopyArrayForward( - Data.Data + index, - Data.Data + index + num, - Data.Size - num - index); - Data.Size -= num; - } - } - - // Removing an element from the array is an expensive operation! - // It compacts only after removing the last element. - // If order of elements in the array is not important then use - // RemoveAtUnordered, that could be much faster than the regular - // RemoveAt. - void RemoveAt(size_t index) - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - if (Data.Size == 1) - { - Clear(); - } - else - { - AllocatorType::Destruct(Data.Data + index); - AllocatorType::CopyArrayForward( - Data.Data + index, - Data.Data + index + 1, - Data.Size - 1 - index); - --Data.Size; - } - } - - // Removes an element from the array without respecting of original order of - // elements for better performance. Do not use on array where order of elements - // is important, otherwise use it instead of regular RemoveAt(). - void RemoveAtUnordered(size_t index) - { - OVR_ASSERT((Data.Data) && (index < Data.Size)); - if (Data.Size == 1) - { - Clear(); - } - else - { - // copy the last element into the 'index' position - // and decrement the size (instead of moving all elements - // in [index + 1 .. size - 1] range). - const size_t lastElemIndex = Data.Size - 1; - if (index < lastElemIndex) - { - AllocatorType::Destruct(Data.Data + index); - AllocatorType::Construct(Data.Data + index, Data.Data[lastElemIndex]); - } - AllocatorType::Destruct(Data.Data + lastElemIndex); - --Data.Size; - } - } - - // Insert the given object at the given index shifting all the elements up. - void InsertAt(size_t index, const ValueType& val = ValueType()) - { - OVR_ASSERT(index <= Data.Size); - - Data.Resize(Data.Size + 1); - if (index < Data.Size - 1) - { - AllocatorType::CopyArrayBackward( - Data.Data + index + 1, - Data.Data + index, - Data.Size - 1 - index); - } - AllocatorType::Construct(Data.Data + index, val); - } - - // Insert the given object at the given index shifting all the elements up. - void InsertMultipleAt(size_t index, size_t num, const ValueType& val = ValueType()) - { - OVR_ASSERT(index <= Data.Size); - - Data.Resize(Data.Size + num); - if (index < Data.Size - num) - { - AllocatorType::CopyArrayBackward( - Data.Data + index + num, - Data.Data + index, - Data.Size - num - index); - } - for (size_t i = 0; i < num; ++i) - AllocatorType::Construct(Data.Data + index + i, val); - } - - // Append the given data to the array. - void Append(const SelfType& other) - { - Append(other.Data.Data, other.GetSize()); - } - - // Append the given data to the array. - void Append(const ValueType other[], size_t count) - { - Data.Append(other, count); - } - - class Iterator - { - SelfType* pArray; - intptr_t CurIndex; - - public: - Iterator() : pArray(0), CurIndex(-1) {} - Iterator(SelfType* parr, intptr_t idx = 0) : pArray(parr), CurIndex(idx) {} - - bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } - bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } - - Iterator& operator++() - { - if (pArray) - { - if (CurIndex < (intptr_t)pArray->GetSize()) - ++CurIndex; - } - return *this; - } - Iterator operator++(int) - { - Iterator it(*this); - operator++(); - return it; - } - Iterator& operator--() - { - if (pArray) - { - if (CurIndex >= 0) - --CurIndex; - } - return *this; - } - Iterator operator--(int) - { - Iterator it(*this); - operator--(); - return it; - } - Iterator operator+(int delta) const - { - return Iterator(pArray, CurIndex + delta); - } - Iterator operator-(int delta) const - { - return Iterator(pArray, CurIndex - delta); - } - intptr_t operator-(const Iterator& right) const - { - OVR_ASSERT(pArray == right.pArray); - return CurIndex - right.CurIndex; - } - ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } - ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } - ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } - - bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } - - void Remove() - { - if (!IsFinished()) - pArray->RemoveAt(CurIndex); - } - - intptr_t GetIndex() const { return CurIndex; } - }; - - Iterator Begin() { return Iterator(this); } - Iterator End() { return Iterator(this, (intptr_t)GetSize()); } - Iterator Last() { return Iterator(this, (intptr_t)GetSize() - 1); } - - class ConstIterator - { - const SelfType* pArray; - intptr_t CurIndex; - - public: - ConstIterator() : pArray(0), CurIndex(-1) {} - ConstIterator(const SelfType* parr, intptr_t idx = 0) : pArray(parr), CurIndex(idx) {} - - bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } - bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } - - ConstIterator& operator++() - { - if (pArray) - { - if (CurIndex < (int)pArray->GetSize()) - ++CurIndex; - } - return *this; - } - ConstIterator operator++(int) - { - ConstIterator it(*this); - operator++(); - return it; - } - ConstIterator& operator--() - { - if (pArray) - { - if (CurIndex >= 0) - --CurIndex; - } - return *this; - } - ConstIterator operator--(int) - { - ConstIterator it(*this); - operator--(); - return it; - } - ConstIterator operator+(int delta) const - { - return ConstIterator(pArray, CurIndex + delta); - } - ConstIterator operator-(int delta) const - { - return ConstIterator(pArray, CurIndex - delta); - } - intptr_t operator-(const ConstIterator& right) const - { - OVR_ASSERT(pArray == right.pArray); - return CurIndex - right.CurIndex; - } - const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } - const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } - const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } - - bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } - - intptr_t GetIndex() const { return CurIndex; } - }; - ConstIterator Begin() const { return ConstIterator(this); } - ConstIterator End() const { return ConstIterator(this, (intptr_t)GetSize()); } - ConstIterator Last() const { return ConstIterator(this, (intptr_t)GetSize() - 1); } - -protected: - ArrayData Data; -}; - - - -//----------------------------------------------------------------------------------- -// ***** Array -// -// General purpose array for movable objects that require explicit -// construction/destruction. -template -class Array : public ArrayBase, SizePolicy> > -{ -public: - typedef T ValueType; - typedef ContainerAllocator AllocatorType; - typedef SizePolicy SizePolicyType; - typedef Array SelfType; - typedef ArrayBase, SizePolicy> > BaseType; - - Array() : BaseType() {} - Array(size_t size) : BaseType(size) {} - Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } - Array(const SelfType& a) : BaseType(a) {} - const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } -}; - -// ***** ArrayPOD -// -// General purpose array for movable objects that DOES NOT require -// construction/destruction. Constructors and destructors are not called! -// Global heap is in use. -template -class ArrayPOD : public ArrayBase, SizePolicy> > -{ -public: - typedef T ValueType; - typedef ContainerAllocator_POD AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayPOD SelfType; - typedef ArrayBase, SizePolicy> > BaseType; - - ArrayPOD() : BaseType() {} - ArrayPOD(size_t size) : BaseType(size) {} - ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } - ArrayPOD(const SelfType& a) : BaseType(a) {} - const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } -}; - - -// ***** ArrayCPP -// -// General purpose, fully C++ compliant array. Can be used with non-movable data. -// Global heap is in use. -template -class ArrayCPP : public ArrayBase, SizePolicy> > -{ -public: - typedef T ValueType; - typedef ContainerAllocator_CPP AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayCPP SelfType; - typedef ArrayBase, SizePolicy> > BaseType; - - ArrayCPP() : BaseType() {} - ArrayCPP(size_t size) : BaseType(size) {} - ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } - ArrayCPP(const SelfType& a) : BaseType(a) {} - const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } -}; - - -// ***** ArrayCC -// -// A modification of the array that uses the given default value to -// construct the elements. The constructors and destructors are -// properly called, the objects must be movable. - -template -class ArrayCC : public ArrayBase, SizePolicy> > -{ -public: - typedef T ValueType; - typedef ContainerAllocator AllocatorType; - typedef SizePolicy SizePolicyType; - typedef ArrayCC SelfType; - typedef ArrayBase, SizePolicy> > BaseType; - - ArrayCC(const ValueType& defval) : BaseType(defval) {} - ArrayCC(const ValueType& defval, size_t size) : BaseType(defval, size) {} - ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); } - ArrayCC(const SelfType& a) : BaseType(a) {} - const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } -}; - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Atomic.cpp b/LibOVR/Src/Kernel/OVR_Atomic.cpp deleted file mode 100644 index f7cf9a6..0000000 --- a/LibOVR/Src/Kernel/OVR_Atomic.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Atomic.cpp -Content : Contains atomic operations and inline fastest locking - functionality. Will contain #ifdefs for OS efficiency. - Have non-thread-safe implementation if not available. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Atomic.h" -#include "OVR_Allocator.h" - -#ifdef OVR_ENABLE_THREADS - -// Include Windows 8-Metro compatible Synchronization API -#if defined(OVR_OS_MS) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) -#include -#endif - - -namespace OVR { - -// ***** Windows Lock implementation - -#if defined(OVR_OS_MS) - -// ***** Standard Win32 Lock implementation - -// Constructors -Lock::Lock(unsigned spinCount) -{ - #if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) - // On Windows 8 we use InitializeCriticalSectionEx due to Metro-Compatibility - InitializeCriticalSectionEx(&cs, (DWORD)spinCount, - OVR_DEBUG_SELECT(NULL, CRITICAL_SECTION_NO_DEBUG_INFO)); - #else - ::InitializeCriticalSectionAndSpinCount(&cs, (DWORD)spinCount); // This is available with WindowsXP+. - #endif -} - - -Lock::~Lock() -{ - DeleteCriticalSection(&cs); -} - - -#endif - - -//------------------------------------------------------------------------------------- -// ***** SharedLock - -// This is a general purpose globally shared Lock implementation that should probably be -// moved to Kernel. -// May in theory busy spin-wait if we hit contention on first lock creation, -// but this shouldn't matter in practice since Lock* should be cached. - - -enum { LockInitMarker = 0xFFFFFFFF }; - -Lock* SharedLock::GetLockAddRef() -{ - int oldUseCount; - - do { - oldUseCount = UseCount; - if (oldUseCount == (int)LockInitMarker) - continue; - - if (oldUseCount == 0) - { - // Initialize marker - if (AtomicOps::CompareAndSet_Sync(&UseCount, 0, LockInitMarker)) - { - Construct(Buffer); - do { } - while (!AtomicOps::CompareAndSet_Sync(&UseCount, LockInitMarker, 1)); - return toLock(); - } - continue; - } - - } while (!AtomicOps::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount + 1)); - - return toLock(); -} - -void SharedLock::ReleaseLock(Lock* plock) -{ - OVR_UNUSED(plock); - OVR_ASSERT(plock == toLock()); - - int oldUseCount; - - do { - oldUseCount = UseCount; - OVR_ASSERT(oldUseCount != (int)LockInitMarker); - - if (oldUseCount == 1) - { - // Initialize marker - if (AtomicOps::CompareAndSet_Sync(&UseCount, 1, LockInitMarker)) - { - Destruct(toLock()); - - do { } - while (!AtomicOps::CompareAndSet_Sync(&UseCount, LockInitMarker, 0)); - - return; - } - continue; - } - - } while (!AtomicOps::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount - 1)); -} - -} // OVR - -#endif // OVR_ENABLE_THREADS diff --git a/LibOVR/Src/Kernel/OVR_Atomic.h b/LibOVR/Src/Kernel/OVR_Atomic.h deleted file mode 100644 index 478077b..0000000 --- a/LibOVR/Src/Kernel/OVR_Atomic.h +++ /dev/null @@ -1,915 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Atomic.h -Content : Contains atomic operations and inline fastest locking - functionality. Will contain #ifdefs for OS efficiency. - Have non-thread-safe implementaion if not available. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Atomic_h -#define OVR_Atomic_h - -#include "OVR_Types.h" - -// Include System thread functionality. -#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#else -#include -#endif - -#ifdef OVR_CC_MSVC -#include -#pragma intrinsic(_ReadBarrier, _WriteBarrier, _ReadWriteBarrier) -#endif - -namespace OVR { - - -// ****** Declared classes - -// If there is NO thread support we implement AtomicOps and -// Lock objects as no-ops. The other classes are not defined. -template class AtomicOps; -template class AtomicInt; -template class AtomicPtr; - -class Lock; - - -//----------------------------------------------------------------------------------- -// ***** AtomicOps - -// Atomic operations are provided by the AtomicOps templates class, -// implemented through system-specific AtomicOpsRaw specializations. -// It provides several fundamental operations such as Exchange, ExchangeAdd -// CompareAndSet, and Store_Release. Each function includes several memory -// synchronization versions, important for multiprocessing CPUs with weak -// memory consistency. The following memory fencing strategies are supported: -// -// - NoSync. No memory synchronization is done for atomic op. -// - Release. All other memory writes are completed before atomic op -// writes its results. -// - Acquire. Further memory reads are forced to wait until atomic op -// executes, guaranteeing that the right values will be seen. -// - Sync. A combination of Release and Acquire. - - -// *** AtomicOpsRaw - -// AtomicOpsRaw is a specialized template that provides atomic operations -// used by AtomicOps. This class has two fundamental qualities: (1) it -// defines a type T of correct size, and (2) provides operations that work -// atomically, such as Exchange_Sync and CompareAndSet_Release. - -// AtomicOpsRawBase class contains shared constants/classes for AtomicOpsRaw. -// The primary thing is does is define sync class objects, whose destructor and -// constructor provide places to insert appropriate synchronization calls, on -// systems where such calls are necessary. So far, the breakdown is as follows: -// -// - X86 systems don't need custom syncs, since their exchange/atomic -// instructions are implicitly synchronized. -// - PowerPC requires lwsync/isync instructions that can use this mechanism. -// - If some other systems require a mechanism where syncing type is associated -// with a particular instruction, the default implementation (which implements -// all Sync, Acquire, and Release modes in terms of NoSync and fence) may not -// work. Ii that case it will need to be #ifdef-ed conditionally. - -struct AtomicOpsRawBase -{ -#if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - // Need to have empty constructor to avoid class 'unused' variable warning. - struct FullSync { inline FullSync() { } }; - struct AcquireSync { inline AcquireSync() { } }; - struct ReleaseSync { inline ReleaseSync() { } }; - -#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC) - struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("isync\n"); } }; - struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("isync\n"); } }; - struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } }; - -#elif defined(OVR_CPU_MIPS) - struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("sync\n"); } }; - struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } }; - struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } }; - -#elif defined(OVR_CPU_ARM) // Includes Android and iOS. - struct FullSync { inline FullSync() { asm volatile("dmb\n"); } ~FullSync() { asm volatile("dmb\n"); } }; - struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("dmb\n"); } }; - struct ReleaseSync { inline ReleaseSync() { asm volatile("dmb\n"); } }; - -#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4) - // __sync functions are already full sync - struct FullSync { inline FullSync() { } }; - struct AcquireSync { inline AcquireSync() { } }; - struct ReleaseSync { inline ReleaseSync() { } }; -#endif -}; - - -// 4-Byte raw data atomic op implementation class. -struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase -{ -#if !defined(OVR_ENABLE_THREADS) - - // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl. - typedef uint32_t T; - - // *** Thread - Safe Atomic Versions. - -#elif defined(OVR_OS_MS) - - // Use special defined for VC6, where volatile is not used and - // InterlockedCompareExchange is declared incorrectly. - typedef LONG T; -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC < 1300) - typedef T* InterlockTPtr; - typedef LPVOID ET; - typedef ET* InterlockETPtr; -#else - typedef volatile T* InterlockTPtr; - typedef T ET; - typedef InterlockTPtr InterlockETPtr; -#endif - inline static T Exchange_NoSync(volatile T* p, T val) { return InterlockedExchange((InterlockTPtr)p, val); } - inline static T ExchangeAdd_NoSync(volatile T* p, T val) { return InterlockedExchangeAdd((InterlockTPtr)p, val); } - inline static bool CompareAndSet_NoSync(volatile T* p, T c, T val) { return InterlockedCompareExchange((InterlockETPtr)p, (ET)val, (ET)c) == (ET)c; } - -#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC) - typedef uint32_t T; - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret; - - asm volatile("1:\n\t" - "lwarx %[r],0,%[i]\n\t" - "stwcx. %[j],0,%[i]\n\t" - "bne- 1b\n" - : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [j] "b" (j) : "cc", "memory"); - - return ret; - } - - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t dummy, ret; - - asm volatile("1:\n\t" - "lwarx %[r],0,%[i]\n\t" - "add %[o],%[r],%[j]\n\t" - "stwcx. %[o],0,%[i]\n\t" - "bne- 1b\n" - : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc", "memory"); - - return ret; - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - uint32_t ret; - - asm volatile("1:\n\t" - "lwarx %[r],0,%[i]\n\t" - "cmpw 0,%[r],%[cmp]\n\t" - "mfcr %[r]\n\t" - "bne- 2f\n\t" - "stwcx. %[val],0,%[i]\n\t" - "bne- 1b\n\t" - "2:\n" - : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc", "memory"); - - return (ret & 0x20000000) ? 1 : 0; - } - -#elif defined(OVR_CPU_MIPS) - typedef uint32_t T; - - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret; - - asm volatile("1:\n\t" - "ll %[r],0(%[i])\n\t" - "sc %[j],0(%[i])\n\t" - "beq %[j],$0,1b\n\t" - "nop \n" - : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory"); - - return ret; - } - - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret; - - asm volatile("1:\n\t" - "ll %[r],0(%[i])\n\t" - "addu %[j],%[r],%[j]\n\t" - "sc %[j],0(%[i])\n\t" - "beq %[j],$0,1b\n\t" - "nop \n" - : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory"); - - return ret; - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - uint32_t ret, dummy; - - asm volatile("1:\n\t" - "move %[r],$0\n\t" - "ll %[o],0(%[i])\n\t" - "bne %[o],%[c],2f\n\t" - "move %[r],%[v]\n\t" - "sc %[r],0(%[i])\n\t" - "beq %[r],$0,1b\n\t" - "nop \n\t" - "2:\n" - : "+m" (*i),[r] "=&d" (ret), [o] "=&d" (dummy) : [i] "d" (i), [c] "d" (c), [v] "d" (value) - : "cc", "memory"); - - return ret; - } - -#elif defined(OVR_CPU_ARM) && defined(OVR_CC_ARM) - typedef uint32_t T; - - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - for(;;) - { - T r = __ldrex(i); - if (__strex(j, i) == 0) - return r; - } - } - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - for(;;) - { - T r = __ldrex(i); - if (__strex(r + j, i) == 0) - return r; - } - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - for(;;) - { - T r = __ldrex(i); - if (r != c) - return 0; - if (__strex(value, i) == 0) - return 1; - } - } - -#elif defined(OVR_CPU_ARM) - typedef uint32_t T; - - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret, dummy; - - asm volatile("1:\n\t" - "ldrex %[r],[%[i]]\n\t" - "strex %[t],%[j],[%[i]]\n\t" - "cmp %[t],#0\n\t" - "bne 1b\n\t" - : "+m" (*i), [r] "=&r" (ret), [t] "=&r" (dummy) : [i] "r" (i), [j] "r" (j) : "cc", "memory"); - - return ret; - } - - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - uint32_t ret, dummy, test; - - asm volatile("1:\n\t" - "ldrex %[r],[%[i]]\n\t" - "add %[o],%[r],%[j]\n\t" - "strex %[t],%[o],[%[i]]\n\t" - "cmp %[t],#0\n\t" - "bne 1b\n\t" - : "+m" (*i), [r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [j] "r" (j) : "cc", "memory"); - - return ret; - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - uint32_t ret = 1, dummy, test; - - asm volatile("1:\n\t" - "ldrex %[o],[%[i]]\n\t" - "cmp %[o],%[c]\n\t" - "bne 2f\n\t" - "strex %[r],%[v],[%[i]]\n\t" - "cmp %[r],#0\n\t" - "bne 1b\n\t" - "2:\n" - : "+m" (*i),[r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [c] "r" (c), [v] "r" (value) - : "cc", "memory"); - - return !ret; - } - -#elif defined(OVR_CPU_X86) - typedef uint32_t T; - - static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) - { - asm volatile("xchgl %1,%[i]\n" - : "+m" (*i), "=q" (j) : [i] "m" (*i), "1" (j) : "cc", "memory"); - - return j; - } - - static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) - { - asm volatile("lock; xaddl %1,%[i]\n" - : "+m" (*i), "+q" (j) : [i] "m" (*i) : "cc", "memory"); - - return j; - } - - static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) - { - uint32_t ret; - - asm volatile("lock; cmpxchgl %[v],%[i]\n" - : "+m" (*i), "=a" (ret) : [i] "m" (*i), "1" (c), [v] "q" (value) : "cc", "memory"); - - return (ret == c); - } - -#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1) - - typedef uint32_t T; - - static inline T Exchange_NoSync(volatile T *i, T j) - { - T v; - do { - v = *i; - } while (!__sync_bool_compare_and_swap(i, v, j)); - return v; - } - - static inline T ExchangeAdd_NoSync(volatile T *i, T j) - { - return __sync_fetch_and_add(i, j); - } - - static inline bool CompareAndSet_NoSync(volatile T *i, T c, T value) - { - return __sync_bool_compare_and_swap(i, c, value); - } - -#endif // OS -}; - - -// 8-Byte raw data data atomic op implementation class. -// Currently implementation is provided only on systems with 64-bit pointers. -struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase -{ -#if !defined(OVR_64BIT_POINTERS) || !defined(OVR_ENABLE_THREADS) - - // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl. - typedef uint64_t T; - - // *** Thread - Safe OS specific versions. -#elif defined(OVR_OS_MS) - - // This is only for 64-bit systems. - typedef LONG64 T; - typedef volatile T* InterlockTPtr; - inline static T Exchange_NoSync(volatile T* p, T val) { return InterlockedExchange64((InterlockTPtr)p, val); } - inline static T ExchangeAdd_NoSync(volatile T* p, T val) { return InterlockedExchangeAdd64((InterlockTPtr)p, val); } - inline static bool CompareAndSet_NoSync(volatile T* p, T c, T val) { return InterlockedCompareExchange64((InterlockTPtr)p, val, c) == c; } - -#elif defined(OVR_CPU_PPC64) - - typedef uint64_t T; - - static inline uint64_t Exchange_NoSync(volatile uint64_t *i, uint64_t j) - { - uint64_t dummy, ret; - - asm volatile("1:\n\t" - "ldarx %[r],0,%[i]\n\t" - "mr %[o],%[j]\n\t" - "stdcx. %[o],0,%[i]\n\t" - "bne- 1b\n" - : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc"); - - return ret; - } - - static inline uint64_t ExchangeAdd_NoSync(volatile uint64_t *i, uint64_t j) - { - uint64_t dummy, ret; - - asm volatile("1:\n\t" - "ldarx %[r],0,%[i]\n\t" - "add %[o],%[r],%[j]\n\t" - "stdcx. %[o],0,%[i]\n\t" - "bne- 1b\n" - : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc"); - - return ret; - } - - static inline bool CompareAndSet_NoSync(volatile uint64_t *i, uint64_t c, uint64_t value) - { - uint64_t ret, dummy; - - asm volatile("1:\n\t" - "ldarx %[r],0,%[i]\n\t" - "cmpw 0,%[r],%[cmp]\n\t" - "mfcr %[r]\n\t" - "bne- 2f\n\t" - "stdcx. %[val],0,%[i]\n\t" - "bne- 1b\n\t" - "2:\n" - : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc"); - - return (ret & 0x20000000) ? 1 : 0; - } - -#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1) - - typedef uint64_t T; - - static inline T Exchange_NoSync(volatile T *i, T j) - { - T v; - do { - v = *i; - } while (!__sync_bool_compare_and_swap(i, v, j)); - return v; - } - - static inline T ExchangeAdd_NoSync(volatile T *i, T j) - { - return __sync_fetch_and_add(i, j); - } - - static inline bool CompareAndSet_NoSync(volatile T *i, T c, T value) - { - return __sync_bool_compare_and_swap(i, c, value); - } - -#endif // OS -}; - - -// Default implementation for AtomicOpsRaw; provides implementation of mem-fenced -// atomic operations where fencing is done with a sync object wrapped around a NoSync -// operation implemented in the base class. If such implementation is not possible -// on a given platform, #ifdefs can be used to disable it and then op functions can be -// implemented individually in the appropriate AtomicOpsRaw class. - -template -struct AtomicOpsRaw_DefImpl : public O -{ - typedef typename O::T O_T; - typedef typename O::FullSync O_FullSync; - typedef typename O::AcquireSync O_AcquireSync; - typedef typename O::ReleaseSync O_ReleaseSync; - - // If there is no thread support, provide the default implementation. In this case, - // the base class (0) must still provide the T declaration. -#ifndef OVR_ENABLE_THREADS - - // Atomic exchange of val with argument. Returns old val. - inline static O_T Exchange_NoSync(volatile O_T* p, O_T val) { O_T old = *p; *p = val; return old; } - // Adds a new val to argument; returns its old val. - inline static O_T ExchangeAdd_NoSync(volatile O_T* p, O_T val) { O_T old = *p; *p += val; return old; } - // Compares the argument data with 'c' val. - // If succeeded, stores val int '*p' and returns true; otherwise returns false. - inline static bool CompareAndSet_NoSync(volatile O_T* p, O_T c, O_T val) { if (*p==c) { *p = val; return 1; } return 0; } - -#endif - - // If NoSync wrapped implementation may not be possible, it this block should be - // replaced with per-function implementation in O. - // "AtomicOpsRaw_DefImpl::" prefix in calls below. - inline static O_T Exchange_Sync(volatile O_T* p, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::Exchange_NoSync(p, val); } - inline static O_T Exchange_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::Exchange_NoSync(p, val); } - inline static O_T Exchange_Acquire(volatile O_T* p, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::Exchange_NoSync(p, val); } - inline static O_T ExchangeAdd_Sync(volatile O_T* p, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::ExchangeAdd_NoSync(p, val); } - inline static O_T ExchangeAdd_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::ExchangeAdd_NoSync(p, val); } - inline static O_T ExchangeAdd_Acquire(volatile O_T* p, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::ExchangeAdd_NoSync(p, val); } - inline static bool CompareAndSet_Sync(volatile O_T* p, O_T c, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::CompareAndSet_NoSync(p,c,val); } - inline static bool CompareAndSet_Release(volatile O_T* p, O_T c, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::CompareAndSet_NoSync(p,c,val); } - inline static bool CompareAndSet_Acquire(volatile O_T* p, O_T c, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::CompareAndSet_NoSync(p,c,val); } - - // Loads and stores with memory fence. These have only the relevant versions. -#ifdef OVR_CPU_X86 - // On X86, Store_Release is implemented as exchange. Note that we can also - // consider 'sfence' in the future, although it is not as compatible with older CPUs. - inline static void Store_Release(volatile O_T* p, O_T val) { Exchange_Release(p, val); } -#else - inline static void Store_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); *p = val; } -#endif - inline static O_T Load_Acquire(const volatile O_T* p) - { - O_AcquireSync sync; - OVR_UNUSED(sync); - -#if defined(OVR_CC_MSVC) - _ReadBarrier(); // Compiler fence and load barrier -#elif defined(OVR_CC_INTEL) - __memory_barrier(); // Compiler fence -#else - // GCC-compatible: - asm volatile ("" : : : "memory"); // Compiler fence -#endif - - return *p; - } -}; - - -template -struct AtomicOpsRaw : public AtomicOpsRawBase { }; - -template<> -struct AtomicOpsRaw<4> : public AtomicOpsRaw_DefImpl -{ - // Ensure that assigned type size is correct. - AtomicOpsRaw() - { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl::T) == 4); } -}; -template<> -struct AtomicOpsRaw<8> : public AtomicOpsRaw_DefImpl -{ - AtomicOpsRaw() - { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl::T) == 8); } -}; - - -// *** AtomicOps - implementation of atomic Ops for specified class - -// Implements atomic ops on a class, provided that the object is either -// 4 or 8 bytes in size (depending on the AtomicOpsRaw specializations -// available). Relies on AtomicOpsRaw for much of implementation. - -template -class AtomicOps -{ - typedef AtomicOpsRaw Ops; - typedef typename Ops::T T; - typedef volatile typename Ops::T* PT; - // We cast through unions to (1) avoid pointer size compiler warnings - // and (2) ensure that there are no problems with strict pointer aliasing. - union C2T_union { C c; T t; }; - -public: - // General purpose implementation for standard syncs. - inline static C Exchange_Sync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Sync((PT)p, u.t); return u.c; } - inline static C Exchange_Release(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Release((PT)p, u.t); return u.c; } - inline static C Exchange_Acquire(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Acquire((PT)p, u.t); return u.c; } - inline static C Exchange_NoSync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_NoSync((PT)p, u.t); return u.c; } - inline static C ExchangeAdd_Sync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Sync((PT)p, u.t); return u.c; } - inline static C ExchangeAdd_Release(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Release((PT)p, u.t); return u.c; } - inline static C ExchangeAdd_Acquire(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Acquire((PT)p, u.t); return u.c; } - inline static C ExchangeAdd_NoSync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_NoSync((PT)p, u.t); return u.c; } - inline static bool CompareAndSet_Sync(volatile C* p, C c, C val) { C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Sync((PT)p, cu.t, u.t); } - inline static bool CompareAndSet_Release(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Release((PT)p, cu.t, u.t); } - inline static bool CompareAndSet_Acquire(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Acquire((PT)p, cu.t, u.t); } - inline static bool CompareAndSet_NoSync(volatile C* p, C c, C val) { C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_NoSync((PT)p, cu.t, u.t); } - - // Loads and stores with memory fence. These have only the relevant versions. - inline static void Store_Release(volatile C* p, C val) { C2T_union u; u.c = val; Ops::Store_Release((PT)p, u.t); } - inline static C Load_Acquire(const volatile C* p) { C2T_union u; u.t = Ops::Load_Acquire((PT)p); return u.c; } - - // Deprecated typo error: - inline static bool CompareAndSet_Relse(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Acquire((PT)p, cu.t, u.t); } -}; - - - -// Atomic value base class - implements operations shared for integers and pointers. -template -class AtomicValueBase -{ -protected: - typedef AtomicOps Ops; -public: - - volatile T Value; - - inline AtomicValueBase() { } - explicit inline AtomicValueBase(T val) { Ops::Store_Release(&Value, val); } - - // Most libraries (TBB and Joshua Scholar's) library do not do Load_Acquire - // here, since most algorithms do not require atomic loads. Needs some research. - inline operator T() const { return Value; } - - // *** Standard Atomic inlines - inline T Exchange_Sync(T val) { return Ops::Exchange_Sync(&Value, val); } - inline T Exchange_Release(T val) { return Ops::Exchange_Release(&Value, val); } - inline T Exchange_Acquire(T val) { return Ops::Exchange_Acquire(&Value, val); } - inline T Exchange_NoSync(T val) { return Ops::Exchange_NoSync(&Value, val); } - inline bool CompareAndSet_Sync(T c, T val) { return Ops::CompareAndSet_Sync(&Value, c, val); } - inline bool CompareAndSet_Release(T c, T val) { return Ops::CompareAndSet_Release(&Value, c, val); } - inline bool CompareAndSet_Acquire(T c, T val) { return Ops::CompareAndSet_Acquire(&Value, c, val); } - inline bool CompareAndSet_NoSync(T c, T val) { return Ops::CompareAndSet_NoSync(&Value, c, val); } - // Load & Store. - inline void Store_Release(T val) { Ops::Store_Release(&Value, val); } - inline T Load_Acquire() const { return Ops::Load_Acquire(&Value); } -}; - - -// ***** AtomicPtr - Atomic pointer template - -// This pointer class supports atomic assignments with release, -// increment / decrement operations, and conditional compare + set. - -template -class AtomicPtr : public AtomicValueBase -{ - typedef typename AtomicValueBase::Ops Ops; - -public: - // Initialize pointer value to 0 by default; use Store_Release only with explicit constructor. - inline AtomicPtr() : AtomicValueBase() { this->Value = 0; } - explicit inline AtomicPtr(T* val) : AtomicValueBase(val) { } - - // Pointer access. - inline T* operator -> () const { return this->Load_Acquire(); } - - // It looks like it is convenient to have Load_Acquire characteristics - // for this, since that is convenient for algorithms such as linked - // list traversals that can be added to bu another thread. - inline operator T* () const { return this->Load_Acquire(); } - - - // *** Standard Atomic inlines (applicable to pointers) - - // ExhangeAdd considers pointer size for pointers. - template - inline T* ExchangeAdd_Sync(I incr) { return Ops::ExchangeAdd_Sync(&this->Value, ((T*)0) + incr); } - template - inline T* ExchangeAdd_Release(I incr) { return Ops::ExchangeAdd_Release(&this->Value, ((T*)0) + incr); } - template - inline T* ExchangeAdd_Acquire(I incr) { return Ops::ExchangeAdd_Acquire(&this->Value, ((T*)0) + incr); } - template - inline T* ExchangeAdd_NoSync(I incr) { return Ops::ExchangeAdd_NoSync(&this->Value, ((T*)0) + incr); } - - // *** Atomic Operators - - inline T* operator = (T* val) { this->Store_Release(val); return val; } - - template - inline T* operator += (I val) { return ExchangeAdd_Sync(val) + val; } - template - inline T* operator -= (I val) { return operator += (-val); } - - inline T* operator ++ () { return ExchangeAdd_Sync(1) + 1; } - inline T* operator -- () { return ExchangeAdd_Sync(-1) - 1; } - inline T* operator ++ (int) { return ExchangeAdd_Sync(1); } - inline T* operator -- (int) { return ExchangeAdd_Sync(-1); } -}; - - -// ***** AtomicInt - Atomic integer template - -// Implements an atomic integer type; the exact type to use is provided -// as an argument. Supports atomic Acquire / Release semantics, atomic -// arithmetic operations, and atomic conditional compare + set. - -template -class AtomicInt : public AtomicValueBase -{ - typedef typename AtomicValueBase::Ops Ops; - -public: - inline AtomicInt() : AtomicValueBase() { } - explicit inline AtomicInt(T val) : AtomicValueBase(val) { } - - - // *** Standard Atomic inlines (applicable to int) - inline T ExchangeAdd_Sync(T val) { return Ops::ExchangeAdd_Sync(&this->Value, val); } - inline T ExchangeAdd_Release(T val) { return Ops::ExchangeAdd_Release(&this->Value, val); } - inline T ExchangeAdd_Acquire(T val) { return Ops::ExchangeAdd_Acquire(&this->Value, val); } - inline T ExchangeAdd_NoSync(T val) { return Ops::ExchangeAdd_NoSync(&this->Value, val); } - // These increments could be more efficient because they don't return a value. - inline void Increment_Sync() { ExchangeAdd_Sync((T)1); } - inline void Increment_Release() { ExchangeAdd_Release((T)1); } - inline void Increment_Acquire() { ExchangeAdd_Acquire((T)1); } - inline void Increment_NoSync() { ExchangeAdd_NoSync((T)1); } - - // *** Atomic Operators - - inline T operator = (T val) { this->Store_Release(val); return val; } - inline T operator += (T val) { return ExchangeAdd_Sync(val) + val; } - inline T operator -= (T val) { return ExchangeAdd_Sync(0 - val) - val; } - - inline T operator ++ () { return ExchangeAdd_Sync((T)1) + 1; } - inline T operator -- () { return ExchangeAdd_Sync(((T)0)-1) - 1; } - inline T operator ++ (int) { return ExchangeAdd_Sync((T)1); } - inline T operator -- (int) { return ExchangeAdd_Sync(((T)0)-1); } - - // More complex atomic operations. Leave it to compiler whether to optimize them or not. - T operator &= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp & arg; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator |= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp | arg; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator ^= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp ^ arg; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator *= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp * arg; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator /= (T arg) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp / arg; - } while(!CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator >>= (unsigned bits) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp >> bits; - } while(!CompareAndSet_Sync(comp, newVal)); - return newVal; - } - - T operator <<= (unsigned bits) - { - T comp, newVal; - do { - comp = this->Value; - newVal = comp << bits; - } while(!this->CompareAndSet_Sync(comp, newVal)); - return newVal; - } -}; - - -//----------------------------------------------------------------------------------- -// ***** Lock - -// Lock is a simplest and most efficient mutual-exclusion lock class. -// Unlike Mutex, it cannot be waited on. - -class Lock -{ - // NOTE: Locks are not allocatable and they themselves should not allocate - // memory by standard means. This is the case because StandardAllocator - // relies on this class. - // Make 'delete' private. Don't do this for 'new' since it can be redefined. - void operator delete(void*) {} - - - // *** Lock implementation for various platforms. - -#if !defined(OVR_ENABLE_THREADS) - -public: - // With no thread support, lock does nothing. - inline Lock() { } - inline Lock(unsigned) { } - inline ~Lock() { } - inline void DoLock() { } - inline void Unlock() { } - - // Windows. -#elif defined(OVR_OS_MS) - - CRITICAL_SECTION cs; -public: - Lock(unsigned spinCount = 10000); // Mutexes with non-zero spin counts usually result in better performance. - ~Lock(); - // Locking functions. - inline void DoLock() { ::EnterCriticalSection(&cs); } - inline void Unlock() { ::LeaveCriticalSection(&cs); } - -#else - pthread_mutex_t mutex; - -public: - static pthread_mutexattr_t RecursiveAttr; - static bool RecursiveAttrInit; - - Lock (unsigned spinCount = 0) // To do: Support spin count, probably via a custom lock implementation. - { - OVR_UNUSED(spinCount); - if (!RecursiveAttrInit) - { - pthread_mutexattr_init(&RecursiveAttr); - pthread_mutexattr_settype(&RecursiveAttr, PTHREAD_MUTEX_RECURSIVE); - RecursiveAttrInit = 1; - } - pthread_mutex_init(&mutex,&RecursiveAttr); - } - ~Lock () { pthread_mutex_destroy(&mutex); } - inline void DoLock() { pthread_mutex_lock(&mutex); } - inline void Unlock() { pthread_mutex_unlock(&mutex); } - -#endif // OVR_ENABLE_THREDS - - -public: - // Locker class, used for automatic locking - class Locker - { - public: - Lock *pLock; - inline Locker(Lock *plock) - { pLock = plock; pLock->DoLock(); } - inline ~Locker() - { pLock->Unlock(); } - }; -}; - - -//------------------------------------------------------------------------------------- -// Globally shared Lock implementation used for MessageHandlers, etc. - -class SharedLock -{ -public: - SharedLock() : UseCount(0) {} - - Lock* GetLockAddRef(); - void ReleaseLock(Lock* plock); - -private: - Lock* toLock() { return (Lock*)Buffer; } - - // UseCount and max alignment. - volatile int UseCount; - uint64_t Buffer[(sizeof(Lock)+sizeof(uint64_t)-1)/sizeof(uint64_t)]; -}; - - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_CRC32.cpp b/LibOVR/Src/Kernel/OVR_CRC32.cpp deleted file mode 100644 index 82cbe7f..0000000 --- a/LibOVR/Src/Kernel/OVR_CRC32.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/************************************************************************************ - -Filename : OVR_CRC32.cpp -Content : CRC-32 with polynomial used for sensor devices -Created : June 20, 2014 -Author : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_CRC32.h" - -namespace OVR { - - -static const uint32_t CRC_Table[256] = { - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, - 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, - 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, - 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, - 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, - 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, - 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, - 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, - 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, - 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, - 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, - 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, - 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, - 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, - 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, - 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, - 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, - 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, - 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, - 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, - 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, - 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 -}; - - -//// CRC-32 - -uint32_t CRC32_Calculate(const void* data, int bytes, uint32_t accumulator) -{ - const uint8_t* inputBytes = reinterpret_cast( data ); - - for (int j = 0; j < bytes; ++j) - { - int i = ((uint32_t)(accumulator >> 24) ^ *inputBytes++) & 0xFF; - - accumulator = (accumulator << 8) ^ CRC_Table[i]; - } - - return ~accumulator; -} - - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_CRC32.h b/LibOVR/Src/Kernel/OVR_CRC32.h deleted file mode 100644 index e4edd65..0000000 --- a/LibOVR/Src/Kernel/OVR_CRC32.h +++ /dev/null @@ -1,45 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_CRC32.h -Content : CRC-32 with polynomial used for sensor devices -Created : June 20, 2014 -Author : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_CRC32_h -#define OVR_CRC32_h - -#include "OVR_Types.h" - -namespace OVR { - - -//----------------------------------------------------------------------------------- -// ***** CRC-32 - -// Polynomial used and algorithm details are proprietary to our sensor board -uint32_t CRC32_Calculate(const void* data, int bytes, uint32_t prevCRC = 0); - - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Color.h b/LibOVR/Src/Kernel/OVR_Color.h deleted file mode 100644 index 7b5e966..0000000 --- a/LibOVR/Src/Kernel/OVR_Color.h +++ /dev/null @@ -1,73 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Color.h -Content : Contains color struct. -Created : February 7, 2013 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ -#ifndef OVR_Color_h -#define OVR_Color_h - -#include "OVR_Types.h" - -namespace OVR { - - -struct Color -{ - uint8_t R,G,B,A; - - Color() - { - #if defined(OVR_BUILD_DEBUG) - R = G = B = A = 0; - #endif - } - - // Constructs color by channel. Alpha is set to 0xFF (fully visible) - // if not specified. - Color(unsigned char r,unsigned char g,unsigned char b, unsigned char a = 0xFF) - : R(r), G(g), B(b), A(a) { } - - // 0xAARRGGBB - Common HTML color Hex layout - Color(unsigned c) - : R((unsigned char)(c>>16)), G((unsigned char)(c>>8)), - B((unsigned char)c), A((unsigned char)(c>>24)) { } - - bool operator==(const Color& b) const - { - return R == b.R && G == b.G && B == b.B && A == b.A; - } - - void GetRGBA(float *r, float *g, float *b, float* a) const - { - *r = R / 255.0f; - *g = G / 255.0f; - *b = B / 255.0f; - *a = A / 255.0f; - } -}; - - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Compiler.h b/LibOVR/Src/Kernel/OVR_Compiler.h deleted file mode 100644 index 93a4181..0000000 --- a/LibOVR/Src/Kernel/OVR_Compiler.h +++ /dev/null @@ -1,1524 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR.h -Filename : OVR_Compiler.h -Content : Compiler-specific feature identification and utilities -Created : June 19, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - - -#ifndef OVR_Compiler_h -#define OVR_Compiler_h - -#pragma once - - -// References -// https://gcc.gnu.org/projects/cxx0x.html -// https://gcc.gnu.org/projects/cxx1y.html -// http://clang.llvm.org/cxx_status.html -// http://msdn.microsoft.com/en-us/library/hh567368.aspx -// https://docs.google.com/spreadsheet/pub?key=0AoBblDsbooe4dHZuVTRoSTFBejk5eFBfVk1GWlE5UlE&output=html -// http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros - - -//----------------------------------------------------------------------------------- -// ***** Compiler -// -// The following compilers are defined: (OVR_CC_x) -// -// MSVC - Microsoft Visual C/C++ -// INTEL - Intel C++ for Linux / Windows -// GNU - GNU C++ -// ARM - ARM C/C++ - -#if defined(__INTEL_COMPILER) -// Intel 4.0 = 400 -// Intel 5.0 = 500 -// Intel 6.0 = 600 -// Intel 8.0 = 800 -// Intel 9.0 = 900 -# define OVR_CC_INTEL __INTEL_COMPILER - -#elif defined(_MSC_VER) -// MSVC 5.0 = 1100 -// MSVC 6.0 = 1200 -// MSVC 7.0 (VC2002) = 1300 -// MSVC 7.1 (VC2003) = 1310 -// MSVC 8.0 (VC2005) = 1400 -// MSVC 9.0 (VC2008) = 1500 -// MSVC 10.0 (VC2010) = 1600 -// MSVC 11.0 (VC2012) = 1700 -// MSVC 12.0 (VC2013) = 1800 -# define OVR_CC_MSVC _MSC_VER - -#if _MSC_VER == 0x1600 -# if _MSC_FULL_VER < 160040219 -# error "Oculus does not support VS2010 without SP1 installed." -# endif -#endif - -#elif defined(__GNUC__) -# define OVR_CC_GNU - -#elif defined(__clang__) -# define OVR_CC_CLANG - -#elif defined(__CC_ARM) -# define OVR_CC_ARM - -#else -# error "Oculus does not support this Compiler" -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CC_VERSION -// -// M = major version -// m = minor version -// p = patch release -// b = build number -// -// Compiler Format Example -// ---------------------------- -// OVR_CC_GNU Mmm 408 means GCC 4.8 -// OVR_CC_CLANG Mmm 305 means clang 3.5 -// OVR_CC_MSVC MMMM 1700 means VS2012 -// OVR_CC_ARM Mmpbbb 401677 means 4.0, patch 1, build 677 -// OVR_CC_INTEL MMmm 1210 means 12.10 -// OVR_CC_EDG Mmm 407 means EDG 4.7 -// -#if defined(OVR_CC_GNU) - #define OVR_CC_VERSION ((__GNUC__ * 100) + __GNUC_MINOR__) -#elif defined(OVR_CC_CLANG) - #define OVR_CC_VERSION ((__clang_major__ * 100) + __clang_minor__) -#elif defined(OVR_CC_MSVC) - #define OVR_CC_VERSION _MSC_VER // Question: Should we recognize _MSC_FULL_VER? -#elif defined(OVR_CC_ARM) - #define OVR_CC_VERSION __ARMCC_VERSION -#elif defined(OVR_CC_INTEL) - #if defined(__INTEL_COMPILER) - #define OVR_CC_VERSION __INTEL_COMPILER - #elif defined(__ICL) - #define OVR_CC_VERSION __ICL - #elif defined(__ICC) - #define OVR_CC_VERSION __ICC - #elif defined(__ECC) - #define OVR_CC_VERSION __ECC - #endif -#elif defined(OVR_CC_EDG) - #define OVR_CC_VERSION __EDG_VERSION__ // This is a generic fallback for EDG-based compilers which aren't specified above (e.g. as OVR_CC_ARM) -#endif - - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_OPTIMIZATION / OVR_RESTORE_OPTIMIZATION -// -// Allows for the dynamic disabling and restoring of compiler optimizations in code. -// This is useful for helping deal with potential compiler code generation problems. -// With VC++ the usage must be outside of function bodies. This can be used only to -// temporarily disable optimization for a block of code and not to temporarily enable -// optimization for a block of code. -// -// Clang doesn't support this as of June 2014, though function __attribute__((optimize(0)) -// is supposedly supported by clang in addition to GCC. To consider: Make a wrapper for -// this attribute-based functionality. -// -// Example usage: -// OVR_DISABLE_OPTIMIZATION() -// void Test() { ... } -// OVR_RESTORE_OPTIMIZATION() -// -#if !defined(OVR_DISABLE_OPTIMIZATION) - #if defined(OVR_CC_GNU) && (OVR_CC_VERSION > 404) && (defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)) - #define OVR_DISABLE_OPTIMIZATION() \ - _Pragma("GCC push_options") \ - _Pragma("GCC optimize 0") - #elif defined(OVR_CC_MSVC) - #define OVR_DISABLE_OPTIMIZATION() __pragma(optimize("", off)) - #else - #define OVR_DISABLE_OPTIMIZATION() - #endif -#endif - -#if !defined(OVR_RESTORE_OPTIMIZATION) - #if defined(OVR_CC_GNU) && (OVR_CC_VERSION > 404) && (defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)) - #define OVR_RESTORE_OPTIMIZATION() _Pragma("GCC pop_options") - #elif defined(OVR_CC_MSVC) - #define OVR_RESTORE_OPTIMIZATION() __pragma(optimize("", on)) - #else - #define OVR_RESTORE_OPTIMIZATION() - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_GNU_WARNING / OVR_RESTORE_GNU_WARNING -// -// Portable wrapper for disabling GCC compiler warnings, one at a time. See example -// usage for usage by example. -// -// Example usage: -// OVR_DISABLE_GNU_WARNING(-Wmissing-braces) // Only one warning per usage. -// OVR_DISABLE_GNU_WARNING(-Wunused-variable) -// -// OVR_RESTORE_GNU_WARNINGS() -// OVR_RESTORE_GNU_WARNINGS() // Must match each disable with a restore. -// -#if !defined(OVR_DISABLE_GNU_WARNING) - #if defined(OVR_CC_GNU) - #define ODGW1(x) #x - #define ODGW2(x) ODGW1(GCC diagnostic ignored x) - #define ODGW3(x) ODGW2(#x) - #endif - - #if defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 406) - #define OVR_DISABLE_GNU_WARNING(w) \ - _Pragma("GCC diagnostic push") \ - _Pragma(ODGW3(w)) - #elif defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 404) // GCC 4.4 doesn't support diagnostic push, but supports disabling warnings. - #define OVR_DISABLE_GNU_WARNING(w) \ - _Pragma(ODGW3(w)) - #else - #define OVR_DISABLE_GNU_WARNING(w) - #endif -#endif - -#if !defined(OVR_RESTORE_GNU_WARNING) - #if defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 4006) - #define OVR_RESTORE_GNU_WARNINGS() \ - _Pragma("GCC diagnostic pop") - #else - #define OVR_RESTORE_GNU_WARNING() - #endif -#endif - - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_CLANG_WARNING / OVR_RESTORE_CLANG_WARNING -// -// Portable wrapper for disabling GCC compiler warnings, one at a time. See example -// usage for usage by example. -// -// Example usage: -// OVR_DISABLE_CLANG_WARNING(-Wmissing-braces) // Only one warning per usage. -// OVR_DISABLE_CLANG_WARNING(-Wunused-variable) -// -// OVR_RESTORE_CLANG_WARNINGS() -// OVR_RESTORE_CLANG_WARNINGS() // Must match each disable with a restore. -// -// -#if !defined(OVR_DISABLE_CLANG_WARNING) - #if defined(OVR_CC_CLANG) - #define ODCW1(x) #x - #define ODCW2(x) ODCW1(clang diagnostic ignored x) - #define ODCW3(x) ODCW2(#x) - - #define OVR_DISABLE_CLANG_WARNING(w) \ - _Pragma("clang diagnostic push") \ - _Pragma(ODCW3(w)) - #else - #define OVR_DISABLE_CLANG_WARNING(w) - #endif -#endif - -#if !defined(OVR_RESTORE_CLANG_WARNING) - #if defined(OVR_CC_CLANG) - #define OVR_RESTORE_CLANG_WARNING() \ - _Pragma("clang diagnostic pop") - #else - #define OVR_RESTORE_CLANG_WARNING() - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_MSVC_WARNING / OVR_RESTORE_MSVC_WARNING -// -// Portable wrapper for disabling VC++ compiler warnings. See example usage for usage -// by example. -// -// Example usage: -// OVR_DISABLE_MSVC_WARNING(4556 4782 4422) -// -// OVR_RESTORE_MSVC_WARNING() -// -#if !defined(OVR_DISABLE_MSVC_WARNING) - #if defined(OVR_CC_MSVC) - #define OVR_DISABLE_MSVC_WARNING(w) \ - __pragma(warning(push)) \ - __pragma(warning(disable:w)) - #else - #define OVR_DISABLE_MSVC_WARNING(w) - #endif -#endif - -#if !defined(OVR_RESTORE_MSVC_WARNING) - #if defined(OVR_CC_MSVC) - #define OVR_RESTORE_MSVC_WARNING() \ - __pragma(warning(pop)) - #else - #define OVR_RESTORE_MSVC_WARNING() - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_DISABLE_ALL_MSVC_WARNINGS / OVR_RESTORE_ALL_MSVC_WARNINGS -// -// Portable wrapper for disabling all VC++ compiler warnings. -// OVR_RESTORE_ALL_MSVC_WARNINGS restores warnings that were disabled by -// OVR_DISABLE_ALL_MSVC_WARNINGS. Any previously enabled warnings will still be -// enabled after OVR_RESTORE_ALL_MSVC_WARNINGS. -// -// Example usage: -// OVR_DISABLE_ALL_MSVC_WARNINGS() -// -// OVR_RESTORE_ALL_MSVC_WARNINGS() - -#if !defined(OVR_DISABLE_ALL_MSVC_WARNINGS) - #if defined(OVR_CC_MSVC) - #define OVR_DISABLE_ALL_MSVC_WARNINGS() \ - __pragma(warning(push, 0)) - #else - #define OVR_DISABLE_ALL_MSVC_WARNINGS() - #endif -#endif - -#if !defined(OVR_RESTORE_ALL_MSVC_WARNINGS) - #if defined(OVR_CC_MSVC) - #define OVR_RESTORE_ALL_MSVC_WARNINGS() \ - __pragma(warning(pop)) - #else - #define OVR_RESTORE_ALL_MSVC_WARNINGS() - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CC_HAS_FEATURE -// -// This is a portable way to use compile-time feature identification available -// with some compilers in a clean way. Direct usage of __has_feature in preprocessing -// statements of non-supporting compilers results in a preprocessing error. -// -// Example usage: -// #if OVR_CC_HAS_FEATURE(is_pod) -// if(__is_pod(T)) // If the type is plain data then we can safely memcpy it. -// memcpy(&destObject, &srcObject, sizeof(object)); -// #endif -// -#if !defined(OVR_CC_HAS_FEATURE) - #if defined(__clang__) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 - #define OVR_CC_HAS_FEATURE(x) __has_feature(x) - #else - #define OVR_CC_HAS_FEATURE(x) 0 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CC_HAS_BUILTIN -// -// -// This is a portable way to use compile-time builtin identification available -// with some compilers in a clean way. Direct usage of __has_builtin in preprocessing -// statements of non-supporting compilers results in a preprocessing error. -// -// Example usage: -// #if OVR_CC_HAS_BUILTIN(__builtin_trap) -// #define DEBUG_BREAK __builtin_trap -// #endif -// -#if !defined(OVR_CC_HAS_BUILTIN) - #if defined(__clang__) - #define OVR_CC_HAS_BUILTIN(x) __has_builtin(x) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 - #else - #define OVR_CC_HAS_BUILTIN(x) 0 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP11_ENABLED / OVR_CPP_CPP14_ENABLED -// -// Defined as 1 if the compiler has its available C++11 support enabled, else undefined. -// This does not mean that all of C++11 or any particular feature of C++11 is supported -// by the compiler. It means that whatever C++11 support the compiler has is enabled. -// This also includes existing and older compilers that still identify C++11 as C++0x. -// -#if !defined(OVR_CPP11_ENABLED) && defined(__cplusplus) - #if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) - #define OVR_CPP11_ENABLED 1 - #elif defined(_MSC_VER) && (_MSC_VER >= 1500) // VS2010+, the first version with any significant C++11 support. - #define OVR_CPP11_ENABLED 1 - #elif (__cplusplus >= 201103L) // 201103 is the first C++11 version. - #define OVR_CPP11_ENABLED 1 - #else - // Leave undefined - #endif -#endif - -#if !defined(OVR_CPP_CPP14_ENABLED) && defined(__cplusplus) - #if defined(_MSC_VER) && (_MSC_VER >= 1800) // VS2013+, the first version with any significant C++14 support. - #define OVR_CPP_CPP14_ENABLED 1 - #elif (__cplusplus > 201103L) - #define OVR_CPP_CPP14_ENABLED 1 - #else - // Leave undefined - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXCEPTIONS / OVR_CPP_NO_UNWIND -// -// OVR_CPP_NO_EXCEPTIONS is defined as 1 if the compiler doesn't support C++ -// exceptions or is configured to disable support for them. Else not defined. -// If OVR_CPP_NO_EXCEPTIONS is defined then attempts to use try/catch -// related C++ statements result in a compilation error with many -// compilers. -// -// OVR_CPP_NO_UNWIND is defined as 1 if the compiler supports exceptions but -// doesn't support stack unwinding in the presence of an exception. Else not defined. -// For the Microsoft compiler, disabling exceptions means disabling stack unwinding -// and not disabling exceptions themselves. -// -// Example usage: -// void Test() { -// #if !defined(OVR_CPP_NO_EXCEPTIONS) -// try { -// #endif -// void* ptr = new Object; -// #if !defined(OVR_CPP_NO_EXCEPTIONS) -// catch(...) { ... } -// #endif - -#if !defined(OVR_CPP_NO_EXCEPTIONS) - #if defined(OVR_CPP_GNUC) && defined(_NO_EX) - #define OVR_CPP_NO_EXCEPTIONS 1 - #elif (defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) || defined(OVR_CC_INTEL) || defined(OVR_CC_ARM)) && !defined(__EXCEPTIONS) - #define OVR_CPP_NO_EXCEPTIONS 1 - #elif defined(OVR_CC_MSVC) && !defined(_CPPUNWIND) - #define OVR_CPP_NO_UNWIND 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_RTTI -// -// Defined as 1 if C++ run-time type information support is unavailable or disabled -// by the compiler. Else undefined. Allows you to write portable code in the face -// of the possibility that RTTI is disabled. -// -// Example usage: -// #if !OVR_CPP_NO_RTTI -// #include -// int x = std::dynamic_cast(3.4f); -// #endif - -#if defined(__clang__) && !OVR_CC_HAS_FEATURE(cxx_rtti) - #define OVR_CPP_NO_RTTI 1 -#elif defined(__GNUC__) && !defined(__GXX_RTTI) - #define OVR_CPP_NO_RTTI 1 -#elif defined(_MSC_VER) && !defined(_CPPRTTI) - #define OVR_CPP_NO_RTTI 1 -#elif defined(__CC_ARM) && defined(__TARGET_CPU_MPCORE) && !defined(__RTTI) - #define OVR_CPP_NO_RTTI 1 -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_STATIC_ASSERT -// -// Defined as 1 if C++ run-time type information support is available and enabled -// by the compiler. Else undefined. -// -// Example usage: -// #if OVR_CPP_NO_STATIC_ASSERT -// #define MY_ASSERT(x) { int zero = 0; switch(zero) {case 0: case (x):;} } -// #else -// #define MY_ASSERT(x) static_assert((x), #x) -// #endif - -#if !defined(OVR_CPP_NO_STATIC_ASSERT) - #if !(defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && (__cplusplus >= 201103L)))) && \ - !(defined(__clang__) && defined(__cplusplus) && OVR_CC_HAS_FEATURE(cxx_static_assert)) && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(__cplusplus)) && /* VS2010+ */ \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) && defined(OVR_CPP11_ENABLED)) /* EDG 4.1+ */ - #define OVR_CPP_NO_STATIC_ASSERT 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NULLPTR -// -// Defined as 1 if the compiler doesn't support C++11 nullptr built in type. -// Otherwise undefined. Does not identify if the standard library defines -// std::nullptr_t, as some standard libraries are further behind in standardization -// than the compilers using them (e.g. Apple clang with the supplied libstdc++). -// -// OVR_Nullptr.h provides a portable nullptr and std::nullptr_t for when the -// compiler or standard library do not. - -#if !defined(OVR_CPP_NO_NULLPTR) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_nullptr)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ - #define OVR_CPP_NO_NULLPTR 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_RVALUE_REFERENCES -// -// Defined as 1 if the compiler doesn't support C++11 rvalue references and move semantics. -// Otherwise undefined. - -#if !defined(OVR_CPP_NO_RVALUE_REFERENCES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_rvalue_references)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ - #define OVR_CPP_NO_RVALUE_REFERENCES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_AUTO -// -// Defined as 1 if the compiler doesn't support C++11 auto keyword. Otherwise undefined. - -#if !defined(OVR_CPP_NO_AUTO) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_auto_type)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 309))) /* EDG 3.9+ */ - #define OVR_CPP_NO_AUTO 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_RANGE_BASED_FOR_LOOP -// -// Defined as 1 if the compiler doesn't support C++11 range-based for loops. -// Otherwise undefined. - -#if !defined(OVR_CPP_NO_RANGE_BASED_FOR_LOOP) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_range_for)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_RANGE_BASED_FOR_LOOP 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_CONSTEXPR / OVR_CPP_NO_RELAXED_CONSTEXPR -// -// OVR_CPP_NO_CONSTEXPR is defined as 1 if the compiler doesn't support C++11 constexpr. -// OVR_CPP_NO_RELAXED_CONSTEXPR is defined as 1 if the compiler doesn't support C++14 constexpr. -// Otherwise undefined. -// See the OVR_CONSTEXPR / OVR_CONSTEXPR_OR_CONST macros for portable wrappers of this functionality. - -#if !defined(OVR_CPP_NO_CONSTEXPR) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_constexpr)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - // Not supported by VC++ through at least VS2013. - #define OVR_CPP_NO_CONSTEXPR 1 - #endif -#endif - -#if !defined(OVR_CPP_NO_RELAXED_CONSTEXPR) - #if !defined(OVR_CPP14_ENABLED) || \ - !(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_relaxed_constexpr)) /* clang */ - // Supported only by clang as of this writing. - #define OVR_CPP_NO_RELAXED_CONSTEXPR 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_LAMBDA_EXPRESSIONS -// -// Defined as 1 if the compiler doesn't support C++11 lambda expressions. Otherwise undefined. -// Some compilers have slightly crippled versions of this. - -#if !defined(OVR_CPP_NO_LAMBDA_EXPRESSIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_lambdas)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - // Conversion of lambdas to function pointers is not supported until EDG 4.5. - #define OVR_CPP_NO_LAMBDA_EXPRESSIONS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_ALIGNOF -// -// Defined as 1 if the compiler supports C++11 alignof. Otherwise undefined. -// Some compilers support __alignof__ instead of alignof, so for portability you -// should use OVR_ALIGNOF instead of directly using C++11 alignof. - -#if !defined(OVR_CPP_NO_ALIGNOF) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 300)) /* Apple clang 3.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 401)) /* GCC 4.1+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400))) /* EDG 4.0+ */ - #define OVR_CPP_NO_ALIGNOF 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_ALIGNAS -// -// Defined as 1 if the compiler supports C++11 alignas. Otherwise undefined. -// See the OVR_ALIGNAS for a portable wrapper for alignas functionality. - -#if !defined(OVR_CPP_NO_ALIGNAS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_ALIGNAS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_OVERRIDE -// -// Defined as 1 if the compiler doesn't support C++11 override. Otherwise undefined. -// See the OVR_OVERRIDE and OVR_FINALOVERRIDE macros for a portable wrapper. - -#if !defined(OOVR_CPP_NO_OVERRIDE) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_OVERRIDE 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_FINAL -// -// Defined as 1 if the compiler doesn't support C++11 final attribute. Otherwise undefined. -// See the OVR_FINAL and OVR_FINALOVERRIDE macros for a portable wrapper. - -#if !defined(OOVR_CPP_NO_FINAL) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_FINAL 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXTERN_TEMPLATE -// -// Defined as 1 if the compiler doesn't support C++11 extern template. -// Otherwise undefined. See OVR_EXTERN_TEMPLATE for wrapper macro. - -#if !defined(OVR_CPP_NO_EXTERN_TEMPLATE) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - #define OVR_CPP_NO_EXTERN_TEMPLATE 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_VARIADIC_TEMPLATES -// -// Defined as 1 if the compiler doesn't support C++11 variadic templates. Otherwise undefined. - -#if !defined(OVR_CPP_NO_VARIADIC_TEMPLATES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_variadic_templates)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ - #define OVR_CPP_NO_VARIADIC_TEMPLATES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NOEXCEPT -// -// Defined as 1 if the compiler supports C++11 noexcept. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/noexcept -// See OVR_NOEXCEPT / OVR_NOEXCEPT_IF / OVR_NOEXCEPT_EXPR for a portable wrapper -// for noexcept functionality. - -#if !defined(OVR_CPP_NO_NOEXCEPT) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_noexcept)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_NOEXCEPT 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DECLTYPE -// -// Defined as 1 if the compiler doesn't support C++11 decltype. Otherwise undefined. -// Some compilers (e.g. VS2012) support most uses of decltype but don't support -// decltype with incomplete types (which is an uncommon usage seen usually in -// template metaprogramming). We don't include this support as a requirement for -// our definition of decltype support here. - -#if !defined(OVR_CPP_NO_DECLTYPE) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_decltype)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ - // VC++ fails to support decltype for incomplete types until VS2013. - // EDG fails to support decltype for incomplete types until v4.8. - #define OVR_CPP_NO_DECLTYPE 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DEFAULTED_FUNCTIONS -// -// Defined as 1 if the compiler doesn't support C++11 defaulted functions. Otherwise undefined. -// Some compilers have slightly crippled versions of this. - -#if !defined(OVR_CPP_NO_DEFAULTED_FUNCTIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_defaulted_functions))/* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - // Up through at least VS2013 it's unsupported for defaulted move constructors and move assignment operators. - // Until EDG 4.8 it's unsupported for defaulted move constructors and move assigment operators. - #define OVR_CPP_NO_DEFAULTED_FUNCTIONS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DELETED_FUNCTIONS -// -// Defined as 1 if the compiler doesn't support C++11 deleted functions. Otherwise undefined. -// Some compilers have slightly crippled versions of this. - -#if !defined(OVR_CPP_NO_DELETED_FUNCTIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_defaulted_functions)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - // Up through at least VS2013 it's unsupported for defaulted move constructors and move assignment operators. - // Until EDG 4.8 it's unsupported for defaulted move constructors and move assigment operators. - #define OVR_CPP_NO_DELETED_FUNCTIONS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_STANDARD_LAYOUT_TYPES -// -// Defined as 1 if the compiler doesn't support C++11 standard layout (relaxed POD). Otherwise undefined. -// http://en.cppreference.com/w/cpp/types/is_standard_layout - -#if !defined(OVR_CPP_NO_STANDARD_LAYOUT_TYPES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - #define OVR_CPP_NO_STANDARD_LAYOUT_TYPES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_FORWARD_DECLARED_ENUMS -// -// Defined as 1 if the compiler doesn't support C++11 forward declared enums. Otherwise undefined. - -#if !defined(OVR_CPP_NO_FORWARD_DECLARED_ENUMS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_FORWARD_DECLARED_ENUMS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_STRONGLY_TYPED_ENUMS -// -// Defined as 1 if the compiler doesn't support C++11 strongly typed enums. Otherwise undefined. - -#if !defined(OVR_CPP_NO_STRONGLY_TYPED_ENUMS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_strong_enums)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400))) /* EDG 4.0+ */ - #define OVR_CPP_NO_STRONGLY_TYPED_ENUMS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_TRAILING_RETURN_TYPES -// -// Defined as 1 if the compiler doesn't support C++11 trailing return types. Otherwise undefined. -// http://en.wikipedia.org/wiki/C%2B%2B11#Alternative_function_syntax - -#if !defined(OVR_CPP_NO_TRAILING_RETURN_TYPES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_trailing_return)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - #define OVR_CPP_NO_TRAILING_RETURN_TYPES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_TEMPLATE_ALIASES -// -// Defined as 1 if the compiler doesn't support C++11 template aliases. Otherwise undefined. - -#if !defined(OVR_CPP_NO_TEMPLATE_ALIASES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_alias_templates)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ - #define OVR_CPP_NO_TEMPLATE_ALIASES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_INITIALIZER_LISTS -// -// Defined as 1 if the compiler doesn't support C++11 initializer lists. Otherwise undefined. -// This refers to the compiler support for this and not the Standard Library support for std::initializer_list, -// as a new compiler with an old standard library (e.g. Apple clang with libstdc++) may not support std::initializer_list. - -#if !defined(OVR_CPP_NO_INITIALIZER_LISTS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_generalized_initializers)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_INITIALIZER_LISTS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NORETURN -// -// Defined as 1 if the compiler doesn't support the C++11 noreturn attribute. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/attributes -// -#if !defined(OVR_CPP_NO_NORETURN) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ - // Supported with VC++ only via __declspec(noreturn) (see OVR_NORETURN). - #define OVR_CPP_NO_NORETURN 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS -// -// Defined as 1 if the compiler doesn't support C++11 in-class non-static member initializers. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/data_members - -#if !defined(OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - #define OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DOUBLE_TEMPLATE_BRACKETS -// -// Defined as 1 if the compiler supports nested template declarations with >>, -// as supported by C++11. Otherwise undefined. - -#if !defined(OVR_CPP_NO_DOUBLE_TEMPLATE_ANGLE_BRACKETS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - #define OVR_CPP_NO_DOUBLE_TEMPLATE_BRACKETS 1 - #endif -#endif - - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_INHERITING_CONSTRUCTORS -// -// Defined as 1 if the compiler supports C++11 inheriting constructors. Otherwise undefined. -// Example usage: -// struct A { explicit A(int x){} }; -// struct B : public A { using A::A; }; // As if B redeclared A::A(int). - -#if !defined(OVR_CPP_NO_INHERITING_CONSTRUCTORS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_inheriting_constructors)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_INHERITING_CONSTRUCTORS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_DELEGATING_CONSTRUCTORS -// -// Defined as 1 if the compiler supports C++11 delegating constructors. Otherwise undefined. - -#if !defined(OVR_CPP_NO_DELEGATING_CONSTRUCTORS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ - #define OVR_CPP_NO_DELEGATING_CONSTRUCTORS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS -// -// Defined as 1 if the compiler supports C++11 function template default arguments. Otherwise undefined. - -#if !defined(OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ - #define OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_UNRESTRICTED_UNIONS -// -// Defined as 1 if the compiler supports C++11 unrestricted unions. Otherwise undefined. - -#if !defined(OVR_CPP_NO_UNRESTRICTED_UNIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_UNRESTRICTED_UNIONS 1 - #endif -#endif - - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXTENDED_SIZEOF -// -// Defined as 1 if the compiler supports C++11 class sizeof extensions (e.g. sizeof SomeClass::someMember). -// Otherwise undefined. - -#if !defined(OVR_CPP_NO_EXTENDED_SIZEOF) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - #define OVR_CPP_NO_EXTENDED_SIZEOF 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_INLINE_NAMESPACES -// -// Defined as 1 if the compiler supports C++11 inlined namespaces. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces - -#if !defined(OVR_CPP_NO_INLINE_NAMESPACES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_INLINE_NAMESPACES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS -// -// Defined as 1 if the compiler supports C++11 explicit conversion operators. Otherwise undefined. -// http://en.cppreference.com/w/cpp/language/explicit - -#if !defined(OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_explicit_conversions)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 404))) /* EDG 4.4+ */ - #define OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS -// -// Defined as 1 if the compiler supports C++11 local class template parameters. Otherwise undefined. -// Example: -// void Test() { -// struct LocalClass{ }; -// SomeTemplateClass t; // Allowed only in C++11 -// } - -#if !defined(OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_local_type_template_args)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ - #define OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_NEW_CHARACTER_TYPES -// -// Defined as 1 if the compiler natively supports C++11 char16_t and char32_t. Otherwise undefined. -// VC++ through at least VS2013 defines char16_t as unsigned short in its standard library, -// but it is not a native type or unique type, nor can you for a string literal with it. - -#if !defined(OVR_CPP_NO_NEW_CHARACTER_TYPES) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_unicode_literals)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_NEW_CHARACTER_TYPES 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS -// -// Defined as 1 if the compiler supports C++11 \u and \U character literals for -// native char16_t and char32_t types. -// -#if !defined(OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - // Not supported by VC++ as of VS2013. VC++'s existing \U and \u are non-conforming. - #define OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_USER_DEFINED_LITERALS -// -// Defined as 1 if the compiler supports C++11 user-defined literals. Otherwise undefined. - -#if !defined(OVR_CPP_NO_USER_DEFINED_LITERALS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_USER_DEFINED_LITERALS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_UNICODE_STRING_LITERALS -// -// Defined as 1 if the compiler supports C++11 Unicode string literals. Otherwise undefined. -// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals - -#if !defined(OVR_CPP_NO_UNICODE_STRING_LITERALS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_unicode_literals)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_UNICODE_STRING_LITERALS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_RAW_STRING_LITERALS -// -// Defined as 1 if the compiler supports C++11 raw literals. Otherwise undefined. -// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals - -#if !defined(OVR_CPP_NO_RAW_STRING_LITERALS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_raw_string_literals)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ - // Not supported by VC++ as of VS2013. - #define OVR_CPP_NO_RAW_STRING_LITERALS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX -// -// Defined as 1 if the compiler supports C++11 unified initialization. -// http://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization - -#if !defined(OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_generalized_initializers)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ - #define OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS -// -// Defined as 1 if the compiler supports C++11 extended friends. - -#if !defined(OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ - !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ - !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ - #define OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_CPP_NO_THREAD_LOCAL -// -// Defined as 1 if the compiler supports C++11 thread_local. Else undefined. Does not -// indicate if the compiler supports C thread-local compiler extensions such as __thread -// and declspec(thread). Use OVR_THREAD_LOCAL if you want to declare a thread-local -// variable that supports C++11 thread_local when available but the C extension when -// it's available. The primary difference between C++11 thread_local and C extensions is -// that C++11 thread_local supports non-PODs and calls their constructors and destructors. -// -// Note that thread_local requires both compiler and linker support, and so it's possible -// that the compiler may support thread_local but the linker does not. - -#if !defined(OVR_CPP_NO_THREAD_LOCAL) - #if !defined(OVR_CPP11_ENABLED) || \ - (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_thread_local)) /* clang */ && \ - !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ - !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ - #define OVR_CPP_NO_THREAD_LOCAL 1 - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_ALIGNAS / OVR_ALIGNOF -// -// OVR_ALIGNAS(n) // Specifies a size_t power of two alignment for a type or instance. -// OVR_ALIGNOF(type) // Returns the size_t alignment of a type or instance. -// -// Example usage: -// OVR_ALIGNAS(8) char c = 'c'; // Specifies that the instance c be aligned to an 8 byte boundary. -// typedef OVR_ALIGNAS(8) char C; // Specifies that the type C be aligned to an 8 byte boundary. -// struct OVR_ALIGNAS(64) S{ char array[16]; }; // Specfies that the struct S have a natural alignment of 64. -// OVR_ALIGNAS(32) S s; // Specifies that the instance s of struct S be aligned to an 32 byte boundary. -// OVR_ALIGNAS(32) struct T{ char array[16]; } t; // Specfies that the instance t of struct T have a natural alignment of 32. -// struct OVR_ALIGNAS(T) U{}; // Specifes that U be aligned the same as T. Supported only by C++11 compilers (see OVR_CPP_NO_ALIGNAS). -// -// size_t a = OVR_ALIGNOF(double); // Returns the natural alignment of the double type. -// size_t a = OVR_ALIGNOF(S); // Returns the natural alignment of the struct S type. -// -// Note: If C++11 alignas is supported, then alignas/OVR_ALIGNAS may take a const expression in addition to a constant. -// Note: The C11 Standard species the _Alignas keyword and alignas as a macro for it in - -#if !defined(OVR_ALIGNAS) - #if defined(OVR_CC_GNU) && !defined(OVR_CPP_NO_ALIGNAS) // If C++11 alignas is supported... - #define OVR_ALIGNAS(n) alignas(n) - #elif defined(__clang__) && !defined(OVR_CPP_NO_ALIGNAS) - #define OVR_ALIGNAS(n) alignas(n) - #elif defined(OVR_CC_GNU) || defined(__clang__) - #define OVR_ALIGNAS(n) __attribute__((aligned(n))) - #elif defined(OVR_CC_MSVC) || defined(OVR_CC_INTEL) - #define OVR_ALIGNAS(n) __declspec(align(n)) // For Microsoft the alignment must be a literal integer. - #elif defined(OVR_CC_ARM) - #define OVR_ALIGNAS(n) __align(n) - #else - #error Need to define OVR_ALIGNAS - #endif -#endif - -#if !defined(OVR_ALIGNOF) - #if defined(OVR_CC_GNU) && !defined(OVR_CPP_NO_ALIGNOF) // If C++11 alignof is supported... - #define OVR_ALIGNOF(type) alignof(type) - #elif defined(__clang__) && !defined(OVR_CPP_NO_ALIGNOF) - #define OVR_ALIGNOF(type) alignof(type) - #elif defined(OVR_CC_GNU) || defined(__clang__) - #define OVR_ALIGNOF(type) ((size_t)__alignof__(type)) - #elif defined(OVR_CC_MSVC) || defined(OVR_CC_INTEL) - #define OVR_ALIGNOF(type) ((size_t)__alignof(type)) - #elif defined(OVR_CC_ARM) - #define OVR_ALIGNOF(type) ((size_t)__ALIGNOF__(type)) - #else - #error Need to define OVR_ALIGNOF - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_ASSUME / OVR_ANALYSIS_ASSUME -// -// This is a portable wrapper for VC++'s __assume and __analysis_assume. -// __analysis_assume is typically used to quell VC++ static analysis warnings. -// -// Example usage: -// void Test(char c){ -// switch(c){ -// case 'a': -// case 'b': -// case 'c': -// case 'd': -// break; -// default: -// OVR_ASSUME(0); // Unreachable code. -// } -// } -// -// size_t Test(char* str){ -// OVR_ANALYSIS_ASSUME(str != nullptr); -// return strlen(str); -// } - -#if !defined(OVR_ASSUME) - #if defined(OVR_CC_MSVC) - #define OVR_ASSUME(x) __assume(x) - #define OVR_ANALYSIS_ASSUME(x) __analysis_assume(!!(x)) - #else - #define OVR_ASSUME(x) - #define OVR_ANALYSIS_ASSUME(x) - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_RESTRICT -// -// Wraps the C99 restrict keyword in a portable way. -// C++11 and C++14 don't have restrict but this functionality is supported by -// all C++ compilers. -// -// Example usage: -// void* memcpy(void* OVR_RESTRICT s1, const void* OVR_RESTRICT s2, size_t n); - -#if !defined(OVR_RESTRICT) - #define OVR_RESTRICT __restrict // Currently supported by all compilers of significance to us. -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_NOEXCEPT / OVR_NOEXCEPT_IF(predicate) / OVR_NOEXCEPT_EXPR(expression) -// -// Implements a portable wrapper for C++11 noexcept. -// http://en.cppreference.com/w/cpp/language/noexcept -// -// Example usage: -// void Test() OVR_NOEXCEPT {} // This function doesn't throw. -// -// template -// void DoNothing() OVR_NOEXCEPT_IF(OVR_NOEXCEPT_EXPR(T())) // Throws an if and only if T::T(int) throws. -// { T t(3); } -// -#if !defined(OVR_NOEXCEPT) - #if defined(OVR_CPP_NOEXCEPT) - #define OVR_NOEXCEPT - #define OVR_NOEXCEPT_IF(predicate) - #define OVR_NOEXCEPT_EXPR(expression) false - #else - #define OVR_NOEXCEPT noexcept - #define OVR_NOEXCEPT_IF(predicate) noexcept((predicate)) - #define OVR_NOEXCEPT_EXPR(expression) noexcept((expression)) - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_FINAL -// -// Wraps the C++11 final keyword in a portable way. -// http://en.cppreference.com/w/cpp/language/final -// -// Example usage: -// struct Test { virtual int GetValue() OVR_FINAL; }; - -#if !defined(OVR_FINAL) - #if defined(OVR_CC_MSVC) && (OVR_CC_VERSION < 1700) // VC++ 2012 and earlier - #define OVR_FINAL sealed - #elif defined(OVR_CPP_INHERITANCE_FINAL) - #define OVR_FINAL - #else - #define OVR_FINAL final - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_OVERRIDE -// -// Wraps the C++11 override keyword in a portable way. -// http://en.cppreference.com/w/cpp/language/override -// -// Example usage: -// struct Parent { virtual void Func(int); }; -// struct Child : public Parent { void Func(int) OVR_OVERRIDE; }; - -#if !defined(OVR_CPP11_ENABLED) -#define OVR_OVERRIDE -#elif !defined(OVR_OVERRIDE) - #if defined(OVR_CPP_OVERRIDE) - #define OVR_OVERRIDE - #else - #if (defined(_MSC_VER) && (_MSC_VER <= 1600)) - #pragma warning(disable : 4481) - #endif - #define OVR_OVERRIDE override - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_FINAL_OVERRIDE -// -// Wraps the C++11 final+override keywords (a common combination) in a portable way. -// -// Example usage: -// struct Parent { virtual void Func(); }; -// struct Child : public Parent { virtual void Func() OVR_FINAL_OVERRIDE; }; - -#if !defined(OVR_FINAL_OVERRIDE) - #define OVR_FINAL_OVERRIDE OVR_FINAL OVR_OVERRIDE -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_EXTERN_TEMPLATE -// -// Portable wrapper for C++11 extern template. This tells the compiler to not instantiate -// the template in the current translation unit, which can significantly speed up -// compilation and avoid problems due to two translation units compiling code with -// different settings. -// -// Example usage: -// OVR_EXTERN_TEMPLATE(class basic_string); // Nothing to do for non-C++11 compilers. - -#if !defined(OVR_EXTERN_TEMPLATE) - #if defined(OVR_CPP_EXTERN_TEMPLATE) - #define OVR_EXTERN_TEMPLATE(decl) - #else - #define OVR_EXTERN_TEMPLATE(decl) extern template decl - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_CONSTEXPR / OVR_CONSTEXPR_OR_CONST -// -// Portable wrapper for C++11 constexpr. Doesn't include C++14 relaxed constexpr, -// for which a different wrapper name is reserved. -// -// Example usage: -// OVR_CONSTEXPR int Test() { return 15; } // This can be optimized better by a C++11 compiler that supports constexpr. -// OVR_CONSTEXPR_OR_CONST float x = 3.14159f; // This can be optimized better by a C++11 compiler, but if not then at least make it const. - -#if !defined(OVR_CONSTEXPR) - #if defined(OVR_CPP_NO_CONSTEXPR) - #define OVR_CONSTEXPR - #else - #define OVR_CONSTEXPR constexpr - #endif -#endif - -#if !defined(OVR_CONSTEXPR_OR_CONST) - #if defined(OVR_CPP_NO_CONSTEXPR) - #define OVR_CONSTEXPR_OR_CONST const - #else - #define OVR_CONSTEXPR_OR_CONST constexpr - #endif -#endif - - - -// ----------------------------------------------------------------------------------- -// ***** OVR_FUNCTION_DELETE / OVR_FUNCTION_DEFAULT -// -// Wraps the C++11 delete and default keywords in a way that allows for cleaner code -// while making for a better version of uncallable or default functions. -// -// Example usage: -// struct Test{ -// Test() OVR_FUNCTION_DEFAULT; // Non-C++11 compilers will require a separate definition for Test(). -// private: // Users should put OVR_FUNCTION_DELETE usage in a private -// void Uncallable() OVR_FUNCTION_DELETE; // area for compatibility with pre-C++11 compilers. -// }; - -#if defined(OVR_CPP_NO_DELETED_FUNCTIONS) - #define OVR_FUNCTION_DELETE -#else - #define OVR_FUNCTION_DELETE = delete -#endif - -#if defined(OVR_CPP_NO_DEFAULTED_FUNCTIONS) - #define OVR_FUNCTION_DEFAULT -#else - #define OVR_FUNCTION_DEFAULT = default -#endif - - - -// ----------------------------------------------------------------------------------- -// ***** OVR_NON_COPYABLE -// -// Allows you to specify a class as being neither copy-constructible nor assignable, -// which is a commonly needed pattern in C++ programming. Classes with this declaration -// are required to be default constructible (as are most classes). For pre-C++11 -// compilers this macro declares a private section for the class, which will be -// inherited by whatever code is directly below the macro invocation by default. -// -// Example usage: -// struct Test { -// Test(); -// ... -// OVR_NON_COPYABLE(Test) -// }; - -#if !defined(OVR_NON_COPYABLE) - #if defined(OVR_CPP_NO_DELETED_FUNCTIONS) - #define OVR_NON_COPYABLE(Type) \ - private: \ - Type(const Type&); \ - void operator=(const Type&); - #else - #define OVR_NON_COPYABLE(Type) \ - Type(const Type&) = delete; \ - void operator=(const Type&) = delete; - #endif -#endif - - - -#endif // header include guard - - - - diff --git a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h b/LibOVR/Src/Kernel/OVR_ContainerAllocator.h deleted file mode 100644 index 46bea2e..0000000 --- a/LibOVR/Src/Kernel/OVR_ContainerAllocator.h +++ /dev/null @@ -1,267 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_ContainerAllocator.h -Content : Template allocators and constructors for containers. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_ContainerAllocator_h -#define OVR_ContainerAllocator_h - -#include "OVR_Allocator.h" -#include - - -namespace OVR { - - -//----------------------------------------------------------------------------------- -// ***** Container Allocator - -// ContainerAllocator serves as a template argument for allocations done by -// containers, such as Array and Hash; replacing it could allow allocator -// substitution in containers. - -class ContainerAllocatorBase -{ -public: - static void* Alloc(size_t size) { return OVR_ALLOC(size); } - static void* Realloc(void* p, size_t newSize) { return OVR_REALLOC(p, newSize); } - static void Free(void *p) { OVR_FREE(p); } -}; - - - -//----------------------------------------------------------------------------------- -// ***** Constructors, Destructors, Copiers - -// Plain Old Data - movable, no special constructors/destructor. -template -class ConstructorPOD -{ -public: - static void Construct(void *) {} - static void Construct(void *p, const T& source) - { - *(T*)p = source; - } - - // Same as above, but allows for a different type of constructor. - template - static void ConstructAlt(void *p, const S& source) - { - *(T*)p = source; - } - - static void ConstructArray(void*, size_t) {} - - static void ConstructArray(void* p, size_t count, const T& source) - { - uint8_t *pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - *(T*)pdata = source; - } - - static void ConstructArray(void* p, size_t count, const T* psource) - { - memcpy(p, psource, sizeof(T) * count); - } - - static void Destruct(T*) {} - static void DestructArray(T*, size_t) {} - - static void CopyArrayForward(T* dst, const T* src, size_t count) - { - memmove(dst, src, count * sizeof(T)); - } - - static void CopyArrayBackward(T* dst, const T* src, size_t count) - { - memmove(dst, src, count * sizeof(T)); - } - - static bool IsMovable() { return true; } -}; - - -//----------------------------------------------------------------------------------- -// ***** ConstructorMov -// -// Correct C++ construction and destruction for movable objects -template -class ConstructorMov -{ -public: - static void Construct(void* p) - { - OVR::Construct(p); - } - - static void Construct(void* p, const T& source) - { - OVR::Construct(p, source); - } - - // Same as above, but allows for a different type of constructor. - template - static void ConstructAlt(void* p, const S& source) - { - OVR::ConstructAlt(p, source); - } - - static void ConstructArray(void* p, size_t count) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata); - } - - static void ConstructArray(void* p, size_t count, const T& source) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata, source); - } - - static void ConstructArray(void* p, size_t count, const T* psource) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata, *psource++); - } - - static void Destruct(T* p) - { - p->~T(); - OVR_UNUSED(p); // Suppress silly MSVC warning - } - - static void DestructArray(T* p, size_t count) - { - p += count - 1; - for (size_t i=0; i~T(); - } - - static void CopyArrayForward(T* dst, const T* src, size_t count) - { - memmove(dst, src, count * sizeof(T)); - } - - static void CopyArrayBackward(T* dst, const T* src, size_t count) - { - memmove(dst, src, count * sizeof(T)); - } - - static bool IsMovable() { return true; } -}; - - -//----------------------------------------------------------------------------------- -// ***** ConstructorCPP -// -// Correct C++ construction and destruction for movable objects -template -class ConstructorCPP -{ -public: - static void Construct(void* p) - { - OVR::Construct(p); - } - - static void Construct(void* p, const T& source) - { - OVR::Construct(p, source); - } - - // Same as above, but allows for a different type of constructor. - template - static void ConstructAlt(void* p, const S& source) - { - OVR::ConstructAlt(p, source); - } - - static void ConstructArray(void* p, size_t count) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata); - } - - static void ConstructArray(void* p, size_t count, const T& source) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata, source); - } - - static void ConstructArray(void* p, size_t count, const T* psource) - { - uint8_t* pdata = (uint8_t*)p; - for (size_t i=0; i< count; ++i, pdata += sizeof(T)) - Construct(pdata, *psource++); - } - - static void Destruct(T* p) - { - p->~T(); - OVR_UNUSED(p); // Suppress silly MSVC warning - } - - static void DestructArray(T* p, size_t count) - { - p += count - 1; - for (size_t i=0; i~T(); - } - - static void CopyArrayForward(T* dst, const T* src, size_t count) - { - for(size_t i = 0; i < count; ++i) - dst[i] = src[i]; - } - - static void CopyArrayBackward(T* dst, const T* src, size_t count) - { - for(size_t i = count; i; --i) - dst[i-1] = src[i-1]; - } - - static bool IsMovable() { return false; } -}; - - -//----------------------------------------------------------------------------------- -// ***** Container Allocator with movement policy -// -// Simple wraps as specialized allocators -template struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD {}; -template struct ContainerAllocator : ContainerAllocatorBase, ConstructorMov {}; -template struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP {}; - - -} // OVR - - -#endif diff --git a/LibOVR/Src/Kernel/OVR_DebugHelp.cpp b/LibOVR/Src/Kernel/OVR_DebugHelp.cpp deleted file mode 100644 index fe7b54f..0000000 --- a/LibOVR/Src/Kernel/OVR_DebugHelp.cpp +++ /dev/null @@ -1,3926 +0,0 @@ -/************************************************************************************ - -Filename : ExceptionHandler.cpp -Content : Platform-independent exception handling interface -Created : October 6, 2014 - -Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - - -#include "OVR_DebugHelp.h" -#include "OVR_Types.h" -#include "OVR_UTF8Util.h" -#include "../OVR_CAPI.h" -#include "../OVR_CAPI_Keys.h" -#include "../CAPI/CAPI_HMDState.h" -#include - -#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) - #pragma warning(push, 0) - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #pragma warning(pop) - - #pragma comment(lib, "Psapi.lib") // To consider: It may be a problem to statically link to these libraries if the application at runtime intends to dynamically - #pragma comment(lib, "ole32.lib") // link to a different version of the same library, and we are statically linked into that application instead of being a DLL. - #pragma comment(lib, "shell32.lib") - - // NtQueryInformation and THREAD_BASIC_INFORMATION are undocumented but frequently needed for digging into thread information. - typedef LONG (WINAPI *NtQueryInformationThreadFunc)(HANDLE, int, PVOID, ULONG, PULONG); - - struct THREAD_BASIC_INFORMATION - { - LONG ExitStatus; - PVOID TebBaseAddress; - PVOID UniqueProcessId; - PVOID UniqueThreadId; - PVOID Priority; - PVOID BasePriority; - }; - - #ifndef UNW_FLAG_NHANDLER // Older Windows SDKs don't support this. - #define UNW_FLAG_NHANDLER 0 - #endif - -#elif defined(OVR_OS_MAC) - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include "OVR_mach_exc_OSX.h" - - #if defined(__LP64__) - typedef struct mach_header_64 MachHeader; - typedef struct segment_command_64 SegmentCommand; - typedef struct section_64 Section; - #define kLCSegment LC_SEGMENT_64 - #else - typedef struct mach_header MachHeader; - typedef struct segment_command SegmentCommand; - typedef struct section Section; - #define kLCSegment LC_SEGMENT - #endif - - extern "C" const struct dyld_all_image_infos* _dyld_get_all_image_infos(); // From libdyld.dylib - -#elif defined(OVR_OS_UNIX) - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - //#include // Can't use this until we can ensure that we have an installed version of it. -#endif - -#if !defined(MIN) - #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) - #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) -#endif - - -OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized -OVR_DISABLE_MSVC_WARNING(4996) // This function or variable may be unsafe - - - - -#if defined(OVR_OS_APPLE) - static OVR::ExceptionHandler* sExceptionHandler = nullptr; - const uint32_t sMachCancelMessageType = 0x0ca9ce11; // This is a made-up value of our own choice. - - extern "C" - { - kern_return_t catch_mach_exception_raise_OVR(mach_port_t /*exceptionPort*/, mach_port_t /*threadSysId*/, - mach_port_t /*machTask*/, exception_type_t /*machExceptionType*/, - mach_exception_data_t /*machExceptionData*/, mach_msg_type_number_t /*machExceptionDataCount*/) - { - return KERN_FAILURE; - } - - kern_return_t catch_mach_exception_raise_state_OVR(mach_port_t /*exceptionPort*/, exception_type_t /*exceptionType*/, - const mach_exception_data_t /*machExceptionData*/, mach_msg_type_number_t /*machExceptionDataCount*/, - int* /*pMachExceptionFlavor*/, const thread_state_t /*threadStatePrev*/, mach_msg_type_number_t /*threaStatePrevCount*/, - thread_state_t /*threadStateNew*/, mach_msg_type_number_t* /*pThreadStateNewCount*/) - { - return KERN_FAILURE; - } - - kern_return_t catch_mach_exception_raise_state_identity_OVR(mach_port_t exceptionPort, mach_port_t threadSysId, mach_port_t machTask, - exception_type_t exceptionType, mach_exception_data_type_t* machExceptionData, - mach_msg_type_number_t machExceptionDataCount, int* pMachExceptionFlavor, - thread_state_t threadStatePrev, mach_msg_type_number_t threadStatePrevCount, - thread_state_t threadStateNew, mach_msg_type_number_t* pThreadStateNewCount) - { - return sExceptionHandler->HandleMachException(exceptionPort, threadSysId, machTask, exceptionType, machExceptionData, - machExceptionDataCount, pMachExceptionFlavor, threadStatePrev, threadStatePrevCount, - threadStateNew, pThreadStateNewCount); - } - - void* MachHandlerThreadFunctionStatic(void* pExceptionHandlerVoid) - { - return static_cast(pExceptionHandlerVoid)->MachHandlerThreadFunction(); - } - - } // extern "C" -#endif - - - - -namespace OVR { - - -void GetInstructionPointer(void*& pInstruction) -{ - #if defined(OVR_CC_MSVC) - pInstruction = _ReturnAddress(); - #else // GCC, clang - pInstruction = __builtin_return_address(0); - #endif -} - - -static size_t SprintfAddress(char* threadHandleStr, size_t threadHandleStrCapacity, const void* pAddress) -{ - #if defined(OVR_CC_MSVC) - #if (OVR_PTR_SIZE >= 8) - return OVR_snprintf(threadHandleStr, threadHandleStrCapacity, "0x%016I64x", pAddress); // e.g. 0x0123456789abcdef - #else - return OVR_snprintf(threadHandleStr, threadHandleStrCapacity, "0x%08x", pAddress); // e.g. 0x89abcdef - #endif - #else - #if (OVR_PTR_SIZE >= 8) - return OVR_snprintf(threadHandleStr, threadHandleStrCapacity, "%016llx", pAddress); // e.g. 0x0123456789abcdef - #else - return OVR_snprintf(threadHandleStr, threadHandleStrCapacity, "%08x", pAddress); // e.g. 0x89abcdef - #endif - #endif -} - - -static size_t SprintfThreadHandle(char* threadHandleStr, size_t threadHandleStrCapacity, const ThreadHandle& threadHandle) -{ - return SprintfAddress(threadHandleStr, threadHandleStrCapacity, threadHandle); -} - - -static size_t SprintfThreadSysId(char* threadSysIdStr, size_t threadSysIdStrCapacity, const ThreadSysId& threadSysId) -{ - #if defined(OVR_CC_MSVC) // Somebody could conceivably use VC++ with a different standard library that supports %ll. And VS2012+ also support %ll. - return OVR_snprintf(threadSysIdStr, threadSysIdStrCapacity, "%I64u", (uint64_t)threadSysId); - #else - return OVR_snprintf(threadSysIdStr, threadSysIdStrCapacity, "%llu", (uint64_t)threadSysId); - #endif -} - - - - - -void GetThreadStackBounds(void*& pStackBase, void*& pStackLimit, ThreadHandle threadHandle) -{ - #if defined(OVR_OS_WIN64) || defined(OVR_OS_WIN32) || (defined(OVR_OS_MS) && defined(OVR_OS_CONSOLE)) - ThreadSysId threadSysIdCurrent = (ThreadSysId)GetCurrentThreadId(); - ThreadSysId threadSysId; - NT_TIB* pTIB = nullptr; - - if(threadHandle == OVR_THREADHANDLE_INVALID) - threadSysId = threadSysIdCurrent; - else - threadSysId = ConvertThreadHandleToThreadSysId(threadHandle); - - if(threadSysId == threadSysIdCurrent) - { - #if (OVR_PTR_SIZE == 4) - // Need to use __asm__("movl %%fs:0x18, %0" : "=r" (pTIB) : : ); under gcc/clang. - __asm { - mov eax, fs:[18h] - mov pTIB, eax - } - #else - pTIB = (NT_TIB*)NtCurrentTeb(); - #endif - } - else - { - #if (OVR_PTR_SIZE == 4) - // It turns out we don't need to suspend the thread when getting SegFs/SegGS, as that's - // constant per thread and doesn't require the thread to be suspended. - //SuspendThread((HANDLE)threadHandle); - CONTEXT context; - memset(&context, 0, sizeof(context)); - context.ContextFlags = CONTEXT_SEGMENTS; - GetThreadContext((HANDLE)threadHandle, &context); // Requires THREAD_QUERY_INFORMATION privileges. - - LDT_ENTRY ldtEntry; - if(GetThreadSelectorEntry(threadHandle, context.SegFs, &ldtEntry)) // Requires THREAD_QUERY_INFORMATION - pTIB = (NT_TIB*)((ldtEntry.HighWord.Bits.BaseHi << 24 ) | (ldtEntry.HighWord.Bits.BaseMid << 16) | ldtEntry.BaseLow); - - //ResumeThread((HANDLE)threadHandle); - #else - // We cannot use GetThreadSelectorEntry or Wow64GetThreadSelectorEntry on Win64. - // We need to read the SegGs qword at offset 0x30. We can't use pTIB = (NT_TIB*)__readgsqword(0x30) because that reads only the current setGs offset. - // mov rax, qword ptr gs:[30h] - // mov qword ptr [pTIB],rax - // In the meantime we rely on the NtQueryInformationThread function. - - static NtQueryInformationThreadFunc spNtQueryInformationThread = nullptr; - - if(!spNtQueryInformationThread) - { - HMODULE hNTDLL = GetModuleHandleA("ntdll.dll"); - spNtQueryInformationThread = (NtQueryInformationThreadFunc)(uintptr_t)GetProcAddress(hNTDLL, "NtQueryInformationThread"); - } - - if(spNtQueryInformationThread) - { - THREAD_BASIC_INFORMATION tbi; - - memset(&tbi, 0, sizeof(tbi)); - LONG result = spNtQueryInformationThread(threadHandle, 0, &tbi, sizeof(tbi), nullptr); // Requires THREAD_QUERY_INFORMATION privileges - if(result == 0) - pTIB = (NT_TIB*)tbi.TebBaseAddress; - } - #endif - } - - if(pTIB) - { - pStackBase = (void*)pTIB->StackBase; - pStackLimit = (void*)pTIB->StackLimit; - } - else - { - pStackBase = nullptr; - pStackLimit = nullptr; - } - - #elif defined(OVR_OS_APPLE) - if(!threadHandle) - threadHandle = pthread_self(); - - pStackBase = pthread_get_stackaddr_np((pthread_t)threadHandle); - size_t stackSize = pthread_get_stacksize_np((pthread_t)threadHandle); - pStackLimit = (void*)((size_t)pStackBase - stackSize); - - #elif defined(OVR_OS_UNIX) - pStackBase = nullptr; - pStackLimit = nullptr; - - pthread_attr_t threadAttr; - pthread_attr_init(&threadAttr); - - #if defined(OVR_OS_LINUX) - int result = pthread_getattr_np((pthread_t)threadHandle, &threadAttr); - #else - int result = pthread_attr_get_np((pthread_t)threadHandle, &threadAttr); - #endif - - if(result == 0) - { - size_t stackSize = 0; - result = pthread_attr_getstack(&threadAttr, &pStackLimit, &stackSize); - - if(result == 0) - pStackBase = (void*)((uintptr_t)pStackLimit + stackSize); // We assume the stack grows downward. - } - - #endif -} - - -bool OVRIsDebuggerPresent() -{ - #if defined(OVR_OS_MS) - return ::IsDebuggerPresent() != 0; - - #elif defined(OVR_OS_APPLE) - int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; - struct kinfo_proc info; - size_t size = sizeof(info); - - info.kp_proc.p_flag = 0; - sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0); - - return ((info.kp_proc.p_flag & P_TRACED) != 0); - - #elif (defined(OVR_OS_LINUX) || defined(OVR_OS_BSD)) && !defined(OVR_OS_ANDROID) - // This works better than the PT_TRACE_ME approach. - // However, it presents a problem: - // http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html - // When the application calls fork() from a signal handler and any of the - // fork handlers registered by pthread_atfork() calls a function that is - // not asynch-signal-safe, the behavior is undefined. - // We may need to provide two pathways within this function, one of which - // doesn't fork and instead uses PT_TRACE_ME. - int pid = fork(); - int status; - bool present = false; - - if (pid == -1) // If fork failed... - { - // perror("fork"); - } - else if (pid == 0) // If we are the child process... - { - int ppid = getppid(); - - #if defined(OVR_OS_LINUX) - if (ptrace(PTRACE_ATTACH, ppid, nullptr, nullptr) == 0) - #else - if (ptrace(PT_ATTACH, ppid, nullptr, nullptr) == 0) - #endif - { - waitpid(ppid, nullptr, 0); - - #if defined(OVR_OS_LINUX) - ptrace(PTRACE_CONT, getppid(), nullptr, nullptr); - ptrace(PTRACE_DETACH, getppid(), nullptr, nullptr); - #else - ptrace(PT_CONTINUE, getppid(), nullptr, nullptr); - ptrace(PT_DETACH, getppid(), nullptr, nullptr); - #endif - } - else - { - // ptrace failed so the debugger is present. - present = true; - } - - exit(present ? 1 : 0); // The WEXITSTATUS call below will read this exit value. - } - else // Else we are the original process. - { - waitpid(pid, &status, 0); - present = WEXITSTATUS(status) ? true : false; // Read the exit value from the child's call to exit. - } - - return present; - - #elif defined(PT_TRACE_ME) && !defined(OVR_OS_ANDROID) - return (ptrace(PT_TRACE_ME, 0, 1, 0) < 0); - - #else - return false; - #endif -} - - -// Exits the process with the given exit code. -void ExitProcess(intptr_t processReturnValue) -{ - exit((int)processReturnValue); -} - - -void* SafeMMapAlloc(size_t size) -{ - #if defined(OVR_OS_MS) - return VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // size is rounded up to a page. // Returned memory is 0-filled. - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - #if !defined(MAP_FAILED) - #define MAP_FAILED ((void*)-1) - #endif - - void* result = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); // Returned memory is 0-filled. - if(result == MAP_FAILED) // mmap returns MAP_FAILED (-1) upon failure. - result = nullptr; - return result; - #endif -} - - -void SafeMMapFree(const void* memory, size_t size) -{ - #if defined(OVR_OS_MS) - OVR_UNUSED(size); - VirtualFree(const_cast(memory), 0, MEM_RELEASE); - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - size_t pageSize = getpagesize(); - size = (((size + (pageSize - 1)) / pageSize) * pageSize); - munmap(const_cast(memory), size); // Must supply the size to munmap. - #endif -} - - -// Note that we can't just return sizeof(void*) == 8, as we may have the case of a -// 32 bit app running on a 64 bit operating system. -static bool Is64BitOS() -{ - #if (OVR_PTR_SIZE >= 8) - return true; - - #elif defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) - BOOL is64BitOS = FALSE; - bool IsWow64ProcessPresent = (GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process") != nullptr); - return (IsWow64ProcessPresent && IsWow64Process(GetCurrentProcess(), &is64BitOS) && is64BitOS); - - #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) - utsname utsName; - memset(&utsName, 0, sizeof(utsName)); - return (uname(&utsName) == 0) && (strcmp(utsName.machine, "x86_64") == 0); - - #else - return false; - #endif -} - - -// The output will always be 0-terminated. -// Returns the required strlen of the output. -// Returns (size_t)-1 on failure. -size_t SpawnShellCommand(const char* shellCommand, char* output, size_t outputCapacity) -{ - #if defined(OVR_OS_UNIX) || defined(OVR_OS_APPLE) - FILE* pFile = popen(shellCommand, "r"); - - if(pFile) - { - size_t requiredLength = 0; - char buffer[256]; - - while(fgets(buffer, sizeof(buffer), pFile)) // fgets 0-terminates the buffer. - { - size_t length = OVR_strlen(buffer); - requiredLength += length; - - if(outputCapacity) - { - OVR_strlcpy(output, buffer, outputCapacity); - length = MIN(outputCapacity, length); - } - - output += length; - outputCapacity -= length; - } - - pclose(pFile); - return requiredLength; - } - #else - // To do. Properly solving this on Windows requires a bit of code. - OVR_UNUSED(shellCommand); - OVR_UNUSED(output); - OVR_UNUSED(outputCapacity); - #endif - - return (size_t)-1; -} - - -// Retrieves a directory path which ends with a path separator. -// Returns the required strlen of the path. -// Guarantees the presence of the directory upon returning true. -static size_t GetUserDocumentsDirectory(char* directoryPath, size_t directoryPathCapacity) -{ - #if defined(OVR_OS_MS) - wchar_t pathW[MAX_PATH + 1]; // +1 because we append a path separator. - HRESULT hr = SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_CREATE, nullptr, SHGFP_TYPE_CURRENT, pathW); - - if(SUCCEEDED(hr)) - { - OVR_UNUSED(directoryPathCapacity); - - intptr_t requiredUTF8Length = OVR::UTF8Util::GetEncodeStringSize(pathW); // Returns required strlen. - if(requiredUTF8Length < MAX_PATH) // We need space for a trailing path separator. - { - OVR::UTF8Util::EncodeString(directoryPath, pathW, -1); - OVR::OVR_strlcat(directoryPath, "\\", directoryPathCapacity); - } - - return (requiredUTF8Length + 1); - } - - #elif defined(OVR_OS_MAC) - // This is the same location that Apple puts its OS-generated .crash files. - const char* home = getenv("HOME"); - size_t requiredStrlen = OVR::OVR_snprintf(directoryPath, directoryPathCapacity, "%s/Library/Logs/DiagnosticReports/", home ? home : "/Users/Shared/Logs/DiagnosticReports/"); - // To do: create the directory if it doesn't already exist. - return requiredStrlen; - - #elif defined(OVR_OS_UNIX) || defined(OVR_OS_MAC) - const char* home = getenv("HOME"); - size_t requiredStrlen = OVR::OVR_snprintf(directoryPath, directoryPathCapacity, "%s/Library/", home ? home : "/Users/Shared/"); - // To do: create the directory if it doesn't already exist. - return requiredStrlen; - #endif - - return 0; -} - - -// Retrieves the name of the given thread. -// To do: Move this to OVR_Threads.h -bool GetThreadName(OVR::ThreadHandle threadHandle, char* threadName, size_t threadNameCapacity) -{ - #if defined(OVR_OS_APPLE) || defined(OVR_OS_LINUX) - int result = pthread_getname_np((pthread_t)threadHandle, threadName, threadNameCapacity); - if(result == 0) - return true; - #else - // This is not currently possible on Windows, as only the debugger stores the thread name. We could potentially use a vectored - // exception handler to catch all thread name exceptions (0x406d1388) and record them in a static list at runtime. To detect - // thread exit we could use WMI Win32_ThreadStopTrace. Maintain a list of thread names between these two events. - OVR_UNUSED(threadHandle); - OVR_UNUSED(threadNameCapacity); - #endif - - if(threadNameCapacity) - threadName[0] = 0; - - return false; -} - - -OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle) -{ - #if defined(OVR_OS_WIN64) - return (OVR::ThreadSysId)::GetThreadId(threadHandle); // Requires THREAD_QUERY_INFORMATION privileges. - - #elif defined(OVR_OS_WIN32) - typedef DWORD (WINAPI *GetThreadIdFunc)(HANDLE); - - static volatile bool sInitialized = false; - static GetThreadIdFunc spGetThreadIdFunc = nullptr; - static NtQueryInformationThreadFunc spNtQueryInformationThread = nullptr; - - if(!sInitialized) - { - HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); - if(hKernel32) - spGetThreadIdFunc = (GetThreadIdFunc)(uintptr_t)GetProcAddress(hKernel32, "GetThreadId"); - - if(!spGetThreadIdFunc) - { - HMODULE hNTDLL = GetModuleHandleA("ntdll.dll"); - - if(hNTDLL) - spNtQueryInformationThread = (NtQueryInformationThreadFunc)(uintptr_t)GetProcAddress(hNTDLL, "NtQueryInformationThread"); - } - - sInitialized = true; - } - - if(spGetThreadIdFunc) - return (OVR::ThreadSysId)spGetThreadIdFunc(threadHandle); - - if(spNtQueryInformationThread) - { - THREAD_BASIC_INFORMATION tbi; - - if(spNtQueryInformationThread(threadHandle, 0, &tbi, sizeof(tbi), nullptr) == 0) - return (OVR::ThreadSysId)tbi.UniqueThreadId; - } - - return OVR_THREADSYSID_INVALID; - - #elif defined(OVR_OS_APPLE) - mach_port_t threadSysId = pthread_mach_thread_np((pthread_t)threadHandle); // OS 10.4 and later. - return (ThreadSysId)threadSysId; - - #elif defined(OVR_OS_LINUX) - - // I believe we can usually (though not portably) intepret the pthread_t as a pointer to a struct whose first member is a lwp id. - OVR_UNUSED(threadHandle); - return OVR_THREADSYSID_INVALID; - - #else - OVR_UNUSED(threadHandle); - return OVR_THREADSYSID_INVALID; - #endif -} - - -OVR::ThreadHandle ConvertThreadSysIdToThreadHandle(OVR::ThreadSysId threadSysId) -{ - #if defined(OVR_OS_MS) - // We currently request the given rights because that's what users of this function typically need it for. Ideally there would - // be a way to specify the requested rights in order to avoid the problem if we need only a subset of them but can't get it. - // The solution we use below to try opening with successively reduced rights will work for our uses here but isn't a good general solution to this. - OVR::ThreadHandle threadHandle = ::OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); - - if(threadHandle == OVR_THREADHANDLE_INVALID) - { - threadHandle = ::OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); - - if(threadHandle == OVR_THREADHANDLE_INVALID) - threadHandle = ::OpenThread(THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); - } - - return threadHandle; - #elif defined(OVR_OS_MAC) - return (ThreadHandle)pthread_from_mach_thread_np((mach_port_t)threadSysId); - #else - return (ThreadHandle)threadSysId; - #endif -} - - -void FreeThreadHandle(OVR::ThreadHandle threadHandle) -{ - #if defined(OVR_OS_MS) - if(threadHandle != OVR_THREADHANDLE_INVALID) - ::CloseHandle(threadHandle); - #else - OVR_UNUSED(threadHandle); - #endif -} - - -OVR::ThreadSysId GetCurrentThreadSysId() -{ - #if defined(OVR_OS_MS) - return ::GetCurrentThreadId(); - #elif defined(OVR_OS_APPLE) - return (ThreadSysId)mach_thread_self(); - #else - return (ThreadSysId)pthread_self(); - #endif -} - - - -static void GetCurrentProcessFilePath(char* appPath, size_t appPathCapacity) -{ - appPath[0] = 0; - - #if defined(OVR_OS_MS) - wchar_t pathW[MAX_PATH]; - GetModuleFileNameW(0, pathW, (DWORD)OVR_ARRAY_COUNT(pathW)); - - size_t requiredUTF8Length = (size_t)OVR::UTF8Util::GetEncodeStringSize(pathW); // Returns required strlen. - - if(requiredUTF8Length < appPathCapacity) - { - OVR::UTF8Util::EncodeString(appPath, pathW, -1); - } - else - { - appPath[0] = 0; - } - - #elif defined(OVR_OS_APPLE) - struct BunderFolder - { - // Returns true if pStr ends with pFind, case insensitively. - // To do: Move OVR_striend to OVRKernel/Std.h - static bool OVR_striend(const char* pStr, const char* pFind, size_t strLength = (size_t)-1, size_t findLength = (size_t)-1) - { - if(strLength == (size_t)-1) - strLength = OVR_strlen(pStr); - if(findLength == (size_t)-1) - findLength = OVR_strlen(pFind); - if(strLength >= findLength) - return (OVR_stricmp(pStr + strLength - findLength, pFind) == 0); - return false; - } - - static bool IsBundleFolder(const char* filePath) - { - // https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1 - static const char* extensionArray[] = { ".app", ".bundle", ".framework", ".plugin", ".kext" }; - - for(size_t i = 0; i < OVR_ARRAY_COUNT(extensionArray); i++) - { - if(OVR_striend(filePath, extensionArray[i])) - return true; - } - - return false; - } - }; - - char appPathTemp[PATH_MAX]; - uint32_t appPathTempCapacity32 = PATH_MAX; - size_t requiredStrlen = appPathCapacity; - - if(_NSGetExecutablePath(appPathTemp, &appPathTempCapacity32) == 0) - { - char appPathTempReal[PATH_MAX]; - - if(realpath(appPathTemp, appPathTempReal)) // If the path is a symbolic link, this converts it to the real path. - { - // To consider: Enable reading the internal bundle executable path. An application on Mac may in - // fact be within a file bundle, which is an private file system within a file. With Objective C - // we could use: [[NSWorkspace sharedWorkspace] isFilePackageAtPath:fullPath]; - bool shouldReadTheBunderPath = false; - - if(shouldReadTheBunderPath) - { - // We recursively call dirname() until we find .app/.bundle/.plugin as a directory name. - OVR_strlcpy(appPathTemp, appPathTempReal, OVR_ARRAY_COUNT(appPathTemp)); - bool found = BunderFolder::IsBundleFolder(appPathTemp); - - while(!found && OVR_strcmp(appPathTemp, ".") && OVR_strcmp(appPathTemp, "/")) - { - OVR_strlcpy(appPathTemp, dirname(appPathTemp), OVR_ARRAY_COUNT(appPathTemp)); - found = BunderFolder::IsBundleFolder(appPathTemp); - } - - if(found) // If somewhere above we found a parent bundle container... - requiredStrlen = OVR_strlcpy(appPath, appPathTemp, appPathCapacity); - else - requiredStrlen = OVR_strlcpy(appPath, appPathTempReal, appPathCapacity); - } - else - { - requiredStrlen = OVR_strlcpy(appPath, appPathTempReal, appPathCapacity); - } - } - } - - if(requiredStrlen >= appPathCapacity) - appPath[0] = '\0'; - - #elif defined(OVR_OS_LINUX) - ssize_t length = readlink("/proc/self/exe", appPath, appPathCapacity); - - if((length != -1) && ((size_t)length < (appPathCapacity - 1))) - { - appPath[length] = '\0'; - } - #endif -} - - -static const char* GetFileNameFromPath(const char* filePath) -{ - #if defined(OVR_OS_MS) - const char* lastPathSeparator = max(strrchr(filePath, '\\'), strrchr(filePath, '/')); // Microsoft APIs are inconsistent with respect to allowing / as a path separator. - #else - const char* lastPathSeparator = strrchr(filePath, '/'); - #endif - - if(lastPathSeparator) - return lastPathSeparator + 1; - - return filePath; -} - - - -static void FormatDateTime(char* buffer, size_t bufferCapacity, time_t timeValue, bool getDate, bool getTime, bool localDateTime, bool fileNameSafeCharacters = false) -{ - char temp[128]; - const tm* pTime = localDateTime ? localtime(&timeValue) : gmtime(&timeValue); - - if(bufferCapacity) - buffer[0] = 0; - - if(getDate) - { - const char* format = fileNameSafeCharacters ? "%Y-%m-%d" : "%Y/%m/%d"; - strftime(temp, OVR_ARRAY_COUNT(temp), format, pTime); - OVR::OVR_strlcpy(buffer, temp, bufferCapacity); - } - - if(getTime) - { - const char* format = fileNameSafeCharacters ? " %H.%M.%S" : " %H:%M:%S"; - strftime(temp, OVR_ARRAY_COUNT(temp), (getDate ? format : format + 1), pTime); - OVR::OVR_strlcat(buffer, temp, bufferCapacity); - } -} - - -static void GetOSVersionName(char* versionName, size_t versionNameCapacity) -{ - #if defined(OVR_OS_MS) - const char* name = "unknown"; - - OSVERSIONINFOEXW vi; - memset(&vi, 0, sizeof(vi)); - vi.dwOSVersionInfoSize = sizeof(vi); - - if(GetVersionExW((LPOSVERSIONINFOW)&vi)) - { - if(vi.dwMajorVersion >= 7) - { - // Unknown recent version. - } - if(vi.dwMajorVersion >= 6) - { - if(vi.dwMinorVersion >= 4) - name = "Windows 10"; - else if(vi.dwMinorVersion >= 3) - { - if(vi.wProductType == VER_NT_WORKSTATION) - name = "Windows 8.1"; - else - name = "Windows Server 2012 R2"; - } - else if(vi.dwMinorVersion >= 2) - { - if(vi.wProductType == VER_NT_WORKSTATION) - name = "Windows 8"; - else - name = "Windows Server 2012"; - } - else if(vi.dwMinorVersion >= 1) - { - if(vi.wProductType == VER_NT_WORKSTATION) - name = "Windows 7"; - else - name = "Windows Server 2008 R2"; - } - else - { - if(vi.wProductType == VER_NT_WORKSTATION) - name = "Windows Vista"; - else - name = "Windows Server 2008"; - } - } - else if(vi.dwMajorVersion >= 5) - { - if(vi.dwMinorVersion == 0) - name = "Windows 2000"; - else if(vi.dwMinorVersion == 1) - name = "Windows XP"; - else // vi.dwMinorVersion == 2 - { - if(GetSystemMetrics(SM_SERVERR2) != 0) - name = "Windows Server 2003 R2"; - else if(vi.wSuiteMask & VER_SUITE_WH_SERVER) - name = "Windows Home Server"; - if(GetSystemMetrics(SM_SERVERR2) == 0) - name = "Windows Server 2003"; - else - name = "Windows XP Professional x64 Edition"; - } - } - else - name = "Windows 98 or earlier"; - } - - OVR_strlcpy(versionName, name, versionNameCapacity); - - #elif defined(OVR_OS_UNIX) || defined(OVR_OS_APPLE) - utsname utsName; - memset(&utsName, 0, sizeof(utsName)); - - if(uname(&utsName) == 0) - OVR_snprintf(versionName, versionNameCapacity, "%s %s %s %s", utsName.sysname, utsName.release, utsName.version, utsName.machine); - else - OVR_snprintf(versionName, versionNameCapacity, "Unix"); - #endif -} - - - - -void CreateException(CreateExceptionType exceptionType) -{ - char buffer[1024] = {}; - - switch(exceptionType) - { - case kCETAccessViolation: - { - int* pNullPtr = reinterpret_cast((rand() / 2) / RAND_MAX); - pNullPtr[0] = 0; // This line should generate an exception. - sprintf(buffer, "%p", pNullPtr); - break; - } - - case kCETDivideByZero: - { - int smallValue = 1; - int largeValue = (1000 * exceptionType); - int divByZero = (smallValue / largeValue); // This line should generate a div/0 exception. - sprintf(buffer, "%d", divByZero); - break; - } - - case kCETIllegalInstruction: - { - #if defined(OVR_CPU_X86) || (defined(OVR_CPU_X86_64) && !defined(OVR_CC_MSVC)) // (if x86) or (if x64 and any computer but VC++)... - #if defined(OVR_CC_MSVC) - __asm ud2 - #else // e.g. GCC - asm volatile("ud2"); - #endif - - #elif defined(OVR_CPU_X86_64) && (defined(OVR_OS_MS) && defined(PAGE_EXECUTE_READWRITE)) - // VC++ for x64 doesn't support inline asm. - void* pVoid = _AddressOfReturnAddress(); - void** ppVoid = reinterpret_cast(pVoid); - void* pReturnAddress = *ppVoid; - DWORD dwProtectPrev = 0; - - if(VirtualProtect(pReturnAddress, 2, PAGE_EXECUTE_READWRITE, &dwProtectPrev)) // If we can set the memory to be executable... - { - // Modify the code we return to. - uint8_t asm_ud2[] = { 0x0f, 0x0b }; - memcpy(pReturnAddress, asm_ud2, sizeof(asm_ud2)); - VirtualProtect(pReturnAddress, 2, dwProtectPrev, &dwProtectPrev); - } - else - { - // To do: Fix this. - } - - #else - // To do: Fix this. - #endif - - break; - } - - case kCETStackCorruption: - { - size_t size = (sizeof(buffer) * 16) - (rand() % 16); - char* pOutsizeStack = buffer - ((sizeof(buffer) * 16) + (rand() % 16)); - - memset(buffer, 0, size); - memset(pOutsizeStack, 0, size); // This line should generate an exception, or an exception will be generated upon return from this function. - break; - } - - case kCETStackOverflow: - { - CreateException(exceptionType); // Call ourselves recursively. This line should generate a div/0 exception. - sprintf(buffer, "%d", exceptionType); - break; - } - - case kCETAlignment: - { - // Not all platforms generate alignment exceptions. Some internally handle it. - void* pAligned = malloc(16); - char* pMisaligned = (char*)pAligned + 1; - uint64_t* pMisaligned64 = reinterpret_cast(pMisaligned); - - *pMisaligned64 = 0; // This line should generate an exception. - free(pAligned); - break; - } - - case kCETFPU: - // Platforms usually have FPU exceptions disabled. In order to test FPU exceptions we will need to at least - // temporarily disable them before executing code here to generate such exceptions. - // To do. - break; - - case kCETTrap: - // To do. This is hardware-specific. - break; - } -} - - - - -#if defined(OVR_OS_MS) - typedef BOOL (WINAPI * StackWalk64Type)(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); - typedef PVOID (WINAPI * SymFunctionTableAccess64Type)(HANDLE hProcess, DWORD64 dwAddr); - typedef DWORD64 (WINAPI * SymGetModuleBase64Type)(HANDLE hProcess, DWORD64 dwAddr); - typedef DWORD (WINAPI * SymSetOptionsType)(DWORD SymOptions); - typedef BOOL (WINAPI * SymInitializeWType)(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess); - typedef BOOL (WINAPI * SymCleanupType)(HANDLE hProcess); - typedef DWORD64 (WINAPI * SymLoadModule64Type)(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll); - typedef BOOL (WINAPI * SymFromAddrType)(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol); - typedef BOOL (WINAPI * SymGetLineFromAddr64Type)(HANDLE hProcess, DWORD64 qwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line64); - - StackWalk64Type pStackWalk64; - SymFunctionTableAccess64Type pSymFunctionTableAccess64; - SymGetModuleBase64Type pSymGetModuleBase64; - SymSetOptionsType pSymSetOptions; - SymInitializeWType pSymInitializeW; - SymCleanupType pSymCleanup; - SymLoadModule64Type pSymLoadModule64; - SymFromAddrType pSymFromAddr; - SymGetLineFromAddr64Type pSymGetLineFromAddr64; -#endif - - - -SymbolLookup::SymbolLookup() - : initialized(false), - allowMemoryAllocation(true), - moduleListUpdated(false), - moduleInfoArray(), - moduleInfoArraySize(0) -{ -} - -SymbolLookup::~SymbolLookup() -{ - Shutdown(); -} - -void SymbolLookup::AddSourceCodeDirectory(const char* pDirectory) -{ - OVR_UNUSED(pDirectory); -} - -bool SymbolLookup::Initialize() -{ - if(!initialized) - { - #if defined(OVR_OS_MS) - // http://msdn.microsoft.com/en-us/library/windows/desktop/ms679294%28v=vs.85%29.aspx - HANDLE hProcess = GetCurrentProcess(); - HMODULE hDbgHelp = LoadLibraryW(L"DbgHelp.dll"); // It's best if the application supplies a recent version of this. - - if(hDbgHelp) - { - pStackWalk64 = (StackWalk64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "StackWalk64"); - pSymFunctionTableAccess64 = (SymFunctionTableAccess64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "SymFunctionTableAccess64"); - pSymGetModuleBase64 = (SymGetModuleBase64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "SymGetModuleBase64"); - pSymSetOptions = (SymSetOptionsType)(uintptr_t)::GetProcAddress(hDbgHelp, "SymSetOptions"); - pSymInitializeW = (SymInitializeWType)(uintptr_t)::GetProcAddress(hDbgHelp, "SymInitializeW"); - pSymCleanup = (SymCleanupType)(uintptr_t)::GetProcAddress(hDbgHelp, "SymCleanup"); - pSymLoadModule64 = (SymLoadModule64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "SymLoadModule64"); - pSymFromAddr = (SymFromAddrType)(uintptr_t)::GetProcAddress(hDbgHelp, "SymFromAddr"); - pSymGetLineFromAddr64 = (SymGetLineFromAddr64Type)(uintptr_t)::GetProcAddress(hDbgHelp, "SymGetLineFromAddr64"); - } - - pSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); - - // To consider: Use a manually created search path: - // wchar_t searchPathW[4096]; // Semicolon-separated strings. - // The current working directory of the application. - // The directory of the application itself (GetModuleFileName). - // The _NT_SYMBOL_PATH environment variable. - // The _NT_ALTERNATE_SYMBOL_PATH environment variable. - - if(pSymInitializeW(hProcess, nullptr /*searchPathW*/, FALSE)) - { - initialized = true; - } - #endif - } - - return true; -} - -void SymbolLookup::Shutdown() -{ - if(initialized) - { - initialized = false; - - #if defined(OVR_OS_MS) - HANDLE hProcess = GetCurrentProcess(); - - // SymCleanup should handle this for us. - //if(moduleListUpdated) - //{ - // for(size_t i = 0; i < moduleInfoArraySize; i++) - // pSymUnloadModule64(hProcess, moduleInfoArray[i].baseAddress); - //} - - moduleInfoArraySize = 0; - - pSymCleanup(hProcess); - #endif - } -} - - -void SymbolLookup::EnableMemoryAllocation(bool enabled) -{ - allowMemoryAllocation = enabled; -} - - -OVR_DISABLE_MSVC_WARNING(4740) // flow in or out of inline asm code suppresses global optimization -OVR_DISABLE_MSVC_WARNING(4748) // /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function - - -size_t SymbolLookup::GetBacktrace(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, void* platformThreadContext, OVR::ThreadSysId threadSysIdHelp) -{ - #if defined(OVR_OS_WIN64) || (defined(OVR_OS_MS) && defined(OVR_OS_CONSOLE)) - OVR_UNUSED(threadSysIdHelp); - - if(platformThreadContext == nullptr) - return RtlCaptureStackBackTrace(1, (ULONG)addressArrayCapacity, addressArray, nullptr); - - // We need to get the call stack of another thread. - size_t frameIndex = 0; - CONTEXT context; - PRUNTIME_FUNCTION pRuntimeFunction; - ULONG64 imageBase = 0; - ULONG64 imageBasePrev = 0; - - memcpy(&context, (CONTEXT*)platformThreadContext, sizeof(CONTEXT)); - context.ContextFlags = CONTEXT_CONTROL; - - if(context.Rip && (frameIndex < addressArrayCapacity)) - addressArray[frameIndex++] = (void*)(uintptr_t)context.Rip; - - while(context.Rip && (frameIndex < addressArrayCapacity)) - { - imageBasePrev = imageBase; - pRuntimeFunction = (PRUNTIME_FUNCTION)RtlLookupFunctionEntry(context.Rip, &imageBase, nullptr); - - if(pRuntimeFunction) - { - VOID* handlerData = nullptr; - ULONG64 establisherFramePointers[2] = { 0, 0 }; - RtlVirtualUnwind(UNW_FLAG_NHANDLER, imageBase, context.Rip, pRuntimeFunction, &context, &handlerData, establisherFramePointers, nullptr); - } - else - { - context.Rip = (ULONG64)(*(PULONG64)context.Rsp); - context.Rsp += 8; - } - - if(context.Rip && (frameIndex < addressArrayCapacity)) - { - if(skipCount) - --skipCount; - else - addressArray[frameIndex++] = (void*)(uintptr_t)context.Rip; - } - } - - return frameIndex; - - #elif defined(OVR_OS_WIN32) - OVR_UNUSED(threadSysIdHelp); - - size_t frameIndex = 0; - - if(pStackWalk64) - { - CONTEXT context; - - if(platformThreadContext) - { - memcpy(&context, platformThreadContext, sizeof(context)); - context.ContextFlags = CONTEXT_CONTROL; - } - else - { - memset(&context, 0, sizeof(context)); - context.ContextFlags = CONTEXT_CONTROL; - - __asm { - mov context.Ebp, EBP - mov context.Esp, ESP - call GetEIP - GetEIP: - pop context.Eip - } - } - - STACKFRAME64 sf; - memset(&sf, 0, sizeof(sf)); - sf.AddrPC.Offset = context.Eip; - sf.AddrPC.Mode = AddrModeFlat; - sf.AddrStack.Offset = context.Esp; - sf.AddrStack.Mode = AddrModeFlat; - sf.AddrFrame.Offset = context.Ebp; - sf.AddrFrame.Mode = AddrModeFlat; - - const HANDLE hCurrentProcess = ::GetCurrentProcess(); - const HANDLE hCurrentThread = ::GetCurrentThread(); - - if(!platformThreadContext) // If we are reading the current thread's call stack then we ignore this current function. - skipCount++; - - while(frameIndex < addressArrayCapacity) - { - if(!pStackWalk64(IMAGE_FILE_MACHINE_I386, hCurrentProcess, hCurrentThread, &sf, &context, nullptr, pSymFunctionTableAccess64, pSymGetModuleBase64, nullptr)) - break; - - if(sf.AddrFrame.Offset == 0) - break; - - if(skipCount) - --skipCount; - else - addressArray[frameIndex++] = ((void*)(uintptr_t)sf.AddrPC.Offset); - } - } - - return frameIndex; - - #elif defined(OVR_OS_APPLE) - struct StackFrame - { - StackFrame* pParentStackFrame; - void* pReturnPC; - }; - - void* pInstruction; - StackFrame* pStackFrame; - size_t frameIndex = 0; - - if(platformThreadContext) - { - #if defined(OVR_CPU_ARM) - arm_thread_state_t* pThreadState = (arm_thread_state_t*)platformThreadContext; - pStackFrame = (StackFrame*)pThreadState->__fp; - pInstruction = (void*) pThreadState->__pc; - #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0x1) == 0) - #elif defined(OVR_CPU_X86_64) - x86_thread_state_t* pThreadState = (x86_thread_state_t*)platformThreadContext; - pInstruction = (void*) pThreadState->uts.ts64.__rip; - pStackFrame = (StackFrame*)pThreadState->uts.ts64.__rbp; - #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0xf) == 0) - #elif defined(OVR_CPU_X86) - x86_thread_state_t* pThreadState = (x86_thread_state_t*)platformThreadContext; - pInstruction = (void*) pThreadState->uts.ts32.__eip; - pStackFrame = (StackFrame*)pThreadState->uts.ts32.__ebp; - #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0xf) == 8) - #endif - - if(frameIndex < addressArrayCapacity) - addressArray[frameIndex++] = pInstruction; - } - else // Else get the current values... - { - pStackFrame = (StackFrame*)__builtin_frame_address(0); - GetInstructionPointer(pInstruction); - } - - pthread_t threadSelf = pthread_self(); - void* pCurrentStackBase = pthread_get_stackaddr_np(threadSelf); - void* pCurrentStackLimit = (void*)((uintptr_t)pCurrentStackBase - pthread_get_stacksize_np(threadSelf)); - bool threadIsCurrent = (platformThreadContext == nullptr) || (((void*)pStackFrame > pCurrentStackLimit) && ((void*)pStackFrame <= pCurrentStackBase)); - StackFrame* pStackBase; - StackFrame* pStackLimit; - - if(threadIsCurrent) - { - pStackBase = (StackFrame*)pCurrentStackBase; - pStackLimit = (StackFrame*)pCurrentStackLimit; - } - else if(threadSysIdHelp) - { - pthread_t threadHandle = pthread_from_mach_thread_np((mach_port_t)threadSysIdHelp); - pStackBase = (StackFrame*)pthread_get_stackaddr_np(threadHandle); - pStackLimit = (StackFrame*)((uintptr_t)pStackBase - pthread_get_stacksize_np(threadHandle)); - } - else - { // We guess what the limits are. - pStackBase = pStackFrame + ((384 * 1024) / sizeof(StackFrame)); - pStackLimit = pStackFrame - ((384 * 1024) / sizeof(StackFrame)); - } - - if((frameIndex < addressArrayCapacity) && pStackFrame && FrameIsAligned(pStackFrame)) - { - addressArray[frameIndex++] = pStackFrame->pReturnPC; - - while(pStackFrame && pStackFrame->pReturnPC && (frameIndex < addressArrayCapacity)) - { - pStackFrame = pStackFrame->pParentStackFrame; - - if(pStackFrame && FrameIsAligned(pStackFrame) && pStackFrame->pReturnPC && (pStackFrame > pStackLimit) && (pStackFrame < pStackBase)) - { - if(skipCount) - --skipCount; - else - addressArray[frameIndex++] = pStackFrame->pReturnPC; - } - else - break; - } - } - - return frameIndex; - - #elif defined(OVR_OS_LINUX) && (defined( __LIBUNWIND__) || defined(LIBUNWIND_AVAIL)) - // Libunwind-based solution. Requires installation of libunwind package. - // Libunwind isn't always safe for threads that are in signal handlers. - // An approach to get the callstack of another thread is to use signal injection into the target thread. - - OVR_UNUSED(platformThreadContext); - OVR_UNUSED(threadSysIdHelp); - - size_t frameIndex = 0; - unw_cursor_t cursor; - unw_context_t uc; - unw_word_t ip, sp; - - unw_getcontext(&uc); // This gets the current thread's context. We could alternatively initialize another thread's context with it. - unw_init_local(&cursor, &uc); - - while((unw_step(&cursor) > 0) && (frameIndex < addressArrayCapacity)) - { - // We can get the function name here too on some platforms with unw_get_proc_info() and unw_get_proc_name(). - - if(skipCount) - --skipCount; - else - { - unw_get_reg(&cursor, UNW_REG_IP, &ip); - addressArray[frameIndex++] = (void*)ip; - } - } - - return frameIndex; - #else - OVR_UNUSED(addressArray); - OVR_UNUSED(addressArrayCapacity); - OVR_UNUSED(skipCount); - OVR_UNUSED(platformThreadContext); - OVR_UNUSED(threadSysIdHelp); - - return 0; - #endif -} - - -size_t SymbolLookup::GetBacktraceFromThreadHandle(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, OVR::ThreadHandle threadHandle) -{ - #if defined(OVR_OS_MS) - size_t count = 0; - DWORD threadSysId = (DWORD)ConvertThreadHandleToThreadSysId(threadHandle); - - // Compare to 0, compare to the self 'pseudohandle' and compare to the self id. - if((threadHandle == OVR_THREADHANDLE_INVALID) || (threadHandle == ::GetCurrentThread()) || (threadSysId == ::GetCurrentThreadId())) // If threadSysId refers to the current thread... - return GetBacktrace(addressArray, addressArrayCapacity, skipCount, nullptr); - - // We are working with another thread. We need to suspend it and get its CONTEXT. - // Suspending other threads is risky, as they may be in some state that cannot be safely blocked. - BOOL result = false; - DWORD suspendResult = ::SuspendThread(threadHandle); // Requires that the handle have THREAD_SUSPEND_RESUME rights. - - if(suspendResult != (DWORD)-1) // Returns previous suspend count, or -1 if failed. - { - CONTEXT context; - context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; // Requires that the handle have THREAD_GET_CONTEXT rights. - result = ::GetThreadContext(threadHandle, &context); - count = GetBacktrace(addressArray, addressArrayCapacity, skipCount, &context); - suspendResult = ::ResumeThread(threadHandle); - OVR_ASSERT_AND_UNUSED(suspendResult != (DWORD)-1, suspendResult); - } - - return count; - - #elif defined(OVR_OS_APPLE) - mach_port_t threadSysID = pthread_mach_thread_np((pthread_t)threadHandle); // Convert pthread_t to mach thread id. - return GetBacktraceFromThreadSysId(addressArray, addressArrayCapacity, skipCount, (OVR::ThreadSysId)threadSysID); - - #elif defined(OVR_OS_LINUX) - // To do. - OVR_UNUSED(addressArray); - OVR_UNUSED(addressArrayCapacity); - OVR_UNUSED(skipCount); - OVR_UNUSED(threadHandle); - return 0; - #endif -} - - -size_t SymbolLookup::GetBacktraceFromThreadSysId(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, OVR::ThreadSysId threadSysId) -{ - #if defined(OVR_OS_MS) - OVR::ThreadHandle threadHandle = ConvertThreadSysIdToThreadHandle(threadSysId); - if(threadHandle) - { - size_t count = GetBacktraceFromThreadHandle(addressArray, addressArrayCapacity, skipCount, threadHandle); - FreeThreadHandle(threadHandle); - return count; - } - return 0; - - #elif defined(OVR_OS_APPLE) - mach_port_t threadCurrent = pthread_mach_thread_np(pthread_self()); - mach_port_t thread = (mach_port_t)threadSysId; - - if(thread == threadCurrent) - { - return GetBacktrace(addressArray, addressArrayCapacity, skipCount, nullptr); - } - else - { - kern_return_t result = thread_suspend(thread); // Do we need to do this if it's an thread who exception is being handled? - size_t count = 0; - - if(result == KERN_SUCCESS) - { - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - x86_thread_state_t threadState; - #elif defined(OVR_CPU_ARM) - arm_thread_state_t threadState; - #endif - mach_msg_type_number_t stateCount = MACHINE_THREAD_STATE_COUNT; - - result = thread_get_state(thread, MACHINE_THREAD_STATE, (natural_t*)(uintptr_t)&threadState, &stateCount); - - if(result == KERN_SUCCESS) - count = GetBacktrace(addressArray, addressArrayCapacity, skipCount, &threadState, threadSysId); - - thread_resume(thread); - - return count; - } - } - - return 0; - - #elif defined(OVR_OS_LINUX) - // To do. - OVR_UNUSED(addressArray); - OVR_UNUSED(addressArrayCapacity); - OVR_UNUSED(skipCount); - OVR_UNUSED(threadSysId); - return 0; - #endif -} - - -// We need to return the required moduleInfoArrayCapacity. -size_t SymbolLookup::GetModuleInfoArray(ModuleInfo* pModuleInfoArray, size_t moduleInfoArrayCapacity) -{ - #if defined(OVR_OS_MS) - size_t moduleCountRequired = 0; // The count we would copy to pModuleInfoArray if moduleInfoArrayCapacity was enough. - size_t moduleCount = 0; // The count we actually copy to pModuleInfoArray. Will be <= moduleInfoArrayCapacity. - HANDLE hProcess = GetCurrentProcess(); - HMODULE hModuleArray[200]; - DWORD cbNeeded = 0; - MODULEINFO mi; - - if(EnumProcessModules(hProcess, hModuleArray, sizeof(hModuleArray), &cbNeeded)) - { - moduleCountRequired = ((cbNeeded / sizeof(HMODULE)) < OVR_ARRAY_COUNT(hModuleArray)) ? (cbNeeded / sizeof(HMODULE)) : OVR_ARRAY_COUNT(hModuleArray); - moduleCount = MIN(moduleCountRequired, OVR_ARRAY_COUNT(hModuleArray)); - moduleCount = MIN(moduleCount, moduleInfoArrayCapacity); - - for(size_t i = 0; i < moduleCount; i++) - { - ModuleInfo& moduleInfo = pModuleInfoArray[i]; - - memset(&mi, 0, sizeof(mi)); - BOOL result = GetModuleInformation(hProcess, hModuleArray[i], &mi, sizeof(mi)); - - if(result) - { - wchar_t pathW[MAX_PATH]; - char pathA[MAX_PATH * 3]; // *3 to handle UTF8 multibyte encoding. - - moduleInfo.handle = hModuleArray[i]; - moduleInfo.baseAddress = (uintptr_t)mi.lpBaseOfDll; - moduleInfo.size = mi.SizeOfImage; - - GetModuleFileNameW(hModuleArray[i], pathW, OVR_ARRAY_COUNT(pathW)); - OVR::UTF8Util::EncodeString(pathA, pathW, -1); // Problem: DecodeString provides no way to specify the destination capacity. - OVR::OVR_strlcpy(moduleInfo.filePath, pathA, OVR_ARRAY_COUNT(moduleInfo.filePath)); - - const char* fileName = GetFileNameFromPath(pathA); - OVR::OVR_strlcpy(moduleInfo.name, fileName, OVR_ARRAY_COUNT(moduleInfo.name)); - } - else - { - moduleInfo.handle = 0; - moduleInfo.baseAddress = 0; - moduleInfo.size = 0; - moduleInfo.filePath[0] = 0; - moduleInfo.name[0] = 0; - } - } - } - - return moduleCountRequired; - - #elif defined(OVR_OS_MAC) - size_t moduleCountRequired = 0; - size_t moduleCount = 0; - - struct MacModuleInfo // This struct exists solely so we can have a local function within this function.. - { - static void AddMacModuleInfo(ModuleInfo* pModuleInfoArrayL, size_t& moduleCountRequiredL, size_t& moduleCountL, size_t moduleInfoArrayCapacityL, - const char* pTypeFilterL, const char* pModulePath, uintptr_t currentSegmentPos, const MachHeader* pMachHeader, uint64_t offset) - { - for(size_t i = 0; i < pMachHeader->ncmds; i++) - { - const SegmentCommand* pSegmentCommand = reinterpret_cast(currentSegmentPos); - - if(pSegmentCommand->cmd == kLCSegment) - { - const size_t segnameSize = (sizeof(pSegmentCommand->segname) + 1); // +1 so we can have a trailing '\0'. - char segname[segnameSize]; - - memcpy(segname, pSegmentCommand->segname, sizeof(pSegmentCommand->segname)); - segname[segnameSize - 1] = '\0'; - - if(!pTypeFilterL || OVR_strncmp(segname, pTypeFilterL, sizeof(segname))) - { - moduleCountRequiredL++; - - if(moduleCountL < moduleInfoArrayCapacityL) - { - ModuleInfo& info = pModuleInfoArrayL[moduleCountL++]; - - info.baseAddress = (uint64_t)(pSegmentCommand->vmaddr + offset); - info.handle = reinterpret_cast((uintptr_t)info.baseAddress); - info.size = (uint64_t)pSegmentCommand->vmsize; - OVR_strlcpy(info.filePath, pModulePath, OVR_ARRAY_COUNT(info.filePath)); - OVR_strlcpy(info.name, GetFileNameFromPath(pModulePath), OVR_ARRAY_COUNT(info.name)); - - info.permissions[0] = (pSegmentCommand->initprot & VM_PROT_READ) ? 'r' : '-'; - info.permissions[1] = (pSegmentCommand->initprot & VM_PROT_WRITE) ? 'w' : '-'; - info.permissions[2] = (pSegmentCommand->initprot & VM_PROT_EXECUTE) ? 'x' : '-'; - info.permissions[3] = '/'; - info.permissions[4] = (pSegmentCommand->maxprot & VM_PROT_READ) ? 'r' : '-'; - info.permissions[5] = (pSegmentCommand->maxprot & VM_PROT_WRITE) ? 'w' : '-'; - info.permissions[6] = (pSegmentCommand->maxprot & VM_PROT_EXECUTE) ? 'x' : '-'; - info.permissions[7] = '\0'; - - OVR_strlcpy(info.type, pSegmentCommand->segname, OVR_ARRAY_COUNT(info.type)); - } - } - } - - currentSegmentPos += pSegmentCommand->cmdsize; - } - } - }; - - // Iterate dyld_all_image_infos->infoArray - const struct dyld_all_image_infos* pAllImageInfos = _dyld_get_all_image_infos(); - - for(uint32_t i = 0; i < pAllImageInfos->infoArrayCount; i++) - { - const char* pModulePath = pAllImageInfos->infoArray[i].imageFilePath; - - if(pModulePath && *pModulePath) - { - uintptr_t currentSegmentPos = (uintptr_t)pAllImageInfos->infoArray[i].imageLoadAddress; - const MachHeader* pMachHeader = reinterpret_cast(currentSegmentPos); - uint64_t offset = (uint64_t)_dyld_get_image_vmaddr_slide(i); - - currentSegmentPos += sizeof(*pMachHeader); - - MacModuleInfo::AddMacModuleInfo(pModuleInfoArray, moduleCountRequired, moduleCount, moduleInfoArrayCapacity, - nullptr /*"__TEXT"*/, pModulePath, currentSegmentPos, pMachHeader, offset); - } - } - - // In addition to iterating dyld_all_image_infos->infoArray we need to also iterate /usr/lib/dyld entries. - const MachHeader* pMachHeader = (const MachHeader*)pAllImageInfos->dyldImageLoadAddress; - uintptr_t currentSegmentPos = (uintptr_t)pMachHeader + sizeof(*pMachHeader); - char modulePath[OVR_MAX_PATH] = ""; - pid_t pid = getpid(); - int filenameLen = proc_regionfilename((int)pid, currentSegmentPos, modulePath, (uint32_t)sizeof(modulePath)); - - if(filenameLen > 0) - MacModuleInfo::AddMacModuleInfo(pModuleInfoArray, moduleCountRequired, moduleCount, moduleInfoArrayCapacity, - "__TEXT", modulePath, currentSegmentPos, pMachHeader, 0); - - return moduleCountRequired; - - #elif defined(EA_PLATFORM_LINUX) - // One approach is to read /proc/self/maps, which is supported by Linux (though not BSD). - // Linux glibc dladdr() can tell us what module an arbitrary function address comes from, but can't tell us the list of modules. - OVR_UNUSED(pModuleInfoArray); - OVR_UNUSED(moduleInfoArrayCapacity); - return 0; - - #else - OVR_UNUSED(pModuleInfoArray); - OVR_UNUSED(moduleInfoArrayCapacity); - return 0; - #endif -} - - -size_t SymbolLookup::GetThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCapacity) -{ - size_t countRequired = 0; - size_t count = 0; - - #if defined(OVR_OS_MS) - // Print a list of threads. - DWORD currentProcessId = GetCurrentProcessId(); - HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, currentProcessId); // ICreateToolhelp32Snapshot actually ignores currentProcessId. - - if(hThreadSnap != INVALID_HANDLE_VALUE) - { - THREADENTRY32 te32; - te32.dwSize = sizeof(THREADENTRY32); - - if(Thread32First(hThreadSnap, &te32)) - { - do - { - if(te32.th32OwnerProcessID == currentProcessId) - { - HANDLE hThread = ConvertThreadSysIdToThreadHandle(te32.th32ThreadID); - - if(hThread) - { - ++countRequired; - - if((threadHandleArray || threadSysIdArray) && (count < threadArrayCapacity)) - { - if(threadHandleArray) - threadHandleArray[count] = hThread; // The caller must call CloseHandle on this thread, or call DoneThreadList on the returned array. - if(threadSysIdArray) - threadSysIdArray[count] = ConvertThreadHandleToThreadSysId(hThread); - ++count; - } - - if(!threadHandleArray) // If we aren't giving this back to the user... - FreeThreadHandle(hThread); - } - } - } while(Thread32Next(hThreadSnap, &te32)); - } - - CloseHandle(hThreadSnap); - } - - #elif defined(OVR_OS_APPLE) - mach_port_t taskSelf = mach_task_self(); - thread_act_port_array_t threadArray; - mach_msg_type_number_t threadCount; - - kern_return_t result = task_threads(taskSelf, &threadArray, &threadCount); - - if(result == KERN_SUCCESS) - { - for(mach_msg_type_number_t i = 0; i < threadCount; i++) - { - ++countRequired; - - if((threadHandleArray || threadSysIdArray) && (count < threadArrayCapacity)) - { - if(threadHandleArray) - threadHandleArray[count] = pthread_from_mach_thread_np(threadArray[i]); - if(threadSysIdArray) - threadSysIdArray[count] = threadArray[i]; - ++count; - } - } - - vm_deallocate(taskSelf, (vm_address_t)threadArray, threadCount * sizeof(thread_act_t)); - } - - #elif defined(OVR_OS_LINUX) - // To do. - OVR_UNUSED(count); - OVR_UNUSED(threadHandleArray); - OVR_UNUSED(threadSysIdArray); - OVR_UNUSED(threadArrayCapacity); - #endif - - return countRequired; -} - - -void SymbolLookup::DoneThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCount) -{ - #if defined(OVR_OS_MS) - for(size_t i = 0; i != threadArrayCount; ++i) - { - if(threadHandleArray[i]) - { - CloseHandle(threadHandleArray[i]); - threadHandleArray[i] = OVR_THREADHANDLE_INVALID; - } - } - - OVR_UNUSED(threadSysIdArray); - #else - OVR_UNUSED(threadHandleArray); - OVR_UNUSED(threadSysIdArray); - OVR_UNUSED(threadArrayCount); - #endif -} - - -// Writes a given thread's callstack wity symbols to the given output. -// It may not be safe to call this from an exception handler, as sOutput allocates memory. -bool SymbolLookup::ReportThreadCallstack(OVR::String& sOutput, size_t skipCount, ThreadSysId threadSysId) -{ - if(!threadSysId) - threadSysId = GetCurrentThreadSysId(); - - void* addressArray[64]; - size_t addressCount = GetBacktraceFromThreadSysId(addressArray, OVR_ARRAY_COUNT(addressArray), skipCount, threadSysId); - - // Print the header - char headerBuffer[256]; - char threadName[32]; - char threadHandleStr[24]; - char threadSysIdStr[24]; - char stackBaseStr[24]; - char stackLimitStr[24]; - void* pStackBase; - void* pStackLimit; - //void* pStackCurrent; // Current stack pointer. To do: support reporting this. - ThreadHandle threadHandle = ConvertThreadSysIdToThreadHandle(threadSysId); - OVR::GetThreadStackBounds(pStackBase, pStackLimit, threadHandle); - - Thread::GetThreadName(threadName, OVR_ARRAY_COUNT(threadName), threadName); - SprintfThreadHandle(threadHandleStr, OVR_ARRAY_COUNT(threadHandleStr), threadHandle); - SprintfThreadSysId(threadSysIdStr, OVR_ARRAY_COUNT(threadSysIdStr), threadSysId); - SprintfAddress(stackBaseStr, OVR_ARRAY_COUNT(stackBaseStr), pStackBase); - SprintfAddress(stackLimitStr, OVR_ARRAY_COUNT(stackLimitStr), pStackLimit); - - if(threadName[0]) - OVR_snprintf(headerBuffer, OVR_ARRAY_COUNT(headerBuffer), "Thread \"%s\" handle: %s, id: %s, stack base: %s, stack limit: %s\r\n", threadName, threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr); - else - OVR_snprintf(headerBuffer, OVR_ARRAY_COUNT(headerBuffer), "Thread handle: %s, id: %s, stack base: %s, stack limit: %s\r\n", threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr); - - sOutput += headerBuffer; - - // Print the backtrace info - char backtraceBuffer[1024]; // Sometimes function symbol names are very long. - SymbolInfo symbolInfo; - const char* pModuleName; - - if(addressCount == 0) - { - sOutput += "\r\n"; - } - else - { - for(size_t i = 0; i < addressCount; ++i) - { - LookupSymbol((uint64_t)addressArray[i], symbolInfo); - - if(symbolInfo.pModuleInfo && symbolInfo.pModuleInfo->name[0]) - pModuleName = symbolInfo.pModuleInfo->name; - else - pModuleName = "(unknown module)"; - - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), addressArray[i]); - - if(symbolInfo.filePath[0]) - OVR_snprintf(backtraceBuffer, OVR_ARRAY_COUNT(backtraceBuffer), "%-2u %-24s %s %s+%d %s:%d\r\n", (unsigned)i, pModuleName, addressStr, symbolInfo.function, symbolInfo.functionOffset, symbolInfo.filePath, symbolInfo.fileLineNumber); - else - OVR_snprintf(backtraceBuffer, OVR_ARRAY_COUNT(backtraceBuffer), "%-2u %-24s %s %s+%d\r\n", (unsigned)i, pModuleName, addressStr, symbolInfo.function, symbolInfo.functionOffset); - - sOutput += backtraceBuffer; - } - } - - FreeThreadHandle(threadHandle); - - return (addressCount > 0); -} - - -// Writes all thread's callstacks with symbols to the given output. -// It may not be safe to call this from an exception handler, as sOutput allocates memory. -bool SymbolLookup::ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount) -{ - ThreadSysId threadSysIdArray[64]; - size_t threadSysIdCount = GetThreadList(nullptr, threadSysIdArray, OVR_ARRAY_COUNT(threadSysIdArray)); - - if(threadSysIdCount > OVR_ARRAY_COUNT(threadSysIdArray)) - threadSysIdCount = OVR_ARRAY_COUNT(threadSysIdArray); - - for(size_t i = 0; i < threadSysIdCount; i++) - { - String sTemp; - ReportThreadCallstack(sTemp, skipCount, threadSysIdArray[i]); - if(i > 0) - sOutput += "\r\n"; - sOutput += sTemp; - } - - return (threadSysIdCount > 0); -} - - -bool SymbolLookup::RefreshModuleList() -{ - if(!moduleListUpdated) - { - #if defined(OVR_OS_MS) - // We can't rely on SymRefreshModuleList because it's present in DbgHelp 6.5, - // which doesn't distribute with Windows 7. - - // Currently we support only refreshing the list once ever. With a little effort we could revise this code to - // support re-refreshing the list at runtime to account for the possibility that modules have recently been - // added or removed. - if(pSymLoadModule64) - { - const size_t requiredCount = GetModuleInfoArray(moduleInfoArray, OVR_ARRAY_COUNT(moduleInfoArray)); - moduleInfoArraySize = MIN(requiredCount, OVR_ARRAY_COUNT(moduleInfoArray)); - - HANDLE hProcess = GetCurrentProcess(); - - for(size_t i = 0; i < moduleInfoArraySize; i++) - pSymLoadModule64(hProcess, nullptr, moduleInfoArray[i].filePath, nullptr, moduleInfoArray[i].baseAddress, (DWORD)moduleInfoArray[i].size); - - moduleListUpdated = true; - } - #else - const size_t requiredCount = GetModuleInfoArray(moduleInfoArray, OVR_ARRAY_COUNT(moduleInfoArray)); - moduleInfoArraySize = MIN(requiredCount, OVR_ARRAY_COUNT(moduleInfoArray)); - moduleListUpdated = true; - #endif - } - - return true; -} - - -bool SymbolLookup::LookupSymbol(uint64_t address, SymbolInfo& symbolInfo) -{ - return LookupSymbols(&address, &symbolInfo, 1); -} - - -bool SymbolLookup::LookupSymbols(uint64_t* addressArray, SymbolInfo* pSymbolInfoArray, size_t arraySize) -{ - if(!moduleListUpdated) - { - RefreshModuleList(); - } - - #if defined(OVR_OS_MS) - union SYMBOL_INFO_UNION - { - SYMBOL_INFO msSymbolInfo; - char suffixPadding[sizeof(SYMBOL_INFO) + 1024]; - }; - - for(size_t i = 0; i < arraySize; i++) - { - uint64_t& address = addressArray[i]; - SymbolInfo& symbolInfo = pSymbolInfoArray[i]; - - // Copy the address and ModuleInfo - symbolInfo.address = addressArray[i]; - symbolInfo.pModuleInfo = GetModuleInfoForAddress(address); // We could also use siu.msSymbolInfo.ModBase to get the module slightly faster. - - // Get the function/offset. - SYMBOL_INFO_UNION siu; - memset(&siu, 0, sizeof(siu)); - siu.msSymbolInfo.SizeOfStruct = sizeof(siu.msSymbolInfo); - siu.msSymbolInfo.MaxNameLen = sizeof(siu.suffixPadding) - sizeof(SYMBOL_INFO) + 1; // +1 because SYMBOL_INFO itself has Name[1]. - - HANDLE hProcess = GetCurrentProcess(); - DWORD64 displacement64 = 0; - bool bResult = (pSymFromAddr != nullptr) && (pSymFromAddr(hProcess, address, &displacement64, &siu.msSymbolInfo) != FALSE); - - if(bResult) - { - symbolInfo.size = siu.msSymbolInfo.Size; - OVR_strlcpy(symbolInfo.function, siu.msSymbolInfo.Name, OVR_ARRAY_COUNT(symbolInfo.function)); - symbolInfo.functionOffset = (int32_t)displacement64; - } - else - { - symbolInfo.size = kMISizeInvalid; - symbolInfo.function[0] = 0; - symbolInfo.functionOffset = kMIFunctionOffsetInvalid; - } - - // Get the file/line - IMAGEHLP_LINE64 iLine64; - DWORD displacement = 0; - memset(&iLine64, 0, sizeof(iLine64)); - iLine64.SizeOfStruct = sizeof(iLine64); - - bResult = (pSymGetLineFromAddr64 != nullptr) && (pSymGetLineFromAddr64(hProcess, address, &displacement, &iLine64) != FALSE); - - if(bResult) - { - OVR_strlcpy(symbolInfo.filePath, iLine64.FileName, OVR_ARRAY_COUNT(symbolInfo.filePath)); - symbolInfo.fileLineNumber = (int32_t)iLine64.LineNumber; - } - else - { - symbolInfo.filePath[0] = 0; - symbolInfo.fileLineNumber = kMILineNumberInvalid; - } - - // To do: get the source code when possible. We need to use the user-registered directory paths and the symbolInfo.filePath - // and find the given file in the tree(s), then open the file and find the symbolInfo.fileLineNumber line (and surrounding lines). - // symbolInfo.sourceCode[1024] - symbolInfo.sourceCode[0] = '\0'; - } - - #elif defined(OVR_OS_APPLE) - // Apple has an internal CoreSymbolication library which could help with this. - // Third party implementations of the CoreSymbolication header are available and could be used - // to get file/line info better than other means. It used Objective C, so we'll need a .m or .mm file. - - memset(pSymbolInfoArray, 0, arraySize * sizeof(SymbolInfo)); - - for(size_t i = 0; i < arraySize; i++) - { - pSymbolInfoArray[i].address = addressArray[i]; - pSymbolInfoArray[i].pModuleInfo = GetModuleInfoForAddress(addressArray[i]); - } - - // Problem: backtrace_symbols allocates memory from malloc. If you got into a SIGSEGV due to - // malloc arena corruption (quite common) you will likely fault in backtrace_symbols. - // To do: Use allowMemoryAllocation here. - - #if (OVR_PTR_SIZE == 4) - // backtrace_symbols takes a void* array, but we have a uint64_t array. So for 32 bit we - // need to convert the 64 bit array to 32 bit temporarily for the backtrace_symbols call. - void* ptr32Array[256]; // To do: Remove this limit. - for(size_t i = 0, iEnd = MIN(arraySize, OVR_ARRAY_COUNT(ptr32Array)); i < iEnd; i++) - ptr32Array[i] = reinterpret_cast(addressArray[i]); - char** symbolArray = backtrace_symbols(reinterpret_cast(ptr32Array), (int)arraySize); - #else - char** symbolArray = backtrace_symbols(reinterpret_cast(addressArray), (int)arraySize); - #endif - - if(symbolArray) - { - for(size_t i = 0; i < arraySize; i++) - { - - // Generates a string like this: "0 OculusWorldDemo 0x000000010000cfd5 _ZN18OculusWorldDemoApp9OnStartupEiPPKc + 213" - static_assert(OVR_ARRAY_COUNT(pSymbolInfoArray[i].function) == 128, "Need to change the string format size below"); - - sscanf(symbolArray[i], "%*d %*s %*x %128s + %d", pSymbolInfoArray[i].function, &pSymbolInfoArray[i].functionOffset); - - if(allowMemoryAllocation) - { - int status = 0; - char* strDemangled = abi::__cxa_demangle(pSymbolInfoArray[i].function, nullptr, nullptr, &status); - - if(strDemangled) - { - OVR_strlcpy(pSymbolInfoArray[i].function, strDemangled, OVR_ARRAY_COUNT(pSymbolInfoArray[i].function)); - free(strDemangled); - } - } - } - - free(symbolArray); - } - - // To consider: use CoreSybolication to get file/line info instead. atos is a bit slow and cumbersome. - // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/atos.1.html - // atos -p ... - // atos -o -l ... - // Generates output like this: "OVR::CreateException(OVR::CreateExceptionType) (in OculusWorldDemo) (ExceptionHandler.cpp:598)" - for(size_t i = 0; i < arraySize; i++) - { - struct stat statStruct; - - if(pSymbolInfoArray[i].pModuleInfo && pSymbolInfoArray[i].pModuleInfo->filePath[0] && (stat(pSymbolInfoArray[i].pModuleInfo->filePath, &statStruct) == 0)) - { - char command[PATH_MAX * 2]; // Problem: We can't unilaterally use pSymbolInfoArray[0] for all addresses. We need to match addresses to the corresponding modules. - OVR_snprintf(command, OVR_ARRAY_COUNT(command), "atos -o %s -l 0x%llx 0x%llx", - pSymbolInfoArray[i].pModuleInfo->filePath, (int64_t)pSymbolInfoArray[i].pModuleInfo->baseAddress, (int64_t)pSymbolInfoArray[i].address); - - char output[512]; - if(SpawnShellCommand(command, output, OVR_ARRAY_COUNT(output)) != (size_t)-1) - { - char* pLastOpenParen = strrchr(output, '('); - char* pColon = strrchr(output, ':'); - - if(pLastOpenParen && (pColon > pLastOpenParen)) - { - *pColon = '\0'; - OVR_strlcpy(pSymbolInfoArray[i].filePath, pLastOpenParen + 1, OVR_ARRAY_COUNT(pSymbolInfoArray[i].filePath)); - } - } - } - } - - #elif defined(OVR_OS_LINUX) - // We can use libunwind's unw_get_proc_name to try to get function name info. It can work regardless of relocation. - // Use backtrace_symbols and addr2line. Need to watch out for module load-time relocation. - // Ned to pass the -rdynamic flag to the linker. It will cause the linker to out in the link - // tables the name of all the none static functions in your code, not just the exported ones. - OVR_UNUSED(addressArray); - OVR_UNUSED(pSymbolInfoArray); - OVR_UNUSED(arraySize); - #endif - - return true; // To do: Return true only if something was found. -} - - -const ModuleInfo* SymbolLookup::GetModuleInfoForAddress(uint64_t address) -{ - // This is a linear seach. To consider: it would be significantly faster to search by - // address if we ordered it by base address and did a binary search. - for(size_t i = 0; i < moduleInfoArraySize; ++i) - { - const ModuleInfo& mi = moduleInfoArray[i]; - - if((mi.baseAddress <= address) && (address < (mi.baseAddress + mi.size))) - return &mi; - } - - return nullptr; -} - - - - -ExceptionInfo::ExceptionInfo() - : time() - , timeVal(0) - , backtrace() - , backtraceCount(0) - , threadHandle(OVR_THREADHANDLE_INVALID) - , threadSysId(OVR_THREADSYSID_INVALID) - , threadName() - , pExceptionInstructionAddress(nullptr) - , pExceptionMemoryAddress(nullptr) - , cpuContext() - , exceptionDescription() - , symbolInfo() - #if defined(OVR_OS_MS) - , exceptionRecord() - #elif defined(OVR_OS_APPLE) - , exceptionType(0) - , cpuExceptionId(0) - , cpuExceptionIdError(0) - , machExceptionDetail() - , machExceptionDetailCount(0) - #endif -{ -} - - - -ExceptionHandler::ExceptionHandler() - : enabled(false) - , reportPrivacyEnabled(true) - , exceptionResponse(kERHandle) - , exceptionListener(nullptr) - , exceptionListenerUserValue(0) - , appDescription() - , codeBasePathArray() - , reportFilePath() - , miniDumpFlags(0) - , miniDumpFilePath() - , file(nullptr) - , scratchBuffer() - , exceptionOccurred(false) - , handlingBusy(0) - , reportFilePathActual() - , minidumpFilePathActual() - , terminateReturnValue(0) - , exceptionInfo() - #if defined(OVR_OS_MS) - , vectoredHandle(nullptr) - , previousFilter(nullptr) - , pExceptionPointers(nullptr) - #elif defined(OVR_OS_MAC) - , machHandlerInitialized(false) - , machExceptionPort(0) - , machExceptionPortsSaved() - , machThreadShouldContinue(false) - , machThreadExecuting(false) - , machThread((pthread_t)OVR_THREADHANDLE_INVALID) - #endif -{ - SetExceptionPaths("default", "default"); -} - - -ExceptionHandler::~ExceptionHandler() -{ - if(enabled) - { - Enable(false); - } -} - - -#if defined(OVR_OS_MS) - static ExceptionHandler* sExceptionHandler = nullptr; - - LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers) - { - if(sExceptionHandler) - return (LONG)sExceptionHandler->ExceptionFilter(pExceptionPointers); - return EXCEPTION_CONTINUE_SEARCH; - } - - LONG ExceptionHandler::ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers) - { - // Exception codes < 0x80000000 are not true exceptions but rather are debugger notifications. They include DBG_TERMINATE_THREAD, - // DBG_TERMINATE_PROCESS, DBG_CONTROL_BREAK, DBG_COMMAND_EXCEPTION, DBG_CONTROL_C, DBG_PRINTEXCEPTION_C, DBG_RIPEXCEPTION, - // and 0x406d1388 (thread named, http://blogs.msdn.com/b/stevejs/archive/2005/12/19/505815.aspx). - - if(pExceptionPointers->ExceptionRecord->ExceptionCode < 0x80000000) - return EXCEPTION_CONTINUE_SEARCH; - - // VC++ C++ exceptions use code 0xe06d7363 ('Emsc') - // http://support.microsoft.com/kb/185294 - // http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx - if(pExceptionPointers->ExceptionRecord->ExceptionCode == 0xe06d7363) - return EXCEPTION_CONTINUE_SEARCH; - - if(handlingBusy.CompareAndSet_Acquire(0, 1)) // If we can successfully change it from 0 to 1. - { - exceptionOccurred = true; - - this->pExceptionPointers = pExceptionPointers; - - // Disable the handler while we do this processing. - ULONG result = RemoveVectoredExceptionHandler(vectoredHandle); - OVR_ASSERT_AND_UNUSED(result != 0, result); - - // Time - exceptionInfo.timeVal = time(nullptr); - exceptionInfo.time = *gmtime(&exceptionInfo.timeVal); - - // Thread id - // This is the thread id of the current thread and not the exception thread. - if(!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &exceptionInfo.threadHandle, 0, true, DUPLICATE_SAME_ACCESS)) - exceptionInfo.threadHandle = 0; - exceptionInfo.threadSysId = ConvertThreadHandleToThreadSysId(exceptionInfo.threadHandle); - - OVR::GetThreadName(exceptionInfo.threadHandle, exceptionInfo.threadName, OVR_ARRAY_COUNT(exceptionInfo.threadName)); - - // Backtraces - exceptionInfo.backtraceCount = symbolLookup.GetBacktrace(exceptionInfo.backtrace, OVR_ARRAY_COUNT(exceptionInfo.backtrace)); - - // Context - exceptionInfo.cpuContext = *pExceptionPointers->ContextRecord; - exceptionInfo.exceptionRecord = *pExceptionPointers->ExceptionRecord; - exceptionInfo.pExceptionInstructionAddress = exceptionInfo.exceptionRecord.ExceptionAddress; - if((exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) || (exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_IN_PAGE_ERROR)) - exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.exceptionRecord.ExceptionInformation[1]; // ExceptionInformation[0] indicates if it was a read (0), write (1), or data execution attempt (8). - else - exceptionInfo.pExceptionMemoryAddress = pExceptionPointers->ExceptionRecord->ExceptionAddress; - - WriteExceptionDescription(); - - if(miniDumpFilePath[0]) - WriteMiniDump(); - - if(reportFilePath[0]) - WriteReport(); - - if(exceptionListener) - exceptionListener->HandleException(exceptionListenerUserValue, this, &exceptionInfo, reportFilePathActual); - - if(exceptionInfo.threadHandle) - { - CloseHandle(exceptionInfo.threadHandle); - exceptionInfo.threadHandle = 0; - } - - // Restore the handler that we temporarily disabled above. - vectoredHandle = AddVectoredExceptionHandler(1, Win32ExceptionFilter); - - handlingBusy.Store_Release(0); - } - - if(exceptionResponse == ExceptionHandler::kERTerminate) - { - TerminateProcess(GetCurrentProcess(), (UINT)terminateReturnValue); - return terminateReturnValue; - } - else if(exceptionResponse == ExceptionHandler::kERThrow) - return EXCEPTION_CONTINUE_SEARCH; - else if(exceptionResponse == ExceptionHandler::kERContinue) - return EXCEPTION_CONTINUE_EXECUTION; - return EXCEPTION_EXECUTE_HANDLER; - } - -#endif // defined(OVR_OS_MS) - - -#if defined(OVR_OS_APPLE) - // http://www.opensource.apple.com/source/xnu/xnu-2050.22.13/ - // http://www.opensource.apple.com/source/xnu/xnu-2050.22.13/osfmk/man/ - // http://www.opensource.apple.com/source/Libc/Libc-825.26/ - // https://mikeash.com/pyblog/friday-qa-2013-01-11-mach-exception-handlers.html - - void* ExceptionHandler::MachHandlerThreadFunction() - { - __Request__mach_exception_raise_state_identity_t msg; - __Reply__mach_exception_raise_state_identity_t reply; - mach_msg_return_t result; - - machThreadExecuting = true; - pthread_setname_np("ExceptionHandler"); - - while(machThreadShouldContinue) - { - mach_msg_option_t options = MACH_RCV_MSG | MACH_RCV_LARGE; - natural_t timeout = 0; // Would be better to support a non-zero time. - - if(timeout) - options |= MACH_RCV_TIMEOUT; - - result = mach_msg(&msg.Head, options, 0, sizeof(msg), machExceptionPort, timeout, MACH_PORT_NULL); - - if(msg.Head.msgh_id != sMachCancelMessageType) - { - if(result == MACH_MSG_SUCCESS) - { - if(mach_exc_server_OVR(&msg.Head, &reply.Head) == 0) //This will call our HandleMachException function. - result = ~MACH_MSG_SUCCESS; - } - - // Send the reply - if(result == MACH_MSG_SUCCESS) - { - result = mach_msg(&reply.Head, MACH_SEND_MSG, reply.Head.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - if(result != MACH_MSG_SUCCESS) - { - // Failure. - } - } - } - } - - machThreadExecuting = false; - - return nullptr; - } - - - kern_return_t ExceptionHandler::HandleMachException(mach_port_t /*machPort*/, mach_port_t threadSysId, mach_port_t machTask, - exception_type_t machExceptionType, mach_exception_data_type_t* pExceptionDetail, - mach_msg_type_number_t exceptionDetailCount, int* /*pMachExceptionFlavor*/, thread_state_t threadStatePrev, - mach_msg_type_number_t /*threadStatePrevCount*/, thread_state_t /*threadStateNew*/, - mach_msg_type_number_t* /*pThreadStateNewCount*/) - { - // We don't want to handle exceptions for other processes. - if(machTask != mach_task_self()) - return ForwardMachException(threadSysId, machTask, machExceptionType, pExceptionDetail, exceptionDetailCount); - - if(handlingBusy.CompareAndSet_Acquire(0, 1)) // If we can successfully change it from 0 to 1. - { - exceptionOccurred = true; - - // Disable the handler while we do this processing. - // To do. - - // Time - exceptionInfo.timeVal = time(nullptr); - exceptionInfo.time = *gmtime(&exceptionInfo.timeVal); - - // Thread id - exceptionInfo.threadHandle = pthread_from_mach_thread_np(threadSysId); - exceptionInfo.threadSysId = threadSysId; - pthread_getname_np((pthread_t)exceptionInfo.threadHandle, exceptionInfo.threadName, sizeof(exceptionInfo.threadName)); - - // Backtraces - exceptionInfo.backtraceCount = symbolLookup.GetBacktraceFromThreadSysId(exceptionInfo.backtrace, OVR_ARRAY_COUNT(exceptionInfo.backtrace), 0, threadSysId); - - // Context - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - // We can read x86_THREAD_STATE directly fromk threadStatePrev. - exceptionInfo.cpuContext.threadState = *reinterpret_cast(threadStatePrev); - - mach_msg_type_number_t stateCount = x86_FLOAT_STATE_COUNT; - thread_get_state(threadSysId, x86_FLOAT_STATE, (natural_t*)&exceptionInfo.cpuContext.floatState, &stateCount); - - stateCount = x86_DEBUG_STATE_COUNT; - thread_get_state(threadSysId, x86_DEBUG_STATE, (natural_t*)&exceptionInfo.cpuContext.debugState, &stateCount); - - stateCount = x86_AVX_STATE_COUNT; - thread_get_state(threadSysId, x86_AVX_STATE, (natural_t*)&exceptionInfo.cpuContext.avxState, &stateCount); - - stateCount = x86_EXCEPTION_STATE_COUNT; - thread_get_state(threadSysId, x86_EXCEPTION_STATE, (natural_t*)&exceptionInfo.cpuContext.exceptionState, &stateCount); - - #if defined(OVR_CPU_X86) - exceptionInfo.pExceptionInstructionAddress = (void*)exceptionInfo.cpuContext.threadState.uts.ts32.__eip; - exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.cpuContext.exceptionState.ues.es32.__faultvaddr; - exceptionInfo.cpuExceptionId = exceptionInfo.cpuContext.exceptionState.ues.es32.__trapno; - exceptionInfo.cpuExceptionIdError = exceptionInfo.cpuContext.exceptionState.ues.es32.__err; - #else - exceptionInfo.pExceptionInstructionAddress = (void*)exceptionInfo.cpuContext.threadState.uts.ts64.__rip; - exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.cpuContext.exceptionState.ues.es64.__faultvaddr; - exceptionInfo.cpuExceptionId = exceptionInfo.cpuContext.exceptionState.ues.es64.__trapno; - exceptionInfo.cpuExceptionIdError = exceptionInfo.cpuContext.exceptionState.ues.es64.__err; - #endif - #endif - - exceptionInfo.exceptionType = machExceptionType; - - exceptionInfo.machExceptionDetailCount = MIN(exceptionDetailCount, OVR_ARRAY_COUNT(exceptionInfo.machExceptionDetail)); - for(int i = 0; i < exceptionInfo.machExceptionDetailCount; i++) - exceptionInfo.machExceptionDetail[i] = pExceptionDetail[i]; - - WriteExceptionDescription(); - - if(reportFilePath[0]) - WriteReport(); - - if(miniDumpFilePath[0]) - WriteMiniDump(); - - if(exceptionListener) - exceptionListener->HandleException(exceptionListenerUserValue, this, &exceptionInfo, reportFilePathActual); - - // Re-restore the handler. - // To do. - - handlingBusy.Store_Release(0); - } - - kern_return_t result = KERN_FAILURE; // By default pass on the exception to another handler after we are done here. - - if(exceptionResponse == ExceptionHandler::kERTerminate) - ::exit(terminateReturnValue); - else if(exceptionResponse == ExceptionHandler::kERThrow) - ForwardMachException(threadSysId, machTask, machExceptionType, pExceptionDetail, exceptionDetailCount); - else if(exceptionResponse == ExceptionHandler::kERDefault) - ::exit(terminateReturnValue); - else if(exceptionResponse == ExceptionHandler::kERContinue) - result = KERN_SUCCESS; // This will trigger a re-execution of the function. - - return result; - } - - - bool ExceptionHandler::InitMachExceptionHandler() - { - if(!machHandlerInitialized) - { - mach_port_t machTaskSelf = mach_task_self(); - kern_return_t result = MACH_MSG_SUCCESS; - exception_mask_t mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_CRASH; - - if(machExceptionPort == MACH_PORT_NULL) - { - result = mach_port_allocate(machTaskSelf, MACH_PORT_RIGHT_RECEIVE, &machExceptionPort); - - if(result == MACH_MSG_SUCCESS) - { - result = mach_port_insert_right(machTaskSelf, machExceptionPort, machExceptionPort, MACH_MSG_TYPE_MAKE_SEND); - - if(result == MACH_MSG_SUCCESS) - result = task_get_exception_ports(machTaskSelf, mask, machExceptionPortsSaved.masks, &machExceptionPortsSaved.count, - machExceptionPortsSaved.ports, machExceptionPortsSaved.behaviors, machExceptionPortsSaved.flavors); - } - } - - if(result == MACH_MSG_SUCCESS) - { - result = task_set_exception_ports(machTaskSelf, mask, machExceptionPort, EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, MACHINE_THREAD_STATE); - - if(result == MACH_MSG_SUCCESS) - { - machThreadShouldContinue = true; - - pthread_attr_t attr; - pthread_attr_init(&attr); - - result = pthread_create(&machThread, &attr, MachHandlerThreadFunctionStatic, (void*)this); - pthread_attr_destroy(&attr); - - machHandlerInitialized = (result == 0); - } - } - - if(!machHandlerInitialized) - ShutdownMachExceptionHandler(); - } - - return machHandlerInitialized; - } - - - void ExceptionHandler::ShutdownMachExceptionHandler() - { - if(machThreadExecuting) - { - machThreadShouldContinue = false; // Tell it to stop. - - // Cancel the current exception handler thread (which is probably blocking in a call to mach_msg) by sending it a cencel message. - struct CancelMessage - { - mach_msg_header_t msgHeader; - }; - - CancelMessage msg; - memset(&msg.msgHeader, 0, sizeof(CancelMessage)); - msg.msgHeader.msgh_id = sMachCancelMessageType; - msg.msgHeader.msgh_size = sizeof(CancelMessage); - msg.msgHeader.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MAKE_SEND); - msg.msgHeader.msgh_remote_port = machExceptionPort; - msg.msgHeader.msgh_local_port = MACH_PORT_NULL; - - mach_msg_return_t result = mach_msg(&msg.msgHeader, MACH_SEND_MSG, msg.msgHeader.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - - if(result == MACH_MSG_SUCCESS) - { - const double threeSecondsLater = ovr_GetTimeInSeconds() + 3.f; - - while(machThreadExecuting && (ovr_GetTimeInSeconds() < threeSecondsLater)) - { - timespec ts = { 0, 1000000000 }; - nanosleep(&ts, nullptr); - } - } - - void* joinResult = nullptr; - pthread_join(machThread, &joinResult); - machThread = 0; - } - - if(machExceptionPort != MACH_PORT_NULL) - { - // Restore the previous ports - kern_return_t result = KERN_SUCCESS; - mach_port_t machTaskSelf = mach_task_self(); - - for(unsigned i = 0; (i < machExceptionPortsSaved.count) && (result == KERN_SUCCESS); i++) - { - result = task_set_exception_ports(machTaskSelf, machExceptionPortsSaved.masks[i], machExceptionPortsSaved.ports[i], - machExceptionPortsSaved.behaviors[i], machExceptionPortsSaved.flavors[i]); - } - - mach_port_deallocate(machTaskSelf, machExceptionPort); - machExceptionPort = MACH_PORT_NULL; - } - - machHandlerInitialized = false; - } - - - kern_return_t ExceptionHandler::ForwardMachException(mach_port_t thread, mach_port_t task, exception_type_t exceptionType, - mach_exception_data_t pExceptionDetail, mach_msg_type_number_t exceptionDetailCount) - { - kern_return_t result = KERN_FAILURE; - mach_msg_type_number_t i; - - for(i = 0; i < machExceptionPortsSaved.count; i++) - { - if(machExceptionPortsSaved.masks[i] & (1 << exceptionType)) - break; - } - - if(i < machExceptionPortsSaved.count) - { - mach_port_t port = machExceptionPortsSaved.ports[i]; - exception_behavior_t behavior = machExceptionPortsSaved.behaviors[i]; - thread_state_flavor_t flavor = machExceptionPortsSaved.flavors[i]; - mach_msg_type_number_t threadStateCount = THREAD_STATE_MAX; - thread_state_data_t threadState; - - if(behavior != EXCEPTION_DEFAULT) - thread_get_state(thread, flavor, threadState, &threadStateCount); - - switch(behavior) - { - case EXCEPTION_DEFAULT: - result = mach_exception_raise_OVR(port, thread, task, exceptionType, pExceptionDetail, exceptionDetailCount); - break; - - case EXCEPTION_STATE: - result = mach_exception_raise_state_OVR(port, exceptionType, pExceptionDetail, exceptionDetailCount, - &flavor, threadState, threadStateCount, threadState, &threadStateCount); - break; - - case EXCEPTION_STATE_IDENTITY: - result = mach_exception_raise_state_identity_OVR(port, thread, task, exceptionType, pExceptionDetail, - exceptionDetailCount, &flavor, threadState, threadStateCount, threadState, &threadStateCount); - break; - - default: - result = KERN_FAILURE; - break; - } - - if(behavior != EXCEPTION_DEFAULT) - result = thread_set_state(thread, flavor, threadState, threadStateCount); - } - - return result; - } - - -#endif // OVR_OS_APPLE - - -bool ExceptionHandler::Enable(bool enable) -{ - #if defined(OVR_OS_MS) - if(enable && !enabled) - { - OVR_ASSERT(vectoredHandle == nullptr); - vectoredHandle = AddVectoredExceptionHandler(1, Win32ExceptionFilter); // Windows call. - enabled = (vectoredHandle != nullptr); - OVR_ASSERT(enabled); - sExceptionHandler = this; - return enabled; - } - else if(!enable && enabled) - { - if(sExceptionHandler == this) - sExceptionHandler = nullptr; - OVR_ASSERT(vectoredHandle != nullptr); - ULONG result = RemoveVectoredExceptionHandler(vectoredHandle); // Windows call. - OVR_ASSERT_AND_UNUSED(result != 0, result); - vectoredHandle = nullptr; - enabled = false; - return true; - } - - #elif defined(OVR_OS_APPLE) - - if(enable && !enabled) - { - enabled = InitMachExceptionHandler(); - OVR_ASSERT(enabled); - sExceptionHandler = this; - return enabled; - } - else if(!enable && enabled) - { - if(sExceptionHandler == this) - sExceptionHandler = nullptr; - ShutdownMachExceptionHandler(); - enabled = false; - return true; - } - #else - OVR_UNUSED(enable); - #endif - - return true; -} - - -void ExceptionHandler::EnableReportPrivacy(bool enable) -{ - reportPrivacyEnabled = enable; -} - -void ExceptionHandler::WriteExceptionDescription() -{ - #if defined(OVR_OS_MS) - // There is some extra information available for AV exception. - if(exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) - { - const char* error = (exceptionInfo.exceptionRecord.ExceptionInformation[0] == 0) ? "reading" : - ((exceptionInfo.exceptionRecord.ExceptionInformation[0] == 1) ? "writing" : "executing"); - - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionMemoryAddress); - OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), "ACCESS_VIOLATION %s address %s", error, addressStr); - } - else - { - exceptionInfo.exceptionDescription[0] = 0; - - // Process "standard" exceptions, other than 'access violation' - #define FORMAT_EXCEPTION(x) \ - case EXCEPTION_##x: \ - OVR::OVR_strlcpy(exceptionInfo.exceptionDescription, #x, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); \ - break; - - switch(exceptionInfo.exceptionRecord.ExceptionCode) - { - //FORMAT_EXCEPTION(ACCESS_VIOLATION) Already handled above. - FORMAT_EXCEPTION(DATATYPE_MISALIGNMENT) - FORMAT_EXCEPTION(BREAKPOINT) - FORMAT_EXCEPTION(SINGLE_STEP) - FORMAT_EXCEPTION(ARRAY_BOUNDS_EXCEEDED) - FORMAT_EXCEPTION(FLT_DENORMAL_OPERAND) - FORMAT_EXCEPTION(FLT_DIVIDE_BY_ZERO) - FORMAT_EXCEPTION(FLT_INEXACT_RESULT) - FORMAT_EXCEPTION(FLT_INVALID_OPERATION) - FORMAT_EXCEPTION(FLT_OVERFLOW) - FORMAT_EXCEPTION(FLT_STACK_CHECK) - FORMAT_EXCEPTION(FLT_UNDERFLOW) - FORMAT_EXCEPTION(INT_DIVIDE_BY_ZERO) - FORMAT_EXCEPTION(INT_OVERFLOW) - FORMAT_EXCEPTION(PRIV_INSTRUCTION) - FORMAT_EXCEPTION(IN_PAGE_ERROR) - FORMAT_EXCEPTION(ILLEGAL_INSTRUCTION) - FORMAT_EXCEPTION(NONCONTINUABLE_EXCEPTION) - FORMAT_EXCEPTION(STACK_OVERFLOW) - FORMAT_EXCEPTION(INVALID_DISPOSITION) - FORMAT_EXCEPTION(GUARD_PAGE) - FORMAT_EXCEPTION(INVALID_HANDLE) - #if defined(EXCEPTION_POSSIBLE_DEADLOCK) && defined(STATUS_POSSIBLE_DEADLOCK) // This type seems to be non-existant in practice. - FORMAT_EXCEPTION(POSSIBLE_DEADLOCK) - #endif - } - - // If not one of the "known" exceptions, try to get the string from NTDLL.DLL's message table. - if(exceptionInfo.exceptionDescription[0] == 0) - { - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionMemoryAddress); - - #if !defined(OVR_OS_CONSOLE) // If FormatMessage is supported... - char buffer[384]; - DWORD capacity = OVR_ARRAY_COUNT(buffer); - - const size_t length = (size_t)FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, - GetModuleHandleW(L"NTDLL.DLL"), exceptionInfo.exceptionRecord.ExceptionCode, 0, buffer, capacity, nullptr); - if(length) - OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), - "%s at instruction %s", buffer, addressStr); - #endif - - // If everything else failed just show the hex code. - if(exceptionInfo.exceptionDescription[0] == 0) - OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), - "Unknown exception 0x%08x at instruction %s", exceptionInfo.exceptionRecord.ExceptionCode, addressStr); - } - } - - #elif defined(OVR_OS_APPLE) - struct MachExceptionInfo - { - static const char* GetCPUExceptionIdString(uint32_t cpuExceptionId) - { - const char* id; - - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - switch (cpuExceptionId) - { - case 0: id = "integer div/0"; break; - case 1: id = "breakpoint fault"; break; - case 2: id = "non-maskable interrupt"; break; - case 3: id = "int 3"; break; - case 4: id = "overflow"; break; - case 5: id = "bounds check failure"; break; - case 6: id = "invalid instruction"; break; - case 7: id = "coprocessor unavailable"; break; - case 8: id = "exception within exception"; break; - case 9: id = "coprocessor segment overrun"; break; - case 10: id = "invalid task switch"; break; - case 11: id = "segment not present"; break; - case 12: id = "stack exception"; break; - case 13: id = "general protection fault"; break; - case 14: id = "page fault"; break; - case 16: id = "coprocessor error"; break; - default: id = ""; break; - } - #else - // To do: Support ARM or others. - #endif - - return id; - } - - static const char* GetMachExceptionTypeString(uint64_t exceptionCause) - { - switch (exceptionCause) - { - case EXC_ARITHMETIC: return "EXC_ARITHMETIC"; - case EXC_BAD_ACCESS: return "EXC_BAD_ACCESS"; - case EXC_BAD_INSTRUCTION: return "EXC_BAD_INSTRUCTION"; - case EXC_BREAKPOINT: return "EXC_BREAKPOINT"; - case EXC_CRASH: return "EXC_CRASH"; - case EXC_EMULATION: return "EXC_EMULATION"; - case EXC_MACH_SYSCALL: return "EXC_MACH_SYSCALL"; - case EXC_RPC_ALERT: return "EXC_RPC_ALERT"; - case EXC_SOFTWARE: return "EXC_SOFTWARE"; - case EXC_SYSCALL: return "EXC_SYSCALL"; - }; - - return "EXC_"; - } - - static const char* GetMachExceptionIdString(uint64_t machExceptionId, uint64_t code0) - { - const char* id = ""; - - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - switch (machExceptionId) - { - case EXC_ARITHMETIC: - switch (code0) - { - case EXC_I386_BOUND: id = "EXC_I386_BOUND"; break; - case EXC_I386_DIV: id = "EXC_I386_DIV"; break; - case EXC_I386_EMERR: id = "EXC_I386_EMERR"; break; - case EXC_I386_EXTERR: id = "EXC_I386_EXTERR"; break; - case EXC_I386_EXTOVR: id = "EXC_I386_EXTOVR"; break; - case EXC_I386_INTO: id = "EXC_I386_INTO"; break; - case EXC_I386_NOEXT: id = "EXC_I386_NOEXT"; break; - case EXC_I386_SSEEXTERR: id = "EXC_I386_SSEEXTERR"; break; - } - break; - - case EXC_BAD_INSTRUCTION: - if(code0 == EXC_I386_INVOP) - id = "EXC_I386_INVOP"; - break; - - case EXC_BREAKPOINT: - if(code0 == EXC_I386_BPT) - id = "EXC_I386_BPT"; - else if(code0 == EXC_I386_SGL) - id = "EXC_I386_SGL"; - break; - }; - #else - // To do. - #endif - - return id; - } - }; - - OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), - "Mach exception type: %llu (%s)\r\n", exceptionInfo.exceptionType, MachExceptionInfo::GetMachExceptionTypeString(exceptionInfo.exceptionType)); - - OVR::OVR_snprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), "CPU exception info: exception id: %u (%s), exception id error: %u, fault memory address: %p\r\n", - exceptionInfo.cpuExceptionId, MachExceptionInfo::GetCPUExceptionIdString(exceptionInfo.cpuExceptionId), exceptionInfo.cpuExceptionIdError, exceptionInfo.pExceptionMemoryAddress); - OVR::OVR_strlcat(exceptionInfo.exceptionDescription, scratchBuffer, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); - - - OVR::OVR_snprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), "Mach exception info: exception id: %llu (%s), 0x%llx (%llu)\r\n", (uint64_t)exceptionInfo.machExceptionDetail[0], - MachExceptionInfo::GetMachExceptionIdString(exceptionInfo.exceptionType, exceptionInfo.machExceptionDetail[0]), - (uint64_t)exceptionInfo.machExceptionDetail[1], (uint64_t)exceptionInfo.machExceptionDetail[1]); - OVR::OVR_strlcat(exceptionInfo.exceptionDescription, scratchBuffer, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); - #else - // To do. - exceptionInfo.exceptionDescription[0] = 0; - #endif -} - - -void ExceptionHandler::WriteReportLine(const char* pLine) -{ - fwrite(pLine, strlen(pLine), 1, file); -} - - -void ExceptionHandler::WriteReportLineF(const char* format, ...) -{ - va_list args; - va_start(args, format); - int length = OVR_vsnprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), format, args); - if(length >= (int)OVR_ARRAY_COUNT(scratchBuffer)) // If we didn't have enough space... - length = (OVR_ARRAY_COUNT(scratchBuffer) - 1); // ... use what we have. - va_end(args); - - fwrite(scratchBuffer, length, 1, file); -} - - -// Thread -// 0
: -// 1
: -// . . . -// -void ExceptionHandler::WriteThreadCallstack(ThreadHandle threadHandle, ThreadSysId threadSysId, const char* additionalInfo) -{ - // We intentionally do not directly use the SymbolInfo::ReportThreadCallstack function because that function allocates memory, - // which we cannot do due to possibly being within an exception handler. - - // Print the header - char threadName[32]; - char threadHandleStr[32]; - char threadSysIdStr[32]; - char stackBaseStr[24]; - char stackLimitStr[24]; - char stackCurrentStr[24]; - void* pStackBase; - void* pStackLimit; - bool isExceptionThread = (threadSysId == exceptionInfo.threadSysId); - - #if defined(OVR_OS_MS) && (OVR_PTR_SIZE == 8) - void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.Rsp : nullptr; // We would need to suspend the thread, get its context, resume it, then read the rsp register. It turns out we are already doing that suspend/resume below in the backtrace call. - #elif defined(OVR_OS_MS) - void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.Esp : nullptr; - #elif defined(OVR_OS_MAC) && (OVR_PTR_SIZE == 8) - void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.threadState.uts.ts64.__rsp : nullptr; - #elif defined(OVR_OS_MAC) - void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.threadState.uts.ts32.__esp : nullptr; - #elif defined(OVR_OS_LINUX) - void* pStackCurrent = nullptr; // To do. - #endif - - OVR::GetThreadStackBounds(pStackBase, pStackLimit, threadHandle); - - OVR::Thread::GetThreadName(threadName, OVR_ARRAY_COUNT(threadName), threadName); - SprintfThreadHandle(threadHandleStr, OVR_ARRAY_COUNT(threadHandleStr), threadHandle); - SprintfThreadSysId(threadSysIdStr, OVR_ARRAY_COUNT(threadSysIdStr), threadSysId); - SprintfAddress(stackBaseStr, OVR_ARRAY_COUNT(stackBaseStr), pStackBase); - SprintfAddress(stackLimitStr, OVR_ARRAY_COUNT(stackLimitStr), pStackLimit); - SprintfAddress(stackCurrentStr, OVR_ARRAY_COUNT(stackCurrentStr), pStackCurrent); - - if(threadName[0]) - WriteReportLineF("Thread \"%s\" handle: %s, id: %s, stack base: %s, stack limit: %s, stack current: %s, %s\r\n", threadName, threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr, stackCurrentStr, additionalInfo ? additionalInfo : ""); - else - WriteReportLineF("Thread handle: %s, id: %s, stack base: %s, stack limit: %s, stack current: %s, %s\r\n", threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr, stackCurrentStr, additionalInfo ? additionalInfo : ""); - - // Print the backtrace info - void* addressArray[64]; - size_t addressCount = symbolLookup.GetBacktraceFromThreadSysId(addressArray, OVR_ARRAY_COUNT(addressArray), 0, threadSysId); - SymbolInfo symbolInfo; - const char* pModuleName; - size_t backtraceSkipCount = 0; - - if(isExceptionThread) - { - // If this thread is the exception thread, skip some frames. - #if defined(OVR_OS_MS) - size_t i, iEnd = MIN(16, addressCount); - - for(i = 0; i < iEnd; i++) - { - symbolLookup.LookupSymbol((uint64_t)addressArray[i], symbolInfo); - if(strstr(symbolInfo.function, "UserExceptionDispatcher") != nullptr) - break; - } - - if(i < iEnd) // If found... - backtraceSkipCount = i; - else if(addressCount >= 9) // Else default to 9, which is coincidentally what works. - backtraceSkipCount = 9; - else - backtraceSkipCount = 0; - - addressArray[backtraceSkipCount] = exceptionInfo.pExceptionInstructionAddress; - #endif - } - - if(addressCount == 0) - { - WriteReportLine("\r\n\r\n"); - } - else - { - for(size_t i = backtraceSkipCount; i < addressCount; ++i) - { - symbolLookup.LookupSymbol((uint64_t)addressArray[i], symbolInfo); - - if(symbolInfo.pModuleInfo && symbolInfo.pModuleInfo->name[0]) - pModuleName = symbolInfo.pModuleInfo->name; - else - pModuleName = "(unknown module)"; - - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), addressArray[i]); - - if(symbolInfo.filePath[0]) - WriteReportLineF("%-2u %-24s %s %s+%d %s:%d\r\n%s", (unsigned)i, pModuleName, addressStr, - symbolInfo.function, symbolInfo.functionOffset, symbolInfo.filePath, - symbolInfo.fileLineNumber, (i + 1) == addressCount ? "\r\n" : ""); - else - WriteReportLineF("%-2u %-24s %s %s+%d\r\n%s", (unsigned)i, pModuleName, addressStr, - symbolInfo.function, symbolInfo.functionOffset, (i + 1) == addressCount ? "\r\n" : ""); // If this is the last line, append another \r\n. - } - } -} - - -void ExceptionHandler::WriteReport() -{ - // It's important that we don't allocate any memory here if we can help it. - using namespace OVR; - - if(strstr(reportFilePath, "%s")) // If the user-specified file path includes a date/time component... - { - char dateTimeBuffer[64]; - FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, true); - OVR_snprintf(reportFilePathActual, OVR_ARRAY_COUNT(reportFilePathActual), reportFilePath, dateTimeBuffer); - } - else - { - OVR_strlcpy(reportFilePathActual, reportFilePath, OVR_ARRAY_COUNT(reportFilePathActual)); - } - - file = fopen(reportFilePathActual, "w"); - OVR_ASSERT(file != nullptr); - if(!file) - return; - - symbolLookup.Initialize(); - - { - // Exception information - WriteReportLine("Exception Info\r\n"); - - WriteReportLineF("Exception report file: %s\r\n", reportFilePathActual); - - #if defined(OVR_OS_MS) - if(miniDumpFilePath[0]) - WriteReportLineF("Exception minidump file: %s\r\n", minidumpFilePathActual); - #endif - - char dateTimeBuffer[64]; - FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, false); - WriteReportLineF("Time (GMT): %s\r\n", dateTimeBuffer); - - FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.timeVal, true, true, true, false); - WriteReportLineF("Time (local): %s\r\n", dateTimeBuffer); - WriteReportLineF("Thread name: %s\r\n", exceptionInfo.threadName[0] ? exceptionInfo.threadName : "(not available)"); // It's never possible on Windows to get thread names, as they are stored in the debugger at runtime. - - SprintfThreadHandle(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.threadHandle); - OVR_strlcat(scratchBuffer, "\r\n", OVR_ARRAY_COUNT(scratchBuffer)); - WriteReportLine("Thread handle: "); - WriteReportLine(scratchBuffer); - - SprintfThreadSysId(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.threadSysId); - OVR_strlcat(scratchBuffer, "\r\n", OVR_ARRAY_COUNT(scratchBuffer)); - WriteReportLine("Thread sys id: "); - WriteReportLine(scratchBuffer); - - char addressStr[24]; - SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionInstructionAddress); - WriteReportLineF("Exception instruction address: %s (see callstack below)\r\n", addressStr); - WriteReportLineF("Exception description: %s\r\n", exceptionInfo.exceptionDescription); - - if(symbolLookup.LookupSymbol((uint64_t)exceptionInfo.pExceptionInstructionAddress, exceptionInfo.symbolInfo)) - { - if(exceptionInfo.symbolInfo.filePath[0]) - WriteReportLineF("Exception location: %s (%d)\r\n", exceptionInfo.symbolInfo.filePath, exceptionInfo.symbolInfo.fileLineNumber); - else - WriteReportLineF("Exception location: %s (%d)\r\n", exceptionInfo.symbolInfo.function, exceptionInfo.symbolInfo.functionOffset); - } - - // To consider: print exceptionInfo.cpuContext registers - } - - // OVR information - WriteReportLine("\r\nOVR Info\r\n"); - WriteReportLineF("OVR time: %f\r\n", ovr_GetTimeInSeconds()); - WriteReportLineF("OVR version: %s\r\n", ovr_GetVersionString()); - - // OVR util information - // The following would be useful to use if they didn't allocate memory, which we can't do. - // To do: see if we can have versions of the functions below which don't allocate memory - // or allocate it safely (e.g. use an alternative heap). - // String OVR::GetDisplayDriverVersion(); - // String OVR::GetCameraDriverVersion(); - - // OVR HMD information - WriteReportLine("\r\nOVR HMD Info\r\n"); - - const OVR::List& hmdStateList = OVR::CAPI::HMDState::GetHMDStateList(); - const OVR::CAPI::HMDState* pHMDState = hmdStateList.GetFirst(); - - if(hmdStateList.IsNull(pHMDState)) - { - WriteReportLine("No HMDs found.\r\n"); - } - - while(!hmdStateList.IsNull(pHMDState)) - { - if(pHMDState->pProfile) - { - const char* user = pHMDState->pProfile->GetValue(OVR_KEY_USER); - - if(user) - WriteReportLineF("Profile user: %s\r\n", reportPrivacyEnabled ? "" : user); - else - WriteReportLine("Null profile user\r\n"); - - float NeckEyeDistance[2]; - float EyeToNoseDistance[2]; - float MaxEyeToPlateDist[2]; - pHMDState->pProfile->GetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, NeckEyeDistance, 2); - pHMDState->pProfile->GetFloatValues(OVR_KEY_EYE_TO_NOSE_DISTANCE, EyeToNoseDistance, 2); - pHMDState->pProfile->GetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, MaxEyeToPlateDist, 2); - - WriteReportLineF("Player height: %f, eye height: %f, IPD: %f, Neck eye distance: %f,%f, eye relief dial: %d, eye to nose distance: %f,%f, max eye to plate distance: %f,%f, custom eye render: %s\r\n", - pHMDState->pProfile->GetFloatValue(OVR_KEY_PLAYER_HEIGHT, 0.f), - pHMDState->pProfile->GetFloatValue(OVR_KEY_EYE_HEIGHT, 0.f), - pHMDState->pProfile->GetFloatValue(OVR_KEY_IPD, 0.f), - NeckEyeDistance[0], NeckEyeDistance[1], - pHMDState->pProfile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, 0), - EyeToNoseDistance[0], EyeToNoseDistance[1], - MaxEyeToPlateDist[0], MaxEyeToPlateDist[1], - pHMDState->pProfile->GetBoolValue(OVR_KEY_CUSTOM_EYE_RENDER, false) ? "yes" : "no"); - - // Not currently used: - // OVR_KEY_NAME - // OVR_KEY_GENDER - // OVR_KEY_EYE_CUP - // OVR_KEY_CAMERA_POSITION - } - else - { - WriteReportLine("Null HMD profile\r\n"); - } - - if(pHMDState->pHmdDesc) // This should usually be true. - { - WriteReportLineF("HMD %d: Type: %u ProductName: %s, Manufacturer: %s VendorId: %d, ProductId: %d, SerialNumber: %s, FirmwareMajor: %d, FirmwareMinor: %d, Resolution: %dx%d, DisplayDeviceName: %s, DisplayId: %d\r\n", - 0, (unsigned)pHMDState->pHmdDesc->Type, pHMDState->pHmdDesc->ProductName, pHMDState->pHmdDesc->Manufacturer, pHMDState->pHmdDesc->VendorId, - pHMDState->pHmdDesc->ProductId, pHMDState->pHmdDesc->SerialNumber, pHMDState->pHmdDesc->FirmwareMajor, pHMDState->pHmdDesc->FirmwareMinor, - pHMDState->pHmdDesc->Resolution.w, pHMDState->pHmdDesc->Resolution.h, pHMDState->pHmdDesc->DisplayDeviceName, pHMDState->pHmdDesc->DisplayId); - - // HSW display state - ovrHSWDisplayState hswDS; - ovrHmd_GetHSWDisplayState(pHMDState->pHmdDesc, &hswDS); - WriteReportLineF("HSW displayed for hmd: %s\r\n", hswDS.Displayed ? "yes" : "no"); - } - - char threadIdStr[24]; - SprintfAddress(threadIdStr, OVR_ARRAY_COUNT(threadIdStr), pHMDState->BeginFrameThreadId); - - WriteReportLineF("Hmd Caps: %x, Hmd Service Caps: %x, Latency test active: %s, Last frame time: %f, Last get frame time: %f, Rendering configred: %s, Begin frame called: %s, Begin frame thread id: %s\r\n", - pHMDState->EnabledHmdCaps, pHMDState->EnabledServiceHmdCaps, pHMDState->LatencyTestActive ? "yes" : "no", pHMDState->LastFrameTimeSeconds, pHMDState->LastGetFrameTimeSeconds, pHMDState->RenderingConfigured ? "yes" : "no", - pHMDState->BeginFrameCalled ? "yes" : "no", threadIdStr); - - if(pHMDState->pLastError) - { - WriteReportLineF("OVR last error for hmd: %s\r\n", pHMDState->pLastError); - } - - pHMDState = hmdStateList.GetNext(pHMDState); - } - - #if defined(OVR_OS_WIN32) - { - WriteReportLine("\r\nApp Info\r\n"); - - // Print the app path. - char appPath[MAX_PATH]; - GetCurrentProcessFilePath(appPath, OVR_ARRAY_COUNT(appPath)); - WriteReportLineF("Process path: %s\r\n", appPath); - - #if (OVR_PTR_SIZE == 4) - WriteReportLine("App format: 32 bit\r\n"); - #else - WriteReportLine("App format: 64 bit\r\n"); - #endif - - // Print the app version - wchar_t pathW[MAX_PATH] = {}; - GetModuleFileNameW(0, pathW, (DWORD)OVR_ARRAY_COUNT(pathW)); - DWORD dwUnused; - DWORD dwSize = GetFileVersionInfoSizeW(pathW, &dwUnused); - scratchBuffer[0] = 0; - - if(dwSize > 0) - { - void* const pVersionData = SafeMMapAlloc(dwSize); - - if(pVersionData) - { - if(GetFileVersionInfoW(pathW, 0, dwSize, pVersionData)) - { - VS_FIXEDFILEINFO* pFFI; - UINT size; - - if(VerQueryValueA(pVersionData, "\\", (void**)&pFFI, &size)) - { - WriteReportLineF("App version: %u.%u.%u.%u\r\n", - HIWORD(pFFI->dwFileVersionMS), LOWORD(pFFI->dwFileVersionMS), - HIWORD(pFFI->dwFileVersionLS), LOWORD(pFFI->dwFileVersionLS)); - } - } - - SafeMMapFree(pVersionData, dwSize); - } - } - - if(!scratchBuffer[0]) // If version info couldn't be found or read... - WriteReportLine("App version info not present\r\n"); - } - - { - WriteReportLine("\r\nSystem Info\r\n"); - - OSVERSIONINFOEXW vi; - memset(&vi, 0, sizeof(vi)); - vi.dwOSVersionInfoSize = sizeof(vi); - GetVersionExW((LPOSVERSIONINFOW)&vi); // Cast to the older type. - - char osVersionName[256]; - GetOSVersionName(osVersionName, OVR_ARRAY_COUNT(osVersionName)); - WriteReportLineF("OS name: %s, version: %u.%u build %u, %s, platform id: %u, service pack: %ls\r\n", - osVersionName, vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, Is64BitOS() ? "64 bit" : "32 bit", - vi.dwPlatformId, vi.szCSDVersion[0] ? vi.szCSDVersion : L""); - - WriteReportLineF("Debugger present: %s\r\n", OVRIsDebuggerPresent() ? "yes" : "no"); - - // System info - SYSTEM_INFO systemInfo; - GetNativeSystemInfo(&systemInfo); - - WriteReportLineF("Processor count: %u\r\n", systemInfo.dwNumberOfProcessors); - - // Windows Vista and later: - // BOOL WINAPI GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, PDWORD ReturnLength); - - if(systemInfo.wProcessorArchitecture == 0) - WriteReportLineF("Processor type: x86\r\n"); - else if(systemInfo.wProcessorArchitecture == 9) - WriteReportLineF("Processor type: x86-64\r\n"); - else if(systemInfo.wProcessorArchitecture == 10) - WriteReportLineF("Processor type: x86 on x86-64\r\n"); - - WriteReportLineF("Processor level: %u\r\n", systemInfo.wProcessorLevel); - WriteReportLineF("Processor revision: %u\r\n", systemInfo.wProcessorRevision); - - // Memory information - MEMORYSTATUSEX memoryStatusEx; - memset(&memoryStatusEx, 0, sizeof(memoryStatusEx)); - memoryStatusEx.dwLength = sizeof(memoryStatusEx); - GlobalMemoryStatusEx(&memoryStatusEx); - - WriteReportLineF("Memory load: %d%%\r\n", memoryStatusEx.dwMemoryLoad); - WriteReportLineF("Total physical memory: %I64d MiB\r\n", memoryStatusEx.ullTotalPhys / (1024 * 1024)); // Or are Mebibytes equal to (1024 * 1000) - WriteReportLineF("Available physical memory: %I64d MiB\r\n", memoryStatusEx.ullAvailPhys / (1024 * 1024)); - WriteReportLineF("Total page file memory: %I64d MiB\r\n", memoryStatusEx.ullTotalPageFile / (1024 * 1024)); - WriteReportLineF("Available page file memory: %I64d MiB\r\n", memoryStatusEx.ullAvailPageFile / (1024 * 1024)); - WriteReportLineF("Total virtual memory: %I64d MiB\r\n", memoryStatusEx.ullTotalVirtual / (1024 * 1024)); - WriteReportLineF("Free virtual memory: %I64d MiB\r\n", memoryStatusEx.ullAvailVirtual / (1024 * 1024)); - - DISPLAY_DEVICE dd; - memset(&dd, 0, sizeof(DISPLAY_DEVICE)); - dd.cb = sizeof(DISPLAY_DEVICE); - - for(int i = 0; EnumDisplayDevicesW(nullptr, (DWORD)i, &dd, EDD_GET_DEVICE_INTERFACE_NAME); ++i) - { - WriteReportLineF("Display Device %d name: %ls, context: %ls, primary: %s, mirroring: %s\r\n", - i, dd.DeviceName, dd.DeviceString, (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) ? "yes" : "no", (dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ? "yes" : "no"); - } - } - - // Print video card information - // http://msdn.microsoft.com/en-us/library/aa394512%28v=vs.85%29.aspx - { - IWbemLocator* pIWbemLocator = nullptr; - BSTR bstrServer = nullptr; - IWbemServices* pIWbemServices = nullptr; - BSTR bstrWQL = nullptr; - BSTR bstrPath = nullptr; - IEnumWbemClassObject* pEnum = nullptr; - - CoInitializeEx(nullptr, COINIT_MULTITHREADED); - - HRESULT hr = CoCreateInstance(__uuidof(WbemLocator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator); - if(FAILED(hr)) - goto End; - - bstrServer = SysAllocString(L"\\\\.\\root\\cimv2"); - hr = pIWbemLocator->ConnectServer(bstrServer, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &pIWbemServices); - if(FAILED(hr)) - goto End; - - hr = CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, - RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DEFAULT); - if(FAILED(hr)) - goto End; - - bstrWQL = SysAllocString(L"WQL"); - bstrPath = SysAllocString(L"select * from Win32_VideoController"); - hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, nullptr, &pEnum); - if(FAILED(hr)) - goto End; - - ULONG uReturned; - IWbemClassObject* pObj = nullptr; - hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned); - if(FAILED(hr)) - goto End; - - WriteReportLine("\r\nDisplay adapter list\r\n"); - - for(unsigned i = 0; SUCCEEDED(hr) && uReturned; i++) - { - char sString[256]; - VARIANT var; - - if(i > 0) - WriteReportLine("\r\n"); - - WriteReportLineF("Info for display adapter %u\r\n", i); - - hr = pObj->Get(L"Name", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter Name: %s\r\n", sString); - } - - hr = pObj->Get(L"AdapterRAM", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WriteReportLineF("Display Adapter RAM: %u %s\r\n", - ((uint32_t)var.lVal > (1024*1024*1024) ? (uint32_t)var.lVal/(1024*1024*1024) : (uint32_t)var.lVal/(1024*1024)), ((uint32_t)var.lVal > (1024*1024*1024) ? "GiB" : "MiB")); - } - - hr = pObj->Get(L"DeviceID", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter DeviceID: %s\r\n", sString); - } - - hr = pObj->Get(L"DriverVersion", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter DriverVersion: %s\r\n", sString); - } - - hr = pObj->Get(L"DriverDate", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - // http://technet.microsoft.com/en-us/library/ee156576.aspx - wchar_t year[5] = { var.bstrVal[0], var.bstrVal[1], var.bstrVal[2], var.bstrVal[3], 0 }; - wchar_t month[3] = { var.bstrVal[4], var.bstrVal[5], 0 }; - wchar_t monthDay[3] = { var.bstrVal[6], var.bstrVal[7], 0 }; - - WriteReportLineF("Display Adapter DriverDate (US format): %ls/%ls/%ls\r\n", month, monthDay, year); - } - - // VideoProcessor - hr = pObj->Get(L"VideoProcessor", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter VideoProcessor %s\r\n", sString); - } - - hr = pObj->Get(L"VideoModeDescription", 0, &var, nullptr, nullptr); - if(SUCCEEDED(hr)) - { - WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); - WriteReportLineF("Display Adapter VideoModeDescription: %s\r\n", sString); - } - - pObj->Release(); - - hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned); - } - - End: - if(pEnum) - pEnum->Release(); - if(bstrPath) - SysFreeString(bstrPath); - if(bstrWQL) - SysFreeString(bstrWQL); - if(pIWbemServices) - pIWbemServices->Release(); - if(bstrServer) - SysFreeString(bstrServer); - if(pIWbemLocator) - pIWbemLocator->Release(); - - CoUninitialize(); - } - - { - // Print a list of threads. - DWORD currentProcessId = GetCurrentProcessId(); - HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, currentProcessId); // ICreateToolhelp32Snapshot actually ignores currentProcessId. - - if(hThreadSnap != INVALID_HANDLE_VALUE) - { - THREADENTRY32 te32; - te32.dwSize = sizeof(THREADENTRY32); - - if(Thread32First(hThreadSnap, &te32)) - { - WriteReportLine("\r\nThread list\r\n"); - - do { - if(te32.th32OwnerProcessID == currentProcessId) - { - HANDLE hThread = ConvertThreadSysIdToThreadHandle(te32.th32ThreadID); - - if(hThread) - { - char buffer[96]; // Can't use scratchBuffer, because it's used by WriteThreadCallstack. - OVR_snprintf(buffer, OVR_ARRAY_COUNT(buffer), "base priority: %ld, delta priority: %ld", te32.tpBasePri, te32.tpDeltaPri); - - bool threadIsExceptionThread = (te32.th32ThreadID == (DWORD)exceptionInfo.threadSysId); - if(threadIsExceptionThread) - OVR_strlcat(buffer, ", exception thread", OVR_ARRAY_COUNT(buffer)); - - WriteThreadCallstack(hThread, (OVR::ThreadSysId)te32.th32ThreadID, buffer); - FreeThreadHandle(hThread); - } - } - } while(Thread32Next(hThreadSnap, &te32)); - } - - CloseHandle(hThreadSnap); - } - } - - { - // Print a list of the current modules within this process. - // DbgHelp.dll also provides a EnumerateLoadedModules64 function. - // To do: Convert the code below to use the GetModuleInfoArray function which we now have. - #if defined(OVR_OS_CONSOLE) - struct MODULEINFO { - LPVOID lpBaseOfDll; - DWORD SizeOfImage; - LPVOID EntryPoint; - }; - HMODULE hModule = LoadLibraryW(L"toolhelpx.dll"); - #else - HMODULE hModule = LoadLibraryW(L"psapi.dll"); - #endif - - if(hModule) - { - typedef BOOL (WINAPI * ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE* phModule, DWORD cb, LPDWORD lpcbNeeded); - typedef DWORD (WINAPI * GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); - typedef DWORD (WINAPI * GETMODULEFILENAMEEX) (HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); - typedef BOOL (WINAPI * GETMODULEINFORMATION)(HANDLE hProcess, HMODULE hModule, MODULEINFO* pmi, DWORD nSize); - - #if defined(OVR_OS_CONSOLE) - ENUMPROCESSMODULES pEnumProcessModules = (ENUMPROCESSMODULES) (uintptr_t)GetProcAddress(hModule, "K32EnumProcessModules"); - GETMODULEBASENAME pGetModuleBaseName = (GETMODULEBASENAME) (uintptr_t)GetProcAddress(hModule, "K32GetModuleBaseNameW"); - GETMODULEFILENAMEEX pGetModuleFileNameEx = (GETMODULEFILENAMEEX) (uintptr_t)GetProcAddress(hModule, "K32GetModuleFileNameExW"); - GETMODULEINFORMATION pGetModuleInformation = (GETMODULEINFORMATION)(uintptr_t)GetProcAddress(hModule, "K32GetModuleInformation"); - #else - ENUMPROCESSMODULES pEnumProcessModules = (ENUMPROCESSMODULES) (uintptr_t)GetProcAddress(hModule, "EnumProcessModules"); - GETMODULEBASENAME pGetModuleBaseName = (GETMODULEBASENAME) (uintptr_t)GetProcAddress(hModule, "GetModuleBaseNameW"); - GETMODULEFILENAMEEX pGetModuleFileNameEx = (GETMODULEFILENAMEEX) (uintptr_t)GetProcAddress(hModule, "GetModuleFileNameExW"); - GETMODULEINFORMATION pGetModuleInformation = (GETMODULEINFORMATION)(uintptr_t)GetProcAddress(hModule, "GetModuleInformation"); - #endif - - HANDLE hProcess = GetCurrentProcess(); - HMODULE hModuleArray[200]; - DWORD cbNeeded; - - if(pEnumProcessModules(hProcess, hModuleArray, sizeof(hModuleArray), &cbNeeded)) - { - size_t actualModuleCount = (cbNeeded / sizeof(HMODULE)); - - if(actualModuleCount > OVR_ARRAY_COUNT(hModuleArray)) //If hModuleArray's capacity was not enough... - actualModuleCount = OVR_ARRAY_COUNT(hModuleArray); - - // Print a header - WriteReportLine("\r\nModule list\r\n"); - - #if (OVR_PTR_SIZE == 4) - WriteReportLine("Base Size Entrypoint Name Path\r\n"); - #else - WriteReportLine("Base Size Entrypoint Name Path\r\n"); - #endif - - // And go through the list one by one - for(size_t i = 0; i < actualModuleCount; i++) - { - MODULEINFO mi; - size_t length; - - if(!pGetModuleInformation(hProcess, hModuleArray[i], &mi, sizeof(mi))) - { - mi.EntryPoint = nullptr; - mi.lpBaseOfDll = nullptr; - mi.SizeOfImage = 0; - } - - // Write the base name. - wchar_t name[MAX_PATH + 3]; - name[0] = '"'; - if(pGetModuleBaseName(hProcess, hModuleArray[i], name + 1, MAX_PATH)) - length = wcslen(name); - else - { - wcscpy(name + 1, L"(unknown)"); - length = 10; - } - - name[length] = '"'; - name[length + 1] = '\0'; - - // Write the path - wchar_t path[MAX_PATH + 3]; - path[0] = '"'; - if(pGetModuleFileNameEx(hProcess, hModuleArray[i], path + 1, MAX_PATH)) - length = wcslen(path); - else - { - wcscpy(path + 1, L"(unknown)"); - length = 10; - } - path[length] = '"'; - path[length + 1] = '\0'; - - #if (OVR_PTR_SIZE == 4) - WriteReportLineF("0x%08x, 0x%08x 0x%08x %-24ls %ls\r\n", (uint32_t)mi.lpBaseOfDll, (uint32_t)mi.SizeOfImage, (uint32_t)mi.EntryPoint, name, path); - #else - WriteReportLineF("0x%016I64x 0x%016I64x 0x%016I64x %-24ls %ls\r\n", (uint64_t)mi.lpBaseOfDll, (uint64_t)mi.SizeOfImage, (uint64_t)mi.EntryPoint, name, path); - #endif - } - } - } - } - - { - // Print a list of processes. - // DbgHelp.dll provides a SymEnumProcesses function, but it's available with DbgHelp.dll v6.2 which doesn't ship with Windows until Windows 8. - WriteReportLine("\r\nProcess list\r\n"); - - if(reportPrivacyEnabled) - WriteReportLine("Disabled by report privacy settings\r\n"); - else - { - HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - - if(hProcessSnapshot != INVALID_HANDLE_VALUE) - { - PROCESSENTRY32W pe32; - memset(&pe32, 0, sizeof(pe32)); - pe32.dwSize = sizeof(pe32); - - if(Process32FirstW(hProcessSnapshot, &pe32)) - { - WriteReportLine("Process Id File\r\n"); - - do { - // Try to get the full path to the process, as pe32.szExeFile holds only the process file name. - // This will typically fail with a privilege error unless this process has debug privileges: http://support.microsoft.com/kb/131065/en-us - wchar_t filePathW[MAX_PATH]; - const wchar_t* pFilePathW = pe32.szExeFile; - HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID); // With Windows Vista+ we can use PROCESS_QUERY_LIMITED_INFORMATION. - if(hProcess) - { - if(GetProcessImageFileName(hProcess, filePathW, (DWORD)OVR_ARRAY_COUNT(filePathW))) - pFilePathW = filePathW; - } - - WriteReportLineF("0x%08x %ls\r\n", pe32.th32ProcessID, pFilePathW); - } while(Process32NextW(hProcessSnapshot, &pe32)); - } - - CloseHandle(hProcessSnapshot); - } - else - { - WriteReportLine("Unable to read process list\r\n"); - } - } - } - - #elif defined(OVR_OS_APPLE) - - WriteReportLine("\r\nApp Info\r\n"); - - // App path - const pid_t processId = getpid(); - WriteReportLineF("Process id: ", "%lld (0x%llx)\r\n", (int64_t)processId, (int64_t)processId); - - char appPath[PATH_MAX]; - GetCurrentProcessFilePath(appPath, OVR_ARRAY_COUNT(appPath)); - WriteReportLineF("Process path: %s\r\n", appPath); - - #if (OVR_PTR_SIZE == 4) - WriteReportLine("App format: 32 bit\r\n"); - #else - WriteReportLine("App format: 64 bit\r\n"); - #endif - - // App version - // To do. - - // System Info - WriteReportLine("\r\nSystem Info\r\n"); - - char osVersionName[256]; - GetOSVersionName(osVersionName, OVR_ARRAY_COUNT(osVersionName)); - WriteReportLineF("OS name: %s, %s\r\n", osVersionName, Is64BitOS() ? "64 bit" : "32 bit"); - - int name[2]; - int intValue; - size_t length; - char tempBuffer[256]; - - name[0] = CTL_KERN; - name[1] = KERN_OSTYPE; - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) - { - WriteReportLineF("KERN_OSTYPE: %s\r\n", tempBuffer); - } - - name[0] = CTL_KERN; - name[1] = KERN_OSREV; - length = sizeof(intValue); - intValue = 0; - if(sysctl(name, 2, &intValue, &length, nullptr, 0) == 0) - { - WriteReportLineF("KERN_OSREV: %d\r\n", intValue); - } - - name[0] = CTL_KERN; - name[1] = KERN_OSRELEASE; - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("KERN_OSRELEASE: %s\r\n", tempBuffer); - - name[0] = CTL_HW; - name[1] = HW_MACHINE; - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("HW_MACHINE: %s\r\n", tempBuffer); - - name[0] = CTL_HW; - name[1] = HW_MODEL; - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("sHW_MODEL: %s\r\n", tempBuffer); - - name[0] = CTL_HW; - name[1] = HW_NCPU; - length = sizeof(intValue); - intValue = 0; - if(sysctl(name, 2, &intValue, &length, nullptr, 0) == 0) - WriteReportLineF("HW_NCPU: %d\r\n", intValue); - - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctlbyname("machdep.cpu.brand_string", &tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("machdep.cpu.brand_string: %s\r\n", tempBuffer); - - length = sizeof(tempBuffer); - tempBuffer[0] = 0; - if(sysctlbyname("hw.acpi.thermal.tz0.temperature", &tempBuffer, &length, nullptr, 0) == 0) - WriteReportLineF("hw.acpi.thermal.tz0.temperature: %s\r\n", tempBuffer); - - host_basic_info_data_t hostinfo; - mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; - kern_return_t kr = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostinfo, &count); - - if(kr == KERN_SUCCESS) - { - const uint64_t memoryMib = (uint64_t)hostinfo.max_mem / (1024 * 1024); - WriteReportLineF("System memory: %lld Mib (%.1f Gib)\r\n", memoryMib, (double)memoryMib / 1024); - } - - // Video card info - // To do. - - // Thread list - mach_port_t taskSelf = mach_task_self(); - thread_act_port_array_t threadArray; - mach_msg_type_number_t threadCount; - - kern_return_t result = task_threads(taskSelf, &threadArray, &threadCount); - - if(result == KERN_SUCCESS) - { - WriteReportLine("\r\nThread list\r\n"); - - for(mach_msg_type_number_t i = 0; i < threadCount; i++) - { - union TBIUnion{ - natural_t words[THREAD_INFO_MAX]; - thread_basic_info tbi; - }; - - TBIUnion tbiUnion; - mach_port_t thread = threadArray[i]; - pthread_t pthread = pthread_from_mach_thread_np(thread); // We assume the thread was created through pthreads. - - char threadState[32] = "unknown"; - mach_msg_type_number_t threadInfoCount = THREAD_INFO_MAX; - result = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&tbiUnion, &threadInfoCount); - - if(result == KERN_SUCCESS) - { - const char* state; - - switch (tbiUnion.tbi.run_state) - { - case TH_STATE_HALTED: state = "halted"; break; - case TH_STATE_RUNNING: state = "running"; break; - case TH_STATE_STOPPED: state = "stopped"; break; - case TH_STATE_UNINTERRUPTIBLE: state = "uninterruptible"; break; - case TH_STATE_WAITING: state = "waiting"; break; - default: state = ""; break; - } - - OVR_snprintf(threadState, OVR_ARRAY_COUNT(threadState), "%s", state); - if(tbiUnion.tbi.flags & TH_FLAGS_IDLE) - OVR_strlcat(threadState, ", idle", sizeof(threadState)); - if(tbiUnion.tbi.flags & TH_FLAGS_SWAPPED) - OVR_strlcat(threadState, ", swapped", sizeof(threadState)); - } - - thread_identifier_info threadIdentifierInfo; - memset(&threadIdentifierInfo, 0, sizeof(threadIdentifierInfo)); - - mach_msg_type_number_t threadIdentifierInfoCount = THREAD_IDENTIFIER_INFO_COUNT; - thread_info(thread, THREAD_IDENTIFIER_INFO, (thread_info_t)&threadIdentifierInfo, &threadIdentifierInfoCount); - - proc_threadinfo procThreadInfo; - memset(&procThreadInfo, 0, sizeof(procThreadInfo)); - result = proc_pidinfo(processId, PROC_PIDTHREADINFO, threadIdentifierInfo.thread_handle, &procThreadInfo, sizeof(procThreadInfo)); - OVR_UNUSED(result); - - char buffer[256]; // Can't use scratchBuffer, because it's used by WriteThreadCallstack. - OVR_snprintf(buffer, OVR_ARRAY_COUNT(buffer), "state: %s, suspend count: %d, kernel priority: %d", threadState, (int)tbiUnion.tbi.suspend_count, (int)procThreadInfo.pth_curpri); - - bool threadIsExceptionThread = (thread == exceptionInfo.threadSysId); - if(threadIsExceptionThread) - OVR_strlcat(buffer, ", exception thread", OVR_ARRAY_COUNT(buffer)); - - WriteThreadCallstack(pthread, thread, buffer); - } - - vm_deallocate(taskSelf, (vm_address_t)threadArray, threadCount * sizeof(thread_act_t)); - } - - - WriteReportLine("\r\nModule list\r\n"); - - const size_t mifCapacity = 256; - const size_t mifAllocSize = mifCapacity * sizeof(ModuleInfo); - ModuleInfo* moduleInfoArray = (ModuleInfo*)SafeMMapAlloc(mifAllocSize); - - if(moduleInfoArray) - { - #if (OVR_PTR_SIZE == 4) - WriteReportLine("Base Size Name Path\r\n"); - #else - WriteReportLine("Base Size Name Path\r\n"); - #endif - - size_t moduleCount = symbolLookup.GetModuleInfoArray(moduleInfoArray, mifCapacity); - if(moduleCount > mifCapacity) - moduleCount = mifCapacity; - - for(size_t i = 0; i < moduleCount; i++) - { - const ModuleInfo& mi = moduleInfoArray[i]; - - #if (OVR_PTR_SIZE == 4) - WriteReportLineF("0x%08x, 0x%08x %-24s %s\r\n", (uint32_t)mi.baseAddress, (uint32_t)mi.size, mi.name, mi.filePath); - #else - WriteReportLineF("0x%016llx 0x%016llx %-24s %s\r\n", (uint64_t)mi.baseAddress, (uint64_t)mi.size, mi.name, mi.filePath); - #endif - } - - SafeMMapFree(moduleInfoArray, mifAllocSize); - } - - - WriteReportLine("\r\nProcess list\r\n"); - - if(reportPrivacyEnabled) - WriteReportLine("Disabled by report privacy settings\r\n"); - else - { - WriteReportLine("Process Id File\r\n"); - - pid_t pidArray[1024]; - int processCount = proc_listpids(PROC_ALL_PIDS, 0, pidArray, sizeof(pidArray)); // Important that we use sizeof not OVR_ARRAY_COUNT. - char processFilePath[PATH_MAX]; - - for(int i = 0; i < processCount; i++) - { - if(proc_pidpath(pidArray[i], processFilePath, sizeof(processFilePath)) > 0) - WriteReportLineF("%-10d %s\r\n", pidArray[i], processFilePath); - } - - if(!processCount) - WriteReportLine("Unable to read process list\r\n"); - } - - #elif defined(OVR_OS_UNIX) - Is64BitOS(); - GetCurrentProcessFilePath(nullptr, 0); - GetFileNameFromPath(nullptr); - GetOSVersionName(nullptr, 0); - - #endif // OVR_OS_MS - - symbolLookup.Shutdown(); - - fclose(file); - file = nullptr; -} - - -void ExceptionHandler::WriteMiniDump() -{ - if(strstr(miniDumpFilePath, "%s")) // If the user-specified file path includes a date/time component... - { - char dateTimeBuffer[64]; - FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, true); - OVR_snprintf(minidumpFilePathActual, OVR_ARRAY_COUNT(minidumpFilePathActual), miniDumpFilePath, dateTimeBuffer); - } - else - { - OVR_strlcpy(minidumpFilePathActual, miniDumpFilePath, OVR_ARRAY_COUNT(minidumpFilePathActual)); - } - - #if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) || (defined(OVR_OS_MS) && defined(OVR_OS_CONSOLE)) - #if defined(OVR_OS_CONSOLE) - typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE dumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PVOID CallbackParam); - HMODULE hModuleDbgHelp = LoadLibraryW(L"toolhelpx.dll"); - #else - typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE dumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); - HMODULE hModuleDbgHelp = LoadLibraryW(L"DbgHelp.dll"); - #endif - - MINIDUMPWRITEDUMP pMiniDumpWriteDump = hModuleDbgHelp ? (MINIDUMPWRITEDUMP)(void*)GetProcAddress(hModuleDbgHelp, "MiniDumpWriteDump") : nullptr; - - if(pMiniDumpWriteDump) - { - wchar_t miniDumpFilePathW[OVR_MAX_PATH]; - OVR::UTF8Util::DecodeString(miniDumpFilePathW, minidumpFilePathActual, -1); // Problem: DecodeString provides no way to specify the destination capacity. - - HANDLE hFile = CreateFileW(miniDumpFilePathW, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0); - - if(hFile != INVALID_HANDLE_VALUE) - { - MINIDUMP_EXCEPTION_INFORMATION minidumpExceptionInfo = { ::GetCurrentThreadId(), pExceptionPointers, TRUE }; - - #if defined(OVR_OS_CONSOLE) - BOOL result = pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, - (MINIDUMP_TYPE)miniDumpType, &exceptionInfo, - (CONST PMINIDUMP_USER_STREAM_INFORMATION)nullptr, nullptr); - #else - BOOL result = pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, - (MINIDUMP_TYPE)miniDumpFlags, &minidumpExceptionInfo, - (CONST PMINIDUMP_USER_STREAM_INFORMATION)nullptr, (CONST PMINIDUMP_CALLBACK_INFORMATION)nullptr); - #endif - - OVR_ASSERT_AND_UNUSED(result, result); - CloseHandle(hFile); - hFile = 0; - } - else - { - OVR_ASSERT(pMiniDumpWriteDump); // OVR_FAIL_F(("ExceptionHandler::WriteMiniDump: Failed to create minidump file at %s", minidumpFilePathActual)); - } - } - - FreeLibrary(hModuleDbgHelp); - #else - // Some platforms support various forms or exception reports and core dumps which are automatically generated upon us - // returning from our own exception handling. We might want to put something here if we are using a custom version of - // this, such as Google Breakpad. - #endif -} - - -void ExceptionHandler::SetExceptionListener(ExceptionListener* pExceptionListener, uintptr_t userValue) -{ - exceptionListener = pExceptionListener; - exceptionListenerUserValue = userValue; -} - - -void ExceptionHandler::SetAppDescription(const char* pAppDescription) -{ - appDescription = pAppDescription; -} - - -void ExceptionHandler::SetExceptionPaths(const char* exceptionReportPath, const char* exceptionMiniDumpFilePath) -{ - char tempPath[OVR_MAX_PATH]; - - if(exceptionReportPath) - { - if(OVR_stricmp(exceptionReportPath, "default") == 0) - { - GetUserDocumentsDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); - OVR::OVR_strlcat(tempPath, "Exception Report (%s).txt", OVR_ARRAY_COUNT(tempPath)); - exceptionReportPath = tempPath; - } - - OVR_strlcpy(reportFilePath, exceptionReportPath, OVR_ARRAY_COUNT(reportFilePath)); - } - else - { - reportFilePath[0] = '\0'; - } - - if(exceptionMiniDumpFilePath) - { - if(OVR_stricmp(exceptionMiniDumpFilePath, "default") == 0) - { - GetUserDocumentsDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); - OVR::OVR_strlcat(tempPath, "Exception Minidump (%s).mdmp", OVR_ARRAY_COUNT(tempPath)); - exceptionMiniDumpFilePath = tempPath; - } - - OVR_strlcpy(miniDumpFilePath, exceptionMiniDumpFilePath, OVR_ARRAY_COUNT(miniDumpFilePath)); - } - else - { - miniDumpFilePath[0] = '\0'; - } -} - - -void ExceptionHandler::SetCodeBaseDirectoryPaths(const char* codeBaseDirectoryPathArray[], size_t codeBaseDirectoryPathCount) -{ - for(size_t i = 0, iCount = OVR::Alg::Min(codeBaseDirectoryPathCount, OVR_ARRAY_COUNT(codeBasePathArray)); i != iCount; ++i) - { - codeBasePathArray[i] = codeBaseDirectoryPathArray[i]; - } -} - -const char* ExceptionHandler::GetExceptionUIText(const char* exceptionReportPath) -{ - char* uiText = nullptr; - OVR::SysFile file(exceptionReportPath, SysFile::Open_Read, SysFile::Mode_ReadWrite); - - if(file.IsValid()) - { - size_t length = (size_t)file.GetLength(); - uiText = (char*)OVR::SafeMMapAlloc(length + 1); - - if(uiText) - { - file.Read((uint8_t*)uiText, (int)length); - uiText[length] = '\0'; - file.Close(); - - // Currently on Mac our message box implementation is unable to display arbitrarily large amounts of text. - // So we reduce its size to a more summary version before presenting. - #if defined(OVR_OS_MAC) - struct Find { static char* PreviousChar(char* p, char c){ while(*p != c) p--; return p; } }; // Assumes the given c is present prior to p. - - // Print that the full report is at - // Exception Info section - // Exception thread callstack. - char empty[] = ""; - char* pExceptionInfoBegin = strstr(uiText, "Exception Info") ? strstr(uiText, "Exception Info") : empty; - char* pExceptionInfoEnd = (pExceptionInfoBegin == empty) ? (empty + 1) : strstr(uiText, "\r\n\r\n"); - char* pExceptionThreadArea = strstr(uiText, ", exception thread"); - char* pExceptionThreadBegin = pExceptionThreadArea ? Find::PreviousChar(pExceptionThreadArea, '\n') + 1 : empty; - char* pExceptionThreadEnd = (pExceptionThreadBegin == empty) ? (empty + 1) : strstr(pExceptionThreadArea, "\r\n\r\n"); - - if(!pExceptionInfoEnd) - pExceptionInfoEnd = pExceptionInfoBegin; - *pExceptionInfoEnd = '\0'; - - if(!pExceptionThreadEnd) - pExceptionThreadEnd = pExceptionThreadBegin; - *pExceptionThreadEnd = '\0'; - - size_t uiTextBriefLength = OVR_snprintf(nullptr, 0, "Full report:%s\n\nSummary report:\n%s\n\n%s", exceptionReportPath, pExceptionInfoBegin, pExceptionThreadBegin); - char* uiTextBrief = (char*)OVR::SafeMMapAlloc(uiTextBriefLength + 1); - - if(uiTextBrief) - { - OVR_snprintf(uiTextBrief, uiTextBriefLength + 1, "Full report:%s\n\nSummary report:\n%s\n\n%s", exceptionReportPath, pExceptionInfoBegin, pExceptionThreadBegin); - OVR::SafeMMapFree(uiText, length); - uiText = uiTextBrief; - } - #endif - } - } - - return uiText; -} - -void ExceptionHandler::FreeExceptionUIText(const char* messageBoxText) -{ - OVR::SafeMMapFree(messageBoxText, OVR_strlen(messageBoxText)); -} - - -} // namespace OVR - - -OVR_RESTORE_MSVC_WARNING() - diff --git a/LibOVR/Src/Kernel/OVR_DebugHelp.h b/LibOVR/Src/Kernel/OVR_DebugHelp.h deleted file mode 100644 index 2430ae4..0000000 --- a/LibOVR/Src/Kernel/OVR_DebugHelp.h +++ /dev/null @@ -1,461 +0,0 @@ -/************************************************************************************ - -Filename : OVR_DebugHelp.h -Content : Platform-independent exception handling interface -Created : October 6, 2014 - -Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_ExceptionHandler_h -#define OVR_ExceptionHandler_h - - -#include "OVR_Types.h" -#include "OVR_String.h" -#include "OVR_Threads.h" -#include "OVR_Atomic.h" -#include "OVR_Nullptr.h" -#include -#include - -#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) - #include - -#elif defined(OVR_OS_APPLE) - #include - #include - #include - - extern "C" void* MachHandlerThreadFunctionStatic(void*); - extern "C" int catch_mach_exception_raise_state_identity_OVR(mach_port_t, mach_port_t, mach_port_t, exception_type_t, mach_exception_data_type_t*, - mach_msg_type_number_t, int*, thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t*); -#elif defined(OVR_OS_LINUX) - #include -#endif - - -OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized - - -namespace OVR { - - // Thread identifiers - //typedef void* ThreadHandle; // Already defined by OVR Threads. Same as Windows thread handle, Unix pthread_t. - //typedef void* ThreadId; // Already defined by OVR Threads. Used by Windows as DWORD thread id, by Unix as pthread_t. - typedef uintptr_t ThreadSysId; // System thread identifier. Used by Windows the same as ThreadId (DWORD), thread_act_t on Mac/BSD, lwp id on Linux. - - // Thread constants - // To do: Move to OVR Threads - #define OVR_THREADHANDLE_INVALID ((ThreadHandle*)nullptr) - #define OVR_THREADID_INVALID ((ThreadId*)nullptr) - #define OVR_THREADSYSID_INVALID ((uintptr_t)0) - - OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle); - OVR::ThreadHandle ConvertThreadSysIdToThreadHandle(OVR::ThreadSysId threadSysId); // The returned handle must be freed with FreeThreadHandle. - void FreeThreadHandle(OVR::ThreadHandle threadHandle); // Frees the handle returned by ConvertThreadSysIdToThreadHandle. - OVR::ThreadSysId GetCurrentThreadSysId(); - - // CPUContext - #if defined(OVR_OS_MS) - typedef CONTEXT CPUContext; - #elif defined(OVR_OS_MAC) - struct CPUContext - { - x86_thread_state_t threadState; // This works for both x86 and x64. - x86_float_state_t floatState; - x86_debug_state_t debugState; - x86_avx_state_t avxState; - x86_exception_state exceptionState; - - CPUContext() { memset(this, 0, sizeof(CPUContext)); } - }; - #elif defined(OVR_OS_LINUX) - typedef int CPUContext; // To do. - #endif - - - // Tells if the current process appears to be running under a debugger. Does not attempt to - // detect the case of sleath debuggers (malware-related for example). - bool OVRIsDebuggerPresent(); - - // Exits the process with the given exit code. - #if !defined(OVR_NORETURN) - #if defined(OVR_CC_MSVC) - #define OVR_NORETURN __declspec(noreturn) - #else - #define OVR_NORETURN __attribute__((noreturn)) - #endif - #endif - OVR_NORETURN void ExitProcess(intptr_t processReturnValue); - - // Returns the instruction pointer of the caller for the position right after the call. - OVR_NO_INLINE void GetInstructionPointer(void*& pInstruction); - - // Returns the stack base and limit addresses for the given thread, or for the current thread if the threadHandle is default. - // The stack limit is a value less than the stack base on most platforms, as stacks usually grow downward. - // Some platforms (e.g. Microsoft) have dynamically resizing stacks, in which case the stack limit reflects the current limit. - void GetThreadStackBounds(void*& pStackBase, void*& pStackLimit, ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); - - - // Equates to VirtualAlloc/VirtualFree on Windows, mmap/munmap on Unix. - // These are useful for when you need system-supplied memory pages. - // These are also useful for when you need to allocate memory in a way - // that doesn't affect the application heap. - void* SafeMMapAlloc(size_t size); - void SafeMMapFree(const void* memory, size_t size); - - - // OVR_MAX_PATH - // Max file path length (for most uses). - // To do: move this to OVR_File. - #if defined(OVR_OS_MS) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx - #define OVR_MAX_PATH 260 // Windows can use paths longer than this in some cases (network paths, UNC paths). - #else - #define OVR_MAX_PATH 1024 // This isn't a strict limit on all Unix-based platforms. - #endif - - - // ModuleHandle - #if defined(OVR_OS_MS) - typedef void* ModuleHandle; // from LoadLibrary() - #elif defined(OVR_OS_APPLE) || defined(OVR_OS_UNIX) - typedef void* ModuleHandle; // from dlopen() - #endif - - #define OVR_MODULEHANDLE_INVALID ((ModuleHandle*)nullptr) - - - - // Module info constants - static const ModuleHandle kMIHandleInvalid = OVR_MODULEHANDLE_INVALID; - static const uint64_t kMIAddressInvalid = 0xffffffffffffffffull; - static const uint64_t kMISizeInvalid = 0xffffffffffffffffull; - static const int32_t kMILineNumberInvalid = -1; - static const int32_t kMIFunctionOffsetInvalid = -1; - static const uint64_t kMIBaseAddressInvalid = 0xffffffffffffffffull; - static const uint64_t kMIBaseAddressUnspecified = 0xffffffffffffffffull; - - struct ModuleInfo - { - ModuleHandle handle; - uint64_t baseAddress; // The actual runtime base address of the module. May be different from the base address specified in the debug symbol file. - uint64_t size; - char filePath[OVR_MAX_PATH]; - char name[32]; - char type[8]; // Unix-specific. e.g. __TEXT - char permissions[8]; // Unix specific. e.g. "drwxr-xr-x" - - ModuleInfo() : handle(kMIHandleInvalid), baseAddress(kMIBaseAddressInvalid), size(0), filePath(), name(){} - }; - - - // Refers to symbol info for an instruction address. - // Info includes function name, source code file/line, and source code itself. - struct SymbolInfo - { - uint64_t address; - uint64_t size; - const ModuleInfo* pModuleInfo; - char filePath[OVR_MAX_PATH]; - int32_t fileLineNumber; - char function[128]; // This is a fixed size because we need to use it during application exceptions. - int32_t functionOffset; - char sourceCode[1024]; // This is a string representing the code itself and not a file path to the code. - - SymbolInfo() : address(kMIAddressInvalid), size(kMISizeInvalid), pModuleInfo(nullptr), filePath(), - fileLineNumber(kMILineNumberInvalid), function(), functionOffset(kMIFunctionOffsetInvalid), sourceCode() {} - }; - - - // Implements support for reading thread lists, module lists, backtraces, and backtrace symbols. - class SymbolLookup - { - public: - SymbolLookup(); - ~SymbolLookup(); - - void AddSourceCodeDirectory(const char* pDirectory); - - bool Initialize(); - void Shutdown(); - - // Should be disabled when within an exception handler. - void EnableMemoryAllocation(bool enabled); - - // Retrieves the backtrace (call stack) of the given thread. There may be some per-platform restrictions on this. - // Returns the number written, which will be <= addressArrayCapacity. - // This may not work on some platforms unless stack frames are enabled. - // For Microsoft platforms the platformThreadContext is CONTEXT*. - // For Apple platforms the platformThreadContext is x86_thread_state_t* or arm_thread_state_t*. - // If threadSysIdHelp is non-zero, it may be used by the implementation to help produce a better backtrace. - size_t GetBacktrace(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, void* platformThreadContext = nullptr, OVR::ThreadSysId threadSysIdHelp = OVR_THREADSYSID_INVALID); - - // Retrieves the backtrace for the given ThreadHandle. - // Returns the number written, which will be <= addressArrayCapacity. - size_t GetBacktraceFromThreadHandle(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, OVR::ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); - - // Retrieves the backtrace for the given ThreadSysId. - // Returns the number written, which will be <= addressArrayCapacity. - size_t GetBacktraceFromThreadSysId(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, OVR::ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); - - // Gets a list of the modules (e.g. DLLs) present in the current process. - // Writes as many ModuleInfos as possible to pModuleInfoArray. - // Returns the required count of ModuleInfos, which will be > moduleInfoArrayCapacity if the capacity needs to be larger. - size_t GetModuleInfoArray(ModuleInfo* pModuleInfoArray, size_t moduleInfoArrayCapacity); - - // Retrieves a list of the current threads. Unless the process is paused the list is volatile. - // Returns the required capacity, which may be larger than threadArrayCapacity. - // Either array can be NULL to specify that it's not written to. - // For Windows the caller needs to CloseHandle the returned ThreadHandles. This can be done by calling DoneThreadList. - size_t GetThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCapacity); - - // Frees any references to thread handles or ids returned by GetThreadList; - void DoneThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCount); - - // Writes a given thread's callstack with symbols to the given output. - // It may not be safe to call this from an exception handler, as sOutput allocates memory. - bool ReportThreadCallstack(OVR::String& sOutput, size_t skipCount = 0, ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); - - // Writes all thread's callstacks with symbols to the given output. - // It may not be safe to call this from an exception handler, as sOutput allocates memory. - bool ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount = 0); - - // Retrieves symbol info for the given address. - bool LookupSymbol(uint64_t address, SymbolInfo& symbolInfo); - bool LookupSymbols(uint64_t* addressArray, SymbolInfo* pSymbolInfoArray, size_t arraySize); - - const ModuleInfo* GetModuleInfoForAddress(uint64_t address); // The returned ModuleInfo points to an internal structure. - - protected: - bool RefreshModuleList(); - - protected: - bool initialized; - bool allowMemoryAllocation; // True by default. If true then we allow allocating memory (and as a result provide less information). This is useful for when in an exception handler. - bool moduleListUpdated; - ModuleInfo moduleInfoArray[96]; // Cached list of modules we use. This is a fixed size because we need to use it during application exceptions. - size_t moduleInfoArraySize; - }; - - - - // ExceptionInfo - // We need to be careful to avoid data types that can allocate memory while we are - // handling an exception, as the memory system may be corrupted at that point in time. - struct ExceptionInfo - { - tm time; // GM time. - time_t timeVal; // GM time_t (seconds since 1970). - void* backtrace[64]; - size_t backtraceCount; - ThreadHandle threadHandle; // - ThreadSysId threadSysId; // - char threadName[32]; // Cannot be an allocating String object. - void* pExceptionInstructionAddress; - void* pExceptionMemoryAddress; - CPUContext cpuContext; - char exceptionDescription[1024]; // Cannot be an allocating String object. - SymbolInfo symbolInfo; // SymbolInfo for the exception location. - - #if defined(OVR_OS_MS) - EXCEPTION_RECORD exceptionRecord; // This is a Windows SDK struct. - #elif defined(OVR_OS_APPLE) - uint64_t exceptionType; // e.g. EXC_BAD_INSTRUCTION, EXC_BAD_ACCESS, etc. - uint32_t cpuExceptionId; // The x86/x64 CPU trap id. - uint32_t cpuExceptionIdError; // The x86/x64 CPU trap id extra info. - int64_t machExceptionDetail[4]; // Kernel exception code info. - int machExceptionDetailCount; // Count of valid entries. - #endif - - ExceptionInfo(); - }; - - - // Implments support for asynchronous exception handling and basic exception report generation. - // If you are implementing exception handling for a commercial application and want auto-uploading - // functionality you may want to consider using something like Google Breakpad. This exception handler - // is for in-application debug/diagnostic services, though it can write a report that has similar - // information to Breakpad or OS-provided reports such as Apple .crash files. - // - // Example usage: - // ExceptionHandler exceptionHandler; - // - // int main(int, char**) - // { - // exceptionHandler.Enable(true); - // exceptionHandler.SetExceptionListener(pSomeListener, 0); // Optional listener hook. - // } - // - class ExceptionHandler - { - public: - ExceptionHandler(); - ~ExceptionHandler(); - - bool Enable(bool enable); - - // Some report info can be considered private information of the user, such as the current process list, - // computer name, IP address or other identifying info, etc. We should not report this information for - // external users unless they agree to this. - void EnableReportPrivacy(bool enable); - - struct ExceptionListener - { - virtual ~ExceptionListener(){} - virtual int HandleException(uintptr_t userValue, ExceptionHandler* pExceptionHandler, ExceptionInfo* pExceptionInfo, const char* reportFilePath) = 0; - }; - - void SetExceptionListener(ExceptionListener* pExceptionListener, uintptr_t userValue); - - // What we do after handling the exception. - enum ExceptionResponse - { - kERContinue, // Continue execution. Will result in the exception being re-generated unless the application has fixed the cause. Similar to Windows EXCEPTION_CONTINUE_EXECUTION. - kERHandle, // Causes the OS to handle the exception as it normally would. Similar to Windows EXCEPTION_EXECUTE_HANDLER. - kERTerminate, // Exit the application. - kERThrow, // Re-throw the exception. Other handlers may catch it. Similar to Windows EXCEPTION_CONTINUE_SEARCH. - kERDefault // Usually set to kERTerminate. - }; - - void SetExceptionResponse(ExceptionResponse er) - { exceptionResponse = er; } - - // Allws you to add an arbitrary description of the current application, which will be added to exception reports. - void SetAppDescription(const char* appDescription); - - // If the report path has a "%s" in its name, then assume the path is a sprintf format and write it - // with the %s specified as a date/time string. - // The report path can be "default" to signify that you want to use the default user location. - // Example usage: - // handler.SetExceptionPaths("/Users/Current/Exceptions/Exception %s.txt"); - void SetExceptionPaths(const char* exceptionReportPath, const char* exceptionMinidumpPath = nullptr); - - // Allows you to specify base directories for code paths, which can be used to associate exception addresses to lines - // of code as opposed to just file names and line numbers, or function names plus binary offsets. - void SetCodeBaseDirectoryPaths(const char* codeBaseDirectoryPathArray[], size_t codeBaseDirectoryPathCount); - - // Given an exception report at a given file path, returns a string suitable for displaying in a message - // box or similar user interface during the handling of an exception. The returned string must be passed - // to FreeMessageBoxText when complete. - static const char* GetExceptionUIText(const char* exceptionReportPath); - static void FreeExceptionUIText(const char* messageBoxText); - - protected: - void WriteExceptionDescription(); - void WriteReport(); - void WriteReportLine(const char* pLine); - void WriteReportLineF(const char* format, ...); - void WriteThreadCallstack(ThreadHandle threadHandle, ThreadSysId threadSysId, const char* additionalInfo); - void WriteMiniDump(); - - // Runtime constants - bool enabled; - bool reportPrivacyEnabled; // Defaults to true. - ExceptionResponse exceptionResponse; // Defaults to kERHandle - ExceptionListener* exceptionListener; - uintptr_t exceptionListenerUserValue; - String appDescription; - String codeBasePathArray[6]; // 6 is arbitrary. - char reportFilePath[OVR_MAX_PATH];// May be an encoded path, in that it has "%s" in it or is named "default". See reporFiletPathActual for the runtime actual report path. - int miniDumpFlags; - char miniDumpFilePath[OVR_MAX_PATH]; - FILE* file; // Can/should we use OVR Files for this? - char scratchBuffer[4096]; - SymbolLookup symbolLookup; - - // Runtime variables - bool exceptionOccurred; - OVR::AtomicInt handlingBusy; - char reportFilePathActual[OVR_MAX_PATH]; - char minidumpFilePathActual[OVR_MAX_PATH]; - int terminateReturnValue; - ExceptionInfo exceptionInfo; - - #if defined(OVR_OS_MS) - void* vectoredHandle; - LPTOP_LEVEL_EXCEPTION_FILTER previousFilter; - LPEXCEPTION_POINTERS pExceptionPointers; - - friend LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); - LONG ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); - - #elif defined(OVR_OS_APPLE) - struct SavedExceptionPorts - { - SavedExceptionPorts() : count(0) { memset(this, 0, sizeof(SavedExceptionPorts)); } - - mach_msg_type_number_t count; - exception_mask_t masks[6]; - exception_handler_t ports[6]; - exception_behavior_t behaviors[6]; - thread_state_flavor_t flavors[6]; - }; - - friend void* ::MachHandlerThreadFunctionStatic(void*); - friend int ::catch_mach_exception_raise_state_identity_OVR(mach_port_t, mach_port_t, mach_port_t, exception_type_t, - mach_exception_data_type_t*, mach_msg_type_number_t, int*, thread_state_t, - mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t*); - - bool InitMachExceptionHandler(); - void ShutdownMachExceptionHandler(); - void* MachHandlerThreadFunction(); - kern_return_t HandleMachException(mach_port_t port, mach_port_t thread, mach_port_t task, exception_type_t exceptionType, - mach_exception_data_type_t* pExceptionDetail, mach_msg_type_number_t exceptionDetailCount, - int* pFlavor, thread_state_t pOldState, mach_msg_type_number_t oldStateCount, thread_state_t pNewState, - mach_msg_type_number_t* pNewStateCount); - kern_return_t ForwardMachException(mach_port_t thread, mach_port_t task, exception_type_t exceptionType, - mach_exception_data_t pExceptionDetail, mach_msg_type_number_t exceptionDetailCount); - - bool machHandlerInitialized; - mach_port_t machExceptionPort; - SavedExceptionPorts machExceptionPortsSaved; - volatile bool machThreadShouldContinue; - volatile bool machThreadExecuting; - pthread_t machThread; - - #elif defined(OVR_OS_LINUX) - // To do. - #endif - }; - - - // Identifies basic exception types for the CreateException function. - enum CreateExceptionType - { - kCETAccessViolation, // Read or write to inaccessable memory. - kCETAlignment, // Misaligned read or write. - kCETDivideByZero, // Integer divide by zero. - kCETFPU, // Floating point / VPU exception. - kCETIllegalInstruction, // Illegal opcode. - kCETStackCorruption, // Stack frame was corrupted. - kCETStackOverflow, // Stack ran out of space, often due to infinite recursion. - kCETTrap // System/OS trap (system call). - }; - - - // Creates an exception of the given type, primarily for testing. - void CreateException(CreateExceptionType exceptionType); - - - -} // namespace OVR - - -OVR_RESTORE_MSVC_WARNING() - - -#endif // Header include guard diff --git a/LibOVR/Src/Kernel/OVR_Delegates.h b/LibOVR/Src/Kernel/OVR_Delegates.h deleted file mode 100644 index 88948b4..0000000 --- a/LibOVR/Src/Kernel/OVR_Delegates.h +++ /dev/null @@ -1,541 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Delegates.h -Content : C++ Delegates -Created : June 15, 2014 -Authors : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -/* - Based on The Impossibly Fast C++ Delegates by Sergey Ryazanov from - http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx (2005) -*/ - -/* - Usage: - - Declare a delegate with a void (int) signature, also known as a - function that returns void and has one parameter that is an int: - typedef Delegate1 MyDelegate; - MyDelegate d; - - Point the delegate to a member function: - d.SetMember(&a); - d = MyDelegate::FromMember(&a); - - Point the delegate to a const member function: - d.SetConstMember(&c); - d = MyDelegate::FromConstMember(&c); - - Point the delegate to a free function: - d.SetFree<&FreeFunctionX>(); - d = MyDelegate::FromFree<&FreeFunctionX>(); - - Invoke the function via the delegate (works for all 3 cases): - d(1000); - - By default the delegates are uninitialized. - To clear an array of delegates quickly just zero the memory. - - This implementation is nicer than FastDelegates in my opinion - because it is simple and easy to read. It is a little slower - for virtual functions, but the size of the delegate is small, - and it will only get better as compilers improve. -*/ - -#ifndef OVR_Delegates_h -#define OVR_Delegates_h - -#include "OVR_Types.h" - -namespace OVR { - - -template -class Delegate0 -{ - typedef ret_type (*StubPointer)(void *); - typedef Delegate0 this_type; - - void *_object; - StubPointer _stub; - - OVR_FORCE_INLINE Delegate0(void *object, StubPointer stub) - { - _object = object; - _stub = stub; - } - - // Stubs - - template - static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/) - { - return (F)(); - } - - template - static OVR_FORCE_INLINE ret_type MemberStub(void *object) - { - T *p = static_cast(object); - return (p->*F)(); - } - - template - static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object) - { - T *p = static_cast(object); - return (p->*F)(); - } - -public: - OVR_FORCE_INLINE Delegate0() : _object(0), _stub(0){} - - // Function invocation - - OVR_FORCE_INLINE ret_type operator()() const - { - return (*_stub)(_object); - } - - // Use stub pointer as a validity flag and equality checker - - OVR_FORCE_INLINE bool operator==(const this_type &rhs) const - { - return _object == rhs._object && _stub == rhs._stub; - } - - OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const - { - return _object != rhs._object || _stub != rhs._stub; - } - - OVR_FORCE_INLINE bool IsValid() const - { - return _stub != 0; - } - - OVR_FORCE_INLINE bool operator!() const - { - return _stub == 0; - } - - OVR_FORCE_INLINE void Invalidate() - { - _stub = 0; - } - - // Delegate creation from a function - - template - static OVR_FORCE_INLINE this_type FromFree() - { - return this_type(0, &FreeStub); - } - - template - static OVR_FORCE_INLINE this_type FromMember(T *object) - { - return this_type(object, &MemberStub); - } - - template - static OVR_FORCE_INLINE this_type FromConstMember(T const *object) - { - return this_type(const_cast( object ), &ConstMemberStub); - } - - // In-place assignment to a different function - - template - OVR_FORCE_INLINE void SetFree() - { - *this = FromFree(); - } - - template - OVR_FORCE_INLINE void SetMember(T *object) - { - *this = FromMember(object); - } - - template - OVR_FORCE_INLINE void SetConstMember(T const *object) - { - *this = FromConstMember(object); - } -}; - - -template -class Delegate1 -{ - typedef ret_type (*StubPointer)(void *, arg1_type); - typedef Delegate1 this_type; - - void *_object; - StubPointer _stub; - - OVR_FORCE_INLINE Delegate1(void *object, StubPointer stub) - { - _object = object; - _stub = stub; - } - - // Stubs - - template - static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1) - { - return (F)(a1); - } - - template - static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1) - { - T *p = static_cast(object); - return (p->*F)(a1); - } - - template - static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1) - { - T *p = static_cast(object); - return (p->*F)(a1); - } - -public: - OVR_FORCE_INLINE Delegate1() : _object(0), _stub(0){} - - // Function invocation - - OVR_FORCE_INLINE ret_type operator()(arg1_type a1) const - { - return (*_stub)(_object, a1); - } - - // Use stub pointer as a validity flag and equality checker - - OVR_FORCE_INLINE bool operator==(const this_type &rhs) const - { - return _object == rhs._object && _stub == rhs._stub; - } - - OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const - { - return _object != rhs._object || _stub != rhs._stub; - } - - OVR_FORCE_INLINE bool IsValid() const - { - return _stub != 0; - } - - OVR_FORCE_INLINE bool operator!() const - { - return _stub == 0; - } - - OVR_FORCE_INLINE void Invalidate() - { - _stub = 0; - } - - // Delegate creation from a function - - template - static OVR_FORCE_INLINE this_type FromFree() - { - return this_type(0, &FreeStub); - } - - template - static OVR_FORCE_INLINE this_type FromMember(T *object) - { - return this_type(object, &MemberStub); - } - - template - static OVR_FORCE_INLINE this_type FromConstMember(T const *object) - { - return this_type(const_cast( object ), &ConstMemberStub); - } - - // In-place assignment to a different function - - template - OVR_FORCE_INLINE void SetFree() - { - *this = FromFree(); - } - - template - OVR_FORCE_INLINE void SetMember(T *object) - { - *this = FromMember(object); - } - - template - OVR_FORCE_INLINE void SetConstMember(T const *object) - { - *this = FromConstMember(object); - } -}; - - -template -class Delegate2 -{ - typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type); - typedef Delegate2 this_type; - - void *_object; - StubPointer _stub; - - OVR_FORCE_INLINE Delegate2(void *object, StubPointer stub) - { - _object = object; - _stub = stub; - } - - // Stubs - - template - static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2) - { - return (F)(a1, a2); - } - - template - static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2) - { - T *p = static_cast(object); - return (p->*F)(a1, a2); - } - - template - static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2) - { - T *p = static_cast(object); - return (p->*F)(a1, a2); - } - -public: - OVR_FORCE_INLINE Delegate2() : _object(0), _stub(0){} - - // Function invocation - - OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2) const - { - return (*_stub)(_object, a1, a2); - } - - // Use stub pointer as a validity flag and equality checker - - OVR_FORCE_INLINE bool operator==(const this_type &rhs) const - { - return _object == rhs._object && _stub == rhs._stub; - } - - OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const - { - return _object != rhs._object || _stub != rhs._stub; - } - - OVR_FORCE_INLINE bool IsValid() const - { - return _stub != 0; - } - - OVR_FORCE_INLINE bool operator!() const - { - return _stub == 0; - } - - OVR_FORCE_INLINE void Invalidate() - { - _stub = 0; - } - - // Delegate creation from a function - - template - static OVR_FORCE_INLINE this_type FromFree() - { - return this_type(0, &FreeStub); - } - - template - static OVR_FORCE_INLINE this_type FromMember(T *object) - { - return this_type(object, &MemberStub); - } - - template - static OVR_FORCE_INLINE this_type FromConstMember(T const *object) - { - return this_type(const_cast( object ), &ConstMemberStub); - } - - // In-place assignment to a different function - - template - OVR_FORCE_INLINE void SetFree() - { - *this = FromFree(); - } - - template - OVR_FORCE_INLINE void SetMember(T *object) - { - *this = FromMember(object); - } - - template - OVR_FORCE_INLINE void SetConstMember(T const *object) - { - *this = FromConstMember(object); - } -}; - - -template -class Delegate3 -{ - typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type, arg3_type); - typedef Delegate3 this_type; - - void *_object; - StubPointer _stub; - - OVR_FORCE_INLINE Delegate3(void *object, StubPointer stub) - { - _object = object; - _stub = stub; - } - - // Stubs - - template - static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2, arg3_type a3) - { - return (F)(a1, a2, a3); - } - - template - static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3) - { - T *p = static_cast(object); - return (p->*F)(a1, a2, a3); - } - - template - static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3) - { - T *p = static_cast(object); - return (p->*F)(a1, a2, a3); - } - -public: - OVR_FORCE_INLINE Delegate3() : _object(0), _stub(0){} - - // Function invocation - - OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2, arg3_type a3) const - { - return (*_stub)(_object, a1, a2, a3); - } - - // Use stub pointer as a validity flag and equality checker - - OVR_FORCE_INLINE bool operator==(const this_type &rhs) const - { - return _object == rhs._object && _stub == rhs._stub; - } - - OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const - { - return _object != rhs._object || _stub != rhs._stub; - } - - OVR_FORCE_INLINE bool IsValid() const - { - return _stub != 0; - } - - OVR_FORCE_INLINE bool operator!() const - { - return _stub == 0; - } - - OVR_FORCE_INLINE void Invalidate() - { - _stub = 0; - } - - // Delegate creation from a function - - template - static OVR_FORCE_INLINE this_type FromFree() - { - return this_type(0, &FreeStub); - } - - template - static OVR_FORCE_INLINE this_type FromMember(T *object) - { - return this_type(object, &MemberStub); - } - - template - static OVR_FORCE_INLINE this_type FromConstMember(T const *object) - { - return this_type(const_cast( object ), &ConstMemberStub); - } - - // In-place assignment to a different function - - template - OVR_FORCE_INLINE void SetFree() - { - *this = FromFree(); - } - - template - OVR_FORCE_INLINE void SetMember(T *object) - { - *this = FromMember(object); - } - - template - OVR_FORCE_INLINE void SetConstMember(T const *object) - { - *this = FromConstMember(object); - } -}; - -// Add more here if needed, but keep in mind that a short, simple interface -// is rewarded by making the delegates faster... - - -} // namespace OVR - -#endif // OVR_Delegates_h diff --git a/LibOVR/Src/Kernel/OVR_Deque.h b/LibOVR/Src/Kernel/OVR_Deque.h deleted file mode 100644 index 951ed84..0000000 --- a/LibOVR/Src/Kernel/OVR_Deque.h +++ /dev/null @@ -1,316 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Deque.h -Content : Deque container -Created : Nov. 15, 2013 -Authors : Dov Katz - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Deque_h -#define OVR_Deque_h - -#include "OVR_ContainerAllocator.h" - -namespace OVR{ - -template > -class Deque -{ -public: - enum - { - DefaultCapacity = 500 - }; - - Deque(int capacity = DefaultCapacity); - virtual ~Deque(void); - - virtual void PushBack (const Elem &Item); // Adds Item to the end - virtual void PushFront (const Elem &Item); // Adds Item to the beginning - virtual Elem PopBack (void); // Removes Item from the end - virtual Elem PopFront (void); // Removes Item from the beginning - virtual const Elem& PeekBack (int count = 0) const; // Returns count-th Item from the end - virtual const Elem& PeekFront (int count = 0) const; // Returns count-th Item from the beginning - - virtual inline size_t GetSize (void) const; // Returns Number of Elements - OVR_FORCE_INLINE int GetSizeI (void) const - { - return (int)GetSize(); - } - virtual inline size_t GetCapacity(void) const; // Returns the maximum possible number of elements - virtual void Clear (void); // Remove all elements - virtual inline bool IsEmpty () const; - virtual inline bool IsFull () const; - -protected: - Elem *Data; // The actual Data array - const int Capacity; // Deque capacity - int Beginning; // Index of the first element - int End; // Index of the next after last element - - // Instead of calculating the number of elements, using this variable - // is much more convenient. - int ElemCount; - -private: - OVR_NON_COPYABLE(Deque); -}; - -template > -class InPlaceMutableDeque : public Deque -{ - typedef Deque BaseType; - -public: - InPlaceMutableDeque( int capacity = BaseType::DefaultCapacity ) : BaseType( capacity ) {} - virtual ~InPlaceMutableDeque() {}; - - using BaseType::PeekBack; - using BaseType::PeekFront; - virtual Elem& PeekBack (int count = 0); // Returns count-th Item from the end - virtual Elem& PeekFront (int count = 0); // Returns count-th Item from the beginning -}; - -// Same as Deque, but allows to write more elements than maximum capacity -// Old elements are lost as they are overwritten with the new ones -template > -class CircularBuffer : public InPlaceMutableDeque -{ - typedef InPlaceMutableDeque BaseType; - -public: - CircularBuffer(int MaxSize = BaseType::DefaultCapacity) : BaseType(MaxSize) { }; - virtual ~CircularBuffer(){} - - // The following methods are inline as a workaround for a VS bug causing erroneous C4505 warnings - // See: http://stackoverflow.com/questions/3051992/compiler-warning-at-c-template-base-class - inline virtual void PushBack (const Elem &Item); // Adds Item to the end, overwriting the oldest element at the beginning if necessary - inline virtual void PushFront (const Elem &Item); // Adds Item to the beginning, overwriting the oldest element at the end if necessary -}; - -//---------------------------------------------------------------------------------- - -// Deque Constructor function -template -Deque::Deque(int capacity) : -Capacity( capacity ), Beginning(0), End(0), ElemCount(0) -{ - Data = (Elem*) Allocator::Alloc(Capacity * sizeof(Elem)); -} - -// Deque Destructor function -template -Deque::~Deque(void) -{ - Clear(); - Allocator::Free(Data); -} - -template -void Deque::Clear() -{ - if (!IsEmpty()) - { - if (Beginning < End) - { - // no wrap-around - Allocator::DestructArray(Data + Beginning, End - Beginning); - } - else - { - // wrap-around - Allocator::DestructArray(Data + Beginning, Capacity - Beginning); - Allocator::DestructArray(Data, End); - } - } - - Beginning = 0; - End = 0; - ElemCount = 0; -} - -// Push functions -template -void Deque::PushBack(const Elem &Item) -{ - // Error Check: Make sure we aren't - // exceeding our maximum storage space - OVR_ASSERT( ElemCount < Capacity ); - - Allocator::Construct(Data + End, Item); - ++End; - ++ElemCount; - - // Check for wrap-around - if (End >= Capacity) - End -= Capacity; -} - -template -void Deque::PushFront(const Elem &Item) -{ - // Error Check: Make sure we aren't - // exceeding our maximum storage space - OVR_ASSERT( ElemCount < Capacity ); - - --Beginning; - // Check for wrap-around - if (Beginning < 0) - Beginning += Capacity; - - Allocator::Construct(Data + Beginning, Item); - ++ElemCount; -} - -// Pop functions -template -Elem Deque::PopFront(void) -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( ElemCount > 0 ); - - Elem ReturnValue = Data[ Beginning ]; - Allocator::Destruct(Data + Beginning); - - ++Beginning; - --ElemCount; - - // Check for wrap-around - if (Beginning >= Capacity) - Beginning -= Capacity; - - return ReturnValue; -} - -template -Elem Deque::PopBack(void) -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( ElemCount > 0 ); - - --End; - --ElemCount; - - // Check for wrap-around - if (End < 0) - End += Capacity; - - Elem ReturnValue = Data[ End ]; - Allocator::Destruct(Data + End); - - return ReturnValue; -} - -// Peek functions -template -const Elem& Deque::PeekFront(int count) const -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( ElemCount > count ); - - int idx = Beginning + count; - if (idx >= Capacity) - idx -= Capacity; - return Data[ idx ]; -} - -template -const Elem& Deque::PeekBack(int count) const -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( ElemCount > count ); - - int idx = End - count - 1; - if (idx < 0) - idx += Capacity; - return Data[ idx ]; -} - -// Mutable Peek functions -template -Elem& InPlaceMutableDeque::PeekFront(int count) -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( BaseType::ElemCount > count ); - - int idx = BaseType::Beginning + count; - if (idx >= BaseType::Capacity) - idx -= BaseType::Capacity; - return BaseType::Data[ idx ]; -} - -template -Elem& InPlaceMutableDeque::PeekBack(int count) -{ - // Error Check: Make sure we aren't reading from an empty Deque - OVR_ASSERT( BaseType::ElemCount > count ); - - int idx = BaseType::End - count - 1; - if (idx < 0) - idx += BaseType::Capacity; - return BaseType::Data[ idx ]; -} - -template -inline size_t Deque::GetCapacity(void) const -{ - return Capacity; -} - -template -inline size_t Deque::GetSize(void) const -{ - return ElemCount; -} - -template -inline bool Deque::IsEmpty(void) const -{ - return ElemCount == 0; -} - -template -inline bool Deque::IsFull(void) const -{ - return ElemCount == Capacity; -} - -// ******* CircularBuffer ******* -// Push functions -template -void CircularBuffer::PushBack(const Elem &Item) -{ - if (this->IsFull()) - this->PopFront(); - BaseType::PushBack(Item); -} - -template -void CircularBuffer::PushFront(const Elem &Item) -{ - if (this->IsFull()) - this->PopBack(); - BaseType::PushFront(Item); -} - -}; - -#endif diff --git a/LibOVR/Src/Kernel/OVR_File.cpp b/LibOVR/Src/Kernel/OVR_File.cpp deleted file mode 100644 index c431928..0000000 --- a/LibOVR/Src/Kernel/OVR_File.cpp +++ /dev/null @@ -1,585 +0,0 @@ -/************************************************************************** - -Filename : OVR_File.cpp -Content : File wrapper class implementation (Win32) - -Created : April 5, 1999 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -**************************************************************************/ - -#define GFILE_CXX - -// Standard C library (Captain Obvious guarantees!) -#include - -#include "OVR_File.h" - -namespace OVR { - -// Buffered file adds buffering to an existing file -// FILEBUFFER_SIZE defines the size of internal buffer, while -// FILEBUFFER_TOLERANCE controls the amount of data we'll effectively try to buffer -#define FILEBUFFER_SIZE (8192-8) -#define FILEBUFFER_TOLERANCE 4096 - -// ** Constructor/Destructor - -// Hidden constructor -// Not supposed to be used -BufferedFile::BufferedFile() : DelegatedFile(0) -{ - pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); - BufferMode = NoBuffer; - FilePos = 0; - Pos = 0; - DataSize = 0; -} - -// Takes another file as source -BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile) -{ - pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); - BufferMode = NoBuffer; - FilePos = pfile->LTell(); - Pos = 0; - DataSize = 0; -} - - -// Destructor -BufferedFile::~BufferedFile() -{ - // Flush in case there's data - if (pFile) - FlushBuffer(); - // Get rid of buffer - if (pBuffer) - OVR_FREE(pBuffer); -} - -/* -bool BufferedFile::VCopy(const Object &source) -{ - if (!DelegatedFile::VCopy(source)) - return 0; - - // Data members - BufferedFile *psource = (BufferedFile*)&source; - - // Buffer & the mode it's in - pBuffer = psource->pBuffer; - BufferMode = psource->BufferMode; - Pos = psource->Pos; - DataSize = psource->DataSize; - return 1; -} -*/ - -// Initializes buffering to a certain mode -bool BufferedFile::SetBufferMode(BufferModeType mode) -{ - if (!pBuffer) - return false; - if (mode == BufferMode) - return true; - - FlushBuffer(); - - // Can't set write mode if we can't write - if ((mode==WriteBuffer) && (!pFile || !pFile->IsWritable()) ) - return 0; - - // And SetMode - BufferMode = mode; - Pos = 0; - DataSize = 0; - return 1; -} - -// Flushes buffer -void BufferedFile::FlushBuffer() -{ - switch(BufferMode) - { - case WriteBuffer: - // Write data in buffer - FilePos += pFile->Write(pBuffer,Pos); - Pos = 0; - break; - - case ReadBuffer: - // Seek back & reset buffer data - if ((DataSize-Pos)>0) - FilePos = pFile->LSeek(-(int)(DataSize-Pos), Seek_Cur); - DataSize = 0; - Pos = 0; - break; - default: - // not handled! - break; - } -} - -// Reloads data for ReadBuffer -void BufferedFile::LoadBuffer() -{ - if (BufferMode == ReadBuffer) - { - // We should only reload once all of pre-loaded buffer is consumed. - OVR_ASSERT(Pos == DataSize); - - // WARNING: Right now LoadBuffer() assumes the buffer's empty - int sz = pFile->Read(pBuffer,FILEBUFFER_SIZE); - DataSize = sz<0 ? 0 : (unsigned)sz; - Pos = 0; - FilePos += DataSize; - } -} - - -// ** Overridden functions - -// We override all the functions that can possibly -// require buffer mode switch, flush, or extra calculations - -// Tell() requires buffer adjustment -int BufferedFile::Tell() -{ - if (BufferMode == ReadBuffer) - return int (FilePos - DataSize + Pos); - - int pos = pFile->Tell(); - // Adjust position based on buffer mode & data - if (pos!=-1) - { - OVR_ASSERT(BufferMode != ReadBuffer); - if (BufferMode == WriteBuffer) - pos += Pos; - } - return pos; -} - -int64_t BufferedFile::LTell() -{ - if (BufferMode == ReadBuffer) - return FilePos - DataSize + Pos; - - int64_t pos = pFile->LTell(); - if (pos!=-1) - { - OVR_ASSERT(BufferMode != ReadBuffer); - if (BufferMode == WriteBuffer) - pos += Pos; - } - return pos; -} - -int BufferedFile::GetLength() -{ - int len = pFile->GetLength(); - // If writing through buffer, file length may actually be bigger - if ((len!=-1) && (BufferMode==WriteBuffer)) - { - int currPos = pFile->Tell() + Pos; - if (currPos>len) - len = currPos; - } - return len; -} -int64_t BufferedFile::LGetLength() -{ - int64_t len = pFile->LGetLength(); - // If writing through buffer, file length may actually be bigger - if ((len!=-1) && (BufferMode==WriteBuffer)) - { - int64_t currPos = pFile->LTell() + Pos; - if (currPos>len) - len = currPos; - } - return len; -} - -/* -bool BufferedFile::Stat(FileStats *pfs) -{ - // Have to fix up length is stat - if (pFile->Stat(pfs)) - { - if (BufferMode==WriteBuffer) - { - int64_t currPos = pFile->LTell() + Pos; - if (currPos > pfs->Size) - { - pfs->Size = currPos; - // ?? - pfs->Blocks = (pfs->Size+511) >> 9; - } - } - return 1; - } - return 0; -} -*/ - -int BufferedFile::Write(const uint8_t *psourceBuffer, int numBytes) -{ - if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer)) - { - // If not data space in buffer, flush - if ((FILEBUFFER_SIZE-(int)Pos)FILEBUFFER_TOLERANCE) - { - int sz = pFile->Write(psourceBuffer,numBytes); - if (sz > 0) - FilePos += sz; - return sz; - } - } - - // Enough space in buffer.. so copy to it - memcpy(pBuffer+Pos, psourceBuffer, numBytes); - Pos += numBytes; - return numBytes; - } - int sz = pFile->Write(psourceBuffer,numBytes); - if (sz > 0) - FilePos += sz; - return sz; -} - -int BufferedFile::Read(uint8_t *pdestBuffer, int numBytes) -{ - if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer)) - { - // Data in buffer... copy it - if ((int)(DataSize-Pos) >= numBytes) - { - memcpy(pdestBuffer, pBuffer+Pos, numBytes); - Pos += numBytes; - return numBytes; - } - - // Not enough data in buffer, copy buffer - int readBytes = DataSize-Pos; - memcpy(pdestBuffer, pBuffer+Pos, readBytes); - numBytes -= readBytes; - pdestBuffer += readBytes; - Pos = DataSize; - - // Don't reload buffer if more then tolerance - // (No major advantage, and we don't want to write a loop) - if (numBytes>FILEBUFFER_TOLERANCE) - { - numBytes = pFile->Read(pdestBuffer,numBytes); - if (numBytes > 0) - { - FilePos += numBytes; - Pos = DataSize = 0; - } - return readBytes + ((numBytes==-1) ? 0 : numBytes); - } - - // Reload the buffer - // WARNING: Right now LoadBuffer() assumes the buffer's empty - LoadBuffer(); - if ((int)(DataSize-Pos) < numBytes) - numBytes = (int)DataSize-Pos; - - memcpy(pdestBuffer, pBuffer+Pos, numBytes); - Pos += numBytes; - return numBytes + readBytes; - - /* - // Alternative Read implementation. The one above is probably better - // due to FILEBUFFER_TOLERANCE. - int total = 0; - - do { - int bufferBytes = (int)(DataSize-Pos); - int copyBytes = (bufferBytes > numBytes) ? numBytes : bufferBytes; - - memcpy(pdestBuffer, pBuffer+Pos, copyBytes); - numBytes -= copyBytes; - pdestBuffer += copyBytes; - Pos += copyBytes; - total += copyBytes; - - if (numBytes == 0) - break; - LoadBuffer(); - - } while (DataSize > 0); - - return total; - */ - } - int sz = pFile->Read(pdestBuffer,numBytes); - if (sz > 0) - FilePos += sz; - return sz; -} - - -int BufferedFile::SkipBytes(int numBytes) -{ - int skippedBytes = 0; - - // Special case for skipping a little data in read buffer - if (BufferMode==ReadBuffer) - { - skippedBytes = (((int)DataSize-(int)Pos) >= numBytes) ? numBytes : (DataSize-Pos); - Pos += skippedBytes; - numBytes -= skippedBytes; - } - - if (numBytes) - { - numBytes = pFile->SkipBytes(numBytes); - // Make sure we return the actual number skipped, or error - if (numBytes!=-1) - { - skippedBytes += numBytes; - FilePos += numBytes; - Pos = DataSize = 0; - } - else if (skippedBytes <= 0) - skippedBytes = -1; - } - return skippedBytes; -} - -int BufferedFile::BytesAvailable() -{ - int available = pFile->BytesAvailable(); - // Adjust available size based on buffers - switch(BufferMode) - { - case ReadBuffer: - available += DataSize-Pos; - break; - case WriteBuffer: - available -= Pos; - if (available<0) - available= 0; - break; - default: - break; - } - return available; -} - -bool BufferedFile::Flush() -{ - FlushBuffer(); - return pFile->Flush(); -} - -// Seeking could be optimized better.. -int BufferedFile::Seek(int offset, int origin) -{ - if (BufferMode == ReadBuffer) - { - if (origin == Seek_Cur) - { - // Seek can fall either before or after Pos in the buffer, - // but it must be within bounds. - if (((unsigned(offset) + Pos)) <= DataSize) - { - Pos += offset; - return int (FilePos - DataSize + Pos); - } - - // Lightweight buffer "Flush". We do this to avoid an extra seek - // back operation which would take place if we called FlushBuffer directly. - origin = Seek_Set; - OVR_ASSERT(((FilePos - DataSize + Pos) + (uint64_t)offset) < ~(uint64_t)0); - offset = (int)(FilePos - DataSize + Pos) + offset; - Pos = DataSize = 0; - } - else if (origin == Seek_Set) - { - if (((unsigned)offset - (FilePos-DataSize)) <= DataSize) - { - OVR_ASSERT((FilePos-DataSize) < ~(uint64_t)0); - Pos = (unsigned)offset - (unsigned)(FilePos-DataSize); - return offset; - } - Pos = DataSize = 0; - } - else - { - FlushBuffer(); - } - } - else - { - FlushBuffer(); - } - - /* - // Old Seek Logic - if (origin == Seek_Cur && offset + Pos < DataSize) - { - //OVR_ASSERT((FilePos - DataSize) >= (FilePos - DataSize + Pos + offset)); - Pos += offset; - OVR_ASSERT(int (Pos) >= 0); - return int (FilePos - DataSize + Pos); - } - else if (origin == Seek_Set && unsigned(offset) >= FilePos - DataSize && unsigned(offset) < FilePos) - { - Pos = unsigned(offset - FilePos + DataSize); - OVR_ASSERT(int (Pos) >= 0); - return int (FilePos - DataSize + Pos); - } - - FlushBuffer(); - */ - - - FilePos = pFile->Seek(offset,origin); - return int (FilePos); -} - -int64_t BufferedFile::LSeek(int64_t offset, int origin) -{ - if (BufferMode == ReadBuffer) - { - if (origin == Seek_Cur) - { - // Seek can fall either before or after Pos in the buffer, - // but it must be within bounds. - if (((unsigned(offset) + Pos)) <= DataSize) - { - Pos += (unsigned)offset; - return int64_t(FilePos - DataSize + Pos); - } - - // Lightweight buffer "Flush". We do this to avoid an extra seek - // back operation which would take place if we called FlushBuffer directly. - origin = Seek_Set; - offset = (int64_t)(FilePos - DataSize + Pos) + offset; - Pos = DataSize = 0; - } - else if (origin == Seek_Set) - { - if (((uint64_t)offset - (FilePos-DataSize)) <= DataSize) - { - Pos = (unsigned)((uint64_t)offset - (FilePos-DataSize)); - return offset; - } - Pos = DataSize = 0; - } - else - { - FlushBuffer(); - } - } - else - { - FlushBuffer(); - } - -/* - OVR_ASSERT(BufferMode != NoBuffer); - - if (origin == Seek_Cur && offset + Pos < DataSize) - { - Pos += int (offset); - return FilePos - DataSize + Pos; - } - else if (origin == Seek_Set && offset >= int64_t(FilePos - DataSize) && offset < int64_t(FilePos)) - { - Pos = unsigned(offset - FilePos + DataSize); - return FilePos - DataSize + Pos; - } - - FlushBuffer(); - */ - - FilePos = pFile->LSeek(offset,origin); - return FilePos; -} - -int BufferedFile::CopyFromStream(File *pstream, int byteSize) -{ - // We can't rely on overridden Write() - // because delegation doesn't override virtual pointers - // So, just re-implement - uint8_t* buff = new uint8_t[0x4000]; - int count = 0; - int szRequest, szRead, szWritten; - - while(byteSize) - { - szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; - - szRead = pstream->Read(buff,szRequest); - szWritten = 0; - if (szRead > 0) - szWritten = Write(buff,szRead); - - count +=szWritten; - byteSize-=szWritten; - if (szWritten < szRequest) - break; - } - - delete[] buff; - - return count; -} - -// Closing files -bool BufferedFile::Close() -{ - switch(BufferMode) - { - case WriteBuffer: - FlushBuffer(); - break; - case ReadBuffer: - // No need to seek back on close - BufferMode = NoBuffer; - break; - default: - break; - } - return pFile->Close(); -} - - -// ***** Global path helpers - -// Find trailing short filename in a path. -const char* OVR_CDECL GetShortFilename(const char* purl) -{ - size_t len = OVR_strlen(purl); - for (size_t i=len; i>0; i--) - if (purl[i]=='\\' || purl[i]=='/') - return purl+i+1; - return purl; -} - -} // OVR - diff --git a/LibOVR/Src/Kernel/OVR_File.h b/LibOVR/Src/Kernel/OVR_File.h deleted file mode 100644 index d9d3b0f..0000000 --- a/LibOVR/Src/Kernel/OVR_File.h +++ /dev/null @@ -1,530 +0,0 @@ -/************************************************************************************ - -PublicHeader: Kernel -Filename : OVR_File.h -Content : Header for all internal file management - functions and structures - to be inherited by OS specific subclasses. -Created : September 19, 2012 -Notes : - -Notes : errno may not be preserved across use of BaseFile member functions - : Directories cannot be deleted while files opened from them are in use - (For the GetFullName function) - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_File_h -#define OVR_File_h - -#include "OVR_RefCount.h" -#include "OVR_Std.h" -#include "OVR_Alg.h" - -#include -#include "OVR_String.h" - -namespace OVR { - -// ***** Declared classes -class FileConstants; -class File; -class DelegatedFile; -class BufferedFile; - - -// ***** Flags for File & Directory accesses - -class FileConstants -{ -public: - - // *** File open flags - enum OpenFlags - { - Open_Read = 1, - Open_Write = 2, - Open_ReadWrite = 3, - - // Opens file and truncates it to zero length - // - file must have write permission - // - when used with Create, it opens an existing - // file and empties it or creates a new file - Open_Truncate = 4, - - // Creates and opens new file - // - does not erase contents if file already - // exists unless combined with Truncate - Open_Create = 8, - - // Returns an error value if the file already exists - Open_CreateOnly = 24, - - // Open file with buffering - Open_Buffered = 32 - }; - - // *** File Mode flags - enum Modes - { - Mode_Read = 0444, - Mode_Write = 0222, - Mode_Execute = 0111, - - Mode_ReadWrite = 0666 - }; - - // *** Seek operations - enum SeekOps - { - Seek_Set = 0, - Seek_Cur = 1, - Seek_End = 2 - }; - - // *** Errors - enum Errors - { - Error_FileNotFound = 0x1001, - Error_Access = 0x1002, - Error_IOError = 0x1003, - Error_DiskFull = 0x1004 - }; -}; - - -//----------------------------------------------------------------------------------- -// ***** File Class - -// The pure virtual base random-access file -// This is a base class to all files - -class File : public RefCountBase, public FileConstants -{ -public: - File() { } - // ** Location Information - - // Returns a file name path relative to the 'reference' directory - // This is often a path that was used to create a file - // (this is not a global path, global path can be obtained with help of directory) - virtual const char* GetFilePath() = 0; - - - // ** File Information - - // Return 1 if file's usable (open) - virtual bool IsValid() = 0; - // Return 1 if file's writable, otherwise 0 - virtual bool IsWritable() = 0; - - // Return position - virtual int Tell() = 0; - virtual int64_t LTell() = 0; - - // File size - virtual int GetLength() = 0; - virtual int64_t LGetLength() = 0; - - // Returns file stats - // 0 for failure - //virtual bool Stat(FileStats *pfs) = 0; - - // Return errno-based error code - // Useful if any other function failed - virtual int GetErrorCode() = 0; - - - // ** Stream implementation & I/O - - // Blocking write, will write in the given number of bytes to the stream - // Returns : -1 for error - // Otherwise number of bytes read - virtual int Write(const uint8_t *pbufer, int numBytes) = 0; - // Blocking read, will read in the given number of bytes or less from the stream - // Returns : -1 for error - // Otherwise number of bytes read, - // if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed - virtual int Read(uint8_t *pbufer, int numBytes) = 0; - - // Skips (ignores) a given # of bytes - // Same return values as Read - virtual int SkipBytes(int numBytes) = 0; - - // Returns the number of bytes available to read from a stream without blocking - // For a file, this should generally be number of bytes to the end - virtual int BytesAvailable() = 0; - - // Causes any implementation's buffered data to be delivered to destination - // Return 0 for error - virtual bool Flush() = 0; - - - // Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking - inline bool IsEOF() { return !BytesAvailable(); } - - - // Seeking - // Returns new position, -1 for error - virtual int Seek(int offset, int origin=Seek_Set) = 0; - virtual int64_t LSeek(int64_t offset, int origin=Seek_Set) = 0; - // Seek simplification - int SeekToBegin() {return Seek(0); } - int SeekToEnd() {return Seek(0,Seek_End); } - int Skip(int numBytes) {return Seek(numBytes,Seek_Cur); } - - - // Appends other file data from a stream - // Return -1 for error, else # of bytes written - virtual int CopyFromStream(File *pstream, int byteSize) = 0; - - // Closes the file - // After close, file cannot be accessed - virtual bool Close() = 0; - - - // ***** Inlines for convenient primitive type serialization - - // Read/Write helpers -private: - uint64_t PRead64() { uint64_t v = 0; Read((uint8_t*)&v, 8); return v; } - uint32_t PRead32() { uint32_t v = 0; Read((uint8_t*)&v, 4); return v; } - uint16_t PRead16() { uint16_t v = 0; Read((uint8_t*)&v, 2); return v; } - uint8_t PRead8() { uint8_t v = 0; Read((uint8_t*)&v, 1); return v; } - void PWrite64(uint64_t v) { Write((uint8_t*)&v, 8); } - void PWrite32(uint32_t v) { Write((uint8_t*)&v, 4); } - void PWrite16(uint16_t v) { Write((uint8_t*)&v, 2); } - void PWrite8(uint8_t v) { Write((uint8_t*)&v, 1); } - -public: - - // Writing primitive types - Little Endian - inline void WriteUByte(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSByte(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt8(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt8(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt16(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt16(int16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt32(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt32(int32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteUInt64(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteSInt64(int64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); } - inline void WriteFloat(float v) { v = Alg::ByteUtil::SystemToLE(v); Write((uint8_t*)&v, 4); } - inline void WriteDouble(double v) { v = Alg::ByteUtil::SystemToLE(v); Write((uint8_t*)&v, 8); } - // Writing primitive types - Big Endian - inline void WriteUByteBE(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSByteBE(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt8BE(uint16_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt8BE(int16_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt16BE(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt16BE(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt32BE(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt32BE(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteUInt64BE(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteSInt64BE(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); } - inline void WriteFloatBE(float v) { v = Alg::ByteUtil::SystemToBE(v); Write((uint8_t*)&v, 4); } - inline void WriteDoubleBE(double v) { v = Alg::ByteUtil::SystemToBE(v); Write((uint8_t*)&v, 8); } - - // Reading primitive types - Little Endian - inline uint8_t ReadUByte() { return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); } - inline int8_t ReadSByte() { return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); } - inline uint8_t ReadUInt8() { return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); } - inline int8_t ReadSInt8() { return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); } - inline uint16_t ReadUInt16() { return (uint16_t)Alg::ByteUtil::LEToSystem(PRead16()); } - inline int16_t ReadSInt16() { return (int16_t)Alg::ByteUtil::LEToSystem(PRead16()); } - inline uint32_t ReadUInt32() { return (uint32_t)Alg::ByteUtil::LEToSystem(PRead32()); } - inline int32_t ReadSInt32() { return (int32_t)Alg::ByteUtil::LEToSystem(PRead32()); } - inline uint64_t ReadUInt64() { return (uint64_t)Alg::ByteUtil::LEToSystem(PRead64()); } - inline int64_t ReadSInt64() { return (int64_t)Alg::ByteUtil::LEToSystem(PRead64()); } - inline float ReadFloat() { float v = 0.0f; Read((uint8_t*)&v, 4); return Alg::ByteUtil::LEToSystem(v); } - inline double ReadDouble() { double v = 0.0; Read((uint8_t*)&v, 8); return Alg::ByteUtil::LEToSystem(v); } - // Reading primitive types - Big Endian - inline uint8_t ReadUByteBE() { return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); } - inline int8_t ReadSByteBE() { return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); } - inline uint8_t ReadUInt8BE() { return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); } - inline int8_t ReadSInt8BE() { return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); } - inline uint16_t ReadUInt16BE() { return (uint16_t)Alg::ByteUtil::BEToSystem(PRead16()); } - inline int16_t ReadSInt16BE() { return (int16_t)Alg::ByteUtil::BEToSystem(PRead16()); } - inline uint32_t ReadUInt32BE() { return (uint32_t)Alg::ByteUtil::BEToSystem(PRead32()); } - inline int32_t ReadSInt32BE() { return (int32_t)Alg::ByteUtil::BEToSystem(PRead32()); } - inline uint64_t ReadUInt64BE() { return (uint64_t)Alg::ByteUtil::BEToSystem(PRead64()); } - inline int64_t ReadSInt64BE() { return (int64_t)Alg::ByteUtil::BEToSystem(PRead64()); } - inline float ReadFloatBE() { float v = 0.0f; Read((uint8_t*)&v, 4); return Alg::ByteUtil::BEToSystem(v); } - inline double ReadDoubleBE() { double v = 0.0; Read((uint8_t*)&v, 8); return Alg::ByteUtil::BEToSystem(v); } -}; - - -// *** Delegated File - -class DelegatedFile : public File -{ -protected: - // Delegating file pointer - Ptr pFile; - - // Hidden default constructor - DelegatedFile() : pFile(0) { } - DelegatedFile(const DelegatedFile &source) : File() { OVR_UNUSED(source); } -public: - // Constructors - DelegatedFile(File *pfile) : pFile(pfile) { } - - // ** Location Information - virtual const char* GetFilePath() { return pFile->GetFilePath(); } - - // ** File Information - virtual bool IsValid() { return pFile && pFile->IsValid(); } - virtual bool IsWritable() { return pFile->IsWritable(); } -// virtual bool IsRecoverable() { return pFile->IsRecoverable(); } - - virtual int Tell() { return pFile->Tell(); } - virtual int64_t LTell() { return pFile->LTell(); } - - virtual int GetLength() { return pFile->GetLength(); } - virtual int64_t LGetLength() { return pFile->LGetLength(); } - - //virtual bool Stat(FileStats *pfs) { return pFile->Stat(pfs); } - - virtual int GetErrorCode() { return pFile->GetErrorCode(); } - - // ** Stream implementation & I/O - virtual int Write(const uint8_t *pbuffer, int numBytes) { return pFile->Write(pbuffer,numBytes); } - virtual int Read(uint8_t *pbuffer, int numBytes) { return pFile->Read(pbuffer,numBytes); } - - virtual int SkipBytes(int numBytes) { return pFile->SkipBytes(numBytes); } - - virtual int BytesAvailable() { return pFile->BytesAvailable(); } - - virtual bool Flush() { return pFile->Flush(); } - - // Seeking - virtual int Seek(int offset, int origin=Seek_Set) { return pFile->Seek(offset,origin); } - virtual int64_t LSeek(int64_t offset, int origin=Seek_Set) { return pFile->LSeek(offset,origin); } - - virtual int CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); } - - // Closing the file - virtual bool Close() { return pFile->Close(); } -}; - - -//----------------------------------------------------------------------------------- -// ***** Buffered File - -// This file class adds buffering to an existing file -// Buffered file never fails by itself; if there's not -// enough memory for buffer, no buffer's used - -class BufferedFile : public DelegatedFile -{ -protected: - enum BufferModeType - { - NoBuffer, - ReadBuffer, - WriteBuffer - }; - - // Buffer & the mode it's in - uint8_t* pBuffer; - BufferModeType BufferMode; - // Position in buffer - unsigned Pos; - // Data in buffer if reading - unsigned DataSize; - // Underlying file position - uint64_t FilePos; - - // Initializes buffering to a certain mode - bool SetBufferMode(BufferModeType mode); - // Flushes buffer - // WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position - void FlushBuffer(); - // Loads data into ReadBuffer - // WARNING: Right now LoadBuffer() assumes the buffer's empty - void LoadBuffer(); - - // Hidden constructor - BufferedFile(); - BufferedFile(const BufferedFile &) : DelegatedFile(), pBuffer(NULL), BufferMode(NoBuffer), Pos(0), DataSize(0), FilePos(0) { } - -public: - - // Constructor - // - takes another file as source - BufferedFile(File *pfile); - ~BufferedFile(); - - - // ** Overridden functions - - // We override all the functions that can possibly - // require buffer mode switch, flush, or extra calculations - virtual int Tell(); - virtual int64_t LTell(); - - virtual int GetLength(); - virtual int64_t LGetLength(); - -// virtual bool Stat(GFileStats *pfs); - - virtual int Write(const uint8_t *pbufer, int numBytes); - virtual int Read(uint8_t *pbufer, int numBytes); - - virtual int SkipBytes(int numBytes); - - virtual int BytesAvailable(); - - virtual bool Flush(); - - virtual int Seek(int offset, int origin=Seek_Set); - virtual int64_t LSeek(int64_t offset, int origin=Seek_Set); - - virtual int CopyFromStream(File *pstream, int byteSize); - - virtual bool Close(); -}; - - -//----------------------------------------------------------------------------------- -// ***** Memory File - -class MemoryFile : public File -{ -public: - - const char* GetFilePath() { return FilePath.ToCStr(); } - - bool IsValid() { return Valid; } - bool IsWritable() { return false; } - - bool Flush() { return true; } - int GetErrorCode() { return 0; } - - int Tell() { return FileIndex; } - int64_t LTell() { return (int64_t) FileIndex; } - - int GetLength() { return FileSize; } - int64_t LGetLength() { return (int64_t) FileSize; } - - bool Close() - { - Valid = false; - return false; - } - - int CopyFromStream(File *pstream, int byteSize) - { OVR_UNUSED2(pstream, byteSize); - return 0; - } - - int Write(const uint8_t *pbuffer, int numBytes) - { OVR_UNUSED2(pbuffer, numBytes); - return 0; - } - - int Read(uint8_t *pbufer, int numBytes) - { - if (FileIndex + numBytes > FileSize) - { - numBytes = FileSize - FileIndex; - } - - if (numBytes > 0) - { - ::memcpy (pbufer, &FileData [FileIndex], numBytes); - - FileIndex += numBytes; - } - - return numBytes; - } - - int SkipBytes(int numBytes) - { - if (FileIndex + numBytes > FileSize) - { - numBytes = FileSize - FileIndex; - } - - FileIndex += numBytes; - - return numBytes; - } - - int BytesAvailable() - { - return (FileSize - FileIndex); - } - - int Seek(int offset, int origin = Seek_Set) - { - switch (origin) - { - case Seek_Set : FileIndex = offset; break; - case Seek_Cur : FileIndex += offset; break; - case Seek_End : FileIndex = FileSize - offset; break; - } - - return FileIndex; - } - - int64_t LSeek(int64_t offset, int origin = Seek_Set) - { - return (int64_t) Seek((int) offset, origin); - } - -public: - - MemoryFile (const String& fileName, const uint8_t *pBuffer, int buffSize) - : FilePath(fileName) - { - FileData = pBuffer; - FileSize = buffSize; - FileIndex = 0; - Valid = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false; - } - - // pfileName should be encoded as UTF-8 to support international file names. - MemoryFile (const char* pfileName, const uint8_t *pBuffer, int buffSize) - : FilePath(pfileName) - { - FileData = pBuffer; - FileSize = buffSize; - FileIndex = 0; - Valid = (pfileName && pBuffer && buffSize > 0) ? true : false; - } -private: - - String FilePath; - const uint8_t *FileData; - int FileSize; - int FileIndex; - bool Valid; -}; - - -// ***** Global path helpers - -// Find trailing short filename in a path. -const char* OVR_CDECL GetShortFilename(const char* purl); - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_FileFILE.cpp b/LibOVR/Src/Kernel/OVR_FileFILE.cpp deleted file mode 100644 index 9b2123f..0000000 --- a/LibOVR/Src/Kernel/OVR_FileFILE.cpp +++ /dev/null @@ -1,609 +0,0 @@ -/************************************************************************** - -Filename : OVR_FileFILE.cpp -Content : File wrapper class implementation (Win32) - -Created : April 5, 1999 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -**************************************************************************/ - -#define GFILE_CXX - -#include "OVR_Types.h" -#include "OVR_Log.h" - -// Standard C library (Captain Obvious guarantees!) -#include -#ifndef OVR_OS_WINCE -#include -#endif - -#include "OVR_SysFile.h" - -#ifndef OVR_OS_WINCE -#include -#endif - -namespace OVR { - -// ***** File interface - -// ***** FILEFile - C streams file - -static int SFerror () -{ - if (errno == ENOENT) - return FileConstants::Error_FileNotFound; - else if (errno == EACCES || errno == EPERM) - return FileConstants::Error_Access; - else if (errno == ENOSPC) - return FileConstants::Error_DiskFull; - else - return FileConstants::Error_IOError; -}; - -#if defined(OVR_OS_WIN32) -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -// A simple helper class to disable/enable system error mode, if necessary -// Disabling happens conditionally only if a drive name is involved -class SysErrorModeDisabler -{ - BOOL Disabled; - UINT OldMode; -public: - SysErrorModeDisabler(const char* pfileName) - { - if (pfileName && (pfileName[0]!=0) && pfileName[1]==':') - { - Disabled = TRUE; - OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); - } - else - { - Disabled = 0; - OldMode = 0; - } - } - - ~SysErrorModeDisabler() - { - if (Disabled) - ::SetErrorMode(OldMode); - } -}; -#else -class SysErrorModeDisabler -{ -public: - SysErrorModeDisabler(const char* pfileName) { OVR_UNUSED(pfileName); } -}; -#endif // OVR_OS_WIN32 - - -// This macro enables verification of I/O results after seeks against a pre-loaded -// full file buffer copy. This is generally not necessary, but can been used to debug -// memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory -// under FMOD with XP64 (32-bit) and Realtek HA Audio driver. -//#define GFILE_VERIFY_SEEK_ERRORS - - -// This is the simplest possible file implementation, it wraps around the descriptor -// This file is delegated to by SysFile. - -class FILEFile : public File -{ -protected: - - // Allocated filename - String FileName; - - // File handle & open mode - bool Opened; - FILE* fs; - int OpenFlags; - // Error code for last request - int ErrorCode; - - int LastOp; - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - uint8_t* pFileTestBuffer; - unsigned FileTestLength; - unsigned TestPos; // File pointer position during tests. -#endif - -public: - - FILEFile() : - FileName(), - Opened(false), - fs(NULL), - OpenFlags(0), - ErrorCode(0), - LastOp(0) - #ifdef OVR_FILE_VERIFY_SEEK_ERRORS - ,pFileTestBuffer(NULL) - ,FileTestLength(0) - ,TestPos(0) - #endif - { - } - - // Initialize file by opening it - FILEFile(const String& fileName, int flags, int Mode); - - // The 'pfileName' should be encoded as UTF-8 to support international file names. - FILEFile(const char* pfileName, int flags, int Mode); - - ~FILEFile() - { - if (Opened) - Close(); - } - - virtual const char* GetFilePath(); - - // ** File Information - virtual bool IsValid(); - virtual bool IsWritable(); - - // Return position / file size - virtual int Tell(); - virtual int64_t LTell(); - virtual int GetLength(); - virtual int64_t LGetLength(); - -// virtual bool Stat(FileStats *pfs); - virtual int GetErrorCode(); - - // ** Stream implementation & I/O - virtual int Write(const uint8_t *pbuffer, int numBytes); - virtual int Read(uint8_t *pbuffer, int numBytes); - virtual int SkipBytes(int numBytes); - virtual int BytesAvailable(); - virtual bool Flush(); - virtual int Seek(int offset, int origin); - virtual int64_t LSeek(int64_t offset, int origin); - - virtual int CopyFromStream(File *pStream, int byteSize); - virtual bool Close(); -private: - void init(); -}; - - -// Initialize file by opening it -FILEFile::FILEFile(const String& fileName, int flags, int mode) - : FileName(fileName), OpenFlags(flags) -{ - OVR_UNUSED(mode); - init(); -} - -// The 'pfileName' should be encoded as UTF-8 to support international file names. -FILEFile::FILEFile(const char* pfileName, int flags, int mode) - : FileName(pfileName), OpenFlags(flags) -{ - OVR_UNUSED(mode); - init(); -} - -void FILEFile::init() -{ - // Open mode for file's open - const char *omode = "rb"; - - if (OpenFlags & Open_Truncate) - { - if (OpenFlags & Open_Read) - omode = "w+b"; - else - omode = "wb"; - } - else if (OpenFlags & Open_Create) - { - if (OpenFlags & Open_Read) - omode = "a+b"; - else - omode = "ab"; - } - else if (OpenFlags & Open_Write) - omode = "r+b"; - -#if defined(OVR_OS_MS) - SysErrorModeDisabler disabler(FileName.ToCStr()); -#endif - -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - wchar_t womode[16]; - wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t)); - UTF8Util::DecodeString(pwFileName, FileName.ToCStr()); - OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0])); - UTF8Util::DecodeString(womode, omode); - _wfopen_s(&fs, pwFileName, womode); - OVR_FREE(pwFileName); -#else - fs = fopen(FileName.ToCStr(), omode); -#endif - if (fs) - rewind (fs); - Opened = (fs != NULL); - // Set error code - if (!Opened) - ErrorCode = SFerror(); - else - { - // If we are testing file seek correctness, pre-load the entire file so - // that we can do comparison tests later. -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - TestPos = 0; - fseek(fs, 0, SEEK_END); - FileTestLength = ftell(fs); - fseek(fs, 0, SEEK_SET); - pFileTestBuffer = (uint8_t*)OVR_ALLOC(FileTestLength); - if (pFileTestBuffer) - { - OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength)); - Seek(0, Seek_Set); - } -#endif - - ErrorCode = 0; - } - LastOp = 0; -} - - -const char* FILEFile::GetFilePath() -{ - return FileName.ToCStr(); -} - - -// ** File Information -bool FILEFile::IsValid() -{ - return Opened; -} -bool FILEFile::IsWritable() -{ - return IsValid() && (OpenFlags&Open_Write); -} -/* -bool FILEFile::IsRecoverable() -{ - return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC); -} -*/ - -// Return position / file size -int FILEFile::Tell() -{ - int pos = (int)ftell (fs); - if (pos < 0) - ErrorCode = SFerror(); - return pos; -} - -int64_t FILEFile::LTell() -{ - int64_t pos = ftell(fs); - if (pos < 0) - ErrorCode = SFerror(); - return pos; -} - -int FILEFile::GetLength() -{ - int pos = Tell(); - if (pos >= 0) - { - Seek (0, Seek_End); - int size = Tell(); - Seek (pos, Seek_Set); - return size; - } - return -1; -} -int64_t FILEFile::LGetLength() -{ - int64_t pos = LTell(); - if (pos >= 0) - { - LSeek (0, Seek_End); - int64_t size = LTell(); - LSeek (pos, Seek_Set); - return size; - } - return -1; -} - -int FILEFile::GetErrorCode() -{ - return ErrorCode; -} - -// ** Stream implementation & I/O -int FILEFile::Write(const uint8_t *pbuffer, int numBytes) -{ - if (LastOp && LastOp != Open_Write) - fflush(fs); - LastOp = Open_Write; - int written = (int) fwrite(pbuffer, 1, numBytes, fs); - if (written < numBytes) - ErrorCode = SFerror(); - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - if (written > 0) - TestPos += written; -#endif - - return written; -} - -int FILEFile::Read(uint8_t *pbuffer, int numBytes) -{ - if (LastOp && LastOp != Open_Read) - fflush(fs); - LastOp = Open_Read; - int read = (int) fread(pbuffer, 1, numBytes, fs); - if (read < numBytes) - ErrorCode = SFerror(); - -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - if (read > 0) - { - // Read-in data must match our pre-loaded buffer data! - uint8_t* pcompareBuffer = pFileTestBuffer + TestPos; - for (int i=0; i< read; i++) - { - OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]); - } - - //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read)); - TestPos += read; - OVR_ASSERT(ftell(fs) == (int)TestPos); - } -#endif - - return read; -} - -// Seeks ahead to skip bytes -int FILEFile::SkipBytes(int numBytes) -{ - int64_t pos = LTell(); - int64_t newPos = LSeek(numBytes, Seek_Cur); - - // Return -1 for major error - if ((pos==-1) || (newPos==-1)) - { - return -1; - } - //ErrorCode = ((NewPos-Pos) int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; - - szRead = pstream->Read(buff, szRequest); - szWritten = 0; - if (szRead > 0) - szWritten = Write(buff, szRead); - - count += szWritten; - byteSize -= szWritten; - if (szWritten < szRequest) - break; - } - - delete[] buff; - - return count; -} - - -bool FILEFile::Close() -{ -#ifdef OVR_FILE_VERIFY_SEEK_ERRORS - if (pFileTestBuffer) - { - OVR_FREE(pFileTestBuffer); - pFileTestBuffer = 0; - FileTestLength = 0; - } -#endif - - bool closeRet = !fclose(fs); - - if (!closeRet) - { - ErrorCode = SFerror(); - return 0; - } - else - { - Opened = 0; - fs = 0; - ErrorCode = 0; - } - - // Handle safe truncate - /* - if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) - { - // Delete original file (if it existed) - DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName); - if (oldAttributes!=0xFFFFFFFF) - if (!FileUtilWin32::DeleteFile(FileName)) - { - // Try to remove the readonly attribute - FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) ); - // And delete the file again - if (!FileUtilWin32::DeleteFile(FileName)) - return 0; - } - - // Rename temp file to real filename - if (!FileUtilWin32::MoveFile(TempName, FileName)) - { - //ErrorCode = errno; - return 0; - } - } - */ - return 1; -} - -/* -bool FILEFile::CloseCancel() -{ - bool closeRet = (bool)::CloseHandle(fd); - - if (!closeRet) - { - //ErrorCode = errno; - return 0; - } - else - { - Opened = 0; - fd = INVALID_HANDLE_VALUE; - ErrorCode = 0; - } - - // Handle safe truncate (delete tmp file, leave original unchanged) - if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) - if (!FileUtilWin32::DeleteFile(TempName)) - { - //ErrorCode = errno; - return 0; - } - return 1; -} -*/ - -Ptr FileFILEOpen(const String& path, int flags, int mode) -{ - Ptr result = *new FILEFile(path, flags, mode); - return result; -} - -// Helper function: obtain file information time. -bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) -{ -#if defined(OVR_OS_MS) - // 64-bit implementation on Windows. - struct __stat64 fileStat; - // Stat returns 0 for success. - wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t)); - UTF8Util::DecodeString(pwpath, path.ToCStr()); - - int ret = _wstat64(pwpath, &fileStat); - OVR_FREE(pwpath); - if (ret) return false; -#else - struct stat fileStat; - // Stat returns 0 for success. - if (stat(path, &fileStat) != 0) - return false; -#endif - pfileStat->AccessTime = fileStat.st_atime; - pfileStat->ModifyTime = fileStat.st_mtime; - pfileStat->FileSize = fileStat.st_size; - return true; -} - -} // Namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_Hash.h b/LibOVR/Src/Kernel/OVR_Hash.h deleted file mode 100644 index 3316d1e..0000000 --- a/LibOVR/Src/Kernel/OVR_Hash.h +++ /dev/null @@ -1,1305 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_Hash.h -Content : Template hash-table/set implementation -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Hash_h -#define OVR_Hash_h - -#include "OVR_ContainerAllocator.h" -#include "OVR_Alg.h" - -// 'new' operator is redefined/used in this file. -#undef new - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Hash Table Implementation - -// HastSet and Hash. -// -// Hash table, linear probing, internal chaining. One interesting/nice thing -// about this implementation is that the table itself is a flat chunk of memory -// containing no pointers, only relative indices. If the key and value types -// of the Hash contain no pointers, then the Hash can be serialized using raw IO. -// -// Never shrinks, unless you explicitly Clear() it. Expands on -// demand, though. For best results, if you know roughly how big your -// table will be, default it to that size when you create it. -// -// Key usability feature: -// -// 1. Allows node hash values to either be cached or not. -// -// 2. Allows for alternative keys with methods such as GetAlt(). Handy -// if you need to search nodes by their components; no need to create -// temporary nodes. -// - - -// *** Hash functors: -// -// IdentityHash - use when the key is already a good hash -// HFixedSizeHash - general hash based on object's in-memory representation. - - -// Hash is just the input value; can use this for integer-indexed hash tables. -template -class IdentityHash -{ -public: - size_t operator()(const C& data) const - { return (size_t) data; } -}; - -// Computes a hash of an object's representation. -template -class FixedSizeHash -{ -public: - // Alternative: "sdbm" hash function, suggested at same web page - // above, http::/www.cs.yorku.ca/~oz/hash.html - // This is somewhat slower then Bernstein, but it works way better than the above - // hash function for hashing large numbers of 32-bit ints. - static OVR_FORCE_INLINE size_t SDBM_Hash(const void* data_in, size_t size, size_t seed = 5381) - { - const uint8_t* data = (const uint8_t*) data_in; - size_t h = seed; - while (size-- > 0) - { - #ifndef __clang_analyzer__ // It mistakenly thinks data is garbage. - h = (h << 16) + (h << 6) - h + (size_t)data[size]; - #endif - } - return h; - } - - size_t operator()(const C& data) const - { - const unsigned char* p = (const unsigned char*) &data; - const size_t size = sizeof(C); - - return SDBM_Hash(p, size); - } -}; - - - -// *** HashsetEntry Entry types. - -// Compact hash table Entry type that re-computes hash keys during hash traversal. -// Good to use if the hash function is cheap or the hash value is already cached in C. -template -class HashsetEntry -{ -public: - // Internal chaining for collisions. - intptr_t NextInChain; - C Value; - - HashsetEntry() - : NextInChain(-2) { } - HashsetEntry(const HashsetEntry& e) - : NextInChain(e.NextInChain), Value(e.Value) { } - HashsetEntry(const C& key, intptr_t next) - : NextInChain(next), Value(key) { } - - bool IsEmpty() const { return NextInChain == -2; } - bool IsEndOfChain() const { return NextInChain == -1; } - - // Cached hash value access - can be optimized bu storing hash locally. - // Mask value only needs to be used if SetCachedHash is not implemented. - size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; } - void SetCachedHash(size_t) {} - - void Clear() - { - Value.~C(); // placement delete - NextInChain = -2; - } - // Free is only used from dtor of hash; Clear is used during regular operations: - // assignment, hash reallocations, value reassignments, so on. - void Free() { Clear(); } -}; - -// Hash table Entry type that caches the Entry hash value for nodes, so that it -// does not need to be re-computed during access. -template -class HashsetCachedEntry -{ -public: - // Internal chaining for collisions. - intptr_t NextInChain; - size_t HashValue; - C Value; - - HashsetCachedEntry() - : NextInChain(-2) { } - HashsetCachedEntry(const HashsetCachedEntry& e) - : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { } - HashsetCachedEntry(const C& key, intptr_t next) - : NextInChain(next), Value(key) { } - - bool IsEmpty() const { return NextInChain == -2; } - bool IsEndOfChain() const { return NextInChain == -1; } - - // Cached hash value access - can be optimized bu storing hash locally. - // Mask value only needs to be used if SetCachedHash is not implemented. - size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; } - void SetCachedHash(size_t hashValue) { HashValue = hashValue; } - - void Clear() - { - Value.~C(); - NextInChain = -2; - } - // Free is only used from dtor of hash; Clear is used during regular operations: - // assignment, hash reallocations, value reassignments, so on. - void Free() { Clear(); } -}; - - -//----------------------------------------------------------------------------------- -// *** HashSet implementation - relies on either cached or regular entries. -// -// Use: Entry = HashsetCachedEntry if hashes are expensive to -// compute and thus need caching in entries. -// Entry = HashsetEntry if hashes are already externally cached. -// -template, - class AltHashF = HashF, - class Allocator = ContainerAllocator, - class Entry = HashsetCachedEntry > -class HashSetBase -{ - enum { HashMinSize = 8 }; - -public: - OVR_MEMORY_REDEFINE_NEW(HashSetBase) - - typedef HashSetBase SelfType; - - HashSetBase() : pTable(NULL) { } - HashSetBase(int sizeHint) : pTable(NULL) { SetCapacity(this, sizeHint); } - HashSetBase(const SelfType& src) : pTable(NULL) { Assign(this, src); } - - ~HashSetBase() - { - if (pTable) - { - // Delete the entries. - for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) - { - Entry* e = &E(i); - if (!e->IsEmpty()) - e->Free(); - } - - Allocator::Free(pTable); - pTable = NULL; - } - } - - - void Assign(const SelfType& src) - { - Clear(); - if (src.IsEmpty() == false) - { - SetCapacity(src.GetSize()); - - for (ConstIterator it = src.Begin(); it != src.End(); ++it) - { - Add(*it); - } - } - } - - - // Remove all entries from the HashSet table. - void Clear() - { - if (pTable) - { - // Delete the entries. - for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) - { - Entry* e = &E(i); - if (!e->IsEmpty()) - e->Clear(); - } - - Allocator::Free(pTable); - pTable = NULL; - } - } - - // Returns true if the HashSet is empty. - bool IsEmpty() const - { - return pTable == NULL || pTable->EntryCount == 0; - } - - - // Set a new or existing value under the key, to the value. - // Pass a different class of 'key' so that assignment reference object - // can be passed instead of the actual object. - template - void Set(const CRef& key) - { - size_t hashValue = HashF()(key); - intptr_t index = (intptr_t)-1; - - if (pTable != NULL) - index = findIndexCore(key, hashValue & pTable->SizeMask); - - if (index >= 0) - { - E(index).Value = key; - } - else - { - // Entry under key doesn't exist. - add(key, hashValue); - } - } - - template - inline void Add(const CRef& key) - { - size_t hashValue = HashF()(key); - add(key, hashValue); - } - - // Remove by alternative key. - template - void RemoveAlt(const K& key) - { - if (pTable == NULL) - return; - - size_t hashValue = AltHashF()(key); - intptr_t index = hashValue & pTable->SizeMask; - - Entry* e = &E(index); - - // If empty node or occupied by collider, we have nothing to remove. - if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (size_t)index)) - return; - - // Save index - intptr_t naturalIndex = index; - intptr_t prevIndex = -1; - - while ((e->GetCachedHash(pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) - { - // Keep looking through the chain. - prevIndex = index; - index = e->NextInChain; - if (index == -1) - return; // End of chain, item not found - e = &E(index); - } - - // Found it - our item is at index - if (naturalIndex == index) - { - // If we have a follower, move it to us - if (!e->IsEndOfChain()) - { - Entry* enext = &E(e->NextInChain); - e->Clear(); - new (e) Entry(*enext); - // Point us to the follower's cell that will be cleared - e = enext; - } - } - else - { - // We are not at natural index, so deal with the prev items next index - E(prevIndex).NextInChain = e->NextInChain; - } - - // Clear us, of the follower cell that was moved. - e->Clear(); - pTable->EntryCount --; - // Should we check the size to condense hash? ... - } - - // Remove by main key. - template - void Remove(const CRef& key) - { - RemoveAlt(key); - } - - // Retrieve the pointer to a value under the given key. - // - If there's no value under the key, then return NULL. - // - If there is a value, return the pointer. - template - C* Get(const K& key) - { - intptr_t index = findIndex(key); - if (index >= 0) - return &E(index).Value; - return 0; - } - - template - const C* Get(const K& key) const - { - intptr_t index = findIndex(key); - if (index >= 0) - return &E(index).Value; - return 0; - } - - // Alternative key versions of Get. Used by Hash. - template - const C* GetAlt(const K& key) const - { - intptr_t index = findIndexAlt(key); - if (index >= 0) - return &E(index).Value; - return 0; - } - - template - C* GetAlt(const K& key) - { - intptr_t index = findIndexAlt(key); - if (index >= 0) - return &E(index).Value; - return 0; - } - - template - bool GetAlt(const K& key, C* pval) const - { - intptr_t index = findIndexAlt(key); - if (index >= 0) - { - if (pval) - *pval = E(index).Value; - return true; - } - return false; - } - - - size_t GetSize() const - { - return pTable == NULL ? 0 : (size_t)pTable->EntryCount; - } - int GetSizeI() const { return (int)GetSize(); } - - - // Resize the HashSet table to fit one more Entry. Often this - // doesn't involve any action. - void CheckExpand() - { - if (pTable == NULL) - { - // Initial creation of table. Make a minimum-sized table. - setRawCapacity(HashMinSize); - } - else if (pTable->EntryCount * 5 > (pTable->SizeMask + 1) * 4) - { - // pTable is more than 5/4 ths full. Expand. - setRawCapacity((pTable->SizeMask + 1) * 2); - } - } - - // Hint the bucket count to >= n. - void Resize(size_t n) - { - // Not really sure what this means in relation to - // STLport's hash_map... they say they "increase the - // bucket count to at least n" -- but does that mean - // their real capacity after Resize(n) is more like - // n*2 (since they do linked-list chaining within - // buckets?). - SetCapacity(n); - } - - // Size the HashSet so that it can comfortably contain the given - // number of elements. If the HashSet already contains more - // elements than newSize, then this may be a no-op. - void SetCapacity(size_t newSize) - { - size_t newRawSize = (newSize * 5) / 4; - if (newRawSize <= GetSize()) - return; - setRawCapacity(newRawSize); - } - - // Disable inappropriate 'operator ->' warning on MSVC6. -#ifdef OVR_CC_MSVC -#if (OVR_CC_MSVC < 1300) -# pragma warning(disable : 4284) -#endif -#endif - - // Iterator API, like STL. - struct ConstIterator - { - const C& operator * () const - { - OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); - return pHash->E(Index).Value; - } - - const C* operator -> () const - { - OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); - return &pHash->E(Index).Value; - } - - void operator ++ () - { - // Find next non-empty Entry. - if (Index <= (intptr_t)pHash->pTable->SizeMask) - { - Index++; - while ((size_t)Index <= pHash->pTable->SizeMask && - pHash->E(Index).IsEmpty()) - { - Index++; - } - } - } - - bool operator == (const ConstIterator& it) const - { - if (IsEnd() && it.IsEnd()) - { - return true; - } - else - { - return (pHash == it.pHash) && (Index == it.Index); - } - } - - bool operator != (const ConstIterator& it) const - { - return ! (*this == it); - } - - - bool IsEnd() const - { - return (pHash == NULL) || - (pHash->pTable == NULL) || - (Index > (intptr_t)pHash->pTable->SizeMask); - } - - ConstIterator() - : pHash(NULL), Index(0) - { } - - public: - // Constructor was intentionally made public to allow create - // iterator with arbitrary index. - ConstIterator(const SelfType* h, intptr_t index) - : pHash(h), Index(index) - { } - - const SelfType* GetContainer() const - { - return pHash; - } - intptr_t GetIndex() const - { - return Index; - } - - protected: - friend class HashSetBase; - - const SelfType* pHash; - intptr_t Index; - }; - - friend struct ConstIterator; - - - // Non-const Iterator; Get most of it from ConstIterator. - struct Iterator : public ConstIterator - { - // Allow non-const access to entries. - C& operator*() const - { - OVR_ASSERT((ConstIterator::pHash) && ConstIterator::pHash->pTable && (ConstIterator::Index >= 0) && (ConstIterator::Index <= (intptr_t)ConstIterator::pHash->pTable->SizeMask)); - return const_cast(ConstIterator::pHash)->E(ConstIterator::Index).Value; - } - - C* operator->() const - { - return &(operator*()); - } - - Iterator() - : ConstIterator(NULL, 0) - { } - - // Removes current element from Hash - void Remove() - { - RemoveAlt(operator*()); - } - - template - void RemoveAlt(const K& key) - { - SelfType* phash = const_cast(ConstIterator::pHash); - //Entry* ee = &phash->E(ConstIterator::Index); - //const C& key = ee->Value; - - size_t hashValue = AltHashF()(key); - intptr_t index = hashValue & phash->pTable->SizeMask; - - Entry* e = &phash->E(index); - - // If empty node or occupied by collider, we have nothing to remove. - if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (size_t)index)) - return; - - // Save index - intptr_t naturalIndex = index; - intptr_t prevIndex = -1; - - while ((e->GetCachedHash(phash->pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) - { - // Keep looking through the chain. - prevIndex = index; - index = e->NextInChain; - if (index == -1) - return; // End of chain, item not found - e = &phash->E(index); - } - - if (index == (intptr_t)ConstIterator::Index) - { - // Found it - our item is at index - if (naturalIndex == index) - { - // If we have a follower, move it to us - if (!e->IsEndOfChain()) - { - Entry* enext = &phash->E(e->NextInChain); - e->Clear(); - new (e) Entry(*enext); - // Point us to the follower's cell that will be cleared - e = enext; - --ConstIterator::Index; - } - } - else - { - // We are not at natural index, so deal with the prev items next index - phash->E(prevIndex).NextInChain = e->NextInChain; - } - - // Clear us, of the follower cell that was moved. - e->Clear(); - phash->pTable->EntryCount --; - } - else - OVR_ASSERT(0); //? - } - - private: - friend class HashSetBase; - - Iterator(SelfType* h, intptr_t i0) - : ConstIterator(h, i0) - { } - }; - - friend struct Iterator; - - Iterator Begin() - { - if (pTable == 0) - return Iterator(NULL, 0); - - // Scan till we hit the First valid Entry. - size_t i0 = 0; - while (i0 <= pTable->SizeMask && E(i0).IsEmpty()) - { - i0++; - } - return Iterator(this, i0); - } - Iterator End() { return Iterator(NULL, 0); } - - ConstIterator Begin() const { return const_cast(this)->Begin(); } - ConstIterator End() const { return const_cast(this)->End(); } - - template - Iterator Find(const K& key) - { - intptr_t index = findIndex(key); - if (index >= 0) - return Iterator(this, index); - return Iterator(NULL, 0); - } - - template - Iterator FindAlt(const K& key) - { - intptr_t index = findIndexAlt(key); - if (index >= 0) - return Iterator(this, index); - return Iterator(NULL, 0); - } - - template - ConstIterator Find(const K& key) const { return const_cast(this)->Find(key); } - - template - ConstIterator FindAlt(const K& key) const { return const_cast(this)->FindAlt(key); } - -private: - // Find the index of the matching Entry. If no match, then return -1. - template - intptr_t findIndex(const K& key) const - { - if (pTable == NULL) - return -1; - size_t hashValue = HashF()(key) & pTable->SizeMask; - return findIndexCore(key, hashValue); - } - - template - intptr_t findIndexAlt(const K& key) const - { - if (pTable == NULL) - return -1; - size_t hashValue = AltHashF()(key) & pTable->SizeMask; - return findIndexCore(key, hashValue); - } - - // Find the index of the matching Entry. If no match, then return -1. - template - intptr_t findIndexCore(const K& key, size_t hashValue) const - { - // Table must exist. - OVR_ASSERT(pTable != 0); - // Hash key must be 'and-ed' by the caller. - OVR_ASSERT((hashValue & ~pTable->SizeMask) == 0); - - size_t index = hashValue; - const Entry* e = &E(index); - - // If empty or occupied by a collider, not found. - if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != index)) - return -1; - - while(1) - { - OVR_ASSERT(e->GetCachedHash(pTable->SizeMask) == hashValue); - - if (e->GetCachedHash(pTable->SizeMask) == hashValue && e->Value == key) - { - // Found it. - return index; - } - // Values can not be equal at this point. - // That would mean that the hash key for the same value differs. - OVR_ASSERT(!(e->Value == key)); - - // Keep looking through the chain. - index = e->NextInChain; - if (index == (size_t)-1) - break; // end of chain - - e = &E(index); - OVR_ASSERT(!e->IsEmpty()); - } - return -1; - } - - - // Add a new value to the HashSet table, under the specified key. - template - void add(const CRef& key, size_t hashValue) - { - CheckExpand(); - hashValue &= pTable->SizeMask; - - pTable->EntryCount++; - - intptr_t index = hashValue; - Entry* naturalEntry = &(E(index)); - - if (naturalEntry->IsEmpty()) - { - // Put the new Entry in. - new (naturalEntry) Entry(key, -1); - } - else - { - // Find a blank spot. - intptr_t blankIndex = index; - do { - blankIndex = (blankIndex + 1) & pTable->SizeMask; - } while(!E(blankIndex).IsEmpty()); - - Entry* blankEntry = &E(blankIndex); - - if (naturalEntry->GetCachedHash(pTable->SizeMask) == (size_t)index) - { - // Collision. Link into this chain. - - // Move existing list head. - new (blankEntry) Entry(*naturalEntry); // placement new, copy ctor - - // Put the new info in the natural Entry. - naturalEntry->Value = key; - naturalEntry->NextInChain = blankIndex; - } - else - { - // Existing Entry does not naturally - // belong in this slot. Existing - // Entry must be moved. - - // Find natural location of collided element (i.e. root of chain) - intptr_t collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask); - OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); - for (;;) - { - Entry* e = &E(collidedIndex); - if (e->NextInChain == index) - { - // Here's where we need to splice. - new (blankEntry) Entry(*naturalEntry); - e->NextInChain = blankIndex; - break; - } - collidedIndex = e->NextInChain; - OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); - } - - // Put the new data in the natural Entry. - naturalEntry->Value = key; - naturalEntry->NextInChain = -1; - } - } - - // Record hash value: has effect only if cached node is used. - naturalEntry->SetCachedHash(hashValue); - } - - // Index access helpers. - Entry& E(size_t index) - { - // Must have pTable and access needs to be within bounds. - OVR_ASSERT(index <= pTable->SizeMask); - return *(((Entry*) (pTable + 1)) + index); - } - const Entry& E(size_t index) const - { - OVR_ASSERT(index <= pTable->SizeMask); - return *(((Entry*) (pTable + 1)) + index); - } - - - // Resize the HashSet table to the given size (Rehash the - // contents of the current table). The arg is the number of - // HashSet table entries, not the number of elements we should - // actually contain (which will be less than this). - void setRawCapacity(size_t newSize) - { - if (newSize == 0) - { - // Special case. - Clear(); - return; - } - - // Minimum size; don't incur rehashing cost when expanding - // very small tables. Not that we perform this check before - // 'log2f' call to avoid fp exception with newSize == 1. - if (newSize < HashMinSize) - newSize = HashMinSize; - else - { - // Force newSize to be a power of two. - int bits = Alg::UpperBit(newSize-1) + 1; // Chop( Log2f((float)(newSize-1)) + 1); - OVR_ASSERT((size_t(1) << bits) >= newSize); - newSize = size_t(1) << bits; - } - - SelfType newHash; - newHash.pTable = (TableType*) - Allocator::Alloc( - sizeof(TableType) + sizeof(Entry) * newSize); - // Need to do something on alloc failure! - OVR_ASSERT(newHash.pTable); - - newHash.pTable->EntryCount = 0; - newHash.pTable->SizeMask = newSize - 1; - size_t i, n; - - // Mark all entries as empty. - for (i = 0; i < newSize; i++) - newHash.E(i).NextInChain = -2; - - // Copy stuff to newHash - if (pTable) - { - for (i = 0, n = pTable->SizeMask; i <= n; i++) - { - Entry* e = &E(i); - if (e->IsEmpty() == false) - { - // Insert old Entry into new HashSet. - newHash.Add(e->Value); - // placement delete of old element - e->Clear(); - } - } - - // Delete our old data buffer. - Allocator::Free(pTable); - } - - // Steal newHash's data. - pTable = newHash.pTable; - newHash.pTable = NULL; - } - - struct TableType - { - size_t EntryCount; - size_t SizeMask; - // Entry array follows this structure - // in memory. - }; - TableType* pTable; -}; - - - -//----------------------------------------------------------------------------------- -template, - class AltHashF = HashF, - class Allocator = ContainerAllocator, - class Entry = HashsetCachedEntry > -class HashSet : public HashSetBase -{ -public: - typedef HashSetBase BaseType; - typedef HashSet SelfType; - - HashSet() { } - HashSet(int sizeHint) : BaseType(sizeHint) { } - HashSet(const SelfType& src) : BaseType(src) { } - ~HashSet() { } - - void operator = (const SelfType& src) { BaseType::Assign(src); } - - // Set a new or existing value under the key, to the value. - // Pass a different class of 'key' so that assignment reference object - // can be passed instead of the actual object. - template - void Set(const CRef& key) - { - BaseType::Set(key); - } - - template - inline void Add(const CRef& key) - { - BaseType::Add(key); - } - - // Hint the bucket count to >= n. - void Resize(size_t n) - { - BaseType::SetCapacity(n); - } - - // Size the HashSet so that it can comfortably contain the given - // number of elements. If the HashSet already contains more - // elements than newSize, then this may be a no-op. - void SetCapacity(size_t newSize) - { - BaseType::SetCapacity(newSize); - } - -}; - -// HashSet with uncached hash code; declared for convenience. -template, - class AltHashF = HashF, - class Allocator = ContainerAllocator > -class HashSetUncached : public HashSet > -{ -public: - - typedef HashSetUncached SelfType; - typedef HashSet > BaseType; - - // Delegated constructors. - HashSetUncached() { } - HashSetUncached(int sizeHint) : BaseType(sizeHint) { } - HashSetUncached(const SelfType& src) : BaseType(src) { } - ~HashSetUncached() { } - - void operator = (const SelfType& src) - { - BaseType::operator = (src); - } -}; - - -//----------------------------------------------------------------------------------- -// ***** Hash hash table implementation - -// Node for Hash - necessary so that Hash can delegate its implementation -// to HashSet. -template -struct HashNode -{ - typedef HashNode SelfType; - typedef C FirstType; - typedef U SecondType; - - C First; - U Second; - - // NodeRef is used to allow passing of elements into HashSet - // without using a temporary object. - struct NodeRef - { - const C* pFirst; - const U* pSecond; - - NodeRef(const C& f, const U& s) : pFirst(&f), pSecond(&s) { } - NodeRef(const NodeRef& src) : pFirst(src.pFirst), pSecond(src.pSecond) { } - - // Enable computation of ghash_node_hashf. - inline size_t GetHash() const { return HashF()(*pFirst); } - // Necessary conversion to allow HashNode::operator == to work. - operator const C& () const { return *pFirst; } - }; - - // Note: No default constructor is necessary. - HashNode(const HashNode& src) : First(src.First), Second(src.Second) { } - HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond) { } - void operator = (const NodeRef& src) { First = *src.pFirst; Second = *src.pSecond; } - - template - bool operator == (const K& src) const { return (First == src); } - - template - static size_t CalcHash(const K& data) { return HashF()(data); } - inline size_t GetHash() const { return HashF()(First); } - - // Hash functors used with this node. A separate functor is used for alternative - // key lookup so that it does not need to access the '.First' element. - struct NodeHashF - { - template - size_t operator()(const K& data) const { return data.GetHash(); } - }; - struct NodeAltHashF - { - template - size_t operator()(const K& data) const { return HashNode::CalcHash(data); } - }; -}; - - - -// **** Extra hashset_entry types to allow NodeRef construction. - -// The big difference between the below types and the ones used in hash_set is that -// these allow initializing the node with 'typename C::NodeRef& keyRef', which -// is critical to avoid temporary node allocation on stack when using placement new. - -// Compact hash table Entry type that re-computes hash keys during hash traversal. -// Good to use if the hash function is cheap or the hash value is already cached in C. -template -class HashsetNodeEntry -{ -public: - // Internal chaining for collisions. - intptr_t NextInChain; - C Value; - - HashsetNodeEntry() - : NextInChain(-2) { } - HashsetNodeEntry(const HashsetNodeEntry& e) - : NextInChain(e.NextInChain), Value(e.Value) { } - HashsetNodeEntry(const C& key, intptr_t next) - : NextInChain(next), Value(key) { } - HashsetNodeEntry(const typename C::NodeRef& keyRef, intptr_t next) - : NextInChain(next), Value(keyRef) { } - - bool IsEmpty() const { return NextInChain == -2; } - bool IsEndOfChain() const { return NextInChain == -1; } - size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; } - void SetCachedHash(size_t hashValue) { OVR_UNUSED(hashValue); } - - void Clear() - { - Value.~C(); // placement delete - NextInChain = -2; - } - // Free is only used from dtor of hash; Clear is used during regular operations: - // assignment, hash reallocations, value reassignments, so on. - void Free() { Clear(); } -}; - -// Hash table Entry type that caches the Entry hash value for nodes, so that it -// does not need to be re-computed during access. -template -class HashsetCachedNodeEntry -{ -public: - // Internal chaining for collisions. - intptr_t NextInChain; - size_t HashValue; - C Value; - - HashsetCachedNodeEntry() - : NextInChain(-2) { } - HashsetCachedNodeEntry(const HashsetCachedNodeEntry& e) - : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { } - HashsetCachedNodeEntry(const C& key, intptr_t next) - : NextInChain(next), Value(key) { } - HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, intptr_t next) - : NextInChain(next), Value(keyRef) { } - - bool IsEmpty() const { return NextInChain == -2; } - bool IsEndOfChain() const { return NextInChain == -1; } - size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; } - void SetCachedHash(size_t hashValue) { HashValue = hashValue; } - - void Clear() - { - Value.~C(); - NextInChain = -2; - } - // Free is only used from dtor of hash; Clear is used during regular operations: - // assignment, hash reallocations, value reassignments, so on. - void Free() { Clear(); } -}; - - -//----------------------------------------------------------------------------------- -template, - class Allocator = ContainerAllocator, - class HashNode = OVR::HashNode, - class Entry = HashsetCachedNodeEntry, - class Container = HashSet > -class Hash -{ -public: - OVR_MEMORY_REDEFINE_NEW(Hash) - - // Types used for hash_set. - typedef U ValueType; - typedef Hash SelfType; - - // Actual hash table itself, implemented as hash_set. - Container mHash; - -public: - Hash() { } - Hash(int sizeHint) : mHash(sizeHint) { } - Hash(const SelfType& src) : mHash(src.mHash) { } - ~Hash() { } - - void operator = (const SelfType& src) { mHash = src.mHash; } - - // Remove all entries from the Hash table. - inline void Clear() { mHash.Clear(); } - // Returns true if the Hash is empty. - inline bool IsEmpty() const { return mHash.IsEmpty(); } - - // Access (set). - inline void Set(const C& key, const U& value) - { - typename HashNode::NodeRef e(key, value); - mHash.Set(e); - } - inline void Add(const C& key, const U& value) - { - typename HashNode::NodeRef e(key, value); - mHash.Add(e); - } - - // Removes an element by clearing its Entry. - inline void Remove(const C& key) - { - mHash.RemoveAlt(key); - } - template - inline void RemoveAlt(const K& key) - { - mHash.RemoveAlt(key); - } - - // Retrieve the value under the given key. - // - If there's no value under the key, then return false and leave *pvalue alone. - // - If there is a value, return true, and Set *Pvalue to the Entry's value. - // - If value == NULL, return true or false according to the presence of the key. - bool Get(const C& key, U* pvalue) const - { - const HashNode* p = mHash.GetAlt(key); - if (p) - { - if (pvalue) - *pvalue = p->Second; - return true; - } - return false; - } - - template - bool GetAlt(const K& key, U* pvalue) const - { - const HashNode* p = mHash.GetAlt(key); - if (p) - { - if (pvalue) - *pvalue = p->Second; - return true; - } - return false; - } - - // Retrieve the pointer to a value under the given key. - // - If there's no value under the key, then return NULL. - // - If there is a value, return the pointer. - inline U* Get(const C& key) - { - HashNode* p = mHash.GetAlt(key); - return p ? &p->Second : 0; - } - inline const U* Get(const C& key) const - { - const HashNode* p = mHash.GetAlt(key); - return p ? &p->Second : 0; - } - - template - inline U* GetAlt(const K& key) - { - HashNode* p = mHash.GetAlt(key); - return p ? &p->Second : 0; - } - template - inline const U* GetAlt(const K& key) const - { - const HashNode* p = mHash.GetAlt(key); - return p ? &p->Second : 0; - } - - // Sizing methods - delegate to Hash. - inline size_t GetSize() const { return mHash.GetSize(); } - inline int GetSizeI() const { return (int)GetSize(); } - inline void Resize(size_t n) { mHash.Resize(n); } - inline void SetCapacity(size_t newSize) { mHash.SetCapacity(newSize); } - - // Iterator API, like STL. - typedef typename Container::ConstIterator ConstIterator; - typedef typename Container::Iterator Iterator; - - inline Iterator Begin() { return mHash.Begin(); } - inline Iterator End() { return mHash.End(); } - inline ConstIterator Begin() const { return mHash.Begin(); } - inline ConstIterator End() const { return mHash.End(); } - - Iterator Find(const C& key) { return mHash.FindAlt(key); } - ConstIterator Find(const C& key) const { return mHash.FindAlt(key); } - - template - Iterator FindAlt(const K& key) { return mHash.FindAlt(key); } - template - ConstIterator FindAlt(const K& key) const { return mHash.FindAlt(key); } -}; - - - -// Hash with uncached hash code; declared for convenience. -template, class Allocator = ContainerAllocator > -class HashUncached - : public Hash, - HashsetNodeEntry, typename HashNode::NodeHashF> > -{ -public: - typedef HashUncached SelfType; - typedef Hash, - HashsetNodeEntry, - typename HashNode::NodeHashF> > BaseType; - - // Delegated constructors. - HashUncached() { } - HashUncached(int sizeHint) : BaseType(sizeHint) { } - HashUncached(const SelfType& src) : BaseType(src) { } - ~HashUncached() { } - void operator = (const SelfType& src) { BaseType::operator = (src); } -}; - - - -// And identity hash in which keys serve as hash value. Can be uncached, -// since hash computation is assumed cheap. -template, class HashF = IdentityHash > -class HashIdentity - : public HashUncached -{ -public: - typedef HashIdentity SelfType; - typedef HashUncached BaseType; - - // Delegated constructors. - HashIdentity() { } - HashIdentity(int sizeHint) : BaseType(sizeHint) { } - HashIdentity(const SelfType& src) : BaseType(src) { } - ~HashIdentity() { } - void operator = (const SelfType& src) { BaseType::operator = (src); } -}; - - -} // OVR - - -#ifdef OVR_DEFINE_NEW -#define new OVR_DEFINE_NEW -#endif - -#endif diff --git a/LibOVR/Src/Kernel/OVR_KeyCodes.h b/LibOVR/Src/Kernel/OVR_KeyCodes.h deleted file mode 100644 index 8ecdc8b..0000000 --- a/LibOVR/Src/Kernel/OVR_KeyCodes.h +++ /dev/null @@ -1,251 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_KeyCodes.h -Content : Common keyboard constants -Created : September 19, 2012 - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_KeyCodes_h -#define OVR_KeyCodes_h - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** KeyCode - -// KeyCode enumeration defines platform-independent keyboard key constants. -// Note that Key_A through Key_Z are mapped to capital ascii constants. - -enum KeyCode -{ - // Key_None indicates that no key was specified. - Key_None = 0, - - // A through Z and numbers 0 through 9. - Key_A = 65, - Key_B, - Key_C, - Key_D, - Key_E, - Key_F, - Key_G, - Key_H, - Key_I, - Key_J, - Key_K, - Key_L, - Key_M, - Key_N, - Key_O, - Key_P, - Key_Q, - Key_R, - Key_S, - Key_T, - Key_U, - Key_V, - Key_W, - Key_X, - Key_Y, - Key_Z, - Key_Num0 = 48, - Key_Num1, - Key_Num2, - Key_Num3, - Key_Num4, - Key_Num5, - Key_Num6, - Key_Num7, - Key_Num8, - Key_Num9, - - // Numeric keypad. - Key_KP_0 = 0xa0, - Key_KP_1, - Key_KP_2, - Key_KP_3, - Key_KP_4, - Key_KP_5, - Key_KP_6, - Key_KP_7, - Key_KP_8, - Key_KP_9, - Key_KP_Multiply, - Key_KP_Add, - Key_KP_Enter, - Key_KP_Subtract, - Key_KP_Decimal, - Key_KP_Divide, - - // Function keys. - Key_F1 = 0xb0, - Key_F2, - Key_F3, - Key_F4, - Key_F5, - Key_F6, - Key_F7, - Key_F8, - Key_F9, - Key_F10, - Key_F11, - Key_F12, - Key_F13, - Key_F14, - Key_F15, - - // Other keys. - Key_Backspace = 8, - Key_Tab, - Key_Clear = 12, - Key_Return, - Key_Shift = 16, - Key_Control, - Key_Alt, - Key_Pause, - Key_CapsLock = 20, // Toggle - Key_Escape = 27, - Key_Space = 32, - Key_Quote = 39, - Key_PageUp = 0xc0, - Key_PageDown, - Key_End, - Key_Home, - Key_Left, - Key_Up, - Key_Right, - Key_Down, - Key_Insert, - Key_Delete, - Key_Help, - - Key_Comma = 44, - Key_Minus, - Key_Slash = 47, - Key_Period, - Key_NumLock = 144, // Toggle - Key_ScrollLock = 145, // Toggle - - Key_Semicolon = 59, - Key_Equal = 61, - Key_Backtick = 96, // ` and tilda~ when shifted (US keyboard) - Key_BracketLeft = 91, - Key_Backslash, - Key_BracketRight, - - Key_OEM_AX = 0xE1, // 'AX' key on Japanese AX keyboard - Key_OEM_102 = 0xE2, // "<>" or "\|" on RT 102-key keyboard. - Key_ICO_HELP = 0xE3, // Help key on ICO - Key_ICO_00 = 0xE4, // 00 key on ICO - - Key_Meta, - - // Total number of keys. - Key_CodeCount -}; - - -//----------------------------------------------------------------------------------- - -class KeyModifiers -{ -public: - enum - { - Key_ShiftPressed = 0x01, - Key_CtrlPressed = 0x02, - Key_AltPressed = 0x04, - Key_MetaPressed = 0x08, - Key_CapsToggled = 0x10, - Key_NumToggled = 0x20, - Key_ScrollToggled = 0x40, - - Initialized_Bit = 0x80, - Initialized_Mask = 0xFF - }; - unsigned char States; - - KeyModifiers() : States(0) { } - KeyModifiers(unsigned char st) : States((unsigned char)(st | Initialized_Bit)) { } - - void Reset() { States = 0; } - - bool IsShiftPressed() const { return (States & Key_ShiftPressed) != 0; } - bool IsCtrlPressed() const { return (States & Key_CtrlPressed) != 0; } - bool IsAltPressed() const { return (States & Key_AltPressed) != 0; } - bool IsMetaPressed() const { return (States & Key_MetaPressed) != 0; } - bool IsCapsToggled() const { return (States & Key_CapsToggled) != 0; } - bool IsNumToggled() const { return (States & Key_NumToggled) != 0; } - bool IsScrollToggled() const{ return (States & Key_ScrollToggled) != 0; } - - void SetShiftPressed(bool v = true) { (v) ? States |= Key_ShiftPressed : States &= ~Key_ShiftPressed; } - void SetCtrlPressed(bool v = true) { (v) ? States |= Key_CtrlPressed : States &= ~Key_CtrlPressed; } - void SetAltPressed(bool v = true) { (v) ? States |= Key_AltPressed : States &= ~Key_AltPressed; } - void SetMetaPressed(bool v = true) { (v) ? States |= Key_MetaPressed : States &= ~Key_MetaPressed; } - void SetCapsToggled(bool v = true) { (v) ? States |= Key_CapsToggled : States &= ~Key_CapsToggled; } - void SetNumToggled(bool v = true) { (v) ? States |= Key_NumToggled : States &= ~Key_NumToggled; } - void SetScrollToggled(bool v = true) { (v) ? States |= Key_ScrollToggled: States &= ~Key_ScrollToggled; } - - bool IsInitialized() const { return (States & Initialized_Mask) != 0; } -}; - - -//----------------------------------------------------------------------------------- - -/* -enum PadKeyCode -{ - Pad_None, // Indicates absence of key code. - Pad_Back, - Pad_Start, - Pad_A, - Pad_B, - Pad_X, - Pad_Y, - Pad_R1, // RightShoulder; - Pad_L1, // LeftShoulder; - Pad_R2, // RightTrigger; - Pad_L2, // LeftTrigger; - Pad_Up, - Pad_Down, - Pad_Right, - Pad_Left, - Pad_Plus, - Pad_Minus, - Pad_1, - Pad_2, - Pad_H, - Pad_C, - Pad_Z, - Pad_O, - Pad_T, - Pad_S, - Pad_Select, - Pad_Home, - Pad_RT, // RightThumb; - Pad_LT // LeftThumb; -}; -*/ - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_List.h b/LibOVR/Src/Kernel/OVR_List.h deleted file mode 100644 index 7e90af3..0000000 --- a/LibOVR/Src/Kernel/OVR_List.h +++ /dev/null @@ -1,342 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_List.h -Content : Template implementation for doubly-connected linked List -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_List_h -#define OVR_List_h - -#include "OVR_Types.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** ListNode -// -// Base class for the elements of the intrusive linked list. -// To store elements in the List do: -// -// struct MyData : ListNode -// { -// . . . -// }; - -template -struct ListNode -{ - union { - T* pPrev; - void* pVoidPrev; - }; - union { - T* pNext; - void* pVoidNext; - }; - - ListNode() - { - pPrev = NULL; - pNext = NULL; - } - - void RemoveNode() - { - pPrev->pNext = pNext; - pNext->pPrev = pPrev; - } - - // Removes us from the list and inserts pnew there instead. - void ReplaceNodeWith(T* pnew) - { - pPrev->pNext = pnew; - pNext->pPrev = pnew; - pnew->pPrev = pPrev; - pnew->pNext = pNext; - } - - // Inserts the argument linked list node after us in the list. - void InsertNodeAfter(T* p) - { - p->pPrev = pNext->pPrev; // this - p->pNext = pNext; - pNext->pPrev = p; - pNext = p; - } - // Inserts the argument linked list node before us in the list. - void InsertNodeBefore(T* p) - { - p->pNext = pNext->pPrev; // this - p->pPrev = pPrev; - pPrev->pNext = p; - pPrev = p; - } - - void Alloc_MoveTo(ListNode* pdest) - { - pdest->pNext = pNext; - pdest->pPrev = pPrev; - pPrev->pNext = (T*)pdest; - pNext->pPrev = (T*)pdest; - } -}; - - -//------------------------------------------------------------------------ -// ***** List -// -// Doubly linked intrusive list. -// The data type must be derived from ListNode. -// -// Adding: PushFront(), PushBack(). -// Removing: Remove() - the element must be in the list! -// Moving: BringToFront(), SendToBack() - the element must be in the list! -// -// Iterating: -// MyData* data = MyList.GetFirst(); -// while (!MyList.IsNull(data)) -// { -// . . . -// data = MyList.GetNext(data); -// } -// -// Removing: -// MyData* data = MyList.GetFirst(); -// while (!MyList.IsNull(data)) -// { -// MyData* next = MyList.GetNext(data); -// if (ToBeRemoved(data)) -// MyList.Remove(data); -// data = next; -// } -// - -// List<> represents a doubly-linked list of T, where each T must derive -// from ListNode. B specifies the base class that was directly -// derived from ListNode, and is only necessary if there is an intermediate -// inheritance chain. - -template class List -{ -public: - typedef T ValueType; - - List() - { - Root.pNext = Root.pPrev = (ValueType*)&Root; - } - - void Clear() - { - Root.pNext = Root.pPrev = (ValueType*)&Root; - } - - const ValueType* GetFirst() const { return (const ValueType*)Root.pNext; } - const ValueType* GetLast () const { return (const ValueType*)Root.pPrev; } - ValueType* GetFirst() { return (ValueType*)Root.pNext; } - ValueType* GetLast () { return (ValueType*)Root.pPrev; } - - // Determine if list is empty (i.e.) points to itself. - // Go through void* access to avoid issues with strict-aliasing optimizing out the - // access after RemoveNode(), etc. - bool IsEmpty() const { return Root.pVoidNext == (const T*)(const B*)&Root; } - bool IsFirst(const ValueType* p) const { return p == Root.pNext; } - bool IsLast (const ValueType* p) const { return p == Root.pPrev; } - bool IsNull (const ValueType* p) const { return p == (const T*)(const B*)&Root; } - - inline static const ValueType* GetPrev(const ValueType* p) { return (const ValueType*)p->pPrev; } - inline static const ValueType* GetNext(const ValueType* p) { return (const ValueType*)p->pNext; } - inline static ValueType* GetPrev( ValueType* p) { return (ValueType*)p->pPrev; } - inline static ValueType* GetNext( ValueType* p) { return (ValueType*)p->pNext; } - - void PushFront(ValueType* p) - { - p->pNext = Root.pNext; - p->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = p; - Root.pNext = p; - } - - void PushBack(ValueType* p) - { - p->pPrev = Root.pPrev; - p->pNext = (ValueType*)&Root; - Root.pPrev->pNext = p; - Root.pPrev = p; - } - - static void Remove(ValueType* p) - { - p->pPrev->pNext = p->pNext; - p->pNext->pPrev = p->pPrev; - } - - void BringToFront(ValueType* p) - { - Remove(p); - PushFront(p); - } - - void SendToBack(ValueType* p) - { - Remove(p); - PushBack(p); - } - - // Appends the contents of the argument list to the front of this list; - // items are removed from the argument list. - void PushListToFront(List& src) - { - if (!src.IsEmpty()) - { - ValueType* pfirst = src.GetFirst(); - ValueType* plast = src.GetLast(); - src.Clear(); - plast->pNext = Root.pNext; - pfirst->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = plast; - Root.pNext = pfirst; - } - } - - void PushListToBack(List& src) - { - if (!src.IsEmpty()) - { - ValueType* pfirst = src.GetFirst(); - ValueType* plast = src.GetLast(); - src.Clear(); - plast->pNext = (ValueType*)&Root; - pfirst->pPrev = Root.pPrev; - Root.pPrev->pNext = pfirst; - Root.pPrev = plast; - } - } - - // Removes all source list items after (and including) the 'pfirst' node from the - // source list and adds them to out list. - void PushFollowingListItemsToFront(List& src, ValueType *pfirst) - { - if (pfirst != &src.Root) - { - ValueType *plast = src.Root.pPrev; - - // Remove list remainder from source. - pfirst->pPrev->pNext = (ValueType*)&src.Root; - src.Root.pPrev = pfirst->pPrev; - // Add the rest of the items to list. - plast->pNext = Root.pNext; - pfirst->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = plast; - Root.pNext = pfirst; - } - } - - // Removes all source list items up to but NOT including the 'pend' node from the - // source list and adds them to out list. - void PushPrecedingListItemsToFront(List& src, ValueType *ptail) - { - if (src.GetFirst() != ptail) - { - ValueType *pfirst = src.Root.pNext; - ValueType *plast = ptail->pPrev; - - // Remove list remainder from source. - ptail->pPrev = (ValueType*)&src.Root; - src.Root.pNext = ptail; - - // Add the rest of the items to list. - plast->pNext = Root.pNext; - pfirst->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = plast; - Root.pNext = pfirst; - } - } - - - // Removes a range of source list items starting at 'pfirst' and up to, but not including 'pend', - // and adds them to out list. Note that source items MUST already be in the list. - void PushListItemsToFront(ValueType *pfirst, ValueType *pend) - { - if (pfirst != pend) - { - ValueType *plast = pend->pPrev; - - // Remove list remainder from source. - pfirst->pPrev->pNext = pend; - pend->pPrev = pfirst->pPrev; - // Add the rest of the items to list. - plast->pNext = Root.pNext; - pfirst->pPrev = (ValueType*)&Root; - Root.pNext->pPrev = plast; - Root.pNext = pfirst; - } - } - - - void Alloc_MoveTo(List* pdest) - { - if (IsEmpty()) - pdest->Clear(); - else - { - pdest->Root.pNext = Root.pNext; - pdest->Root.pPrev = Root.pPrev; - - Root.pNext->pPrev = (ValueType*)&pdest->Root; - Root.pPrev->pNext = (ValueType*)&pdest->Root; - } - } - - -private: - // Copying is prohibited - List(const List&); - const List& operator = (const List&); - - ListNode Root; -}; - - -//------------------------------------------------------------------------ -// ***** FreeListElements -// -// Remove all elements in the list and free them in the allocator - -template -void FreeListElements(List& list, Allocator& allocator) -{ - typename List::ValueType* self = list.GetFirst(); - while(!list.IsNull(self)) - { - typename List::ValueType* next = list.GetNext(self); - allocator.Free(self); - self = next; - } - list.Clear(); -} - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Lockless.cpp b/LibOVR/Src/Kernel/OVR_Lockless.cpp deleted file mode 100644 index 6a5ec6b..0000000 --- a/LibOVR/Src/Kernel/OVR_Lockless.cpp +++ /dev/null @@ -1,225 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Lockless.cpp -Content : Test logic for lock-less classes -Created : December 27, 2013 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "OVR_Lockless.h" - -#ifdef OVR_LOCKLESS_TEST - -#include "OVR_Threads.h" -#include "OVR_Timer.h" -#include "OVR_Log.h" - -namespace OVR { namespace LocklessTest { - - -const int TestIterations = 10000000; - -// Use volatile dummies to force compiler to do spinning. -volatile int Dummy1; -int Unused1[32]; -volatile int Dummy2; -int Unused2[32]; -volatile int Dummy3; -int Unused3[32]; - - -// Data block out of 20 consecutive integers, should be internally consistent. -struct TestData -{ - enum { ItemCount = 20 }; - - int Data[ItemCount]; - - - void Set(int val) - { - for (int i=0; i TestDataUpdater; - -// Use this lock to verify that testing algorithm is otherwise correct... -Lock TestLock; - - -//------------------------------------------------------------------------------------- - -// Consumer thread reads values from TestDataUpdater and -// ensures that each one is internally consistent. - -class Consumer : public Thread -{ - virtual int Run() - { - LogText("LocklessTest::Consumer::Run started.\n"); - - while (!FirstItemWritten) - { - // spin until producer wrote first value... - } - - TestData d; - int oldValue = 0; - int newValue; - - do - { - { - //Lock::Locker scope(&TestLock); - d = TestDataUpdater.GetState(); - } - - newValue = d.ReadAndCheckConsistency(oldValue); - - // Values should increase or stay the same! - if (newValue < oldValue) - { - LogText("LocklessTest Fail - %d after %d; delta = %d\n", - newValue, oldValue, newValue - oldValue); - // OVR_ASSERT(0); - } - - - if (oldValue != newValue) - { - oldValue = newValue; - - if (oldValue % (TestIterations/30) == 0) - { - LogText("LocklessTest::Consumer - %5.2f%% done\n", - 100.0f * (float)oldValue/(float)TestIterations); - } - } - - // Spin a while - for (int j = 0; j< 300; j++) - { - Dummy3 = j; - } - - - } while (oldValue < (TestIterations * 99 / 100)); - - LogText("LocklessTest::Consumer::Run exiting.\n"); - return 0; - } - -}; - - -//------------------------------------------------------------------------------------- - -class Producer : public Thread -{ - - virtual int Run() - { - LogText("LocklessTest::Producer::Run started.\n"); - - for (int testVal = 0; testVal < TestIterations; testVal++) - { - TestData d; - d.Set(testVal); - - { - //Lock::Locker scope(&TestLock); - TestDataUpdater.SetState(d); - } - - FirstItemWritten = true; - - // Spin a bit - for(int j = 0; j < 1000; j++) - { - Dummy2 = j; - } - - if (testVal % (TestIterations/30) == 0) - { - LogText("LocklessTest::Producer - %5.2f%% done\n", - 100.0f * (float)testVal/(float)TestIterations); - } - } - - LogText("LocklessTest::Producer::Run exiting.\n"); - return 0; - } -}; - - -} // namespace LocklessTest - - - -void StartLocklessTest() -{ - // These threads will release themselves once done - Ptr producerThread = *new LocklessTest::Producer; - Ptr consumerThread = *new LocklessTest::Consumer; - - producerThread->Start(); - consumerThread->Start(); - - while (!producerThread->IsFinished() && consumerThread->IsFinished()) - { - Thread::MSleep(500); - } -} - - -} // namespace OVR - -#endif // OVR_LOCKLESS_TEST diff --git a/LibOVR/Src/Kernel/OVR_Lockless.h b/LibOVR/Src/Kernel/OVR_Lockless.h deleted file mode 100644 index 4d5b87e..0000000 --- a/LibOVR/Src/Kernel/OVR_Lockless.h +++ /dev/null @@ -1,117 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Lockless.h -Content : Lock-less classes for producer/consumer communication -Created : November 9, 2013 -Authors : John Carmack - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Lockless_h -#define OVR_Lockless_h - -#include "OVR_Atomic.h" - -// Define this to compile-in Lockless test logic -//#define OVR_LOCKLESS_TEST - -namespace OVR { - - -// ***** LocklessUpdater - -// For single producer cases where you only care about the most recent update, not -// necessarily getting every one that happens (vsync timing, SensorFusion updates). -// -// This is multiple consumer safe, but is currently only used with a single consumer. -// -// The SlotType can be the same as T, but should probably be a larger fixed size. -// This allows for forward compatibility when the updater is shared between processes. - -// FIXME: ExchangeAdd_Sync() should be replaced with a portable read-only primitive, -// so that the lockless pose state can be read-only on remote processes and to reduce -// false sharing between processes and improve performance. - -template -class LocklessUpdater -{ -public: - LocklessUpdater() : UpdateBegin( 0 ), UpdateEnd( 0 ) - { - OVR_COMPILER_ASSERT(sizeof(T) <= sizeof(SlotType)); - } - - T GetState() const - { - // Copy the state out, then retry with the alternate slot - // if we determine that our copy may have been partially - // stepped on by a new update. - T state; - int begin, end, final; - - for(;;) - { - // We are adding 0, only using these as atomic memory barriers, so it - // is ok to cast off the const, allowing GetState() to remain const. - end = UpdateEnd.Load_Acquire(); - state = Slots[ end & 1 ]; - begin = UpdateBegin.Load_Acquire(); - if ( begin == end ) { - break; - } - - // The producer is potentially blocked while only having partially - // written the update, so copy out the other slot. - state = Slots[ (begin & 1) ^ 1 ]; - final = UpdateBegin.Load_Acquire(); - if ( final == begin ) { - break; - } - - // The producer completed the last update and started a new one before - // we got it copied out, so try fetching the current buffer again. - } - return state; - } - - void SetState( const T& state ) - { - const int slot = UpdateBegin.ExchangeAdd_Sync(1) & 1; - // Write to (slot ^ 1) because ExchangeAdd returns 'previous' value before add. - Slots[slot ^ 1] = state; - UpdateEnd.ExchangeAdd_Sync(1); - } - - AtomicInt UpdateBegin; - AtomicInt UpdateEnd; - SlotType Slots[2]; -}; - - -#ifdef OVR_LOCKLESS_TEST -void StartLocklessTest(); -#endif - - -} // namespace OVR - -#endif // OVR_Lockless_h - diff --git a/LibOVR/Src/Kernel/OVR_Log.cpp b/LibOVR/Src/Kernel/OVR_Log.cpp deleted file mode 100644 index 2631879..0000000 --- a/LibOVR/Src/Kernel/OVR_Log.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Log.cpp -Content : Logging support -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Log.h" -#include "OVR_Std.h" -#include -#include -#include -#include "../Kernel/OVR_System.h" -#include "../Kernel/OVR_DebugHelp.h" -#include "../Util/Util_SystemGUI.h" - -#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) -#define WIN32_LEAN_AND_MEAN -#include -#elif defined(OVR_OS_ANDROID) -#include -#elif defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) -#include -#endif - - -class LogSubject : public OVR::SystemSingletonBase -{ - static bool isShuttingDown; - -public: - - LogSubject(){ - isShuttingDown = false; - // Must be at end of function - PushDestroyCallbacks(); - } - - virtual ~LogSubject(){} // Required because we use delete this below. - - virtual void OnThreadDestroy() - { - isShuttingDown = true; - } - - virtual void OnSystemDestroy() - { - delete this; - } - - static bool IsValid() { - return isShuttingDown == false; - } - - OVR::Lock logSubjectLock; - OVR::ObserverScope logSubject; -}; - -bool LogSubject::isShuttingDown; - -OVR_DEFINE_SINGLETON(LogSubject); - -namespace OVR { - - // Global Log pointer. - Log* volatile OVR_GlobalLog = 0; - -//----------------------------------------------------------------------------------- -// ***** Log Implementation - -Log::Log(unsigned logMask) : - LoggingMask(logMask) -{ -#ifdef OVR_OS_WIN32 - hEventSource = RegisterEventSourceA(NULL, "OculusVR"); - OVR_ASSERT(hEventSource != NULL); -#endif -} - -Log::~Log() -{ -#ifdef OVR_OS_WIN32 - if (hEventSource) - { - DeregisterEventSource(hEventSource); - } -#endif - - // Clear out global log - if (this == OVR_GlobalLog) - { - // TBD: perhaps we should ASSERT if this happens before system shutdown? - OVR_GlobalLog = 0; - } -} -void Log::AddLogObserver(ObserverScope *logObserver) -{ - if (OVR::System::IsInitialized() && LogSubject::GetInstance()->IsValid()) - { - Lock::Locker locker(&LogSubject::GetInstance()->logSubjectLock); - logObserver->GetPtr()->Observe(LogSubject::GetInstance()->logSubject); - } -} -void Log::LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList) -{ - if (OVR::System::IsInitialized() && LogSubject::GetInstance()->IsValid()) - { - // Invoke subject - char buffer[MaxLogBufferMessageSize]; - char* pBuffer = buffer; - char* pAllocated = NULL; - - #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. - va_list argListSaved; - va_copy(argListSaved, argList); - #endif - - int result = FormatLog(pBuffer, MaxLogBufferMessageSize, Log_Text, fmt, argList); - - if(result >= MaxLogBufferMessageSize) // If there was insufficient capacity... - { - pAllocated = (char*)OVR_ALLOC(result + 1); // We assume C++ exceptions are disabled. FormatLog will handle the case that pAllocated is NULL. - pBuffer = pAllocated; - - #if !defined(OVR_CC_MSVC) - va_end(argList); // The caller owns argList and will call va_end on it. - va_copy(argList, argListSaved); - #endif - - FormatLog(pBuffer, (size_t)result + 1, Log_Text, fmt, argList); - } - - Lock::Locker locker(&LogSubject::GetInstance()->logSubjectLock); - LogSubject::GetInstance()->logSubject.GetPtr()->Call(pBuffer, messageType); - - delete[] pAllocated; - } -} - -void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList) -{ - if ((messageType & LoggingMask) == 0) - return; -#ifndef OVR_BUILD_DEBUG - if (IsDebugMessage(messageType)) - return; -#endif - - char buffer[MaxLogBufferMessageSize]; - char* pBuffer = buffer; - char* pAllocated = NULL; - - #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. - va_list argListSaved; - va_copy(argListSaved, argList); - #endif - - int result = FormatLog(pBuffer, MaxLogBufferMessageSize, messageType, fmt, argList); - - if(result >= MaxLogBufferMessageSize) // If there was insufficient capacity... - { - pAllocated = (char*)OVR_ALLOC(result + 1); // We assume C++ exceptions are disabled. FormatLog will handle the case that pAllocated is NULL. - pBuffer = pAllocated; - - #if !defined(OVR_CC_MSVC) - va_end(argList); // The caller owns argList and will call va_end on it. - va_copy(argList, argListSaved); - #endif - - FormatLog(pBuffer, (size_t)result + 1, messageType, fmt, argList); - } - - DefaultLogOutput(pBuffer, messageType, result); - delete[] pAllocated; -} - -void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...) -{ - va_list argList; - va_start(argList, pfmt); - LogMessageVarg(messageType, pfmt, argList); - va_end(argList); -} - - -// Return behavior is the same as ISO C vsnprintf: returns the required strlen of buffer (which will -// be >= bufferSize if bufferSize is insufficient) or returns a negative value because the input was bad. -int Log::FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType, - const char* fmt, va_list argList) -{ - OVR_ASSERT(buffer && (bufferSize >= 10)); // Need to be able to at least print "Assert: \n" to it. - if(!buffer || (bufferSize < 10)) - return -1; - - int addNewline = 1; - int prefixLength = 0; - - switch(messageType) - { - case Log_Error: OVR_strcpy(buffer, bufferSize, "Error: "); prefixLength = 7; break; - case Log_Debug: OVR_strcpy(buffer, bufferSize, "Debug: "); prefixLength = 7; break; - case Log_Assert: OVR_strcpy(buffer, bufferSize, "Assert: "); prefixLength = 8; break; - case Log_Text: buffer[0] = 0; addNewline = 0; break; - case Log_DebugText: buffer[0] = 0; addNewline = 0; break; - default: buffer[0] = 0; addNewline = 0; break; - } - - char* buffer2 = buffer + prefixLength; - size_t size2 = bufferSize - (size_t)prefixLength; - int messageLength = OVR_vsnprintf(buffer2, size2, fmt, argList); - - if (addNewline) - { - if (messageLength < 0) // If there was a format error... - { - // To consider: append to the buffer here. - buffer2[0] = '\n'; // We are guaranteed to have capacity for this. - buffer2[1] = '\0'; - } - else - { - // If the printed string used all of the capacity or required more than the capacity, - // Chop the output by one character so we can append the \n safely. - int messageEnd = (messageLength >= (int)(size2 - 1)) ? (int)(size2 - 2) : messageLength; - buffer2[messageEnd + 0] = '\n'; - buffer2[messageEnd + 1] = '\0'; - } - } - - if (messageLength >= 0) // If the format was OK... - return prefixLength + messageLength + addNewline; // Return the required strlen of buffer. - - return messageLength; // Else we cannot know what the required strlen is and return the error to the caller. -} - -void Log::DefaultLogOutput(const char* formattedText, LogMessageType messageType, int bufferSize) -{ - bool debug = IsDebugMessage(messageType); - OVR_UNUSED(bufferSize); - -#if defined(OVR_OS_WIN32) - // Under Win32, output regular messages to console if it exists; debug window otherwise. - static DWORD dummyMode; - static bool hasConsole = (GetStdHandle(STD_OUTPUT_HANDLE) != INVALID_HANDLE_VALUE) && - (GetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE), &dummyMode)); - - if (!hasConsole || debug) - { - ::OutputDebugStringA(formattedText); - } - - fputs(formattedText, stdout); - -#elif defined(OVR_OS_MS) // Any other Microsoft OSs - - ::OutputDebugStringA(formattedText); - -#elif defined(OVR_OS_ANDROID) - // To do: use bufferSize to deal with the case that Android has a limited output length. - __android_log_write(ANDROID_LOG_INFO, "OVR", formattedText); - -#else - fputs(formattedText, stdout); - -#endif - - if (messageType == Log_Error) - { -#if defined(OVR_OS_WIN32) - if (!ReportEventA(hEventSource, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 1, 0, &formattedText, NULL)) - { - OVR_ASSERT(false); - } -#elif defined(OVR_OS_MS) // Any other Microsoft OSs - // TBD -#elif defined(OVR_OS_ANDROID) - // TBD -#elif defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) - syslog(LOG_ERR, "%s", formattedText); -#else - // TBD -#endif - } - - // Just in case. - OVR_UNUSED2(formattedText, debug); -} - - -//static -void Log::SetGlobalLog(Log *log) -{ - OVR_GlobalLog = log; -} -//static -Log* Log::GetGlobalLog() -{ -// No global log by default? -// if (!OVR_GlobalLog) -// OVR_GlobalLog = GetDefaultLog(); - return OVR_GlobalLog; -} - -//static -Log* Log::GetDefaultLog() -{ - // Create default log pointer statically so that it can be used - // even during startup. - static Log defaultLog; - return &defaultLog; -} - - -//----------------------------------------------------------------------------------- -// ***** Global Logging functions - -#if !defined(OVR_CC_MSVC) -// The reason for va_copy is because you can't use va_start twice on Linux -#define OVR_LOG_FUNCTION_IMPL(Name) \ - void Log##Name(const char* fmt, ...) \ - { \ - if (OVR_GlobalLog) \ - { \ - va_list argList1; \ - va_start(argList1, fmt); \ - va_list argList2; \ - va_copy(argList2, argList1); \ - OVR_GlobalLog->LogMessageVargInt(Log_##Name, fmt, argList2); \ - va_end(argList2); \ - OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList1); \ - va_end(argList1); \ - } \ - } -#else -#define OVR_LOG_FUNCTION_IMPL(Name) \ - void Log##Name(const char* fmt, ...) \ - { \ - if (OVR_GlobalLog) \ - { \ - va_list argList1; \ - va_start(argList1, fmt); \ - OVR_GlobalLog->LogMessageVargInt(Log_##Name, fmt, argList1); \ - OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList1); \ - va_end(argList1); \ - } \ - } -#endif // #if !defined(OVR_OS_WIN32) - -OVR_LOG_FUNCTION_IMPL(Text) -OVR_LOG_FUNCTION_IMPL(Error) - -#ifdef OVR_BUILD_DEBUG -OVR_LOG_FUNCTION_IMPL(DebugText) -OVR_LOG_FUNCTION_IMPL(Debug) -OVR_LOG_FUNCTION_IMPL(Assert) -#endif - - - -// Assertion handler support -// To consider: Move this to an OVR_Types.cpp or OVR_Assert.cpp source file. - -static OVRAssertionHandler sOVRAssertionHandler = OVR::DefaultAssertionHandler; -static intptr_t sOVRAssertionHandlerUserParameter = 0; - -OVRAssertionHandler GetAssertionHandler(intptr_t* userParameter) -{ - if(userParameter) - *userParameter = sOVRAssertionHandlerUserParameter; - return sOVRAssertionHandler; -} - -void SetAssertionHandler(OVRAssertionHandler assertionHandler, intptr_t userParameter) -{ - sOVRAssertionHandler = assertionHandler; - sOVRAssertionHandlerUserParameter = userParameter; -} - -intptr_t DefaultAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message) -{ - if(OVRIsDebuggerPresent()) - { - OVR_DEBUG_BREAK; - } - else - { - #if defined(OVR_BUILD_DEBUG) - // Print a stack trace of all threads. - OVR::String s; - OVR::String threadListOutput; - static OVR::SymbolLookup symbolLookup; - - s = "Failure: "; - s += message; - - if(symbolLookup.Initialize() && symbolLookup.ReportThreadCallstack(threadListOutput, 4)) // This '4' is there to skip our internal handling and retrieve starting at the assertion location (our caller) only. - { - s += "\r\n\r\n"; - s += threadListOutput; - } - - OVR::Util::DisplayMessageBox(title, s.ToCStr()); - #else - OVR::Util::DisplayMessageBox(title, message); - #endif - } - - return 0; -} - - - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_Log.h b/LibOVR/Src/Kernel/OVR_Log.h deleted file mode 100644 index 5982395..0000000 --- a/LibOVR/Src/Kernel/OVR_Log.h +++ /dev/null @@ -1,227 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_Log.h -Content : Logging support -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Log_h -#define OVR_Log_h - -#include "OVR_Types.h" -#include "../Kernel/OVR_Delegates.h" -#include "../Kernel//OVR_Observer.h" -#include - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Logging Constants - -// LogMaskConstants defined bit mask constants that describe what log messages -// should be displayed. -enum LogMaskConstants -{ - LogMask_Regular = 0x100, - LogMask_Debug = 0x200, - LogMask_None = 0, - LogMask_All = LogMask_Regular|LogMask_Debug -}; - - -// LogMessageType describes the type of the log message, controls when it is -// displayed and what prefix/suffix is given to it. Messages are subdivided into -// regular and debug logging types. Debug logging is only generated in debug builds. -// -// Log_Text - General output text displayed without prefix or new-line. -// Used in OVR libraries for general log flow messages -// such as "Device Initialized". -// -// Log_Error - Error message output with "Error: %s\n", intended for -// application/sample-level use only, in cases where an expected -// operation failed. OVR libraries should not use this internally, -// reporting status codes instead. -// -// Log_DebugText - Message without prefix or new lines; output in Debug build only. -// -// Log_Debug - Debug-build only message, formatted with "Debug: %s\n". -// Intended to comment on incorrect API usage that doesn't lead -// to crashes but can be avoided with proper use. -// There is no Debug Error on purpose, since real errors should -// be handled by API user. -// -// Log_Assert - Debug-build only message, formatted with "Assert: %s\n". -// Intended for severe unrecoverable conditions in library -// source code. Generated though OVR_ASSERT_MSG(c, "Text"). - -enum LogMessageType -{ - // General Logging - Log_Text = LogMask_Regular | 0, - Log_Error = LogMask_Regular | 1, // "Error: %s\n". - - // Debug-only messages (not generated in release build) - Log_DebugText = LogMask_Debug | 0, - Log_Debug = LogMask_Debug | 1, // "Debug: %s\n". - Log_Assert = LogMask_Debug | 2, // "Assert: %s\n". -}; - - -// LOG_VAARG_ATTRIBUTE macro, enforces printf-style fromatting for message types -#ifdef __GNUC__ -# define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b))) -#else -# define OVR_LOG_VAARG_ATTRIBUTE(a,b) -#endif - -//----------------------------------------------------------------------------------- -// ***** Log - -// Log defines a base class interface that can be implemented to catch both -// debug and runtime messages. -// Debug logging can be overridden by calling Log::SetGlobalLog. - -class Log -{ - friend class System; - -#ifdef OVR_OS_WIN32 - void* hEventSource; -#endif - -public: - Log(unsigned logMask = LogMask_Debug); - virtual ~Log(); - - typedef Delegate2 LogHandler; - - // The following is deprecated, as there is no longer a max log buffer message size. - enum { MaxLogBufferMessageSize = 4096 }; - - unsigned GetLoggingMask() const { return LoggingMask; } - void SetLoggingMask(unsigned logMask) { LoggingMask = logMask; } - - // Internal - // Invokes observers, then calls LogMessageVarg() - static void LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList); - - // This virtual function receives all the messages, - // developers should override this function in order to do custom logging - virtual void LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList); - - static void AddLogObserver(ObserverScope *logObserver); - - // Call the logging function with specific message type, with no type filtering. - void LogMessage(LogMessageType messageType, - const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4); - - - // Helper used by LogMessageVarg to format the log message, writing the resulting - // string into buffer. It formats text based on fmt and appends prefix/new line - // based on LogMessageType. Return behavior is the same as ISO C vsnprintf: returns the - // required strlen of buffer (which will be >= bufferSize if bufferSize is insufficient) - // or returns a negative value because the input was bad. - static int FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType, - const char* fmt, va_list argList); - - // Default log output implementation used by by LogMessageVarg. - // Debug flag may be used to re-direct output on some platforms, but doesn't - // necessarily disable it in release builds; that is the job of the called. - void DefaultLogOutput(const char* textBuffer, LogMessageType messageType, int bufferSize = -1); - - // Determines if the specified message type is for debugging only. - static bool IsDebugMessage(LogMessageType messageType) - { - return (messageType & LogMask_Debug) != 0; - } - - // *** Global APIs - - // Global Log registration APIs. - // - Global log is used for OVR_DEBUG messages. Set global log to null (0) - // to disable all logging. - static void SetGlobalLog(Log *log); - static Log* GetGlobalLog(); - - // Returns default log singleton instance. - static Log* GetDefaultLog(); - - // Applies logMask to the default log and returns a pointer to it. - // By default, only Debug logging is enabled, so to avoid SDK generating console - // messages in user app (those are always disabled in release build, - // even if the flag is set). This function is useful in System constructor. - static Log* ConfigureDefaultLog(unsigned logMask = LogMask_Debug) - { - Log* log = GetDefaultLog(); - log->SetLoggingMask(logMask); - return log; - } - -private: - // Logging mask described by LogMaskConstants. - unsigned LoggingMask; -}; - - -//----------------------------------------------------------------------------------- -// ***** Global Logging Functions and Debug Macros - -// These functions will output text to global log with semantics described by -// their LogMessageType. -void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); -void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); - -#ifdef OVR_BUILD_DEBUG - - // Debug build only logging. - void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); - void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); - void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); - - // Macro to do debug logging, printf-style. - // An extra set of set of parenthesis must be used around arguments, - // as in: OVR_DEBUG_LOG(("Value %d", 2)). - #define OVR_DEBUG_LOG(args) do { OVR::LogDebug args; } while(0) - #define OVR_DEBUG_LOG_TEXT(args) do { OVR::LogDebugText args; } while(0) - - // Conditional logging. It logs when the condition 'c' is true. - #define OVR_DEBUG_LOG_COND(c, args) do { if ((c)) { OVR::LogDebug args; } } while(0) - #define OVR_DEBUG_LOG_TEXT_COND(c, args) do { if ((c)) { OVR::LogDebugText args; } } while(0) - - // Conditional logging & asserting. It asserts/logs when the condition 'c' is NOT true. - #define OVR_ASSERT_LOG(c, args) do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0) - -#else - - // If not in debug build, macros do nothing. - #define OVR_DEBUG_LOG(args) ((void)0) - #define OVR_DEBUG_LOG_TEXT(args) ((void)0) - #define OVR_DEBUG_LOG_COND(c, args) ((void)0) - #define OVR_DEBUG_LOG_TEXT_COND(args) ((void)0) - #define OVR_ASSERT_LOG(c, args) ((void)0) - -#endif - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Math.cpp b/LibOVR/Src/Kernel/OVR_Math.cpp deleted file mode 100644 index 52977ed..0000000 --- a/LibOVR/Src/Kernel/OVR_Math.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Math.h -Content : Implementation of 3D primitives such as vectors, matrices. -Created : September 4, 2012 -Authors : Andrew Reisse, Michael Antonov, Anna Yershova - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "OVR_Math.h" -#include "OVR_Log.h" - -#include - - -namespace OVR { - - -//------------------------------------------------------------------------------------- -// ***** Constants - -template<> -const Vector3 Vector3::ZERO = Vector3(); - -template<> -const Vector3 Vector3::ZERO = Vector3(); - -template<> -const Matrix4 Matrix4::IdentityValue = Matrix4(1.0f, 0.0f, 0.0f, 0.0f, - 0.0f, 1.0f, 0.0f, 0.0f, - 0.0f, 0.0f, 1.0f, 0.0f, - 0.0f, 0.0f, 0.0f, 1.0f); - -template<> -const Matrix4 Matrix4::IdentityValue = Matrix4(1.0, 0.0, 0.0, 0.0, - 0.0, 1.0, 0.0, 0.0, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0); - - -} // Namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_Math.h b/LibOVR/Src/Kernel/OVR_Math.h deleted file mode 100644 index c187cda..0000000 --- a/LibOVR/Src/Kernel/OVR_Math.h +++ /dev/null @@ -1,2791 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Math.h -Content : Implementation of 3D primitives such as vectors, matrices. -Created : September 4, 2012 -Authors : Andrew Reisse, Michael Antonov, Steve LaValle, - Anna Yershova, Max Katsev, Dov Katz - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Math_h -#define OVR_Math_h - -#include -#include -#include - -#include "OVR_Types.h" -#include "OVR_RefCount.h" -#include "OVR_Std.h" -#include "OVR_Alg.h" - - -namespace OVR { - -//------------------------------------------------------------------------------------- -// ***** Constants for 3D world/axis definitions. - -// Definitions of axes for coordinate and rotation conversions. -enum Axis -{ - Axis_X = 0, Axis_Y = 1, Axis_Z = 2 -}; - -// RotateDirection describes the rotation direction around an axis, interpreted as follows: -// CW - Clockwise while looking "down" from positive axis towards the origin. -// CCW - Counter-clockwise while looking from the positive axis towards the origin, -// which is in the negative axis direction. -// CCW is the default for the RHS coordinate system. Oculus standard RHS coordinate -// system defines Y up, X right, and Z back (pointing out from the screen). In this -// system Rotate_CCW around Z will specifies counter-clockwise rotation in XY plane. -enum RotateDirection -{ - Rotate_CCW = 1, - Rotate_CW = -1 -}; - -// Constants for right handed and left handed coordinate systems -enum HandedSystem -{ - Handed_R = 1, Handed_L = -1 -}; - -// AxisDirection describes which way the coordinate axis points. Used by WorldAxes. -enum AxisDirection -{ - Axis_Up = 2, - Axis_Down = -2, - Axis_Right = 1, - Axis_Left = -1, - Axis_In = 3, - Axis_Out = -3 -}; - -struct WorldAxes -{ - AxisDirection XAxis, YAxis, ZAxis; - - WorldAxes(AxisDirection x, AxisDirection y, AxisDirection z) - : XAxis(x), YAxis(y), ZAxis(z) - { OVR_ASSERT(abs(x) != abs(y) && abs(y) != abs(z) && abs(z) != abs(x));} -}; - -} // namespace OVR - - -//------------------------------------------------------------------------------------// -// ***** C Compatibility Types - -// These declarations are used to support conversion between C types used in -// LibOVR C interfaces and their C++ versions. As an example, they allow passing -// Vector3f into a function that expects ovrVector3f. - -typedef struct ovrQuatf_ ovrQuatf; -typedef struct ovrQuatd_ ovrQuatd; -typedef struct ovrSizei_ ovrSizei; -typedef struct ovrSizef_ ovrSizef; -typedef struct ovrRecti_ ovrRecti; -typedef struct ovrVector2i_ ovrVector2i; -typedef struct ovrVector2f_ ovrVector2f; -typedef struct ovrVector3f_ ovrVector3f; -typedef struct ovrVector3d_ ovrVector3d; -typedef struct ovrMatrix3d_ ovrMatrix3d; -typedef struct ovrMatrix4f_ ovrMatrix4f; -typedef struct ovrPosef_ ovrPosef; -typedef struct ovrPosed_ ovrPosed; -typedef struct ovrPoseStatef_ ovrPoseStatef; -typedef struct ovrPoseStated_ ovrPoseStated; - -namespace OVR { - -// Forward-declare our templates. -template class Quat; -template class Size; -template class Rect; -template class Vector2; -template class Vector3; -template class Matrix3; -template class Matrix4; -template class Pose; -template class PoseState; - -// CompatibleTypes::Type is used to lookup a compatible C-version of a C++ class. -template -struct CompatibleTypes -{ - // Declaration here seems necessary for MSVC; specializations are - // used instead. - typedef struct {} Type; -}; - -// Specializations providing CompatibleTypes::Type value. -template<> struct CompatibleTypes > { typedef ovrQuatf Type; }; -template<> struct CompatibleTypes > { typedef ovrQuatd Type; }; -template<> struct CompatibleTypes > { typedef ovrMatrix3d Type; }; -template<> struct CompatibleTypes > { typedef ovrMatrix4f Type; }; -template<> struct CompatibleTypes > { typedef ovrSizei Type; }; -template<> struct CompatibleTypes > { typedef ovrSizef Type; }; -template<> struct CompatibleTypes > { typedef ovrRecti Type; }; -template<> struct CompatibleTypes > { typedef ovrVector2i Type; }; -template<> struct CompatibleTypes > { typedef ovrVector2f Type; }; -template<> struct CompatibleTypes > { typedef ovrVector3f Type; }; -template<> struct CompatibleTypes > { typedef ovrVector3d Type; }; - -template<> struct CompatibleTypes > { typedef ovrPosef Type; }; -template<> struct CompatibleTypes > { typedef ovrPosed Type; }; - -//------------------------------------------------------------------------------------// -// ***** Math -// -// Math class contains constants and functions. This class is a template specialized -// per type, with Math and Math being distinct. -template -class Math -{ -public: - // By default, support explicit conversion to float. This allows Vector2 to - // compile, for example. - typedef float OtherFloatType; -}; - - -#define MATH_FLOAT_PI (3.1415926f) -#define MATH_FLOAT_TWOPI (2.0f *MATH_FLOAT_PI) -#define MATH_FLOAT_PIOVER2 (0.5f *MATH_FLOAT_PI) -#define MATH_FLOAT_PIOVER4 (0.25f*MATH_FLOAT_PI) -#define MATH_FLOAT_E (2.7182818f) -#define MATH_FLOAT_MAXVALUE (FLT_MAX) -#define MATH_FLOAT MINPOSITIVEVALUE (FLT_MIN) -#define MATH_FLOAT_RADTODEGREEFACTOR (360.0f / MATH_FLOAT_TWOPI) -#define MATH_FLOAT_DEGREETORADFACTOR (MATH_FLOAT_TWOPI / 360.0f) -#define MATH_FLOAT_TOLERANCE (0.00001f) -#define MATH_FLOAT_SINGULARITYRADIUS (0.0000001f) // Use for Gimbal lock numerical problems - -#define MATH_DOUBLE_PI (3.14159265358979) -#define MATH_DOUBLE_TWOPI (2.0f *MATH_DOUBLE_PI) -#define MATH_DOUBLE_PIOVER2 (0.5f *MATH_DOUBLE_PI) -#define MATH_DOUBLE_PIOVER4 (0.25f*MATH_DOUBLE_PI) -#define MATH_DOUBLE_E (2.71828182845905) -#define MATH_DOUBLE_MAXVALUE (DBL_MAX) -#define MATH_DOUBLE MINPOSITIVEVALUE (DBL_MIN) -#define MATH_DOUBLE_RADTODEGREEFACTOR (360.0f / MATH_DOUBLE_TWOPI) -#define MATH_DOUBLE_DEGREETORADFACTOR (MATH_DOUBLE_TWOPI / 360.0f) -#define MATH_DOUBLE_TOLERANCE (0.00001) -#define MATH_DOUBLE_SINGULARITYRADIUS (0.000000000001) // Use for Gimbal lock numerical problems - - - - -// Single-precision Math constants class. -template<> -class Math -{ -public: - typedef double OtherFloatType; -}; - -// Double-precision Math constants class. -template<> -class Math -{ -public: - typedef float OtherFloatType; -}; - - -typedef Math Mathf; -typedef Math Mathd; - -// Conversion functions between degrees and radians -template -T RadToDegree(T rads) { return rads * ((T)MATH_DOUBLE_RADTODEGREEFACTOR); } -template -T DegreeToRad(T rads) { return rads * ((T)MATH_DOUBLE_DEGREETORADFACTOR); } - -// Numerically stable acos function -template -T Acos(T val) { - if (val > T(1)) return T(0); - else if (val < T(-1)) return ((T)MATH_DOUBLE_PI); - else return acos(val); -}; - -// Numerically stable asin function -template -T Asin(T val) { - if (val > T(1)) return ((T)MATH_DOUBLE_PIOVER2); - else if (val < T(-1)) return ((T)MATH_DOUBLE_PIOVER2) * T(3); - else return asin(val); -}; - -#ifdef OVR_CC_MSVC -inline int isnan(double x) { return _isnan(x); }; -#endif - -template -class Quat; - - -//------------------------------------------------------------------------------------- -// ***** Vector2<> - -// Vector2f (Vector2d) represents a 2-dimensional vector or point in space, -// consisting of coordinates x and y - -template -class Vector2 -{ -public: - T x, y; - - Vector2() : x(0), y(0) { } - Vector2(T x_, T y_) : x(x_), y(y_) { } - explicit Vector2(T s) : x(s), y(s) { } - explicit Vector2(const Vector2::OtherFloatType> &src) - : x((T)src.x), y((T)src.y) { } - - - // C-interop support. - typedef typename CompatibleTypes >::Type CompatibleType; - - Vector2(const CompatibleType& s) : x(s.x), y(s.y) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Vector2) == sizeof(CompatibleType), "sizeof(Vector2) failure"); - return reinterpret_cast(*this); - } - - - bool operator== (const Vector2& b) const { return x == b.x && y == b.y; } - bool operator!= (const Vector2& b) const { return x != b.x || y != b.y; } - - Vector2 operator+ (const Vector2& b) const { return Vector2(x + b.x, y + b.y); } - Vector2& operator+= (const Vector2& b) { x += b.x; y += b.y; return *this; } - Vector2 operator- (const Vector2& b) const { return Vector2(x - b.x, y - b.y); } - Vector2& operator-= (const Vector2& b) { x -= b.x; y -= b.y; return *this; } - Vector2 operator- () const { return Vector2(-x, -y); } - - // Scalar multiplication/division scales vector. - Vector2 operator* (T s) const { return Vector2(x*s, y*s); } - Vector2& operator*= (T s) { x *= s; y *= s; return *this; } - - Vector2 operator/ (T s) const { T rcp = T(1)/s; - return Vector2(x*rcp, y*rcp); } - Vector2& operator/= (T s) { T rcp = T(1)/s; - x *= rcp; y *= rcp; - return *this; } - - static Vector2 Min(const Vector2& a, const Vector2& b) { return Vector2((a.x < b.x) ? a.x : b.x, - (a.y < b.y) ? a.y : b.y); } - static Vector2 Max(const Vector2& a, const Vector2& b) { return Vector2((a.x > b.x) ? a.x : b.x, - (a.y > b.y) ? a.y : b.y); } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool Compare(const Vector2&b, T tolerance = ((T)MATH_DOUBLE_TOLERANCE)) - { - return (fabs(b.x-x) < tolerance) && (fabs(b.y-y) < tolerance); - } - - // Access element by index - T& operator[] (int idx) - { - OVR_ASSERT(0 <= idx && idx < 2); - return *(&x + idx); - } - const T& operator[] (int idx) const - { - OVR_ASSERT(0 <= idx && idx < 2); - return *(&x + idx); - } - - // Entry-wise product of two vectors - Vector2 EntrywiseMultiply(const Vector2& b) const { return Vector2(x * b.x, y * b.y);} - - - // Multiply and divide operators do entry-wise math. Used Dot() for dot product. - Vector2 operator* (const Vector2& b) const { return Vector2(x * b.x, y * b.y); } - Vector2 operator/ (const Vector2& b) const { return Vector2(x / b.x, y / b.y); } - - // Dot product - // Used to calculate angle q between two vectors among other things, - // as (A dot B) = |a||b|cos(q). - T Dot(const Vector2& b) const { return x*b.x + y*b.y; } - - // Returns the angle from this vector to b, in radians. - T Angle(const Vector2& b) const - { - T div = LengthSq()*b.LengthSq(); - OVR_ASSERT(div != T(0)); - T result = Acos((this->Dot(b))/sqrt(div)); - return result; - } - - // Return Length of the vector squared. - T LengthSq() const { return (x * x + y * y); } - - // Return vector length. - T Length() const { return sqrt(LengthSq()); } - - // Returns squared distance between two points represented by vectors. - T DistanceSq(const Vector2& b) const { return (*this - b).LengthSq(); } - - // Returns distance between two points represented by vectors. - T Distance(const Vector2& b) const { return (*this - b).Length(); } - - // Determine if this a unit vector. - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } - - // Normalize, convention vector length to 1. - void Normalize() - { - T l = Length(); - OVR_ASSERT(l != T(0)); - *this /= l; - } - // Returns normalized (unit) version of the vector without modifying itself. - Vector2 Normalized() const - { - T l = Length(); - OVR_ASSERT(l != T(0)); - return *this / l; - } - - // Linearly interpolates from this vector to another. - // Factor should be between 0.0 and 1.0, with 0 giving full value to this. - Vector2 Lerp(const Vector2& b, T f) const { return *this*(T(1) - f) + b*f; } - - // Projects this vector onto the argument; in other words, - // A.Project(B) returns projection of vector A onto B. - Vector2 ProjectTo(const Vector2& b) const - { - T l2 = b.LengthSq(); - OVR_ASSERT(l2 != T(0)); - return b * ( Dot(b) / l2 ); - } -}; - - -typedef Vector2 Vector2f; -typedef Vector2 Vector2d; -typedef Vector2 Vector2i; - -typedef Vector2 Point2f; -typedef Vector2 Point2d; -typedef Vector2 Point2i; - -//------------------------------------------------------------------------------------- -// ***** Vector3<> - 3D vector of {x, y, z} - -// -// Vector3f (Vector3d) represents a 3-dimensional vector or point in space, -// consisting of coordinates x, y and z. - -template -class Vector3 -{ -public: - T x, y, z; - - // FIXME: default initialization of a vector class can be very expensive in a full-blown - // application. A few hundred thousand vector constructions is not unlikely and can add - // up to milliseconds of time on processors like the PS3 PPU. - Vector3() : x(0), y(0), z(0) { } - Vector3(T x_, T y_, T z_ = 0) : x(x_), y(y_), z(z_) { } - explicit Vector3(T s) : x(s), y(s), z(s) { } - explicit Vector3(const Vector3::OtherFloatType> &src) - : x((T)src.x), y((T)src.y), z((T)src.z) { } - - static const Vector3 ZERO; - - // C-interop support. - typedef typename CompatibleTypes >::Type CompatibleType; - - Vector3(const CompatibleType& s) : x(s.x), y(s.y), z(s.z) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Vector3) == sizeof(CompatibleType), "sizeof(Vector3) failure"); - return reinterpret_cast(*this); - } - - bool operator== (const Vector3& b) const { return x == b.x && y == b.y && z == b.z; } - bool operator!= (const Vector3& b) const { return x != b.x || y != b.y || z != b.z; } - - Vector3 operator+ (const Vector3& b) const { return Vector3(x + b.x, y + b.y, z + b.z); } - Vector3& operator+= (const Vector3& b) { x += b.x; y += b.y; z += b.z; return *this; } - Vector3 operator- (const Vector3& b) const { return Vector3(x - b.x, y - b.y, z - b.z); } - Vector3& operator-= (const Vector3& b) { x -= b.x; y -= b.y; z -= b.z; return *this; } - Vector3 operator- () const { return Vector3(-x, -y, -z); } - - // Scalar multiplication/division scales vector. - Vector3 operator* (T s) const { return Vector3(x*s, y*s, z*s); } - Vector3& operator*= (T s) { x *= s; y *= s; z *= s; return *this; } - - Vector3 operator/ (T s) const { T rcp = T(1)/s; - return Vector3(x*rcp, y*rcp, z*rcp); } - Vector3& operator/= (T s) { T rcp = T(1)/s; - x *= rcp; y *= rcp; z *= rcp; - return *this; } - - static Vector3 Min(const Vector3& a, const Vector3& b) - { - return Vector3((a.x < b.x) ? a.x : b.x, - (a.y < b.y) ? a.y : b.y, - (a.z < b.z) ? a.z : b.z); - } - static Vector3 Max(const Vector3& a, const Vector3& b) - { - return Vector3((a.x > b.x) ? a.x : b.x, - (a.y > b.y) ? a.y : b.y, - (a.z > b.z) ? a.z : b.z); - } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool Compare(const Vector3&b, T tolerance = ((T)MATH_DOUBLE_TOLERANCE)) - { - return (fabs(b.x-x) < tolerance) && - (fabs(b.y-y) < tolerance) && - (fabs(b.z-z) < tolerance); - } - - T& operator[] (int idx) - { - OVR_ASSERT(0 <= idx && idx < 3); - return *(&x + idx); - } - - const T& operator[] (int idx) const - { - OVR_ASSERT(0 <= idx && idx < 3); - return *(&x + idx); - } - - // Entrywise product of two vectors - Vector3 EntrywiseMultiply(const Vector3& b) const { return Vector3(x * b.x, - y * b.y, - z * b.z);} - - // Multiply and divide operators do entry-wise math - Vector3 operator* (const Vector3& b) const { return Vector3(x * b.x, - y * b.y, - z * b.z); } - - Vector3 operator/ (const Vector3& b) const { return Vector3(x / b.x, - y / b.y, - z / b.z); } - - - // Dot product - // Used to calculate angle q between two vectors among other things, - // as (A dot B) = |a||b|cos(q). - T Dot(const Vector3& b) const { return x*b.x + y*b.y + z*b.z; } - - // Compute cross product, which generates a normal vector. - // Direction vector can be determined by right-hand rule: Pointing index finder in - // direction a and middle finger in direction b, thumb will point in a.Cross(b). - Vector3 Cross(const Vector3& b) const { return Vector3(y*b.z - z*b.y, - z*b.x - x*b.z, - x*b.y - y*b.x); } - - // Returns the angle from this vector to b, in radians. - T Angle(const Vector3& b) const - { - T div = LengthSq()*b.LengthSq(); - OVR_ASSERT(div != T(0)); - T result = Acos((this->Dot(b))/sqrt(div)); - return result; - } - - // Return Length of the vector squared. - T LengthSq() const { return (x * x + y * y + z * z); } - - // Return vector length. - T Length() const { return sqrt(LengthSq()); } - - // Returns squared distance between two points represented by vectors. - T DistanceSq(Vector3 const& b) const { return (*this - b).LengthSq(); } - - // Returns distance between two points represented by vectors. - T Distance(Vector3 const& b) const { return (*this - b).Length(); } - - // Determine if this a unit vector. - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } - - // Normalize, convention vector length to 1. - void Normalize() - { - T l = Length(); - OVR_ASSERT(l != T(0)); - *this /= l; - } - - // Returns normalized (unit) version of the vector without modifying itself. - Vector3 Normalized() const - { - T l = Length(); - OVR_ASSERT(l != T(0)); - return *this / l; - } - - // Linearly interpolates from this vector to another. - // Factor should be between 0.0 and 1.0, with 0 giving full value to this. - Vector3 Lerp(const Vector3& b, T f) const { return *this*(T(1) - f) + b*f; } - - // Projects this vector onto the argument; in other words, - // A.Project(B) returns projection of vector A onto B. - Vector3 ProjectTo(const Vector3& b) const - { - T l2 = b.LengthSq(); - OVR_ASSERT(l2 != T(0)); - return b * ( Dot(b) / l2 ); - } - - // Projects this vector onto a plane defined by a normal vector - Vector3 ProjectToPlane(const Vector3& normal) const { return *this - this->ProjectTo(normal); } -}; - -typedef Vector3 Vector3f; -typedef Vector3 Vector3d; -typedef Vector3 Vector3i; - -static_assert((sizeof(Vector3f) == 3*sizeof(float)), "sizeof(Vector3f) failure"); -static_assert((sizeof(Vector3d) == 3*sizeof(double)), "sizeof(Vector3d) failure"); -static_assert((sizeof(Vector3i) == 3*sizeof(int32_t)), "sizeof(Vector3i) failure"); - -typedef Vector3 Point3f; -typedef Vector3 Point3d; -typedef Vector3 Point3i; - - -//------------------------------------------------------------------------------------- -// ***** Vector4<> - 4D vector of {x, y, z, w} - -// -// Vector4f (Vector4d) represents a 3-dimensional vector or point in space, -// consisting of coordinates x, y, z and w. - -template -class Vector4 -{ -public: - T x, y, z, w; - - // FIXME: default initialization of a vector class can be very expensive in a full-blown - // application. A few hundred thousand vector constructions is not unlikely and can add - // up to milliseconds of time on processors like the PS3 PPU. - Vector4() : x(0), y(0), z(0), w(0) { } - Vector4(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { } - explicit Vector4(T s) : x(s), y(s), z(s), w(s) { } - explicit Vector4(const Vector3& v, const float w_=1) : x(v.x), y(v.y), z(v.z), w(w_) { } - explicit Vector4(const Vector4::OtherFloatType> &src) - : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { } - - static const Vector4 ZERO; - - // C-interop support. - typedef typename CompatibleTypes< Vector4 >::Type CompatibleType; - - Vector4(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Vector4) == sizeof(CompatibleType), "sizeof(Vector4) failure"); - return reinterpret_cast(*this); - } - - Vector4& operator= (const Vector3& other) { x=other.x; y=other.y; z=other.z; w=1; return *this; } - bool operator== (const Vector4& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; } - bool operator!= (const Vector4& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; } - - Vector4 operator+ (const Vector4& b) const { return Vector4(x + b.x, y + b.y, z + b.z, w + b.w); } - Vector4& operator+= (const Vector4& b) { x += b.x; y += b.y; z += b.z; w += b.w; return *this; } - Vector4 operator- (const Vector4& b) const { return Vector4(x - b.x, y - b.y, z - b.z, w - b.w); } - Vector4& operator-= (const Vector4& b) { x -= b.x; y -= b.y; z -= b.z; w -= b.w; return *this; } - Vector4 operator- () const { return Vector4(-x, -y, -z, -w); } - - // Scalar multiplication/division scales vector. - Vector4 operator* (T s) const { return Vector4(x*s, y*s, z*s, w*s); } - Vector4& operator*= (T s) { x *= s; y *= s; z *= s; w *= s;return *this; } - - Vector4 operator/ (T s) const { T rcp = T(1)/s; - return Vector4(x*rcp, y*rcp, z*rcp, w*rcp); } - Vector4& operator/= (T s) { T rcp = T(1)/s; - x *= rcp; y *= rcp; z *= rcp; w *= rcp; - return *this; } - - static Vector4 Min(const Vector4& a, const Vector4& b) - { - return Vector4((a.x < b.x) ? a.x : b.x, - (a.y < b.y) ? a.y : b.y, - (a.z < b.z) ? a.z : b.z, - (a.w < b.w) ? a.w : b.w); - } - static Vector4 Max(const Vector4& a, const Vector4& b) - { - return Vector4((a.x > b.x) ? a.x : b.x, - (a.y > b.y) ? a.y : b.y, - (a.z > b.z) ? a.z : b.z, - (a.w > b.w) ? a.w : b.w); - } - - // Compare two vectors for equality with tolerance. Returns true if vectors match withing tolerance. - bool Compare(const Vector4&b, T tolerance = ((T)MATH_DOUBLE_TOLERANCE)) - { - return (fabs(b.x-x) < tolerance) && - (fabs(b.y-y) < tolerance) && - (fabs(b.z-z) < tolerance) && - (fabs(b.w-w) < tolerance); - } - - T& operator[] (int idx) - { - OVR_ASSERT(0 <= idx && idx < 4); - return *(&x + idx); - } - - const T& operator[] (int idx) const - { - OVR_ASSERT(0 <= idx && idx < 4); - return *(&x + idx); - } - - // Entry wise product of two vectors - Vector4 EntrywiseMultiply(const Vector4& b) const { return Vector4(x * b.x, - y * b.y, - z * b.z);} - - // Multiply and divide operators do entry-wise math - Vector4 operator* (const Vector4& b) const { return Vector4(x * b.x, - y * b.y, - z * b.z, - w * b.w); } - - Vector4 operator/ (const Vector4& b) const { return Vector4(x / b.x, - y / b.y, - z / b.z, - w / b.w); } - - - // Dot product - T Dot(const Vector4& b) const { return x*b.x + y*b.y + z*b.z + w*b.w; } - - // Return Length of the vector squared. - T LengthSq() const { return (x * x + y * y + z * z + w * w); } - - // Return vector length. - T Length() const { return sqrt(LengthSq()); } - - // Determine if this a unit vector. - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < Math::Tolerance; } - - // Normalize, convention vector length to 1. - void Normalize() - { - T l = Length(); - OVR_ASSERT(l != T(0)); - *this /= l; - } - - // Returns normalized (unit) version of the vector without modifying itself. - Vector4 Normalized() const - { - T l = Length(); - OVR_ASSERT(l != T(0)); - return *this / l; - } -}; - -typedef Vector4 Vector4f; -typedef Vector4 Vector4d; -typedef Vector4 Vector4i; - - -//------------------------------------------------------------------------------------- -// ***** Bounds3 - -// Bounds class used to describe a 3D axis aligned bounding box. - -template -class Bounds3 -{ -public: - Vector3 b[2]; - - Bounds3() - { - } - - Bounds3( const Vector3 & mins, const Vector3 & maxs ) -{ - b[0] = mins; - b[1] = maxs; - } - - void Clear() - { - b[0].x = b[0].y = b[0].z = Math::MaxValue; - b[1].x = b[1].y = b[1].z = -Math::MaxValue; - } - - void AddPoint( const Vector3 & v ) - { - b[0].x = Alg::Min( b[0].x, v.x ); - b[0].y = Alg::Min( b[0].y, v.y ); - b[0].z = Alg::Min( b[0].z, v.z ); - b[1].x = Alg::Max( b[1].x, v.x ); - b[1].y = Alg::Max( b[1].y, v.y ); - b[1].z = Alg::Max( b[1].z, v.z ); - } - - const Vector3 & GetMins() const { return b[0]; } - const Vector3 & GetMaxs() const { return b[1]; } - - Vector3 & GetMins() { return b[0]; } - Vector3 & GetMaxs() { return b[1]; } -}; - -typedef Bounds3 Bounds3f; -typedef Bounds3 Bounds3d; - - -//------------------------------------------------------------------------------------- -// ***** Size - -// Size class represents 2D size with Width, Height components. -// Used to describe distentions of render targets, etc. - -template -class Size -{ -public: - T w, h; - - Size() : w(0), h(0) { } - Size(T w_, T h_) : w(w_), h(h_) { } - explicit Size(T s) : w(s), h(s) { } - explicit Size(const Size::OtherFloatType> &src) - : w((T)src.w), h((T)src.h) { } - - // C-interop support. - typedef typename CompatibleTypes >::Type CompatibleType; - - Size(const CompatibleType& s) : w(s.w), h(s.h) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Size) == sizeof(CompatibleType), "sizeof(Size) failure"); - return reinterpret_cast(*this); - } - - bool operator== (const Size& b) const { return w == b.w && h == b.h; } - bool operator!= (const Size& b) const { return w != b.w || h != b.h; } - - Size operator+ (const Size& b) const { return Size(w + b.w, h + b.h); } - Size& operator+= (const Size& b) { w += b.w; h += b.h; return *this; } - Size operator- (const Size& b) const { return Size(w - b.w, h - b.h); } - Size& operator-= (const Size& b) { w -= b.w; h -= b.h; return *this; } - Size operator- () const { return Size(-w, -h); } - Size operator* (const Size& b) const { return Size(w * b.w, h * b.h); } - Size& operator*= (const Size& b) { w *= b.w; h *= b.h; return *this; } - Size operator/ (const Size& b) const { return Size(w / b.w, h / b.h); } - Size& operator/= (const Size& b) { w /= b.w; h /= b.h; return *this; } - - // Scalar multiplication/division scales both components. - Size operator* (T s) const { return Size(w*s, h*s); } - Size& operator*= (T s) { w *= s; h *= s; return *this; } - Size operator/ (T s) const { return Size(w/s, h/s); } - Size& operator/= (T s) { w /= s; h /= s; return *this; } - - static Size Min(const Size& a, const Size& b) { return Size((a.w < b.w) ? a.w : b.w, - (a.h < b.h) ? a.h : b.h); } - static Size Max(const Size& a, const Size& b) { return Size((a.w > b.w) ? a.w : b.w, - (a.h > b.h) ? a.h : b.h); } - - T Area() const { return w * h; } - - inline Vector2 ToVector() const { return Vector2(w, h); } -}; - - -typedef Size Sizei; -typedef Size Sizeu; -typedef Size Sizef; -typedef Size Sized; - - - -//----------------------------------------------------------------------------------- -// ***** Rect - -// Rect describes a rectangular area for rendering, that includes position and size. -template -class Rect -{ -public: - T x, y; - T w, h; - - Rect() { } - Rect(T x1, T y1, T w1, T h1) : x(x1), y(y1), w(w1), h(h1) { } - Rect(const Vector2& pos, const Size& sz) : x(pos.x), y(pos.y), w(sz.w), h(sz.h) { } - Rect(const Size& sz) : x(0), y(0), w(sz.w), h(sz.h) { } - - // C-interop support. - typedef typename CompatibleTypes >::Type CompatibleType; - - Rect(const CompatibleType& s) : x(s.Pos.x), y(s.Pos.y), w(s.Size.w), h(s.Size.h) { } - - operator const CompatibleType& () const - { - static_assert(sizeof(Rect) == sizeof(CompatibleType), "sizeof(Rect) failure"); - return reinterpret_cast(*this); - } - - Vector2 GetPos() const { return Vector2(x, y); } - Size GetSize() const { return Size(w, h); } - void SetPos(const Vector2& pos) { x = pos.x; y = pos.y; } - void SetSize(const Size& sz) { w = sz.w; h = sz.h; } - - bool operator == (const Rect& vp) const - { return (x == vp.x) && (y == vp.y) && (w == vp.w) && (h == vp.h); } - bool operator != (const Rect& vp) const - { return !operator == (vp); } -}; - -typedef Rect Recti; - - -//-------------------------------------------------------------------------------------// -// ***** Quat -// -// Quatf represents a quaternion class used for rotations. -// -// Quaternion multiplications are done in right-to-left order, to match the -// behavior of matrices. - - -template -class Quat -{ -public: - // w + Xi + Yj + Zk - T x, y, z, w; - - Quat() : x(0), y(0), z(0), w(1) { } - Quat(T x_, T y_, T z_, T w_) : x(x_), y(y_), z(z_), w(w_) { } - explicit Quat(const Quat::OtherFloatType> &src) - : x((T)src.x), y((T)src.y), z((T)src.z), w((T)src.w) { } - - typedef typename CompatibleTypes >::Type CompatibleType; - - // C-interop support. - Quat(const CompatibleType& s) : x(s.x), y(s.y), z(s.z), w(s.w) { } - - operator CompatibleType () const - { - CompatibleType result; - result.x = x; - result.y = y; - result.z = z; - result.w = w; - return result; - } - - // Constructs quaternion for rotation around the axis by an angle. - Quat(const Vector3& axis, T angle) - { - // Make sure we don't divide by zero. - if (axis.LengthSq() == 0) - { - // Assert if the axis is zero, but the angle isn't - OVR_ASSERT(angle == 0); - x = 0; y = 0; z = 0; w = 1; - return; - } - - Vector3 unitAxis = axis.Normalized(); - T sinHalfAngle = sin(angle * T(0.5)); - - w = cos(angle * T(0.5)); - x = unitAxis.x * sinHalfAngle; - y = unitAxis.y * sinHalfAngle; - z = unitAxis.z * sinHalfAngle; - } - - // Constructs quaternion for rotation around one of the coordinate axis by an angle. - Quat(Axis A, T angle, RotateDirection d = Rotate_CCW, HandedSystem s = Handed_R) - { - T sinHalfAngle = s * d *sin(angle * T(0.5)); - T v[3]; - v[0] = v[1] = v[2] = T(0); - v[A] = sinHalfAngle; - - w = cos(angle * T(0.5)); - x = v[0]; - y = v[1]; - z = v[2]; - } - - // Compute axis and angle from quaternion - void GetAxisAngle(Vector3* axis, T* angle) const - { - if ( x*x + y*y + z*z > ((T)MATH_DOUBLE_TOLERANCE) * ((T)MATH_DOUBLE_TOLERANCE) ) { - *axis = Vector3(x, y, z).Normalized(); - *angle = 2 * Acos(w); - if (*angle > ((T)MATH_DOUBLE_PI)) // Reduce the magnitude of the angle, if necessary - { - *angle = ((T)MATH_DOUBLE_TWOPI) - *angle; - *axis = *axis * (-1); - } - } - else - { - *axis = Vector3(1, 0, 0); - *angle= 0; - } - } - - // Constructs the quaternion from a rotation matrix - explicit Quat(const Matrix4& m) - { - T trace = m.M[0][0] + m.M[1][1] + m.M[2][2]; - - // In almost all cases, the first part is executed. - // However, if the trace is not positive, the other - // cases arise. - if (trace > T(0)) - { - T s = sqrt(trace + T(1)) * T(2); // s=4*qw - w = T(0.25) * s; - x = (m.M[2][1] - m.M[1][2]) / s; - y = (m.M[0][2] - m.M[2][0]) / s; - z = (m.M[1][0] - m.M[0][1]) / s; - } - else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2])) - { - T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2); - w = (m.M[2][1] - m.M[1][2]) / s; - x = T(0.25) * s; - y = (m.M[0][1] + m.M[1][0]) / s; - z = (m.M[2][0] + m.M[0][2]) / s; - } - else if (m.M[1][1] > m.M[2][2]) - { - T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy - w = (m.M[0][2] - m.M[2][0]) / s; - x = (m.M[0][1] + m.M[1][0]) / s; - y = T(0.25) * s; - z = (m.M[1][2] + m.M[2][1]) / s; - } - else - { - T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz - w = (m.M[1][0] - m.M[0][1]) / s; - x = (m.M[0][2] + m.M[2][0]) / s; - y = (m.M[1][2] + m.M[2][1]) / s; - z = T(0.25) * s; - } - } - - // Constructs the quaternion from a rotation matrix - explicit Quat(const Matrix3& m) - { - T trace = m.M[0][0] + m.M[1][1] + m.M[2][2]; - - // In almost all cases, the first part is executed. - // However, if the trace is not positive, the other - // cases arise. - if (trace > T(0)) - { - T s = sqrt(trace + T(1)) * T(2); // s=4*qw - w = T(0.25) * s; - x = (m.M[2][1] - m.M[1][2]) / s; - y = (m.M[0][2] - m.M[2][0]) / s; - z = (m.M[1][0] - m.M[0][1]) / s; - } - else if ((m.M[0][0] > m.M[1][1])&&(m.M[0][0] > m.M[2][2])) - { - T s = sqrt(T(1) + m.M[0][0] - m.M[1][1] - m.M[2][2]) * T(2); - w = (m.M[2][1] - m.M[1][2]) / s; - x = T(0.25) * s; - y = (m.M[0][1] + m.M[1][0]) / s; - z = (m.M[2][0] + m.M[0][2]) / s; - } - else if (m.M[1][1] > m.M[2][2]) - { - T s = sqrt(T(1) + m.M[1][1] - m.M[0][0] - m.M[2][2]) * T(2); // S=4*qy - w = (m.M[0][2] - m.M[2][0]) / s; - x = (m.M[0][1] + m.M[1][0]) / s; - y = T(0.25) * s; - z = (m.M[1][2] + m.M[2][1]) / s; - } - else - { - T s = sqrt(T(1) + m.M[2][2] - m.M[0][0] - m.M[1][1]) * T(2); // S=4*qz - w = (m.M[1][0] - m.M[0][1]) / s; - x = (m.M[0][2] + m.M[2][0]) / s; - y = (m.M[1][2] + m.M[2][1]) / s; - z = T(0.25) * s; - } - } - - bool operator== (const Quat& b) const { return x == b.x && y == b.y && z == b.z && w == b.w; } - bool operator!= (const Quat& b) const { return x != b.x || y != b.y || z != b.z || w != b.w; } - - Quat operator+ (const Quat& b) const { return Quat(x + b.x, y + b.y, z + b.z, w + b.w); } - Quat& operator+= (const Quat& b) { w += b.w; x += b.x; y += b.y; z += b.z; return *this; } - Quat operator- (const Quat& b) const { return Quat(x - b.x, y - b.y, z - b.z, w - b.w); } - Quat& operator-= (const Quat& b) { w -= b.w; x -= b.x; y -= b.y; z -= b.z; return *this; } - - Quat operator* (T s) const { return Quat(x * s, y * s, z * s, w * s); } - Quat& operator*= (T s) { w *= s; x *= s; y *= s; z *= s; return *this; } - Quat operator/ (T s) const { T rcp = T(1)/s; return Quat(x * rcp, y * rcp, z * rcp, w *rcp); } - Quat& operator/= (T s) { T rcp = T(1)/s; w *= rcp; x *= rcp; y *= rcp; z *= rcp; return *this; } - - - // Get Imaginary part vector - Vector3 Imag() const { return Vector3(x,y,z); } - - // Get quaternion length. - T Length() const { return sqrt(LengthSq()); } - - // Get quaternion length squared. - T LengthSq() const { return (x * x + y * y + z * z + w * w); } - - // Simple Euclidean distance in R^4 (not SLERP distance, but at least respects Haar measure) - T Distance(const Quat& q) const - { - T d1 = (*this - q).Length(); - T d2 = (*this + q).Length(); // Antipodal point check - return (d1 < d2) ? d1 : d2; - } - - T DistanceSq(const Quat& q) const - { - T d1 = (*this - q).LengthSq(); - T d2 = (*this + q).LengthSq(); // Antipodal point check - return (d1 < d2) ? d1 : d2; - } - - T Dot(const Quat& q) const - { - return x * q.x + y * q.y + z * q.z + w * q.w; - } - - // Angle between two quaternions in radians - T Angle(const Quat& q) const - { - return 2 * Acos(Alg::Abs(Dot(q))); - } - - // Normalize - bool IsNormalized() const { return fabs(LengthSq() - T(1)) < ((T)MATH_DOUBLE_TOLERANCE); } - - void Normalize() - { - T l = Length(); - OVR_ASSERT(l != T(0)); - *this /= l; - } - - Quat Normalized() const - { - T l = Length(); - OVR_ASSERT(l != T(0)); - return *this / l; - } - - // Returns conjugate of the quaternion. Produces inverse rotation if quaternion is normalized. - Quat Conj() const { return Quat(-x, -y, -z, w); } - - // Quaternion multiplication. Combines quaternion rotations, performing the one on the - // right hand side first. - Quat operator* (const Quat& b) const { return Quat(w * b.x + x * b.w + y * b.z - z * b.y, - w * b.y - x * b.z + y * b.w + z * b.x, - w * b.z + x * b.y - y * b.x + z * b.w, - w * b.w - x * b.x - y * b.y - z * b.z); } - - // - // this^p normalized; same as rotating by this p times. - Quat PowNormalized(T p) const - { - Vector3 v; - T a; - GetAxisAngle(&v, &a); - return Quat(v, a * p); - } - - // Normalized linear interpolation of quaternions - Quat Nlerp(const Quat& other, T a) - { - T sign = (Dot(other) >= 0) ? 1 : -1; - return (*this * sign * a + other * (1-a)).Normalized(); - } - - // Rotate transforms vector in a manner that matches Matrix rotations (counter-clockwise, - // assuming negative direction of the axis). Standard formula: q(t) * V * q(t)^-1. - Vector3 Rotate(const Vector3& v) const - { - return ((*this * Quat(v.x, v.y, v.z, T(0))) * Inverted()).Imag(); - } - - // Inversed quaternion rotates in the opposite direction. - Quat Inverted() const - { - return Quat(-x, -y, -z, w); - } - - // Sets this quaternion to the one rotates in the opposite direction. - void Invert() - { - *this = Quat(-x, -y, -z, w); - } - - // GetEulerAngles extracts Euler angles from the quaternion, in the specified order of - // axis rotations and the specified coordinate system. Right-handed coordinate system - // is the default, with CCW rotations while looking in the negative axis direction. - // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned. - // rotation a around axis A1 - // is followed by rotation b around axis A2 - // is followed by rotation c around axis A3 - // rotations are CCW or CW (D) in LH or RH coordinate system (S) - template - void GetEulerAngles(T *a, T *b, T *c) const - { - static_assert((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); - - T Q[3] = { x, y, z }; //Quaternion components x,y,z - - T ww = w*w; - T Q11 = Q[A1]*Q[A1]; - T Q22 = Q[A2]*Q[A2]; - T Q33 = Q[A3]*Q[A3]; - - T psign = T(-1); - // Determine whether even permutation - if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) - psign = T(1); - - T s2 = psign * T(2) * (psign*w*Q[A2] + Q[A1]*Q[A3]); - - if (s2 < T(-1) + ((T)MATH_DOUBLE_SINGULARITYRADIUS)) - { // South pole singularity - *a = T(0); - *b = -S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]), - ww + Q22 - Q11 - Q33 ); - } - else if (s2 > T(1) - ((T)MATH_DOUBLE_SINGULARITYRADIUS)) - { // North pole singularity - *a = T(0); - *b = S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2(T(2)*(psign*Q[A1]*Q[A2] + w*Q[A3]), - ww + Q22 - Q11 - Q33); - } - else - { - *a = -S*D*atan2(T(-2)*(w*Q[A1] - psign*Q[A2]*Q[A3]), - ww + Q33 - Q11 - Q22); - *b = S*D*asin(s2); - *c = S*D*atan2(T(2)*(w*Q[A3] - psign*Q[A1]*Q[A2]), - ww + Q11 - Q22 - Q33); - } - return; - } - - template - void GetEulerAngles(T *a, T *b, T *c) const - { GetEulerAngles(a, b, c); } - - template - void GetEulerAngles(T *a, T *b, T *c) const - { GetEulerAngles(a, b, c); } - - // GetEulerAnglesABA extracts Euler angles from the quaternion, in the specified order of - // axis rotations and the specified coordinate system. Right-handed coordinate system - // is the default, with CCW rotations while looking in the negative axis direction. - // Here a,b,c, are the Yaw/Pitch/Roll angles to be returned. - // rotation a around axis A1 - // is followed by rotation b around axis A2 - // is followed by rotation c around axis A1 - // Rotations are CCW or CW (D) in LH or RH coordinate system (S) - template - void GetEulerAnglesABA(T *a, T *b, T *c) const - { - static_assert(A1 != A2, "A1 != A2"); - - T Q[3] = {x, y, z}; // Quaternion components - - // Determine the missing axis that was not supplied - int m = 3 - A1 - A2; - - T ww = w*w; - T Q11 = Q[A1]*Q[A1]; - T Q22 = Q[A2]*Q[A2]; - T Qmm = Q[m]*Q[m]; - - T psign = T(-1); - if ((A1 + 1) % 3 == A2) // Determine whether even permutation - { - psign = T(1); - } - - T c2 = ww + Q11 - Q22 - Qmm; - if (c2 < T(-1) + Math::SingularityRadius) - { // South pole singularity - *a = T(0); - *b = S*D*((T)MATH_DOUBLE_PI); - *c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]), - ww + Q22 - Q11 - Qmm); - } - else if (c2 > T(1) - Math::SingularityRadius) - { // North pole singularity - *a = T(0); - *b = T(0); - *c = S*D*atan2( T(2)*(w*Q[A1] - psign*Q[A2]*Q[m]), - ww + Q22 - Q11 - Qmm); - } - else - { - *a = S*D*atan2( psign*w*Q[m] + Q[A1]*Q[A2], - w*Q[A2] -psign*Q[A1]*Q[m]); - *b = S*D*acos(c2); - *c = S*D*atan2( -psign*w*Q[m] + Q[A1]*Q[A2], - w*Q[A2] + psign*Q[A1]*Q[m]); - } - return; - } -}; - -typedef Quat Quatf; -typedef Quat Quatd; - -static_assert((sizeof(Quatf) == 4*sizeof(float)), "sizeof(Quatf) failure"); -static_assert((sizeof(Quatd) == 4*sizeof(double)), "sizeof(Quatd) failure"); - -//------------------------------------------------------------------------------------- -// ***** Pose - -// Position and orientation combined. - -template -class Pose -{ -public: - typedef typename CompatibleTypes >::Type CompatibleType; - - Pose() { } - Pose(const Quat& orientation, const Vector3& pos) - : Rotation(orientation), Translation(pos) { } - Pose(const Pose& s) - : Rotation(s.Rotation), Translation(s.Translation) { } - Pose(const CompatibleType& s) - : Rotation(s.Orientation), Translation(s.Position) { } - explicit Pose(const Pose::OtherFloatType> &s) - : Rotation(s.Rotation), Translation(s.Translation) { } - - operator typename CompatibleTypes >::Type () const - { - typename CompatibleTypes >::Type result; - result.Orientation = Rotation; - result.Position = Translation; - return result; - } - - Quat Rotation; - Vector3 Translation; - - static_assert((sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float)), "(sizeof(T) == sizeof(double) || sizeof(T) == sizeof(float))"); - - void ToArray(T* arr) const - { - T temp[7] = { Rotation.x, Rotation.y, Rotation.z, Rotation.w, Translation.x, Translation.y, Translation.z }; - for (int i = 0; i < 7; i++) arr[i] = temp[i]; - } - - static Pose FromArray(const T* v) - { - Quat rotation(v[0], v[1], v[2], v[3]); - Vector3 translation(v[4], v[5], v[6]); - return Pose(rotation, translation); - } - - Vector3 Rotate(const Vector3& v) const - { - return Rotation.Rotate(v); - } - - Vector3 Translate(const Vector3& v) const - { - return v + Translation; - } - - Vector3 Apply(const Vector3& v) const - { - return Translate(Rotate(v)); - } - - Pose operator*(const Pose& other) const - { - return Pose(Rotation * other.Rotation, Apply(other.Translation)); - } - - Pose Inverted() const - { - Quat inv = Rotation.Inverted(); - return Pose(inv, inv.Rotate(-Translation)); - } -}; - -typedef Pose Posef; -typedef Pose Posed; - -static_assert((sizeof(Posed) == sizeof(Quatd) + sizeof(Vector3d)), "sizeof(Posed) failure"); -static_assert((sizeof(Posef) == sizeof(Quatf) + sizeof(Vector3f)), "sizeof(Posef) failure"); - - -//------------------------------------------------------------------------------------- -// ***** Matrix4 -// -// Matrix4 is a 4x4 matrix used for 3d transformations and projections. -// Translation stored in the last column. -// The matrix is stored in row-major order in memory, meaning that values -// of the first row are stored before the next one. -// -// The arrangement of the matrix is chosen to be in Right-Handed -// coordinate system and counterclockwise rotations when looking down -// the axis -// -// Transformation Order: -// - Transformations are applied from right to left, so the expression -// M1 * M2 * M3 * V means that the vector V is transformed by M3 first, -// followed by M2 and M1. -// -// Coordinate system: Right Handed -// -// Rotations: Counterclockwise when looking down the axis. All angles are in radians. -// -// | sx 01 02 tx | // First column (sx, 10, 20): Axis X basis vector. -// | 10 sy 12 ty | // Second column (01, sy, 21): Axis Y basis vector. -// | 20 21 sz tz | // Third columnt (02, 12, sz): Axis Z basis vector. -// | 30 31 32 33 | -// -// The basis vectors are first three columns. - -template -class Matrix4 -{ - static const Matrix4 IdentityValue; - -public: - T M[4][4]; - - enum NoInitType { NoInit }; - - // Construct with no memory initialization. - Matrix4(NoInitType) { } - - // By default, we construct identity matrix. - Matrix4() - { - SetIdentity(); - } - - Matrix4(T m11, T m12, T m13, T m14, - T m21, T m22, T m23, T m24, - T m31, T m32, T m33, T m34, - T m41, T m42, T m43, T m44) - { - M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = m14; - M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = m24; - M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = m34; - M[3][0] = m41; M[3][1] = m42; M[3][2] = m43; M[3][3] = m44; - } - - Matrix4(T m11, T m12, T m13, - T m21, T m22, T m23, - T m31, T m32, T m33) - { - M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; M[0][3] = 0; - M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; M[1][3] = 0; - M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; M[2][3] = 0; - M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; - } - - explicit Matrix4(const Quat& q) - { - T ww = q.w*q.w; - T xx = q.x*q.x; - T yy = q.y*q.y; - T zz = q.z*q.z; - - M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); M[0][3] = 0; - M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x); M[1][3] = 0; - M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz; M[2][3] = 0; - M[3][0] = 0; M[3][1] = 0; M[3][2] = 0; M[3][3] = 1; - } - - explicit Matrix4(const Pose& p) - { - Matrix4 result(p.Rotation); - result.SetTranslation(p.Translation); - *this = result; - } - - // C-interop support - explicit Matrix4(const Matrix4::OtherFloatType> &src) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] = (T)src.M[i][j]; - } - - // C-interop support. - Matrix4(const typename CompatibleTypes >::Type& s) - { - static_assert(sizeof(s) == sizeof(Matrix4), "sizeof(s) == sizeof(Matrix4)"); - memcpy(M, s.M, sizeof(M)); - } - - operator typename CompatibleTypes >::Type () const - { - typename CompatibleTypes >::Type result; - static_assert(sizeof(result) == sizeof(Matrix4), "sizeof(result) == sizeof(Matrix4)"); - memcpy(result.M, M, sizeof(M)); - return result; - } - - void ToString(char* dest, size_t destsize) const - { - size_t pos = 0; - for (int r=0; r<4; r++) - for (int c=0; c<4; c++) - pos += OVR_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]); - } - - static Matrix4 FromString(const char* src) - { - Matrix4 result; - if (src) - { - for (int r=0; r<4; r++) - { - for (int c=0; c<4; c++) - { - result.M[r][c] = (T)atof(src); - while (src && *src != ' ') - { - src++; - } - while (src && *src == ' ') - { - src++; - } - } - } - } - return result; - } - - static const Matrix4& Identity() { return IdentityValue; } - - void SetIdentity() - { - M[0][0] = M[1][1] = M[2][2] = M[3][3] = 1; - M[0][1] = M[1][0] = M[2][3] = M[3][1] = 0; - M[0][2] = M[1][2] = M[2][0] = M[3][2] = 0; - M[0][3] = M[1][3] = M[2][1] = M[3][0] = 0; - } - - void SetXBasis(const Vector3f & v) - { - M[0][0] = v.x; - M[1][0] = v.y; - M[2][0] = v.z; - } - Vector3f GetXBasis() const - { - return Vector3f(M[0][0], M[1][0], M[2][0]); - } - - void SetYBasis(const Vector3f & v) - { - M[0][1] = v.x; - M[1][1] = v.y; - M[2][1] = v.z; - } - Vector3f GetYBasis() const - { - return Vector3f(M[0][1], M[1][1], M[2][1]); - } - - void SetZBasis(const Vector3f & v) - { - M[0][2] = v.x; - M[1][2] = v.y; - M[2][2] = v.z; - } - Vector3f GetZBasis() const - { - return Vector3f(M[0][2], M[1][2], M[2][2]); - } - - bool operator== (const Matrix4& b) const - { - bool isEqual = true; - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - isEqual &= (M[i][j] == b.M[i][j]); - - return isEqual; - } - - Matrix4 operator+ (const Matrix4& b) const - { - Matrix4 result(*this); - result += b; - return result; - } - - Matrix4& operator+= (const Matrix4& b) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] += b.M[i][j]; - return *this; - } - - Matrix4 operator- (const Matrix4& b) const - { - Matrix4 result(*this); - result -= b; - return result; - } - - Matrix4& operator-= (const Matrix4& b) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] -= b.M[i][j]; - return *this; - } - - // Multiplies two matrices into destination with minimum copying. - static Matrix4& Multiply(Matrix4* d, const Matrix4& a, const Matrix4& b) - { - OVR_ASSERT((d != &a) && (d != &b)); - int i = 0; - do { - d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0] + a.M[i][3] * b.M[3][0]; - d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1] + a.M[i][3] * b.M[3][1]; - d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2] + a.M[i][3] * b.M[3][2]; - d->M[i][3] = a.M[i][0] * b.M[0][3] + a.M[i][1] * b.M[1][3] + a.M[i][2] * b.M[2][3] + a.M[i][3] * b.M[3][3]; - } while((++i) < 4); - - return *d; - } - - Matrix4 operator* (const Matrix4& b) const - { - Matrix4 result(Matrix4::NoInit); - Multiply(&result, *this, b); - return result; - } - - Matrix4& operator*= (const Matrix4& b) - { - return Multiply(this, Matrix4(*this), b); - } - - Matrix4 operator* (T s) const - { - Matrix4 result(*this); - result *= s; - return result; - } - - Matrix4& operator*= (T s) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] *= s; - return *this; - } - - - Matrix4 operator/ (T s) const - { - Matrix4 result(*this); - result /= s; - return result; - } - - Matrix4& operator/= (T s) - { - for (int i = 0; i < 4; i++) - for (int j = 0; j < 4; j++) - M[i][j] /= s; - return *this; - } - - Vector3 Transform(const Vector3& v) const - { - const T rcpW = 1.0f / (M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3]); - return Vector3((M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3]) * rcpW, - (M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3]) * rcpW, - (M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3]) * rcpW); - } - - Vector4 Transform(const Vector4& v) const - { - return Vector4(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z + M[0][3] * v.w, - M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z + M[1][3] * v.w, - M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z + M[2][3] * v.w, - M[3][0] * v.x + M[3][1] * v.y + M[3][2] * v.z + M[3][3] * v.w); - } - - Matrix4 Transposed() const - { - return Matrix4(M[0][0], M[1][0], M[2][0], M[3][0], - M[0][1], M[1][1], M[2][1], M[3][1], - M[0][2], M[1][2], M[2][2], M[3][2], - M[0][3], M[1][3], M[2][3], M[3][3]); - } - - void Transpose() - { - *this = Transposed(); - } - - - T SubDet (const size_t* rows, const size_t* cols) const - { - return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]]) - - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]]) - + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]); - } - - T Cofactor(size_t I, size_t J) const - { - const size_t indices[4][3] = {{1,2,3},{0,2,3},{0,1,3},{0,1,2}}; - return ((I+J)&1) ? -SubDet(indices[I],indices[J]) : SubDet(indices[I],indices[J]); - } - - T Determinant() const - { - return M[0][0] * Cofactor(0,0) + M[0][1] * Cofactor(0,1) + M[0][2] * Cofactor(0,2) + M[0][3] * Cofactor(0,3); - } - - Matrix4 Adjugated() const - { - return Matrix4(Cofactor(0,0), Cofactor(1,0), Cofactor(2,0), Cofactor(3,0), - Cofactor(0,1), Cofactor(1,1), Cofactor(2,1), Cofactor(3,1), - Cofactor(0,2), Cofactor(1,2), Cofactor(2,2), Cofactor(3,2), - Cofactor(0,3), Cofactor(1,3), Cofactor(2,3), Cofactor(3,3)); - } - - Matrix4 Inverted() const - { - T det = Determinant(); - assert(det != 0); - return Adjugated() * (1.0f/det); - } - - void Invert() - { - *this = Inverted(); - } - - // This is more efficient than general inverse, but ONLY works - // correctly if it is a homogeneous transform matrix (rot + trans) - Matrix4 InvertedHomogeneousTransform() const - { - // Make the inverse rotation matrix - Matrix4 rinv = this->Transposed(); - rinv.M[3][0] = rinv.M[3][1] = rinv.M[3][2] = 0.0f; - // Make the inverse translation matrix - Vector3 tvinv(-M[0][3],-M[1][3],-M[2][3]); - Matrix4 tinv = Matrix4::Translation(tvinv); - return rinv * tinv; // "untranslate", then "unrotate" - } - - // This is more efficient than general inverse, but ONLY works - // correctly if it is a homogeneous transform matrix (rot + trans) - void InvertHomogeneousTransform() - { - *this = InvertedHomogeneousTransform(); - } - - // Matrix to Euler Angles conversion - // a,b,c, are the YawPitchRoll angles to be returned - // rotation a around axis A1 - // is followed by rotation b around axis A2 - // is followed by rotation c around axis A3 - // rotations are CCW or CW (D) in LH or RH coordinate system (S) - template - void ToEulerAngles(T *a, T *b, T *c) const - { - static_assert((A1 != A2) && (A2 != A3) && (A1 != A3), "(A1 != A2) && (A2 != A3) && (A1 != A3)"); - - T psign = -1; - if (((A1 + 1) % 3 == A2) && ((A2 + 1) % 3 == A3)) // Determine whether even permutation - psign = 1; - - T pm = psign*M[A1][A3]; - if (pm < -1.0f + Math::SingularityRadius) - { // South pole singularity - *a = 0; - *b = -S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] ); - } - else if (pm > 1.0f - Math::SingularityRadius) - { // North pole singularity - *a = 0; - *b = S*D*((T)MATH_DOUBLE_PIOVER2); - *c = S*D*atan2( psign*M[A2][A1], M[A2][A2] ); - } - else - { // Normal case (nonsingular) - *a = S*D*atan2( -psign*M[A2][A3], M[A3][A3] ); - *b = S*D*asin(pm); - *c = S*D*atan2( -psign*M[A1][A2], M[A1][A1] ); - } - - return; - } - - // Matrix to Euler Angles conversion - // a,b,c, are the YawPitchRoll angles to be returned - // rotation a around axis A1 - // is followed by rotation b around axis A2 - // is followed by rotation c around axis A1 - // rotations are CCW or CW (D) in LH or RH coordinate system (S) - template - void ToEulerAnglesABA(T *a, T *b, T *c) const - { - static_assert(A1 != A2, "A1 != A2"); - - // Determine the axis that was not supplied - int m = 3 - A1 - A2; - - T psign = -1; - if ((A1 + 1) % 3 == A2) // Determine whether even permutation - psign = 1.0f; - - T c2 = M[A1][A1]; - if (c2 < -1 + Math::SingularityRadius) - { // South pole singularity - *a = 0; - *b = S*D*((T)MATH_DOUBLE_PI); - *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]); - } - else if (c2 > 1.0f - Math::SingularityRadius) - { // North pole singularity - *a = 0; - *b = 0; - *c = S*D*atan2( -psign*M[A2][m],M[A2][A2]); - } - else - { // Normal case (nonsingular) - *a = S*D*atan2( M[A2][A1],-psign*M[m][A1]); - *b = S*D*acos(c2); - *c = S*D*atan2( M[A1][A2],psign*M[A1][m]); - } - return; - } - - // Creates a matrix that converts the vertices from one coordinate system - // to another. - static Matrix4 AxisConversion(const WorldAxes& to, const WorldAxes& from) - { - // Holds axis values from the 'to' structure - int toArray[3] = { to.XAxis, to.YAxis, to.ZAxis }; - - // The inverse of the toArray - int inv[4]; - inv[0] = inv[abs(to.XAxis)] = 0; - inv[abs(to.YAxis)] = 1; - inv[abs(to.ZAxis)] = 2; - - Matrix4 m(0, 0, 0, - 0, 0, 0, - 0, 0, 0); - - // Only three values in the matrix need to be changed to 1 or -1. - m.M[inv[abs(from.XAxis)]][0] = T(from.XAxis/toArray[inv[abs(from.XAxis)]]); - m.M[inv[abs(from.YAxis)]][1] = T(from.YAxis/toArray[inv[abs(from.YAxis)]]); - m.M[inv[abs(from.ZAxis)]][2] = T(from.ZAxis/toArray[inv[abs(from.ZAxis)]]); - return m; - } - - - // Creates a matrix for translation by vector - static Matrix4 Translation(const Vector3& v) - { - Matrix4 t; - t.M[0][3] = v.x; - t.M[1][3] = v.y; - t.M[2][3] = v.z; - return t; - } - - // Creates a matrix for translation by vector - static Matrix4 Translation(T x, T y, T z = 0.0f) - { - Matrix4 t; - t.M[0][3] = x; - t.M[1][3] = y; - t.M[2][3] = z; - return t; - } - - // Sets the translation part - void SetTranslation(const Vector3& v) - { - M[0][3] = v.x; - M[1][3] = v.y; - M[2][3] = v.z; - } - - Vector3 GetTranslation() const - { - return Vector3( M[0][3], M[1][3], M[2][3] ); - } - - // Creates a matrix for scaling by vector - static Matrix4 Scaling(const Vector3& v) - { - Matrix4 t; - t.M[0][0] = v.x; - t.M[1][1] = v.y; - t.M[2][2] = v.z; - return t; - } - - // Creates a matrix for scaling by vector - static Matrix4 Scaling(T x, T y, T z) - { - Matrix4 t; - t.M[0][0] = x; - t.M[1][1] = y; - t.M[2][2] = z; - return t; - } - - // Creates a matrix for scaling by constant - static Matrix4 Scaling(T s) - { - Matrix4 t; - t.M[0][0] = s; - t.M[1][1] = s; - t.M[2][2] = s; - return t; - } - - // Simple L1 distance in R^12 - T Distance(const Matrix4& m2) const - { - T d = fabs(M[0][0] - m2.M[0][0]) + fabs(M[0][1] - m2.M[0][1]); - d += fabs(M[0][2] - m2.M[0][2]) + fabs(M[0][3] - m2.M[0][3]); - d += fabs(M[1][0] - m2.M[1][0]) + fabs(M[1][1] - m2.M[1][1]); - d += fabs(M[1][2] - m2.M[1][2]) + fabs(M[1][3] - m2.M[1][3]); - d += fabs(M[2][0] - m2.M[2][0]) + fabs(M[2][1] - m2.M[2][1]); - d += fabs(M[2][2] - m2.M[2][2]) + fabs(M[2][3] - m2.M[2][3]); - d += fabs(M[3][0] - m2.M[3][0]) + fabs(M[3][1] - m2.M[3][1]); - d += fabs(M[3][2] - m2.M[3][2]) + fabs(M[3][3] - m2.M[3][3]); - return d; - } - - // Creates a rotation matrix rotating around the X axis by 'angle' radians. - // Just for quick testing. Not for final API. Need to remove case. - static Matrix4 RotationAxis(Axis A, T angle, RotateDirection d, HandedSystem s) - { - T sina = s * d *sin(angle); - T cosa = cos(angle); - - switch(A) - { - case Axis_X: - return Matrix4(1, 0, 0, - 0, cosa, -sina, - 0, sina, cosa); - case Axis_Y: - return Matrix4(cosa, 0, sina, - 0, 1, 0, - -sina, 0, cosa); - case Axis_Z: - return Matrix4(cosa, -sina, 0, - sina, cosa, 0, - 0, 0, 1); - } - } - - - // Creates a rotation matrix rotating around the X axis by 'angle' radians. - // Rotation direction is depends on the coordinate system: - // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), - // while looking in the negative axis direction. This is the - // same as looking down from positive axis values towards origin. - // LHS: Positive angle values rotate clock-wise (CW), while looking in the - // negative axis direction. - static Matrix4 RotationX(T angle) - { - T sina = sin(angle); - T cosa = cos(angle); - return Matrix4(1, 0, 0, - 0, cosa, -sina, - 0, sina, cosa); - } - - // Creates a rotation matrix rotating around the Y axis by 'angle' radians. - // Rotation direction is depends on the coordinate system: - // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), - // while looking in the negative axis direction. This is the - // same as looking down from positive axis values towards origin. - // LHS: Positive angle values rotate clock-wise (CW), while looking in the - // negative axis direction. - static Matrix4 RotationY(T angle) - { - T sina = sin(angle); - T cosa = cos(angle); - return Matrix4(cosa, 0, sina, - 0, 1, 0, - -sina, 0, cosa); - } - - // Creates a rotation matrix rotating around the Z axis by 'angle' radians. - // Rotation direction is depends on the coordinate system: - // RHS (Oculus default): Positive angle values rotate Counter-clockwise (CCW), - // while looking in the negative axis direction. This is the - // same as looking down from positive axis values towards origin. - // LHS: Positive angle values rotate clock-wise (CW), while looking in the - // negative axis direction. - static Matrix4 RotationZ(T angle) - { - T sina = sin(angle); - T cosa = cos(angle); - return Matrix4(cosa, -sina, 0, - sina, cosa, 0, - 0, 0, 1); - } - - // LookAtRH creates a View transformation matrix for right-handed coordinate system. - // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up' - // specifying the up vector. The resulting matrix should be used with PerspectiveRH - // projection. - static Matrix4 LookAtRH(const Vector3& eye, const Vector3& at, const Vector3& up) - { - Vector3 z = (eye - at).Normalized(); // Forward - Vector3 x = up.Cross(z).Normalized(); // Right - Vector3 y = z.Cross(x); - - Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)), - y.x, y.y, y.z, -(y.Dot(eye)), - z.x, z.y, z.z, -(z.Dot(eye)), - 0, 0, 0, 1 ); - return m; - } - - // LookAtLH creates a View transformation matrix for left-handed coordinate system. - // The resulting matrix points camera from 'eye' towards 'at' direction, with 'up' - // specifying the up vector. - static Matrix4 LookAtLH(const Vector3& eye, const Vector3& at, const Vector3& up) - { - Vector3 z = (at - eye).Normalized(); // Forward - Vector3 x = up.Cross(z).Normalized(); // Right - Vector3 y = z.Cross(x); - - Matrix4 m(x.x, x.y, x.z, -(x.Dot(eye)), - y.x, y.y, y.z, -(y.Dot(eye)), - z.x, z.y, z.z, -(z.Dot(eye)), - 0, 0, 0, 1 ); - return m; - } - - // PerspectiveRH creates a right-handed perspective projection matrix that can be - // used with the Oculus sample renderer. - // yfov - Specifies vertical field of view in radians. - // aspect - Screen aspect ration, which is usually width/height for square pixels. - // Note that xfov = yfov * aspect. - // znear - Absolute value of near Z clipping clipping range. - // zfar - Absolute value of far Z clipping clipping range (larger then near). - // Even though RHS usually looks in the direction of negative Z, positive values - // are expected for znear and zfar. - static Matrix4 PerspectiveRH(T yfov, T aspect, T znear, T zfar) - { - Matrix4 m; - T tanHalfFov = tan(yfov * 0.5f); - - m.M[0][0] = 1. / (aspect * tanHalfFov); - m.M[1][1] = 1. / tanHalfFov; - m.M[2][2] = zfar / (znear - zfar); - m.M[3][2] = -1.; - m.M[2][3] = (zfar * znear) / (znear - zfar); - m.M[3][3] = 0.; - - // Note: Post-projection matrix result assumes Left-Handed coordinate system, - // with Y up, X right and Z forward. This supports positive z-buffer values. - // This is the case even for RHS coordinate input. - return m; - } - - // PerspectiveLH creates a left-handed perspective projection matrix that can be - // used with the Oculus sample renderer. - // yfov - Specifies vertical field of view in radians. - // aspect - Screen aspect ration, which is usually width/height for square pixels. - // Note that xfov = yfov * aspect. - // znear - Absolute value of near Z clipping clipping range. - // zfar - Absolute value of far Z clipping clipping range (larger then near). - static Matrix4 PerspectiveLH(T yfov, T aspect, T znear, T zfar) - { - Matrix4 m; - T tanHalfFov = tan(yfov * 0.5f); - - m.M[0][0] = 1. / (aspect * tanHalfFov); - m.M[1][1] = 1. / tanHalfFov; - //m.M[2][2] = zfar / (znear - zfar); - m.M[2][2] = zfar / (zfar - znear); - m.M[3][2] = -1.; - m.M[2][3] = (zfar * znear) / (znear - zfar); - m.M[3][3] = 0.; - - // Note: Post-projection matrix result assumes Left-Handed coordinate system, - // with Y up, X right and Z forward. This supports positive z-buffer values. - // This is the case even for RHS coordinate input. - return m; - } - - static Matrix4 Ortho2D(T w, T h) - { - Matrix4 m; - m.M[0][0] = 2.0/w; - m.M[1][1] = -2.0/h; - m.M[0][3] = -1.0; - m.M[1][3] = 1.0; - m.M[2][2] = 0; - return m; - } -}; - -typedef Matrix4 Matrix4f; -typedef Matrix4 Matrix4d; - -//------------------------------------------------------------------------------------- -// ***** Matrix3 -// -// Matrix3 is a 3x3 matrix used for representing a rotation matrix. -// The matrix is stored in row-major order in memory, meaning that values -// of the first row are stored before the next one. -// -// The arrangement of the matrix is chosen to be in Right-Handed -// coordinate system and counterclockwise rotations when looking down -// the axis -// -// Transformation Order: -// - Transformations are applied from right to left, so the expression -// M1 * M2 * M3 * V means that the vector V is transformed by M3 first, -// followed by M2 and M1. -// -// Coordinate system: Right Handed -// -// Rotations: Counterclockwise when looking down the axis. All angles are in radians. - -template -class SymMat3; - -template -class Matrix3 -{ - static const Matrix3 IdentityValue; - -public: - T M[3][3]; - - enum NoInitType { NoInit }; - - // Construct with no memory initialization. - Matrix3(NoInitType) { } - - // By default, we construct identity matrix. - Matrix3() - { - SetIdentity(); - } - - Matrix3(T m11, T m12, T m13, - T m21, T m22, T m23, - T m31, T m32, T m33) - { - M[0][0] = m11; M[0][1] = m12; M[0][2] = m13; - M[1][0] = m21; M[1][1] = m22; M[1][2] = m23; - M[2][0] = m31; M[2][1] = m32; M[2][2] = m33; - } - - /* - explicit Matrix3(const Quat& q) - { - T ww = q.w*q.w; - T xx = q.x*q.x; - T yy = q.y*q.y; - T zz = q.z*q.z; - - M[0][0] = ww + xx - yy - zz; M[0][1] = 2 * (q.x*q.y - q.w*q.z); M[0][2] = 2 * (q.x*q.z + q.w*q.y); - M[1][0] = 2 * (q.x*q.y + q.w*q.z); M[1][1] = ww - xx + yy - zz; M[1][2] = 2 * (q.y*q.z - q.w*q.x); - M[2][0] = 2 * (q.x*q.z - q.w*q.y); M[2][1] = 2 * (q.y*q.z + q.w*q.x); M[2][2] = ww - xx - yy + zz; - } - */ - - explicit Matrix3(const Quat& q) - { - const T tx = q.x+q.x, ty = q.y+q.y, tz = q.z+q.z; - const T twx = q.w*tx, twy = q.w*ty, twz = q.w*tz; - const T txx = q.x*tx, txy = q.x*ty, txz = q.x*tz; - const T tyy = q.y*ty, tyz = q.y*tz, tzz = q.z*tz; - M[0][0] = T(1) - (tyy + tzz); M[0][1] = txy - twz; M[0][2] = txz + twy; - M[1][0] = txy + twz; M[1][1] = T(1) - (txx + tzz); M[1][2] = tyz - twx; - M[2][0] = txz - twy; M[2][1] = tyz + twx; M[2][2] = T(1) - (txx + tyy); - } - - inline explicit Matrix3(T s) - { - M[0][0] = M[1][1] = M[2][2] = s; - M[0][1] = M[0][2] = M[1][0] = M[1][2] = M[2][0] = M[2][1] = 0; - } - - explicit Matrix3(const Pose& p) - { - Matrix3 result(p.Rotation); - result.SetTranslation(p.Translation); - *this = result; - } - - // C-interop support - explicit Matrix3(const Matrix4::OtherFloatType> &src) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] = (T)src.M[i][j]; - } - - // C-interop support. - Matrix3(const typename CompatibleTypes >::Type& s) - { - static_assert(sizeof(s) == sizeof(Matrix3), "sizeof(s) == sizeof(Matrix3)"); - memcpy(M, s.M, sizeof(M)); - } - - operator const typename CompatibleTypes >::Type () const - { - typename CompatibleTypes >::Type result; - static_assert(sizeof(result) == sizeof(Matrix3), "sizeof(result) == sizeof(Matrix3)"); - memcpy(result.M, M, sizeof(M)); - return result; - } - - void ToString(char* dest, size_t destsize) const - { - size_t pos = 0; - for (int r=0; r<3; r++) - for (int c=0; c<3; c++) - pos += OVR_sprintf(dest+pos, destsize-pos, "%g ", M[r][c]); - } - - static Matrix3 FromString(const char* src) - { - Matrix3 result; - for (int r=0; r<3; r++) - for (int c=0; c<3; c++) - { - result.M[r][c] = (T)atof(src); - while (src && *src != ' ') - src++; - while (src && *src == ' ') - src++; - } - return result; - } - - static const Matrix3& Identity() { return IdentityValue; } - - void SetIdentity() - { - M[0][0] = M[1][1] = M[2][2] = 1; - M[0][1] = M[1][0] = M[2][0] = 0; - M[0][2] = M[1][2] = M[2][1] = 0; - } - - bool operator== (const Matrix3& b) const - { - bool isEqual = true; - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - isEqual &= (M[i][j] == b.M[i][j]); - - return isEqual; - } - - Matrix3 operator+ (const Matrix3& b) const - { - Matrix4 result(*this); - result += b; - return result; - } - - Matrix3& operator+= (const Matrix3& b) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] += b.M[i][j]; - return *this; - } - - void operator= (const Matrix3& b) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] = b.M[i][j]; - return; - } - - void operator= (const SymMat3& b) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] = 0; - - M[0][0] = b.v[0]; - M[0][1] = b.v[1]; - M[0][2] = b.v[2]; - M[1][1] = b.v[3]; - M[1][2] = b.v[4]; - M[2][2] = b.v[5]; - - return; - } - - Matrix3 operator- (const Matrix3& b) const - { - Matrix3 result(*this); - result -= b; - return result; - } - - Matrix3& operator-= (const Matrix3& b) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] -= b.M[i][j]; - return *this; - } - - // Multiplies two matrices into destination with minimum copying. - static Matrix3& Multiply(Matrix3* d, const Matrix3& a, const Matrix3& b) - { - OVR_ASSERT((d != &a) && (d != &b)); - int i = 0; - do { - d->M[i][0] = a.M[i][0] * b.M[0][0] + a.M[i][1] * b.M[1][0] + a.M[i][2] * b.M[2][0]; - d->M[i][1] = a.M[i][0] * b.M[0][1] + a.M[i][1] * b.M[1][1] + a.M[i][2] * b.M[2][1]; - d->M[i][2] = a.M[i][0] * b.M[0][2] + a.M[i][1] * b.M[1][2] + a.M[i][2] * b.M[2][2]; - } while((++i) < 3); - - return *d; - } - - Matrix3 operator* (const Matrix3& b) const - { - Matrix3 result(Matrix3::NoInit); - Multiply(&result, *this, b); - return result; - } - - Matrix3& operator*= (const Matrix3& b) - { - return Multiply(this, Matrix3(*this), b); - } - - Matrix3 operator* (T s) const - { - Matrix3 result(*this); - result *= s; - return result; - } - - Matrix3& operator*= (T s) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] *= s; - return *this; - } - - Vector3 operator* (const Vector3 &b) const - { - Vector3 result; - result.x = M[0][0]*b.x + M[0][1]*b.y + M[0][2]*b.z; - result.y = M[1][0]*b.x + M[1][1]*b.y + M[1][2]*b.z; - result.z = M[2][0]*b.x + M[2][1]*b.y + M[2][2]*b.z; - - return result; - } - - Matrix3 operator/ (T s) const - { - Matrix3 result(*this); - result /= s; - return result; - } - - Matrix3& operator/= (T s) - { - for (int i = 0; i < 3; i++) - for (int j = 0; j < 3; j++) - M[i][j] /= s; - return *this; - } - - Vector2 Transform(const Vector2& v) const - { - const float rcpZ = 1.0f / (M[2][0] * v.x + M[2][1] * v.y + M[2][2]); - return Vector2((M[0][0] * v.x + M[0][1] * v.y + M[0][2]) * rcpZ, - (M[1][0] * v.x + M[1][1] * v.y + M[1][2]) * rcpZ); - } - - Vector3 Transform(const Vector3& v) const - { - return Vector3(M[0][0] * v.x + M[0][1] * v.y + M[0][2] * v.z, - M[1][0] * v.x + M[1][1] * v.y + M[1][2] * v.z, - M[2][0] * v.x + M[2][1] * v.y + M[2][2] * v.z); - } - - Matrix3 Transposed() const - { - return Matrix3(M[0][0], M[1][0], M[2][0], - M[0][1], M[1][1], M[2][1], - M[0][2], M[1][2], M[2][2]); - } - - void Transpose() - { - *this = Transposed(); - } - - - T SubDet (const size_t* rows, const size_t* cols) const - { - return M[rows[0]][cols[0]] * (M[rows[1]][cols[1]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[1]]) - - M[rows[0]][cols[1]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[2]] - M[rows[1]][cols[2]] * M[rows[2]][cols[0]]) - + M[rows[0]][cols[2]] * (M[rows[1]][cols[0]] * M[rows[2]][cols[1]] - M[rows[1]][cols[1]] * M[rows[2]][cols[0]]); - } - - // M += a*b.t() - inline void Rank1Add(const Vector3 &a, const Vector3 &b) - { - M[0][0] += a.x*b.x; M[0][1] += a.x*b.y; M[0][2] += a.x*b.z; - M[1][0] += a.y*b.x; M[1][1] += a.y*b.y; M[1][2] += a.y*b.z; - M[2][0] += a.z*b.x; M[2][1] += a.z*b.y; M[2][2] += a.z*b.z; - } - - // M -= a*b.t() - inline void Rank1Sub(const Vector3 &a, const Vector3 &b) - { - M[0][0] -= a.x*b.x; M[0][1] -= a.x*b.y; M[0][2] -= a.x*b.z; - M[1][0] -= a.y*b.x; M[1][1] -= a.y*b.y; M[1][2] -= a.y*b.z; - M[2][0] -= a.z*b.x; M[2][1] -= a.z*b.y; M[2][2] -= a.z*b.z; - } - - inline Vector3 Col(int c) const - { - return Vector3(M[0][c], M[1][c], M[2][c]); - } - - inline Vector3 Row(int r) const - { - return Vector3(M[r][0], M[r][1], M[r][2]); - } - - inline T Determinant() const - { - const Matrix3& m = *this; - T d; - - d = m.M[0][0] * (m.M[1][1]*m.M[2][2] - m.M[1][2] * m.M[2][1]); - d -= m.M[0][1] * (m.M[1][0]*m.M[2][2] - m.M[1][2] * m.M[2][0]); - d += m.M[0][2] * (m.M[1][0]*m.M[2][1] - m.M[1][1] * m.M[2][0]); - - return d; - } - - inline Matrix3 Inverse() const - { - Matrix3 a; - const Matrix3& m = *this; - T d = Determinant(); - - assert(d != 0); - T s = T(1)/d; - - a.M[0][0] = s * (m.M[1][1] * m.M[2][2] - m.M[1][2] * m.M[2][1]); - a.M[1][0] = s * (m.M[1][2] * m.M[2][0] - m.M[1][0] * m.M[2][2]); - a.M[2][0] = s * (m.M[1][0] * m.M[2][1] - m.M[1][1] * m.M[2][0]); - - a.M[0][1] = s * (m.M[0][2] * m.M[2][1] - m.M[0][1] * m.M[2][2]); - a.M[1][1] = s * (m.M[0][0] * m.M[2][2] - m.M[0][2] * m.M[2][0]); - a.M[2][1] = s * (m.M[0][1] * m.M[2][0] - m.M[0][0] * m.M[2][1]); - - a.M[0][2] = s * (m.M[0][1] * m.M[1][2] - m.M[0][2] * m.M[1][1]); - a.M[1][2] = s * (m.M[0][2] * m.M[1][0] - m.M[0][0] * m.M[1][2]); - a.M[2][2] = s * (m.M[0][0] * m.M[1][1] - m.M[0][1] * m.M[1][0]); - - return a; - } - -}; - -typedef Matrix3 Matrix3f; -typedef Matrix3 Matrix3d; - -//------------------------------------------------------------------------------------- - -template -class SymMat3 -{ -private: - typedef SymMat3 this_type; - -public: - typedef T Value_t; - // Upper symmetric - T v[6]; // _00 _01 _02 _11 _12 _22 - - inline SymMat3() {} - - inline explicit SymMat3(T s) - { - v[0] = v[3] = v[5] = s; - v[1] = v[2] = v[4] = 0; - } - - inline explicit SymMat3(T a00, T a01, T a02, T a11, T a12, T a22) - { - v[0] = a00; v[1] = a01; v[2] = a02; - v[3] = a11; v[4] = a12; - v[5] = a22; - } - - static inline int Index(unsigned int i, unsigned int j) - { - return (i <= j) ? (3*i - i*(i+1)/2 + j) : (3*j - j*(j+1)/2 + i); - } - - inline T operator()(int i, int j) const { return v[Index(i,j)]; } - - inline T &operator()(int i, int j) { return v[Index(i,j)]; } - - template - inline SymMat3 CastTo() const - { - return SymMat3(static_cast(v[0]), static_cast(v[1]), static_cast(v[2]), - static_cast(v[3]), static_cast(v[4]), static_cast(v[5])); - } - - inline this_type& operator+=(const this_type& b) - { - v[0]+=b.v[0]; - v[1]+=b.v[1]; - v[2]+=b.v[2]; - v[3]+=b.v[3]; - v[4]+=b.v[4]; - v[5]+=b.v[5]; - return *this; - } - - inline this_type& operator-=(const this_type& b) - { - v[0]-=b.v[0]; - v[1]-=b.v[1]; - v[2]-=b.v[2]; - v[3]-=b.v[3]; - v[4]-=b.v[4]; - v[5]-=b.v[5]; - - return *this; - } - - inline this_type& operator*=(T s) - { - v[0]*=s; - v[1]*=s; - v[2]*=s; - v[3]*=s; - v[4]*=s; - v[5]*=s; - - return *this; - } - - inline SymMat3 operator*(T s) const - { - SymMat3 d; - d.v[0] = v[0]*s; - d.v[1] = v[1]*s; - d.v[2] = v[2]*s; - d.v[3] = v[3]*s; - d.v[4] = v[4]*s; - d.v[5] = v[5]*s; - - return d; - } - - // Multiplies two matrices into destination with minimum copying. - static SymMat3& Multiply(SymMat3* d, const SymMat3& a, const SymMat3& b) - { - // _00 _01 _02 _11 _12 _22 - - d->v[0] = a.v[0] * b.v[0]; - d->v[1] = a.v[0] * b.v[1] + a.v[1] * b.v[3]; - d->v[2] = a.v[0] * b.v[2] + a.v[1] * b.v[4]; - - d->v[3] = a.v[3] * b.v[3]; - d->v[4] = a.v[3] * b.v[4] + a.v[4] * b.v[5]; - - d->v[5] = a.v[5] * b.v[5]; - - return *d; - } - - inline T Determinant() const - { - const this_type& m = *this; - T d; - - d = m(0,0) * (m(1,1)*m(2,2) - m(1,2) * m(2,1)); - d -= m(0,1) * (m(1,0)*m(2,2) - m(1,2) * m(2,0)); - d += m(0,2) * (m(1,0)*m(2,1) - m(1,1) * m(2,0)); - - return d; - } - - inline this_type Inverse() const - { - this_type a; - const this_type& m = *this; - T d = Determinant(); - - assert(d != 0); - T s = T(1)/d; - - a(0,0) = s * (m(1,1) * m(2,2) - m(1,2) * m(2,1)); - - a(0,1) = s * (m(0,2) * m(2,1) - m(0,1) * m(2,2)); - a(1,1) = s * (m(0,0) * m(2,2) - m(0,2) * m(2,0)); - - a(0,2) = s * (m(0,1) * m(1,2) - m(0,2) * m(1,1)); - a(1,2) = s * (m(0,2) * m(1,0) - m(0,0) * m(1,2)); - a(2,2) = s * (m(0,0) * m(1,1) - m(0,1) * m(1,0)); - - return a; - } - - inline T Trace() const { return v[0] + v[3] + v[5]; } - - // M = a*a.t() - inline void Rank1(const Vector3 &a) - { - v[0] = a.x*a.x; v[1] = a.x*a.y; v[2] = a.x*a.z; - v[3] = a.y*a.y; v[4] = a.y*a.z; - v[5] = a.z*a.z; - } - - // M += a*a.t() - inline void Rank1Add(const Vector3 &a) - { - v[0] += a.x*a.x; v[1] += a.x*a.y; v[2] += a.x*a.z; - v[3] += a.y*a.y; v[4] += a.y*a.z; - v[5] += a.z*a.z; - } - - // M -= a*a.t() - inline void Rank1Sub(const Vector3 &a) - { - v[0] -= a.x*a.x; v[1] -= a.x*a.y; v[2] -= a.x*a.z; - v[3] -= a.y*a.y; v[4] -= a.y*a.z; - v[5] -= a.z*a.z; - } -}; - -typedef SymMat3 SymMat3f; -typedef SymMat3 SymMat3d; - -template -inline Matrix3 operator*(const SymMat3& a, const SymMat3& b) -{ - #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c)) - return Matrix3( - AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2), - AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2), - AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2)); - #undef AJB_ARBC -} - -template -inline Matrix3 operator*(const Matrix3& a, const SymMat3& b) -{ - #define AJB_ARBC(r,c) (a(r,0)*b(0,c)+a(r,1)*b(1,c)+a(r,2)*b(2,c)) - return Matrix3( - AJB_ARBC(0,0), AJB_ARBC(0,1), AJB_ARBC(0,2), - AJB_ARBC(1,0), AJB_ARBC(1,1), AJB_ARBC(1,2), - AJB_ARBC(2,0), AJB_ARBC(2,1), AJB_ARBC(2,2)); - #undef AJB_ARBC -} - -//------------------------------------------------------------------------------------- -// ***** Angle - -// Cleanly representing the algebra of 2D rotations. -// The operations maintain the angle between -Pi and Pi, the same range as atan2. - -template -class Angle -{ -public: - enum AngularUnits - { - Radians = 0, - Degrees = 1 - }; - - Angle() : a(0) {} - - // Fix the range to be between -Pi and Pi - Angle(T a_, AngularUnits u = Radians) : a((u == Radians) ? a_ : a_*((T)MATH_DOUBLE_DEGREETORADFACTOR)) { FixRange(); } - - T Get(AngularUnits u = Radians) const { return (u == Radians) ? a : a*((T)MATH_DOUBLE_RADTODEGREEFACTOR); } - void Set(const T& x, AngularUnits u = Radians) { a = (u == Radians) ? x : x*((T)MATH_DOUBLE_DEGREETORADFACTOR); FixRange(); } - int Sign() const { if (a == 0) return 0; else return (a > 0) ? 1 : -1; } - T Abs() const { return (a > 0) ? a : -a; } - - bool operator== (const Angle& b) const { return a == b.a; } - bool operator!= (const Angle& b) const { return a != b.a; } -// bool operator< (const Angle& b) const { return a < a.b; } -// bool operator> (const Angle& b) const { return a > a.b; } -// bool operator<= (const Angle& b) const { return a <= a.b; } -// bool operator>= (const Angle& b) const { return a >= a.b; } -// bool operator= (const T& x) { a = x; FixRange(); } - - // These operations assume a is already between -Pi and Pi. - Angle& operator+= (const Angle& b) { a = a + b.a; FastFixRange(); return *this; } - Angle& operator+= (const T& x) { a = a + x; FixRange(); return *this; } - Angle operator+ (const Angle& b) const { Angle res = *this; res += b; return res; } - Angle operator+ (const T& x) const { Angle res = *this; res += x; return res; } - Angle& operator-= (const Angle& b) { a = a - b.a; FastFixRange(); return *this; } - Angle& operator-= (const T& x) { a = a - x; FixRange(); return *this; } - Angle operator- (const Angle& b) const { Angle res = *this; res -= b; return res; } - Angle operator- (const T& x) const { Angle res = *this; res -= x; return res; } - - T Distance(const Angle& b) { T c = fabs(a - b.a); return (c <= ((T)MATH_DOUBLE_PI)) ? c : ((T)MATH_DOUBLE_TWOPI) - c; } - -private: - - // The stored angle, which should be maintained between -Pi and Pi - T a; - - // Fixes the angle range to [-Pi,Pi], but assumes no more than 2Pi away on either side - inline void FastFixRange() - { - if (a < -((T)MATH_DOUBLE_PI)) - a += ((T)MATH_DOUBLE_TWOPI); - else if (a > ((T)MATH_DOUBLE_PI)) - a -= ((T)MATH_DOUBLE_TWOPI); - } - - // Fixes the angle range to [-Pi,Pi] for any given range, but slower then the fast method - inline void FixRange() - { - // do nothing if the value is already in the correct range, since fmod call is expensive - if (a >= -((T)MATH_DOUBLE_PI) && a <= ((T)MATH_DOUBLE_PI)) - return; - a = fmod(a,((T)MATH_DOUBLE_TWOPI)); - if (a < -((T)MATH_DOUBLE_PI)) - a += ((T)MATH_DOUBLE_TWOPI); - else if (a > ((T)MATH_DOUBLE_PI)) - a -= ((T)MATH_DOUBLE_TWOPI); - } -}; - - -typedef Angle Anglef; -typedef Angle Angled; - - -//------------------------------------------------------------------------------------- -// ***** Plane - -// Consists of a normal vector and distance from the origin where the plane is located. - -template -class Plane -{ -public: - Vector3 N; - T D; - - Plane() : D(0) {} - - // Normals must already be normalized - Plane(const Vector3& n, T d) : N(n), D(d) {} - Plane(T x, T y, T z, T d) : N(x,y,z), D(d) {} - - // construct from a point on the plane and the normal - Plane(const Vector3& p, const Vector3& n) : N(n), D(-(p * n)) {} - - // Find the point to plane distance. The sign indicates what side of the plane the point is on (0 = point on plane). - T TestSide(const Vector3& p) const - { - return (N.Dot(p)) + D; - } - - Plane Flipped() const - { - return Plane(-N, -D); - } - - void Flip() - { - N = -N; - D = -D; - } - - bool operator==(const Plane& rhs) const - { - return (this->D == rhs.D && this->N == rhs.N); - } -}; - -typedef Plane Planef; -typedef Plane Planed; - - -} // Namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Nullptr.h b/LibOVR/Src/Kernel/OVR_Nullptr.h deleted file mode 100644 index a09f446..0000000 --- a/LibOVR/Src/Kernel/OVR_Nullptr.h +++ /dev/null @@ -1,150 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Nullptr.h -Content : Implements C++11 nullptr for the case that the compiler doesn't. -Created : June 19, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Nullptr_h -#define OVR_Nullptr_h - -#pragma once - -#include "OVR_Types.h" - - -//----------------------------------------------------------------------------------- -// ***** OVR_HAVE_std_nullptr_t -// -// Identifies if includes std::nullptr_t. -// -#if !defined(OVR_HAVE_std_nullptr_t) && defined(OVR_CPP11_ENABLED) - #if defined(OVR_STDLIB_LIBCPP) - #define OVR_HAVE_std_nullptr_t 1 - #elif defined(OVR_STDLIB_LIBSTDCPP) - #if (__GLIBCXX__ >= 20110325) && (__GLIBCXX__ != 20110428) && (__GLIBCXX__ != 20120702) - #define OVR_HAVE_std_nullptr_t 1 - #endif - #elif defined(_MSC_VER) && (_MSC_VER >= 1600) // VS2010+ - #define OVR_HAVE_std_nullptr_t 1 - #elif defined(__clang__) - #define OVR_HAVE_std_nullptr_t 1 - #elif defined(OVR_CPP_GNUC) && (OVR_CC_VERSION >= 406) // GCC 4.6+ - #define OVR_HAVE_std_nullptr_t 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** nullptr / std::nullptr_t -// -// Declares and defines nullptr and related types. -// -#if defined(OVR_CPP_NO_NULLPTR) - namespace std - { - class nullptr_t - { - public: - template - operator T*() const - { return 0; } - - template - operator T C::*() const - { return 0; } - - #if OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS - typedef void* (nullptr_t::*bool_)() const; // 4.12,p1. We can't portably use operator bool(){ return false; } because bool - operator bool_() const // is convertable to int which breaks other required functionality. - { return false; } - #else - operator bool() const - { return false; } - #endif - - private: - void operator&() const; // 5.2.10,p9 - }; - - inline nullptr_t nullptr_get() - { - nullptr_t n = { }; - return n; - } - - #if !defined(nullptr) - #define nullptr nullptr_get() - #endif - - } // namespace std - - - // 5.9,p2 p4 - // 13.6, p13 - template - inline bool operator==(T* pT, const std::nullptr_t) - { return pT == 0; } - - template - inline bool operator==(const std::nullptr_t, T* pT) - { return pT == 0; } - - template - inline bool operator==(const std::nullptr_t, T U::* pU) - { return pU == 0; } - - template - inline bool operator==(T U::* pTU, const std::nullptr_t) - { return pTU == 0; } - - inline bool operator==(const std::nullptr_t, const std::nullptr_t) - { return true; } - - inline bool operator!=(const std::nullptr_t, const std::nullptr_t) - { return false; } - - inline bool operator<(const std::nullptr_t, const std::nullptr_t) - { return false; } - - inline bool operator<=(const std::nullptr_t, const std::nullptr_t) - { return true; } - - inline bool operator>(const std::nullptr_t, const std::nullptr_t) - { return false; } - - inline bool operator>=(const std::nullptr_t, const std::nullptr_t) - { return true; } - - using std::nullptr_t; - using std::nullptr_get; - -// Some compilers natively support C++11 nullptr but the standard library being used -// doesn't declare std::nullptr_t, in which case we provide one ourselves. -#elif !defined(OVR_HAVE_std_nullptr_t) && !defined(OVR_CPP_NO_DECLTYPE) - namespace std { typedef decltype(nullptr) nullptr_t; } -#endif - - -#endif - diff --git a/LibOVR/Src/Kernel/OVR_Observer.h b/LibOVR/Src/Kernel/OVR_Observer.h deleted file mode 100644 index 76b4be6..0000000 --- a/LibOVR/Src/Kernel/OVR_Observer.h +++ /dev/null @@ -1,457 +0,0 @@ -/************************************************************************************ - -PublicHeader: Kernel -Filename : OVR_Observer.h -Content : Observer pattern -Created : June 20, 2014 -Author : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Observer_h -#define OVR_Observer_h - -#include "OVR_Types.h" -#include "OVR_Atomic.h" -#include "OVR_RefCount.h" -#include "OVR_Delegates.h" -#include "OVR_Array.h" -#include "OVR_String.h" -#include "OVR_Hash.h" - -namespace OVR { - -template class Observer; -template class ObserverScope; -template class ObserverHash; - - -//----------------------------------------------------------------------------- -// Observer pattern - -// An Observer will observe a Subject. The Subject can emit callbacks that get -// serviced by the Observers. - -// The trickiest part of this is the shutdown code. -// To simplify shutdown, the Observer is a reference-counted object divorced -// from the handler that is called. To avoid misuse, the ObserverScope object -// is provided to ensure that the Shutdown() method is called when it goes out -// of scope. - -// The Observer<> class doubles as the subject class. -// To avoid misuse, assertions are added if a subject tries to observe, or if -// an observer tries to be watched. - -/* - Usage example: - - Say we want to invoke a handler with the signature: - - void MyHandler(int i, bool b); - - The corresponding delegate type is: - - typedef Delegate2 Handler; - - Note: The return value will be ignored for the Observer pattern. - - For this example there are two classes, one that emits events and another - that listens for events: -*/ - -/* - Event emitter example: - - class MyEmitter - { - ObserverScope TheSubject; - - public: - void ClearAllListeners() - { - TheSubject.ReleaseAll(); - } - - void CallListeners(int x, bool y) - { - TheSubject->Call(x, y); - } - - Observer* GetSubject() - { - return TheSubject; - } - }; -*/ - -/* - Event listener example: - - class MyListener - { - ObserverScope TheObserver; - - void OnEvent(int x, bool y) - { - // Handle event here - } - - public: - MyListener() - { - TheObserver.SetHandler( - Handler::FromMember(this) - ); - } - - void ClearListener() - { - TheObserver.ReleaseAll(); - } - - void ListenTo(Observer* emitter) - { - TheObserver->Observe(emitter); - } - }; -*/ - -/* - Usage example: - - MyListener listener; - MyEmitter emitter; - - // To listen to an emitter, - listener.ListenTo(emitter.GetSubject()); - - // To call the listeners, - emitter.CallListeners(22, true); -*/ - -template -class Observer : public RefCountBase< Observer > -{ - friend class ObserverScope; - friend class ObserverHash; - -public: - typedef Observer ThisType; - typedef DelegateT Handler; - -protected: - bool IsShutdown; // Flag to indicate that the object went out of scope - mutable Lock TheLock; // Lock to synchronize calls and shutdown - Array< Ptr< ThisType > > References; // List of observed or observing objects - Handler TheHandler; // Observer-only: Handler for callbacks - - Observer() : - IsShutdown(false) - { - TheHandler.Invalidate(); - } - Observer(Handler handler) : - IsShutdown(false), - TheHandler(handler) - { - } - ~Observer() - { - OVR_ASSERT(References.GetSizeI() == 0); - } - -public: - void SetHandler(Handler handler) - { - OVR_ASSERT(References.GetSizeI() == 0); - TheHandler = handler; - } - - // Release references and prevent further actions - void Shutdown() - { - Lock::Locker locker(&TheLock); - IsShutdown = true; - References.ClearAndRelease(); - } - - // Get count of references held - int GetSizeI() const - { - Lock::Locker locker(&TheLock); - return References.GetSizeI(); - } - - // Observe a subject - bool Observe(ThisType *subject) - { - OVR_ASSERT(TheHandler.IsValid()); - - if (!subject) - { - return false; - } - - Lock::Locker locker(&TheLock); - - if (IsShutdown) - { - return false; - } - - if (!subject->SubjectAddObserver(this)) - { - return false; - } - - References.PushBack(subject); - return true; - } - -protected: - // Subject function: AddObserver() - // Returns true if the observer was added - bool SubjectAddObserver(ThisType* observer) - { - OVR_ASSERT(!TheHandler.IsValid()); - - if (!observer) - { - return true; - } - - Lock::Locker locker(&TheLock); - - if (IsShutdown) - { - return false; - } - - const int count = References.GetSizeI(); - for (int i = 0; i < count; ++i) - { - if (References[i] == observer) - { - // Already watched - return true; - } - } - - References.PushBack(observer); - - return true; - } - -public: - // Subject function: Call() -#define OVR_OBSERVER_CALL_BODY(params) \ - bool callSuccess = false; \ - Lock::Locker locker(&TheLock); \ - int count = References.GetSizeI(); \ - for (int i = 0; i < count; ++i) \ - { \ - if (!References[i]->IsShutdown) \ - { \ - OVR_ASSERT(References[i]->TheHandler.IsValid()); \ - References[i]->TheHandler params; \ - callSuccess = true; \ - } \ - if (References[i]->IsShutdown) \ - { \ - References.RemoveAt(i); \ - --i; --count; \ - } \ - } \ - return callSuccess; - - // Call: Various parameter counts - // Returns true if a call was made - bool Call() - { - OVR_OBSERVER_CALL_BODY(()) - } - template - bool Call(Param1& p1) - { - OVR_OBSERVER_CALL_BODY((p1)) - } - template - bool Call(Param1* p1) - { - OVR_OBSERVER_CALL_BODY((p1)) - } - template - bool Call(Param1& p1, Param2& p2) - { - OVR_OBSERVER_CALL_BODY((p1, p2)) - } - template - bool Call(Param1* p1, Param2* p2) - { - OVR_OBSERVER_CALL_BODY((p1, p2)) - } - template - bool Call(Param1& p1, Param2& p2, Param3& p3) - { - OVR_OBSERVER_CALL_BODY((p1, p2, p3)) - } - template - bool Call(Param1* p1, Param2* p2, Param3* p3) - { - OVR_OBSERVER_CALL_BODY((p1, p2, p3)) - } - -#undef OVR_OBSERVER_CALL_BODY -}; - - -//----------------------------------------------------------------------------- -// ObserverScope - -// Scoped shutdown of the Observer object -template -class ObserverScope : public NewOverrideBase -{ - Ptr< Observer > TheObserver; - DelegateT TheHandler; - - void Shutdown() - { - if (TheObserver) - { - TheObserver->Shutdown(); - TheObserver.Clear(); - } - } - -public: - ObserverScope() - { - TheObserver = *new Observer; - } - ~ObserverScope() - { - Shutdown(); - } - - // Release all references and recreate it - void ReleaseAll() - { - Shutdown(); - TheObserver = *new Observer; - if (TheHandler.IsValid()) - { - TheObserver->SetHandler(TheHandler); - } - } - - void SetHandler(DelegateT handler) - { - TheHandler = handler; - TheObserver->SetHandler(handler); - } - - Observer* GetPtr() - { - return TheObserver.GetPtr(); - } - Observer* operator->() - { - return TheObserver.GetPtr(); - } - const Observer* operator->() const - { - return TheObserver.GetPtr(); - } - operator Observer*() - { - return TheObserver.GetPtr(); - } -}; - - -//----------------------------------------------------------------------------- -// ObserverHash - -// A hash containing Observers -template -class ObserverHash : public NewOverrideBase -{ -public: - ObserverHash() {} - ~ObserverHash() {Clear();} - void Clear() - { - Lock::Locker locker(&TheLock); - typename OVR::Hash< String, Ptr >, OVR::String::HashFunctor >::Iterator it = _Hash.Begin(); - for( it = _Hash.Begin(); it != _Hash.End(); ++it ) - { - Ptr > o = it->Second; - o->Shutdown(); - } - } - - Ptr > GetSubject(OVR::String key) - { - Lock::Locker locker(&TheLock); - Ptr > *o = _Hash.Get(key); - if (o) - return (*o); - return NULL; - } - - // Add handler to new observer with implicit creation of subject. - void AddObserverToSubject(OVR::String key, Observer *observer) - { - Lock::Locker locker(&TheLock); - Ptr > *subjectPtr = _Hash.Get(key); - - if (subjectPtr==NULL) - { - Ptr > subject = *new Observer(); - _Hash.Add(key, subject); - observer->Observe(subject); - } - else - { - observer->Observe(*subjectPtr); - } - } - - void RemoveSubject(OVR::String key) - { - Lock::Locker locker(&TheLock); - Ptr > *subjectPtr = _Hash.Get(key); - if (subjectPtr!=NULL) - { - (*subjectPtr)->Shutdown(); - _Hash.Remove(key); - } - } - -protected: - OVR::Hash< OVR::String, Ptr >, OVR::String::HashFunctor > _Hash; - Lock TheLock; // Lock to synchronize calls and shutdown -}; - - -} // namespace OVR - -#endif // OVR_Observer_h diff --git a/LibOVR/Src/Kernel/OVR_RefCount.cpp b/LibOVR/Src/Kernel/OVR_RefCount.cpp deleted file mode 100644 index f761811..0000000 --- a/LibOVR/Src/Kernel/OVR_RefCount.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/************************************************************************************ - -Filename : OVR_RefCount.cpp -Content : Reference counting implementation -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_RefCount.h" -#include "OVR_Atomic.h" -#include "OVR_Log.h" - -namespace OVR { - -#ifdef OVR_CC_ARM -void* ReturnArg0(void* p) -{ - return p; -} -#endif - -// ***** Reference Count Base implementation - -RefCountImplCore::~RefCountImplCore() -{ - // RefCount can be either 1 or 0 here. - // 0 if Release() was properly called. - // 1 if the object was declared on stack or as an aggregate. - OVR_ASSERT(RefCount <= 1); -} - -#ifdef OVR_BUILD_DEBUG -void RefCountImplCore::reportInvalidDelete(void *pmem) -{ - OVR_DEBUG_LOG( - ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); - OVR_ASSERT(0); -} -#endif - -RefCountNTSImplCore::~RefCountNTSImplCore() -{ - // RefCount can be either 1 or 0 here. - // 0 if Release() was properly called. - // 1 if the object was declared on stack or as an aggregate. - OVR_ASSERT(RefCount <= 1); -} - -#ifdef OVR_BUILD_DEBUG -void RefCountNTSImplCore::reportInvalidDelete(void *pmem) -{ - OVR_DEBUG_LOG( - ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); - OVR_ASSERT(0); -} -#endif - - -// *** Thread-Safe RefCountImpl - -void RefCountImpl::AddRef() -{ - AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); -} -void RefCountImpl::Release() -{ - if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) - delete this; -} - -// *** Thread-Safe RefCountVImpl w/virtual AddRef/Release - -void RefCountVImpl::AddRef() -{ - AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); -} -void RefCountVImpl::Release() -{ - if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) - delete this; -} - -// *** NON-Thread-Safe RefCountImpl - -void RefCountNTSImpl::Release() const -{ - RefCount--; - if (RefCount == 0) - delete this; -} - - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_RefCount.h b/LibOVR/Src/Kernel/OVR_RefCount.h deleted file mode 100644 index 33c6f37..0000000 --- a/LibOVR/Src/Kernel/OVR_RefCount.h +++ /dev/null @@ -1,565 +0,0 @@ -/************************************************************************************ - -PublicHeader: Kernel -Filename : OVR_RefCount.h -Content : Reference counting implementation headers -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_RefCount_h -#define OVR_RefCount_h - -#include "OVR_Types.h" -#include "OVR_Allocator.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Reference Counting - -// There are three types of reference counting base classes: -// -// RefCountBase - Provides thread-safe reference counting (Default). -// RefCountBaseNTS - Non Thread Safe version of reference counting. - - -// ***** Declared classes - -template -class RefCountBase; -template -class RefCountBaseNTS; - -class RefCountImpl; -class RefCountNTSImpl; - - -//----------------------------------------------------------------------------------- -// ***** Implementation For Reference Counting - -// RefCountImplCore holds RefCount value and defines a few utility -// functions shared by all implementations. - -class RefCountImplCore -{ -protected: - volatile int RefCount; - -public: - // RefCountImpl constructor always initializes RefCount to 1 by default. - OVR_FORCE_INLINE RefCountImplCore() : RefCount(1) { } - - // Need virtual destructor - // This: 1. Makes sure the right destructor's called. - // 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem() - virtual ~RefCountImplCore(); - - // Debug method only. - int GetRefCount() const { return RefCount; } - - // This logic is used to detect invalid 'delete' calls of reference counted - // objects. Direct delete calls are not allowed on them unless they come in - // internally from Release. -#ifdef OVR_BUILD_DEBUG - static void OVR_CDECL reportInvalidDelete(void *pmem); - inline static void checkInvalidDelete(RefCountImplCore *pmem) - { - if (pmem->RefCount != 0) - reportInvalidDelete(pmem); - } -#else - inline static void checkInvalidDelete(RefCountImplCore *) { } -#endif - - // Base class ref-count content should not be copied. - void operator = (const RefCountImplCore &) { } -}; - -class RefCountNTSImplCore -{ -protected: - mutable int RefCount; - -public: - // RefCountImpl constructor always initializes RefCount to 1 by default. - OVR_FORCE_INLINE RefCountNTSImplCore() : RefCount(1) { } - - // Need virtual destructor - // This: 1. Makes sure the right destructor's called. - // 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem() - virtual ~RefCountNTSImplCore(); - - // Debug method only. - int GetRefCount() const { return RefCount; } - - // This logic is used to detect invalid 'delete' calls of reference counted - // objects. Direct delete calls are not allowed on them unless they come in - // internally from Release. -#ifdef OVR_BUILD_DEBUG - static void OVR_CDECL reportInvalidDelete(void *pmem); - OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *pmem) - { - if (pmem->RefCount != 0) - reportInvalidDelete(pmem); - } -#else - OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *) { } -#endif - - // Base class ref-count content should not be copied. - void operator = (const RefCountNTSImplCore &) { } -}; - - - -// RefCountImpl provides Thread-Safe implementation of reference counting, so -// it should be used by default in most places. - -class RefCountImpl : public RefCountImplCore -{ -public: - // Thread-Safe Ref-Count Implementation. - void AddRef(); - void Release(); -}; - -// RefCountVImpl provides Thread-Safe implementation of reference counting, plus, -// virtual AddRef and Release. - -class RefCountVImpl : virtual public RefCountImplCore -{ -public: - // Thread-Safe Ref-Count Implementation. - virtual void AddRef(); - virtual void Release(); -}; - - -// RefCountImplNTS provides Non-Thread-Safe implementation of reference counting, -// which is slightly more efficient since it doesn't use atomics. - -class RefCountNTSImpl : public RefCountNTSImplCore -{ -public: - OVR_FORCE_INLINE void AddRef() const { RefCount++; } - void Release() const; -}; - - - -// RefCountBaseStatImpl<> is a common class that adds new/delete override with Stat tracking -// to the reference counting implementation. Base must be one of the RefCountImpl classes. - -template -class RefCountBaseStatImpl : public Base -{ -public: - RefCountBaseStatImpl() { } - - // *** Override New and Delete - - // DOM-IGNORE-BEGIN - // Undef new temporarily if it is being redefined -#ifdef OVR_DEFINE_NEW -#undef new -#endif - -#ifdef OVR_BUILD_DEBUG - // Custom check used to detect incorrect calls of 'delete' on ref-counted objects. - #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) \ - do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0) -#else - #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) -#endif - - // Redefine all new & delete operators. - OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE) - -#undef OVR_REFCOUNTALLOC_CHECK_DELETE - -#ifdef OVR_DEFINE_NEW -#define new OVR_DEFINE_NEW -#endif - // OVR_BUILD_DEFINE_NEW - // DOM-IGNORE-END -}; - - -template -class RefCountBaseStatVImpl : virtual public Base -{ -public: - RefCountBaseStatVImpl() { } - - // *** Override New and Delete - - // DOM-IGNORE-BEGIN - // Undef new temporarily if it is being redefined -#ifdef OVR_DEFINE_NEW -#undef new -#endif - -#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) - - // Redefine all new & delete operators. - OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE) - -#undef OVR_REFCOUNTALLOC_CHECK_DELETE - -#ifdef OVR_DEFINE_NEW -#define new OVR_DEFINE_NEW -#endif - // OVR_BUILD_DEFINE_NEW - // DOM-IGNORE-END -}; - - - -//----------------------------------------------------------------------------------- -// *** End user RefCountBase<> classes - - -// RefCountBase is a base class for classes that require thread-safe reference -// counting; it also overrides the new and delete operators to use MemoryHeap. -// -// Reference counted objects start out with RefCount value of 1. Further lifetime -// management is done through the AddRef() and Release() methods, typically -// hidden by Ptr<>. - -template -class RefCountBase : public RefCountBaseStatImpl -{ -public: - // Constructor. - OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl() { } -}; - -// RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release - -template -class RefCountBaseV : virtual public RefCountBaseStatVImpl -{ -public: - // Constructor. - OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatVImpl() { } -}; - - -// RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference -// counting; it also overrides the new and delete operators to use MemoryHeap. -// This class should only be used if all pointers to it are known to be assigned, -// destroyed and manipulated within one thread. -// -// Reference counted objects start out with RefCount value of 1. Further lifetime -// management is done through the AddRef() and Release() methods, typically -// hidden by Ptr<>. - -template -class RefCountBaseNTS : public RefCountBaseStatImpl -{ -public: - // Constructor. - OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl() { } -}; - -//----------------------------------------------------------------------------------- -// ***** Pickable template pointer -enum PickType { PickValue }; - -template -class Pickable -{ -public: - Pickable() : pV(NULL) {} - explicit Pickable(T* p) : pV(p) {} - Pickable(T* p, PickType) : pV(p) - { - OVR_ASSERT(pV); - if (pV) - pV->AddRef(); - } - template - Pickable(const Pickable& other) : pV(other.GetPtr()) {} - -public: - Pickable& operator =(const Pickable& other) - { - OVR_ASSERT(pV == NULL); - pV = other.pV; - // Extra check. - //other.pV = NULL; - return *this; - } - -public: - T* GetPtr() const { return pV; } - T* operator->() const - { - return pV; - } - T& operator*() const - { - OVR_ASSERT(pV); - return *pV; - } - -private: - T* pV; -}; - -template -OVR_FORCE_INLINE -Pickable MakePickable(T* p) -{ - return Pickable(p); -} - -//----------------------------------------------------------------------------------- -// ***** Ref-Counted template pointer - -// Automatically AddRefs and Releases interfaces - -void* ReturnArg0(void* p); - -template -class Ptr -{ -#ifdef OVR_CC_ARM - static C* ReturnArg(void* p) { return (C*)ReturnArg0(p); } -#endif - -protected: - C *pObject; - -public: - - // Constructors - OVR_FORCE_INLINE Ptr() : pObject(0) - { } -#ifdef OVR_CC_ARM - OVR_FORCE_INLINE Ptr(C &robj) : pObject(ReturnArg(&robj)) -#else - OVR_FORCE_INLINE Ptr(C &robj) : pObject(&robj) -#endif - { } - OVR_FORCE_INLINE Ptr(Pickable v) : pObject(v.GetPtr()) - { - // No AddRef() on purpose. - } - OVR_FORCE_INLINE Ptr(Ptr& other, PickType) : pObject(other.pObject) - { - other.pObject = NULL; - // No AddRef() on purpose. - } - OVR_FORCE_INLINE Ptr(C *pobj) - { - if (pobj) pobj->AddRef(); - pObject = pobj; - } - OVR_FORCE_INLINE Ptr(const Ptr &src) - { - if (src.pObject) src.pObject->AddRef(); - pObject = src.pObject; - } - - template - OVR_FORCE_INLINE Ptr(Ptr &src) - { - if (src) src->AddRef(); - pObject = src; - } - template - OVR_FORCE_INLINE Ptr(Pickable v) : pObject(v.GetPtr()) - { - // No AddRef() on purpose. - } - - // Destructor - OVR_FORCE_INLINE ~Ptr() - { - if (pObject) pObject->Release(); - } - - // Compares - OVR_FORCE_INLINE bool operator == (const Ptr &other) const { return pObject == other.pObject; } - OVR_FORCE_INLINE bool operator != (const Ptr &other) const { return pObject != other.pObject; } - - OVR_FORCE_INLINE bool operator == (C *pother) const { return pObject == pother; } - OVR_FORCE_INLINE bool operator != (C *pother) const { return pObject != pother; } - - - OVR_FORCE_INLINE bool operator < (const Ptr &other) const { return pObject < other.pObject; } - - // Assignment - template - OVR_FORCE_INLINE const Ptr& operator = (const Ptr &src) - { - // By design we don't check for src == pObject, as we don't expect that to be the case the large majority of the time. - if (src) src->AddRef(); - if (pObject) pObject->Release(); - pObject = src; - return *this; - } - // Specialization - OVR_FORCE_INLINE const Ptr& operator = (const Ptr &src) - { - if (src) src->AddRef(); - if (pObject) pObject->Release(); - pObject = src; - return *this; - } - - OVR_FORCE_INLINE const Ptr& operator = (C *psrc) - { - if (psrc) psrc->AddRef(); - if (pObject) pObject->Release(); - pObject = psrc; - return *this; - } - OVR_FORCE_INLINE const Ptr& operator = (C &src) - { - if (pObject) pObject->Release(); - pObject = &src; - return *this; - } - OVR_FORCE_INLINE Ptr& operator = (Pickable src) - { - return Pick(src); - } - template - OVR_FORCE_INLINE Ptr& operator = (Pickable src) - { - return Pick(src); - } - - // Set Assignment - template - OVR_FORCE_INLINE Ptr& SetPtr(const Ptr &src) - { - if (src) src->AddRef(); - if (pObject) pObject->Release(); - pObject = src; - return *this; - } - // Specialization - OVR_FORCE_INLINE Ptr& SetPtr(const Ptr &src) - { - if (src) src->AddRef(); - if (pObject) pObject->Release(); - pObject = src; - return *this; - } - - OVR_FORCE_INLINE Ptr& SetPtr(C *psrc) - { - if (psrc) psrc->AddRef(); - if (pObject) pObject->Release(); - pObject = psrc; - return *this; - } - OVR_FORCE_INLINE Ptr& SetPtr(C &src) - { - if (pObject) pObject->Release(); - pObject = &src; - return *this; - } - OVR_FORCE_INLINE Ptr& SetPtr(Pickable src) - { - return Pick(src); - } - - // Nulls ref-counted pointer without decrement - OVR_FORCE_INLINE void NullWithoutRelease() - { - pObject = 0; - } - - // Clears the pointer to the object - OVR_FORCE_INLINE void Clear() - { - if (pObject) pObject->Release(); - pObject = 0; - } - - // Obtain pointer reference directly, for D3D interfaces - OVR_FORCE_INLINE C*& GetRawRef() { return pObject; } - - // Access Operators - OVR_FORCE_INLINE C* GetPtr() const { return pObject; } - OVR_FORCE_INLINE C& operator * () const { return *pObject; } - OVR_FORCE_INLINE C* operator -> () const { return pObject; } - // Conversion - OVR_FORCE_INLINE operator C* () const { return pObject; } - - // Pickers. - - // Pick a value. - OVR_FORCE_INLINE Ptr& Pick(Ptr& other) - { - if (&other != this) - { - if (pObject) pObject->Release(); - pObject = other.pObject; - other.pObject = 0; - } - - return *this; - } - - OVR_FORCE_INLINE Ptr& Pick(Pickable v) - { - if (v.GetPtr() != pObject) - { - if (pObject) pObject->Release(); - pObject = v.GetPtr(); - } - - return *this; - } - - template - OVR_FORCE_INLINE Ptr& Pick(Pickable v) - { - if (v.GetPtr() != pObject) - { - if (pObject) pObject->Release(); - pObject = v.GetPtr(); - } - - return *this; - } - - OVR_FORCE_INLINE Ptr& Pick(C* p) - { - if (p != pObject) - { - if (pObject) pObject->Release(); - pObject = p; - } - - return *this; - } -}; - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp b/LibOVR/Src/Kernel/OVR_SharedMemory.cpp deleted file mode 100644 index 1a6ccd9..0000000 --- a/LibOVR/Src/Kernel/OVR_SharedMemory.cpp +++ /dev/null @@ -1,691 +0,0 @@ -/************************************************************************************ - -Filename : OVR_SharedMemory.cpp -Content : Inter-process shared memory subsystem -Created : June 1, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_SharedMemory.h" -#include "OVR_Atomic.h" -#include "OVR_Log.h" -#include "OVR_String.h" -#include "OVR_Array.h" - -#if defined(OVR_OS_WIN32) && !defined(OVR_FAKE_SHAREDMEMORY) -#include // ConvertStringSecurityDescriptorToSecurityDescriptor -#endif // OVR_OS_WIN32 - -#if (defined(OVR_OS_LINUX) || defined(OVR_OS_MAC)) && !defined(OVR_FAKE_SHAREDMEMORY) -#include // shm_open(), mmap() -#include // error results for mmap -#include // mode constants -#include // O_ constants -#include // close() -#endif // OVR_OS_LINUX - -OVR_DEFINE_SINGLETON(OVR::SharedMemoryFactory); - -namespace OVR { - - - //// Fake version - -#if defined(OVR_FAKE_SHAREDMEMORY) - - class FakeMemoryBlock : public RefCountBase - { - String Name; - char* Data; - int SizeBytes; - int References; - - public: - FakeMemoryBlock(const String& name, int size) : - Name(name), - Data(NULL), - SizeBytes(size), - References(1) - { - Data = new char[SizeBytes]; - } - ~FakeMemoryBlock() - { - delete[] Data; - } - - bool IsNamed(const String& name) - { - return Name.CompareNoCase(name) == 0; - } - void* GetData() - { - return Data; - } - int GetSizeI() - { - return SizeBytes; - } - void IncrementReferences() - { - ++References; - } - bool DecrementReferences() - { - return --References <= 0; - } - }; - - class SharedMemoryInternal : public NewOverrideBase - { - public: - void* FileView; - Ptr Block; - - void Close(); - - SharedMemoryInternal(FakeMemoryBlock* block) : - Block(block) - { - FileView = Block->GetData(); - } - ~SharedMemoryInternal() - { - Close(); - } - - static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params); - }; - - - //// FakeMemoryManager - - class FakeMemoryManager : public NewOverrideBase, public SystemSingletonBase - { - OVR_DECLARE_SINGLETON(FakeMemoryManager); - - Lock FakeLock; - Array< Ptr > FakeArray; - - public: - SharedMemoryInternal* Open(const char *name, int bytes, bool openOnly) - { - Lock::Locker locker(&FakeLock); - - const int count = FakeArray.GetSizeI(); - for (int ii = 0; ii < count; ++ii) - { - if (FakeArray[ii]->IsNamed(name)) - { - FakeArray[ii]->IncrementReferences(); - return new SharedMemoryInternal(FakeArray[ii]); - } - } - - if (openOnly) - { - return NULL; - } - - Ptr data = *new FakeMemoryBlock(name, bytes); - FakeArray.PushBack(data); - return new SharedMemoryInternal(data); - } - - void Free(FakeMemoryBlock* block) - { - Lock::Locker locker(&FakeLock); - - const int count = FakeArray.GetSizeI(); - for (int ii = 0; ii < count; ++ii) - { - if (FakeArray[ii].GetPtr() == block) - { - // If the reference count hit zero, - if (FakeArray[ii]->DecrementReferences()) - { - // Toast - FakeArray.RemoveAtUnordered(ii); - } - break; - } - } - } - }; - - FakeMemoryManager::FakeMemoryManager() - { - PushDestroyCallbacks(); - } - - FakeMemoryManager::~FakeMemoryManager() - { - OVR_ASSERT(FakeArray.GetSizeI() == 0); - } - - void FakeMemoryManager::OnSystemDestroy() - { - delete this; - } - - -} // namespace OVR - -OVR_DEFINE_SINGLETON(FakeMemoryManager); - -namespace OVR { - - -void SharedMemoryInternal::Close() -{ - FakeMemoryManager::GetInstance()->Free(Block); - Block.Clear(); -} - -SharedMemoryInternal* SharedMemoryInternal::CreateSharedMemory(const SharedMemory::OpenParameters& params) -{ - return FakeMemoryManager::GetInstance()->Open(params.globalName, params.minSizeBytes, params.openMode == SharedMemory::OpenMode_OpenOnly); -} - -#endif - - -//// Windows version - -#if defined(OVR_OS_WIN32) && !defined(OVR_FAKE_SHAREDMEMORY) - -#pragma comment(lib, "advapi32.lib") - -// Hidden implementation class for OS-specific behavior -class SharedMemoryInternal : public NewOverrideBase -{ -public: - HANDLE FileMapping; - void* FileView; - - SharedMemoryInternal(HANDLE fileMapping, void* fileView) : - FileMapping(fileMapping), - FileView(fileView) - { - } - - ~SharedMemoryInternal() - { - // If file view is set, - if (FileView) - { - UnmapViewOfFile(FileView); - FileView = NULL; - } - - // If file mapping is set, - if (FileMapping != NULL) - { - CloseHandle(FileMapping); - FileMapping = NULL; - } - } - - static SharedMemoryInternal* DoFileMap(HANDLE hFileMapping, const char* fileName, bool openReadOnly, int minSize); - static SharedMemoryInternal* AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly); - static SharedMemoryInternal* AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite); - static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params); -}; - -SharedMemoryInternal* SharedMemoryInternal::DoFileMap(HANDLE hFileMapping, const char* fileName, bool openReadOnly, int minSize) -{ - // Interpret the access mode as a map desired access code - DWORD mapDesiredAccess = openReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE; - - // Map view of the file to this process - void* pFileView = MapViewOfFile(hFileMapping, mapDesiredAccess, 0, 0, minSize); - - // If mapping could not be created, - if (!pFileView) - { - CloseHandle(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to map view of file for %s error code = %d", fileName, GetLastError())); - OVR_UNUSED(fileName); - return NULL; - } - - // Create internal representation - SharedMemoryInternal* pimple = new SharedMemoryInternal(hFileMapping, pFileView); - - // If memory allocation fails, - if (!pimple) - { - UnmapViewOfFile(pFileView); - CloseHandle(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Out of memory")); - return NULL; - } - - return pimple; -} - -SharedMemoryInternal* SharedMemoryInternal::AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly) -{ - // Interpret the access mode as a map desired access code - DWORD mapDesiredAccess = openReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE; - - // Open file mapping - HANDLE hFileMapping = OpenFileMappingA(mapDesiredAccess, TRUE, fileName); - - // If file was mapped unsuccessfully, - if (NULL == hFileMapping) - { - OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to open file mapping for %s error code = %d (not necessarily bad)", fileName, GetLastError())); - return NULL; - } - - // Map the file - return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); -} - -SharedMemoryInternal* SharedMemoryInternal::AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite) -{ - // Prepare a SECURITY_ATTRIBUTES object - SECURITY_ATTRIBUTES security; - ZeroMemory(&security, sizeof(security)); - security.nLength = sizeof(security); - - // Security descriptor by DACL strings: - // ACE strings grant Allow(A), Object/Contains Inheritance (OICI) of: - // + Grant All (GA) to System (SY) - // + Grant All (GA) to Built-in Administrators (BA) - // + Grant Read-Only (GR) or Read-Write (GWGR) to Interactive Users (IU) - ie. games - static const char* DACLString_ReadOnly = "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)"; - static const char* DACLString_ReadWrite = "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GWGR;;;IU)"; - - // Select the remote process access mode - const char* remoteAccessString = - allowRemoteWrite ? DACLString_ReadWrite : DACLString_ReadOnly; - - // Attempt to convert access string to security attributes - // Note: This will allocate the security descriptor with LocalAlloc() and must be freed later - BOOL bConvertOkay = ConvertStringSecurityDescriptorToSecurityDescriptorA( - remoteAccessString, SDDL_REVISION_1, &security.lpSecurityDescriptor, NULL); - - // If conversion fails, - if (!bConvertOkay) - { - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to convert access string, error code = %d", GetLastError())); - return NULL; - } - - // Interpret the access mode as a page protection code - int pageProtectCode = openReadOnly ? PAGE_READONLY : PAGE_READWRITE; - - // Attempt to create a file mapping - HANDLE hFileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, // From page file - &security, // Security attributes - pageProtectCode, // Read-only? - 0, // High word for size = 0 - minSize, // Low word for size - fileName); // Name of global shared memory file - - // Free the security descriptor buffer - LocalFree(security.lpSecurityDescriptor); - - // If mapping could not be created, - if (NULL == hFileMapping) - { - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to create file mapping for %s error code = %d", fileName, GetLastError())); - return NULL; - } - -#ifndef OVR_ALLOW_CREATE_FILE_MAPPING_IF_EXISTS - // If the file mapping already exists, - if (GetLastError() == ERROR_ALREADY_EXISTS) - { - CloseHandle(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: File mapping at %s already exists", fileName)); - return NULL; - } -#endif - - // Map the file - return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); -} - -SharedMemoryInternal* SharedMemoryInternal::CreateSharedMemory(const SharedMemory::OpenParameters& params) -{ - SharedMemoryInternal* retval = NULL; - - // Construct the file mapping name in a Windows-specific way - OVR::String fileMappingName = params.globalName; - const char *fileName = fileMappingName.ToCStr(); - - // Is being opened read-only? - const bool openReadOnly = (params.accessMode == SharedMemory::AccessMode_ReadOnly); - - // Try up to 3 times to reduce low-probability failures: - static const int ATTEMPTS_MAX = 3; - for (int attempts = 0; attempts < ATTEMPTS_MAX; ++attempts) - { - // If opening should be attempted first, - if (params.openMode != SharedMemory::OpenMode_CreateOnly) - { - // Attempt to open a shared memory map - retval = AttemptOpenSharedMemory(fileName, params.minSizeBytes, openReadOnly); - - // If successful, - if (retval) - { - // Done! - break; - } - } - - // If creating the shared memory is also acceptable, - if (params.openMode != SharedMemory::OpenMode_OpenOnly) - { - // Interpret create mode - const bool allowRemoteWrite = (params.remoteMode == SharedMemory::RemoteMode_ReadWrite); - - // Attempt to create a shared memory map - retval = AttemptCreateSharedMemory(fileName, params.minSizeBytes, openReadOnly, allowRemoteWrite); - - // If successful, - if (retval) - { - // Done! - break; - } - } - } // Re-attempt create/open - - // Note: On Windows the initial contents of the region are guaranteed to be zero. - return retval; -} - -#endif // OVR_OS_WIN32 - - -#if (defined(OVR_OS_LINUX) || defined(OVR_OS_MAC)) && !defined(OVR_FAKE_SHAREDMEMORY) - -// Hidden implementation class for OS-specific behavior -class SharedMemoryInternal -{ -public: - int FileMapping; - void* FileView; - int FileSize; - - SharedMemoryInternal(int fileMapping, void* fileView, int fileSize) : - FileMapping(fileMapping), - FileView(fileView), - FileSize(fileSize) - { - } - - ~SharedMemoryInternal() - { - // If file view is set, - if (FileView) - { - munmap(FileView, FileSize); - FileView = MAP_FAILED; - } - - // If file mapping is set, - if (FileMapping >= 0) - { - close(FileMapping); - FileMapping = -1; - } - } - - static SharedMemoryInternal* DoFileMap(int hFileMapping, const char* fileName, bool openReadOnly, int minSize); - static SharedMemoryInternal* AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly); - static SharedMemoryInternal* AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite); - static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params); -}; - -SharedMemoryInternal* SharedMemoryInternal::DoFileMap(int hFileMapping, const char* fileName, bool openReadOnly, int minSize) -{ - // Calculate the required flags based on read/write mode - int prot = openReadOnly ? PROT_READ : (PROT_READ|PROT_WRITE); - - // Map the file view - void* pFileView = mmap(NULL, minSize, prot, MAP_SHARED, hFileMapping, 0); - - if (pFileView == MAP_FAILED) - { - close(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to map view of file for %s error code = %d", fileName, errno)); - OVR_UNUSED(fileName); - return NULL; - } - - // Create internal representation - SharedMemoryInternal* pimple = new SharedMemoryInternal(hFileMapping, pFileView, minSize); - - // If memory allocation fails, - if (!pimple) - { - munmap(pFileView, minSize); - close(hFileMapping); - - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Out of memory")); - return NULL; - } - - return pimple; -} - -SharedMemoryInternal* SharedMemoryInternal::AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly) -{ - // Calculate permissions and flags based on read/write mode - int flags = openReadOnly ? O_RDONLY : O_RDWR; - int perms = openReadOnly ? S_IRUSR : (S_IRUSR | S_IWUSR); - - // Attempt to open the shared memory file - int hFileMapping = shm_open(fileName, flags, perms); - - // If file was not opened successfully, - if (hFileMapping < 0) - { - OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to open file mapping for %s error code = %d (not necessarily bad)", fileName, errno)); - return NULL; - } - - // Map the file - return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); -} - -SharedMemoryInternal* SharedMemoryInternal::AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite) -{ - // Create mode - // Note: Cannot create the shared memory file read-only because then ftruncate() will fail. - int flags = O_CREAT | O_RDWR; - -#ifndef OVR_ALLOW_CREATE_FILE_MAPPING_IF_EXISTS - // Require exclusive access when creating (seems like a good idea without trying it yet..) - if (shm_unlink(fileName) < 0) - { - OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to unlink shared memory file %s error code = %d", fileName, errno)); - } - flags |= O_EXCL; -#endif - - // Set own read/write permissions - int perms = openReadOnly ? S_IRUSR : (S_IRUSR|S_IWUSR); - - // Allow other users to read/write the shared memory file - perms |= allowRemoteWrite ? (S_IWGRP|S_IWOTH|S_IRGRP|S_IROTH) : (S_IRGRP|S_IROTH); - - // Attempt to open the shared memory file - int hFileMapping = shm_open(fileName, flags, perms); - - // If file was not opened successfully, - if (hFileMapping < 0) - { - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to create file mapping for %s error code = %d", fileName, errno)); - return NULL; - } - - int truncRes = ftruncate(hFileMapping, minSize); - - // If file was not opened successfully, - if (truncRes < 0) - { - close(hFileMapping); - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to truncate file for %s to %d error code = %d", fileName, minSize, errno)); - return NULL; - } - - // Map the file - return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); -} - -SharedMemoryInternal* SharedMemoryInternal::CreateSharedMemory(const SharedMemory::OpenParameters& params) -{ - SharedMemoryInternal* retval = NULL; - - // Construct the file mapping name in a Linux-specific way - OVR::String fileMappingName = "/"; - fileMappingName += params.globalName; - const char *fileName = fileMappingName.ToCStr(); - - // Is being opened read-only? - const bool openReadOnly = (params.accessMode == SharedMemory::AccessMode_ReadOnly); - - // Try up to 3 times to reduce low-probability failures: - static const int ATTEMPTS_MAX = 3; - for (int attempts = 0; attempts < ATTEMPTS_MAX; ++attempts) - { - // If opening should be attempted first, - if (params.openMode != SharedMemory::OpenMode_CreateOnly) - { - // Attempt to open a shared memory map - retval = AttemptOpenSharedMemory(fileName, params.minSizeBytes, openReadOnly); - - // If successful, - if (retval) - { - // Done! - break; - } - } - - // If creating the shared memory is also acceptable, - if (params.openMode != SharedMemory::OpenMode_OpenOnly) - { - // Interpret create mode - const bool allowRemoteWrite = (params.remoteMode == SharedMemory::RemoteMode_ReadWrite); - - // Attempt to create a shared memory map - retval = AttemptCreateSharedMemory(fileName, params.minSizeBytes, openReadOnly, allowRemoteWrite); - - // If successful, - if (retval) - { - // Done! - break; - } - } - } // Re-attempt create/open - - // Note: On Windows the initial contents of the region are guaranteed to be zero. - return retval; -} - -#endif // OVR_OS_LINUX - - -//// SharedMemory - -SharedMemory::SharedMemory(int size, void* data, SharedMemoryInternal* pInternal) : - Size(size), - Data(data), - Internal(pInternal) -{ -} -// Call close when it goes out of scope -SharedMemory::~SharedMemory() -{ - Close(); - delete Internal; -} - -void SharedMemory::Close() -{ - if (Internal) - { - delete Internal; - Internal = NULL; - } -} - - -//// SharedMemoryFactory - -Ptr SharedMemoryFactory::Open(const SharedMemory::OpenParameters& params) -{ - Ptr retval; - - // If no name specified or no size requested, - if (!params.globalName || (params.minSizeBytes <= 0)) - { - OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Invalid parameters to Create()")); - return NULL; - } - - OVR_DEBUG_LOG(("[SharedMemory] Creating shared memory region: %s > %d bytes", - params.globalName, params.minSizeBytes)); - - // Attempt to create a shared memory region from the parameters - SharedMemoryInternal* pInternal = SharedMemoryInternal::CreateSharedMemory(params); - - if (pInternal) - { - // Create the wrapper object - retval = *new SharedMemory(params.minSizeBytes, pInternal->FileView, pInternal); - } - - return retval; -} - -SharedMemoryFactory::SharedMemoryFactory() -{ - OVR_DEBUG_LOG(("[SharedMemory] Creating factory")); - - PushDestroyCallbacks(); -} - -SharedMemoryFactory::~SharedMemoryFactory() -{ - OVR_DEBUG_LOG(("[SharedMemory] Destroying factory")); -} - -void SharedMemoryFactory::OnSystemDestroy() -{ - delete this; -} - - -} // namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_SharedMemory.h b/LibOVR/Src/Kernel/OVR_SharedMemory.h deleted file mode 100644 index 2cc8b04..0000000 --- a/LibOVR/Src/Kernel/OVR_SharedMemory.h +++ /dev/null @@ -1,240 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_SharedMemory.h -Content : Inter-process shared memory subsystem -Created : June 1, 2014 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_SharedMemory_h -#define OVR_SharedMemory_h - -#include "OVR_Types.h" -#include "OVR_RefCount.h" -#include "OVR_Allocator.h" -#include "OVR_System.h" - -#ifdef OVR_SINGLE_PROCESS /* Everything running in one process usually for debugging */ -#define OVR_FAKE_SHAREDMEMORY /* Single-process version to avoid admin privs */ -#endif - -namespace OVR { - -class SharedMemoryInternal; // Opaque - - -// SharedMemory -// Note: Safe when used between 32-bit and 64-bit processes -class SharedMemory : public RefCountBase -{ - friend class SharedMemoryFactory; - - OVR_NON_COPYABLE(SharedMemory); - -public: - // Only constructed by the SharedMemory Factory - SharedMemory(int size, void* data, SharedMemoryInternal* pInternal); - // Call close when it goes out of scope - ~SharedMemory(); - - // Modes for opening a new shared memory region - enum OpenMode - { - // Note: On Windows, Create* requires Administrator priviledges or running as a Service. - OpenMode_CreateOnly, // Must not already exist - OpenMode_OpenOnly, // Must already exist - OpenMode_CreateOrOpen // May exist or not - }; - - // Local access restrictions - enum AccessMode - { - AccessMode_ReadOnly, // Acquire read-only access - AccessMode_ReadWrite, // Acquire read or write access - }; - - // Remote access restrictions - enum RemoteMode - { - RemoteMode_ReadOnly, // Other processes will need to open in read-only mode - RemoteMode_ReadWrite // Other processes can open in read-write mode - }; - - // Modes for opening a new shared memory region - struct OpenParameters - { - OpenParameters() : - globalName(NULL), - minSizeBytes(0), - openMode(SharedMemory::OpenMode_CreateOrOpen), - remoteMode(SharedMemory::RemoteMode_ReadWrite), - accessMode(SharedMemory::AccessMode_ReadWrite) - { - } - - // Creation parameters - const char* globalName; // Name of the shared memory region - int minSizeBytes; // Minimum number of bytes to request - SharedMemory::OpenMode openMode; // Creating the file or opening the file? - SharedMemory::RemoteMode remoteMode; // When creating, what access should other processes get? - SharedMemory::AccessMode accessMode; // When opening/creating, what access should this process get? - }; - -public: - // Returns the size of the shared memory region - int GetSizeI() const - { - return Size; - } - - // Returns the process-local pointer to the shared memory region - // Note: This may be different on different processes - void* GetData() const - { - return Data; - } - -protected: - int Size; // How many shared bytes are shared at the pointer address? - void* Data; // Pointer to the shared memory region. - - // Hidden implementation class for OS-specific behavior - SharedMemoryInternal* Internal; - - // Close and cleanup the shared memory region - // Note: This is called on destruction - void Close(); -}; - - -// SharedMemoryFactory -class SharedMemoryFactory : public NewOverrideBase, public SystemSingletonBase -{ - OVR_DECLARE_SINGLETON(SharedMemoryFactory); - -public: - // Construct a SharedMemory object. - // Note: The new object is reference-counted so it should be stored with Ptr<>. Initial reference count is 1. - Ptr Open(const SharedMemory::OpenParameters&); -}; - - -// A shared object -// Its constructor will be called when creating a writer -// Its destructor will not be called -template -class ISharedObject : public NewOverrideBase -{ -public: - static const int RegionSize = (int)sizeof(SharedType); - -protected: - Ptr pSharedMemory; - - bool Open(const char* name, bool readOnly) - { - // Configure open parameters based on read-only mode - SharedMemory::OpenParameters params; - - // FIXME: This is a hack. We currently need to allow clients to open this for read-write even - // though they only need read-only access. This is because in the first 0.4 release the - // LocklessUpdater class technically writes to it (increments by 0) to read from the space. - // This was quickly corrected in 0.4.1 and we are waiting for the right time to disallow write - // access when everyone upgrades to 0.4.1+. - //params.remoteMode = SharedMemory::RemoteMode_ReadOnly; - params.remoteMode = SharedMemory::RemoteMode_ReadWrite; - - params.globalName = name; - params.accessMode = readOnly ? SharedMemory::AccessMode_ReadOnly : SharedMemory::AccessMode_ReadWrite; - params.minSizeBytes = RegionSize; - params.openMode = readOnly ? SharedMemory::OpenMode_OpenOnly : SharedMemory::OpenMode_CreateOrOpen; - - // Attempt to open the shared memory file - pSharedMemory = SharedMemoryFactory::GetInstance()->Open(params); - - // If it was not able to be opened, - if (pSharedMemory && pSharedMemory->GetSizeI() >= RegionSize && pSharedMemory->GetData()) - { - // If writing, - if (!readOnly) - { - // Construct the object also - Construct(pSharedMemory->GetData()); - } - - return true; - } - - return false; - } - - SharedType* Get() const - { - if (!pSharedMemory) - { - return NULL; - } - - void* data = pSharedMemory->GetData(); - if (!data) - { - return NULL; - } - - return reinterpret_cast(data); - } -}; - -// Writer specialized shared object: Ctor will be called on Open() -template -class SharedObjectWriter : public ISharedObject -{ -public: - OVR_FORCE_INLINE bool Open(const char* name) - { - return ISharedObject::Open(name, false); - } - OVR_FORCE_INLINE SharedType* Get() - { - return ISharedObject::Get(); - } -}; - -// Reader specialized shared object: Ctor will not be called -template -class SharedObjectReader : public ISharedObject -{ -public: - OVR_FORCE_INLINE bool Open(const char* name) - { - return ISharedObject::Open(name, true); - } - OVR_FORCE_INLINE const SharedType* Get() const - { - return ISharedObject::Get(); - } -}; - - -} // namespace OVR - -#endif // OVR_SharedMemory_h diff --git a/LibOVR/Src/Kernel/OVR_Std.cpp b/LibOVR/Src/Kernel/OVR_Std.cpp deleted file mode 100644 index fc5ad04..0000000 --- a/LibOVR/Src/Kernel/OVR_Std.cpp +++ /dev/null @@ -1,1097 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Std.cpp -Content : Standard C function implementation -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Std.h" -#include "OVR_Alg.h" - -// localeconv() call in OVR_strtod() -#include - -namespace OVR { - -// Source for functions not available on all platforms is included here. - -size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize) -{ - const char* s = src; - size_t n = destsize; - - if(n && --n) - { - do{ - if((*dest++ = *s++) == 0) - break; - } while(--n); - } - - if(!n) - { - if(destsize) - *dest = 0; - while(*s++) - { } - } - - return (size_t)((s - src) - 1); -} - - -size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize) -{ - const size_t d = destsize ? OVR_strlen(dest) : 0; - const size_t s = OVR_strlen(src); - const size_t t = s + d; - - OVR_ASSERT((destsize == 0) || (d < destsize)); - - if(t < destsize) - memcpy(dest + d, src, (s + 1) * sizeof(*src)); - else - { - if(destsize) - { - memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src)); - dest[destsize - 1] = 0; - } - } - - return t; -} - - -// Case insensitive compare implemented in platform-specific way. -int OVR_CDECL OVR_stricmp(const char* a, const char* b) -{ -#if defined(OVR_OS_MS) - #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_stricmp(a, b); - #else - return ::stricmp(a, b); - #endif - -#else - return strcasecmp(a, b); -#endif -} - -int OVR_CDECL OVR_strnicmp(const char* a, const char* b, size_t count) -{ -#if defined(OVR_OS_MS) - #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_strnicmp(a, b, count); - #else - return ::strnicmp(a, b, count); - #endif - -#else - return strncasecmp(a, b, count); -#endif -} - -wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src) -{ -#if defined(OVR_MSVC_SAFESTRING) - wcscpy_s(dest, destsize, src); - return dest; -#elif defined(OVR_OS_MS) - OVR_UNUSED(destsize); - wcscpy(dest, src); - return dest; -#else - size_t l = OVR_wcslen(src) + 1; // incl term null - l = (l < destsize) ? l : destsize; - memcpy(dest, src, l * sizeof(wchar_t)); - return dest; -#endif -} - -wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count) -{ -#if defined(OVR_MSVC_SAFESTRING) - wcsncpy_s(dest, destsize, src, count); - return dest; -#else - size_t srclen = OVR_wcslen(src); - size_t l = Alg::Min(srclen, count); - l = (l < destsize) ? l : destsize; - memcpy(dest, src, l * sizeof(wchar_t)); - if (count > srclen) - { - size_t remLen = Alg::Min(destsize - l, (count - srclen)); - memset(&dest[l], 0, sizeof(wchar_t)*remLen); - } - else if (l < destsize) - dest[l] = 0; - return dest; -#endif -} - - -wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src) -{ -#if defined(OVR_MSVC_SAFESTRING) - wcscat_s(dest, destsize, src); - return dest; -#elif defined(OVR_OS_MS) - OVR_UNUSED(destsize); - wcscat(dest, src); - return dest; -#else - size_t dstlen = OVR_wcslen(dest); // do not incl term null - size_t srclen = OVR_wcslen(src) + 1; // incl term null - size_t copylen = (dstlen + srclen < destsize) ? srclen : destsize - dstlen; - memcpy(dest + dstlen, src, copylen * sizeof(wchar_t)); - return dest; -#endif -} - -size_t OVR_CDECL OVR_wcslen(const wchar_t* str) -{ -#if defined(OVR_OS_MS) - return wcslen(str); -#else - size_t i = 0; - while(str[i] != '\0') - ++i; - return i; -#endif -} - -int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) -{ -#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) - return wcscmp(a, b); -#else - // not supported, use custom implementation - const wchar_t *pa = a, *pb = b; - while (*pa && *pb) - { - wchar_t ca = *pa; - wchar_t cb = *pb; - if (ca < cb) - return -1; - else if (ca > cb) - return 1; - pa++; - pb++; - } - if (*pa) - return 1; - else if (*pb) - return -1; - else - return 0; -#endif -} - -int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b) -{ -#if defined(OVR_OS_MS) - #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_wcsicmp(a, b); - #else - return ::wcsicmp(a, b); - #endif -#elif defined(OVR_OS_MAC) || defined(__CYGWIN__) || defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) - // not supported, use custom implementation - const wchar_t *pa = a, *pb = b; - while (*pa && *pb) - { - wchar_t ca = OVR_towlower(*pa); - wchar_t cb = OVR_towlower(*pb); - if (ca < cb) - return -1; - else if (ca > cb) - return 1; - pa++; - pb++; - } - if (*pa) - return 1; - else if (*pb) - return -1; - else - return 0; -#else - return wcscasecmp(a, b); -#endif -} - -// This function is not inline because of dependency on -double OVR_CDECL OVR_strtod(const char* str, char** tailptr) -{ -#if !defined(OVR_OS_ANDROID) // The Android C library doesn't have localeconv. - const char s = *localeconv()->decimal_point; - - if (s != '.') // If the C library is using a locale that is not using '.' as a decimal point, we convert the input str's '.' chars to the char that the C library expects (e.g. ',' or ' '). - { - char buffer[347 + 1]; - - OVR_strcpy(buffer, sizeof(buffer), str); - - // Ensure null-termination of string - buffer[sizeof(buffer)-1] = '\0'; - - for (char* c = buffer; *c != '\0'; ++c) - { - if (*c == '.') - { - *c = s; - break; - } - } - - char *nextPtr = NULL; - double retval = strtod(buffer, &nextPtr); - - // If a tail pointer is requested, - if (tailptr) - { - // Return a tail pointer that points to the same offset as nextPtr, in the orig string - *tailptr = !nextPtr ? NULL : (char*)str + (int)(nextPtr - buffer); - } - - return retval; - } -#endif - - return strtod(str, tailptr); -} - - -#ifndef OVR_NO_WCTYPE - -//// Use this class to generate Unicode bitsets. For example: -//// -//// UnicodeBitSet bitSet; -//// for(unsigned i = 0; i < 65536; ++i) -//// { -//// if (iswalpha(i)) -//// bitSet.Set(i); -//// } -//// bitSet.Dump(); -//// -////--------------------------------------------------------------- -//class UnicodeBitSet -//{ -//public: -// UnicodeBitSet() -// { -// memset(Offsets, 0, sizeof(Offsets)); -// memset(Bits, 0, sizeof(Bits)); -// } -// -// void Set(unsigned bit) { Bits[bit >> 8][(bit >> 4) & 15] |= 1 << (bit & 15); } -// -// void Dump() -// { -// unsigned i, j; -// unsigned offsetCount = 0; -// for(i = 0; i < 256; ++i) -// { -// if (isNull(i)) Offsets[i] = 0; -// else -// if (isFull(i)) Offsets[i] = 1; -// else Offsets[i] = uint16_t(offsetCount++ * 16 + 256); -// } -// for(i = 0; i < 16; ++i) -// { -// for(j = 0; j < 16; ++j) -// { -// printf("%5u,", Offsets[i*16+j]); -// } -// printf("\n"); -// } -// for(i = 0; i < 256; ++i) -// { -// if (Offsets[i] > 255) -// { -// for(j = 0; j < 16; j++) -// { -// printf("%5u,", Bits[i][j]); -// } -// printf("\n"); -// } -// } -// } -// -//private: -// bool isNull(unsigned n) const -// { -// const uint16_t* p = Bits[n]; -// for(unsigned i = 0; i < 16; ++i) -// if (p[i] != 0) return false; -// return true; -// } -// -// bool isFull(unsigned n) const -// { -// const uint16_t* p = Bits[n]; -// for(unsigned i = 0; i < 16; ++i) -// if (p[i] != 0xFFFF) return false; -// return true; -// } -// -// uint16_t Offsets[256]; -// uint16_t Bits[256][16]; -//}; - - -const uint16_t UnicodeAlnumBits[] = { - 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, - 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, - 640, 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 672, 688, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 704, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, - 1, 1, 1, 1, 736, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 768, 784, 1, 800, 816, 832, - 0, 0, 0, 1023,65534, 2047,65534, 2047, 0, 0, 0, 524,65535,65407,65535,65407, -65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, - 0, 0, 0, 0, 32, 0, 0, 1024,55104,65535,65531,65535,32767,64767,65535, 15, -65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, - 0, 0, 0,65534,65535, 639,65534,65535, 255, 0, 0, 0, 0,65535, 2047, 7, - 0, 0,65534, 2047,65534, 63, 1023,65535,65535,65535,65535,65535,65535, 8175, 8702, 8191, - 0,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, -65518,65535,65535,58367, 8191,65281,65487, 0,40942,65529,65023,50117, 6559,45184,65487, 3, -34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, -40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, -57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, -57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 12, -65534,65535,65535, 2047,32767, 1023, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, - 1, 0, 1023, 0,65279,65535, 2047,65534, 3843,65279,65535, 8191, 0, 0, 0, 0, -65535,65535,63227, 327, 1023, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 127, -65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, -65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, -32767,32573,65535,65535,65407, 2047,65024, 3, 0, 0,65535,65535,65535,65535,65535, 31, -65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, -65535,65535,65535,65535,65535,65535,40959, 127,65534, 2047,65535,65535,65535,65535, 2047, 0, - 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 0, 1023, 0, - 0, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, -65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, - 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, -64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, - 192, 0, 1022, 1792,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 2047, -65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, -65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, -65535,65535,65535,16383, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, - 0, 0, 0, 0, 0, 0, 0,65495,65535,65535,65535,65535,65535,65535,65535, 8191, - 0, 1023,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; - -const uint16_t UnicodeAlphaBits[] = { - 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, - 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, - 640, 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 672, 688, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 704, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, - 1, 1, 1, 1, 736, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 768, 784, 1, 800, 816, 832, - 0, 0, 0, 0,65534, 2047,65534, 2047, 0, 0, 0, 0,65535,65407,65535,65407, -65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, - 0, 0, 0, 0, 32, 0, 0, 1024,55104,65535,65531,65535,32767,64767,65535, 15, -65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, - 0, 0, 0,65534,65535, 639,65534,65535, 255, 0, 0, 0, 0,65535, 2047, 7, - 0, 0,65534, 2047,65534, 63, 0,65535,65535,65535,65535,65535,65535, 8175, 8702, 7168, - 0,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, -65518,65535,65535,58367, 8191,65281, 15, 0,40942,65529,65023,50117, 6559,45184, 15, 3, -34788,65529,65023,50029, 6535,24064, 0, 31,45038,65531,65023,58349, 7103, 1, 1, 0, -40942,65529,65023,58317, 6543,45248, 3, 0,51180,54845,50968,50111, 7623, 128, 0, 0, -57326,65533,65023,50159, 7647, 96, 3, 0,57324,65533,65023,50159, 7647,16480, 3, 0, -57324,65533,65023,50175, 7631, 128, 3, 0,65516,64639,65535,12283,32895,65375, 0, 12, -65534,65535,65535, 2047,32767, 0, 0, 0, 9622,65264,60590,15359, 8223,12288, 0, 0, - 1, 0, 0, 0,65279,65535, 2047,65534, 3843,65279,65535, 8191, 0, 0, 0, 0, -65535,65535,63227, 327, 0, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 127, -65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, -65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, -32767,32573,65535,65535,65407, 2047, 0, 0, 0, 0,65535,65535,65535,65535,65535, 31, -65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, -65535,65535,65535,65535,65535,65535,40959, 127,65534, 2047,65535,65535,65535,65535, 2047, 0, - 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 0, 0, 0, - 0, 0,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, -65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, - 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, -64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, - 192, 0, 1022, 1792,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 2047, -65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, -65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, -65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, -65535,65535,65535,16383, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, - 0, 0, 0, 0, 0, 0, 0,65495,65535,65535,65535,65535,65535,65535,65535, 8191, - 0, 0,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; - -const uint16_t UnicodeDigitBits[] = { - 256, 0, 0, 0, 0, 0, 272, 0, 0, 288, 304, 320, 336, 352, 368, 384, - 400, 0, 0, 416, 0, 0, 0, 432, 448, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, - 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 1023, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65408, 0, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, - 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 1023, 0, 0, - 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,65024, 3, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1023, 0, - 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -const uint16_t UnicodeSpaceBits[] = { - 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -15872, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, - 4095, 0,33536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -const uint16_t UnicodeXDigitBits[] = { - 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, - 0, 0, 0, 1023, 126, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1023, 126, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -// Uncomment if necessary -//const uint16_t UnicodeCntrlBits[] = { -// 256, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, -// 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 336, -//65535,65535, 0, 0, 0, 0, 0,32768,65535,65535, 0, 0, 0, 0, 0, 0, -//32768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//30720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//61440, 0,31744, 0, 0, 0,64512, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32768, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3584}; -// -//const uint16_t UnicodeGraphBits[] = { -// 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, -// 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, -// 640, 656, 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 688, 704, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 736, -// 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 768, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 784, 800, 1, 816, 832, 848, -// 0, 0,65534,65535,65535,65535,65535,32767, 0, 0,65534,65535,65535,65535,65535,65535, -//65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, -// 0, 0, 0, 0, 32, 0, 0,17408,55232,65535,65531,65535,32767,64767,65535, 15, -//65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, -// 0, 0, 0,65534,65535,65151,65534,65535, 1791, 0, 0,16384, 9,65535, 2047, 31, -// 4096,34816,65534, 2047,65534, 63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191, -//16383,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, -//65518,65535,65535,58367, 8191,65281,65535, 1,40942,65529,65023,50117, 6559,45184,65487, 3, -//34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, -//40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, -//57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, -//57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 28, -//65534,65535,65535, 2047,65535, 4095, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, -//65521, 7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191, 0, 0, 0, 0, -//65535,65535,63227, 327,65535, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 2175, -//65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, -//65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, -//32767,32573,65535,65535,65407, 2047,65534, 3, 0, 0,65535,65535,65535,65535,65535, 31, -//65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, -//65535,65535,65535,65535,65535,65535,65535, 127,65534, 8191,65535,65535,65535,65535,16383, 0, -// 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 6128, 1023, 0, -// 2047, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, -//65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, -// 0,65535, 255,65535,16239, 0, 0,57344,24576, 0, 0, 0, 0, 0, 0, 0, -//64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//65486,65523, 1022, 1793,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 4095, -//65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, -//65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, -//65535,65535,65535,65535, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, -// 0, 0, 0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535, 8191, -//63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; -// -//const uint16_t UnicodePrintBits[] = { -// 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, -// 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, -// 640, 656, 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 688, 704, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 736, -// 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, -// 1, 1, 1, 1, 1, 1, 1, 768, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 784, 800, 1, 816, 832, 848, -// 512, 0,65535,65535,65535,65535,65535,32767, 0, 0,65535,65535,65535,65535,65535,65535, -//65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, -// 0, 0, 0, 0, 32, 0, 0,17408,55232,65535,65531,65535,32767,64767,65535, 15, -//65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, -// 0, 0, 0,65534,65535,65151,65534,65535, 1791, 0, 0,16384, 9,65535, 2047, 31, -// 4096,34816,65534, 2047,65534, 63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191, -//16383,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, -//65518,65535,65535,58367, 8191,65281,65535, 1,40942,65529,65023,50117, 6559,45184,65487, 3, -//34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, -//40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, -//57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, -//57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 28, -//65534,65535,65535, 2047,65535, 4095, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, -//65521, 7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191, 0, 0, 0, 0, -//65535,65535,63227, 327,65535, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 2175, -//65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, -//65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, -//32767,32573,65535,65535,65407, 2047,65534, 3, 0, 0,65535,65535,65535,65535,65535, 31, -//65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, -//65535,65535,65535,65535,65535,65535,65535, 127,65534, 8191,65535,65535,65535,65535,16383, 0, -// 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 6128, 1023, 0, -// 2047, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, -//65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, -// 0,65535, 255,65535,16239, 0, 0,57344,24576, 0, 0, 0, 0, 0, 0, 0, -//64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//65487,65523, 1022, 1793,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 4095, -//65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, -//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, -//65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, -//65535,65535,65535,65535, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, -// 0, 0, 0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535,40959, -//63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; -// -//const uint16_t UnicodePunctBits[] = { -// 256, 0, 0, 272, 0, 288, 304, 320, 0, 336, 0, 0, 0, 352, 368, 384, -// 400, 0, 0, 416, 0, 0, 432, 448, 464, 0, 0, 0, 0, 0, 0, 0, -// 480, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 528, 544, 560, -// 0, 0,65534,64512, 1,63488, 1,30720, 0, 0,65534,65535, 0, 128, 0, 128, -// 0, 0, 0, 0, 0, 0, 0,16384, 128, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0,64512, 0, 0, 1536, 0, 0,16384, 9, 0, 0, 24, -// 4096,34816, 0, 0, 0, 0,15360, 0, 0, 0, 0, 0, 0, 16, 0, 0, -//16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, -// 0, 0, 0, 0,32768, 3072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//65520, 7, 0,15360, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0,64512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, -// 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0,24576, 0, 0, 6144, 0, 0, 0, 0,14336, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6128, 0, 0, -// 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0,65535, 255,65535,16239, 0, 0,24576,24576, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//65294,65523, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, -// 0, 0, 0,49152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0,65535,65055,65527, 3339, 0, 0, 0, 0, 0, 0, 0, 0, 0, -//63470,35840, 1,47104, 0,10240, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -// -//const uint16_t UnicodeLowerBits[] = { -// 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 368, -// 384, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 432, -// 0, 0, 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0,32768,65535,65407, -//43690,43690,43690,21930,43861,43690,43690,54442,12585,20004,11562,58961,23392,46421,43690,43565, -//43690,43690,43688, 10, 0,65535,65535,65535,65535,65535,16383, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,61440,65535,32767,43235,43690, 15, -// 0, 0, 0,65535,65535,65535,43690,43690,40962,43690,43690,43690, 4372,43690,43690, 554, -// 0, 0, 0, 0, 0, 0,65534,65535, 255, 0, 0, 0, 0, 0, 0, 0, -//43690,43690,43690,43690,43690,43690,43690,43690,43690, 4074,43690,43690,43690,43690,43690, 682, -// 255, 63, 255, 255, 63, 255, 255,16383,65535,65535,65535,20703, 4316, 207, 255, 4316, -// 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, -//50176, 8,32768, 528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 127, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; -// -//const uint16_t UnicodeUpperBits[] = { -// 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 384, -// 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, -// 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,32639, 0, 0, -//21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53973, 4526,44464,19114,21845,21974, -//21845,21845,21844, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0,55104,65534, 4091, 0, 0,21532,21845, 0, -//65535,65535,65535, 0, 0, 0,21845,21845,20481,21845,21845,21845, 2187,21845,21845, 277, -// 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535,65535, 63, 0, 0, 0, -//21845,21845,21845,21845,21845,21845,21845,21845,21845, 21,21845,21845,21845,21845,21845, 341, -//65280,16128,65280,65280,16128,43520,65280, 0,65280,65280,65280, 7936, 7936, 3840, 7936, 7936, -//14468,15911,15696, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -// 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - - -// MA: March 19, 2010 -// Modified ToUpper and ToLower tables to match values expected by AS3 tests. -// ToLower modifications: -// 304 -> 105 -// 1024 -> 1104 * -// 1037 -> 1117 * -// UoUpper modifications: -// 255 -> 376 -// 305 -> 73 -// 383 -> 83 -// 1104 -> 1024 * -// 1117 -> 1037 * -// Entries marked with a '*' don't make complete sense based on Unicode manual, although -// they match AS3. - - -static const uint16_t UnicodeToUpperBits[] = { - 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 368, - 0, 384, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, - 0, 0, 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,65407, -43690,43690,43690,21674,43349,43690,43690,54442, 4392, 516, 8490, 8785,21056,46421,43690,43048, // MA: Modified for AS3. -43690, 170, 0, 0, 0, 2776,33545, 36, 3336, 4, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,61440,65534,32767, 0,43688, 0, - 0, 0, 0,65535,65535,65535,43690,43690, 2,43690,43690,43690, 4372,43690,35498, 554, // MA: Modified for AS3. - 0, 0, 0, 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, -43690,43690,43690,43690,43690,43690,43690,43690,43690, 42,43690,43690,43690,43690,43690, 682, - 255, 63, 255, 255, 63, 170, 255,16383, 0, 0, 0, 3, 0, 3, 35, 0, - 0, 0, 0, 0, 0, 0, 0,65535, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535, 1023, 0, - 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -static const uint16_t UnicodeToLowerBits[] = { - 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 384, - 0, 400, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, - 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,32639, 0, 0, -21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53909, 4526,42128,19114,21845,21522,// MA: Modidied for AS3. -21845, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0,55104,65534, 4091, 0, 0, 0,21844, 0, -65535,65535,65535, 0, 0, 0,21845,21845, 1,21845,21845,21845, 2186,21845,17749, 277, - 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535,65535, 63, 0, 0, 0, -21845,21845,21845,21845,21845,21845,21845,21845,21845, 21,21845,21845,21845,21845,21845, 341, -65280,16128,65280,65280,16128,43520,65280, 0, 0, 0, 0, 3840, 3840, 3840, 7936, 3840, - 0, 0, 0, 0, 0, 0,65535, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65472,65535, 0, 0, 0, - 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -struct GUnicodePairType -{ - uint16_t Key, Value; -}; - -static inline bool CmpUnicodeKey(const GUnicodePairType& a, uint16_t key) -{ - return a.Key < key; -} - -static const GUnicodePairType UnicodeToUpperTable[] = { -{ 97, 65}, { 98, 66}, { 99, 67}, { 100, 68}, { 101, 69}, { 102, 70}, { 103, 71}, -{ 104, 72}, { 105, 73}, { 106, 74}, { 107, 75}, { 108, 76}, { 109, 77}, { 110, 78}, -{ 111, 79}, { 112, 80}, { 113, 81}, { 114, 82}, { 115, 83}, { 116, 84}, { 117, 85}, -{ 118, 86}, { 119, 87}, { 120, 88}, { 121, 89}, { 122, 90}, { 224, 192}, { 225, 193}, -{ 226, 194}, { 227, 195}, { 228, 196}, { 229, 197}, { 230, 198}, { 231, 199}, { 232, 200}, -{ 233, 201}, { 234, 202}, { 235, 203}, { 236, 204}, { 237, 205}, { 238, 206}, { 239, 207}, -{ 240, 208}, { 241, 209}, { 242, 210}, { 243, 211}, { 244, 212}, { 245, 213}, { 246, 214}, -{ 248, 216}, { 249, 217}, { 250, 218}, { 251, 219}, { 252, 220}, { 253, 221}, { 254, 222}, -{ 255, 376}, { 257, 256}, { 259, 258}, { 261, 260}, { 263, 262}, { 265, 264}, { 267, 266}, -{ 269, 268}, { 271, 270}, { 273, 272}, { 275, 274}, { 277, 276}, { 279, 278}, { 281, 280}, -{ 283, 282}, { 285, 284}, { 287, 286}, { 289, 288}, { 291, 290}, { 293, 292}, { 295, 294}, -{ 297, 296}, { 299, 298}, { 301, 300}, { 303, 302}, { 305, 73}, { 307, 306}, { 309, 308}, { 311, 310}, -{ 314, 313}, { 316, 315}, { 318, 317}, { 320, 319}, { 322, 321}, { 324, 323}, { 326, 325}, -{ 328, 327}, { 331, 330}, { 333, 332}, { 335, 334}, { 337, 336}, { 339, 338}, { 341, 340}, -{ 343, 342}, { 345, 344}, { 347, 346}, { 349, 348}, { 351, 350}, { 353, 352}, { 355, 354}, -{ 357, 356}, { 359, 358}, { 361, 360}, { 363, 362}, { 365, 364}, { 367, 366}, { 369, 368}, -{ 371, 370}, { 373, 372}, { 375, 374}, { 378, 377}, { 380, 379}, { 382, 381}, { 383, 83}, { 387, 386}, -{ 389, 388}, { 392, 391}, { 396, 395}, { 402, 401}, { 409, 408}, { 417, 416}, { 419, 418}, -{ 421, 420}, { 424, 423}, { 429, 428}, { 432, 431}, { 436, 435}, { 438, 437}, { 441, 440}, -{ 445, 444}, { 454, 452}, { 457, 455}, { 460, 458}, { 462, 461}, { 464, 463}, { 466, 465}, -{ 468, 467}, { 470, 469}, { 472, 471}, { 474, 473}, { 476, 475}, { 477, 398}, { 479, 478}, -{ 481, 480}, { 483, 482}, { 485, 484}, { 487, 486}, { 489, 488}, { 491, 490}, { 493, 492}, -{ 495, 494}, { 499, 497}, { 501, 500}, { 507, 506}, { 509, 508}, { 511, 510}, { 513, 512}, -{ 515, 514}, { 517, 516}, { 519, 518}, { 521, 520}, { 523, 522}, { 525, 524}, { 527, 526}, -{ 529, 528}, { 531, 530}, { 533, 532}, { 535, 534}, { 595, 385}, { 596, 390}, { 598, 393}, -{ 599, 394}, { 601, 399}, { 603, 400}, { 608, 403}, { 611, 404}, { 616, 407}, { 617, 406}, -{ 623, 412}, { 626, 413}, { 629, 415}, { 643, 425}, { 648, 430}, { 650, 433}, { 651, 434}, -{ 658, 439}, { 940, 902}, { 941, 904}, { 942, 905}, { 943, 906}, { 945, 913}, { 946, 914}, -{ 947, 915}, { 948, 916}, { 949, 917}, { 950, 918}, { 951, 919}, { 952, 920}, { 953, 921}, -{ 954, 922}, { 955, 923}, { 956, 924}, { 957, 925}, { 958, 926}, { 959, 927}, { 960, 928}, -{ 961, 929}, { 962, 931}, { 963, 931}, { 964, 932}, { 965, 933}, { 966, 934}, { 967, 935}, -{ 968, 936}, { 969, 937}, { 970, 938}, { 971, 939}, { 972, 908}, { 973, 910}, { 974, 911}, -{ 995, 994}, { 997, 996}, { 999, 998}, { 1001, 1000}, { 1003, 1002}, { 1005, 1004}, { 1007, 1006}, -{ 1072, 1040}, { 1073, 1041}, { 1074, 1042}, { 1075, 1043}, { 1076, 1044}, { 1077, 1045}, { 1078, 1046}, -{ 1079, 1047}, { 1080, 1048}, { 1081, 1049}, { 1082, 1050}, { 1083, 1051}, { 1084, 1052}, { 1085, 1053}, -{ 1086, 1054}, { 1087, 1055}, { 1088, 1056}, { 1089, 1057}, { 1090, 1058}, { 1091, 1059}, { 1092, 1060}, -{ 1093, 1061}, { 1094, 1062}, { 1095, 1063}, { 1096, 1064}, { 1097, 1065}, { 1098, 1066}, { 1099, 1067}, -{ 1100, 1068}, { 1101, 1069}, { 1102, 1070}, { 1103, 1071}, { 1104, 1024}, { 1105, 1025}, { 1106, 1026}, { 1107, 1027}, -{ 1108, 1028}, { 1109, 1029}, { 1110, 1030}, { 1111, 1031}, { 1112, 1032}, { 1113, 1033}, { 1114, 1034}, -{ 1115, 1035}, { 1116, 1036}, { 1117, 1037}, { 1118, 1038}, { 1119, 1039}, { 1121, 1120}, { 1123, 1122}, { 1125, 1124}, -{ 1127, 1126}, { 1129, 1128}, { 1131, 1130}, { 1133, 1132}, { 1135, 1134}, { 1137, 1136}, { 1139, 1138}, -{ 1141, 1140}, { 1143, 1142}, { 1145, 1144}, { 1147, 1146}, { 1149, 1148}, { 1151, 1150}, { 1153, 1152}, -{ 1169, 1168}, { 1171, 1170}, { 1173, 1172}, { 1175, 1174}, { 1177, 1176}, { 1179, 1178}, { 1181, 1180}, -{ 1183, 1182}, { 1185, 1184}, { 1187, 1186}, { 1189, 1188}, { 1191, 1190}, { 1193, 1192}, { 1195, 1194}, -{ 1197, 1196}, { 1199, 1198}, { 1201, 1200}, { 1203, 1202}, { 1205, 1204}, { 1207, 1206}, { 1209, 1208}, -{ 1211, 1210}, { 1213, 1212}, { 1215, 1214}, { 1218, 1217}, { 1220, 1219}, { 1224, 1223}, { 1228, 1227}, -{ 1233, 1232}, { 1235, 1234}, { 1237, 1236}, { 1239, 1238}, { 1241, 1240}, { 1243, 1242}, { 1245, 1244}, -{ 1247, 1246}, { 1249, 1248}, { 1251, 1250}, { 1253, 1252}, { 1255, 1254}, { 1257, 1256}, { 1259, 1258}, -{ 1263, 1262}, { 1265, 1264}, { 1267, 1266}, { 1269, 1268}, { 1273, 1272}, { 1377, 1329}, { 1378, 1330}, -{ 1379, 1331}, { 1380, 1332}, { 1381, 1333}, { 1382, 1334}, { 1383, 1335}, { 1384, 1336}, { 1385, 1337}, -{ 1386, 1338}, { 1387, 1339}, { 1388, 1340}, { 1389, 1341}, { 1390, 1342}, { 1391, 1343}, { 1392, 1344}, -{ 1393, 1345}, { 1394, 1346}, { 1395, 1347}, { 1396, 1348}, { 1397, 1349}, { 1398, 1350}, { 1399, 1351}, -{ 1400, 1352}, { 1401, 1353}, { 1402, 1354}, { 1403, 1355}, { 1404, 1356}, { 1405, 1357}, { 1406, 1358}, -{ 1407, 1359}, { 1408, 1360}, { 1409, 1361}, { 1410, 1362}, { 1411, 1363}, { 1412, 1364}, { 1413, 1365}, -{ 1414, 1366}, { 7681, 7680}, { 7683, 7682}, { 7685, 7684}, { 7687, 7686}, { 7689, 7688}, { 7691, 7690}, -{ 7693, 7692}, { 7695, 7694}, { 7697, 7696}, { 7699, 7698}, { 7701, 7700}, { 7703, 7702}, { 7705, 7704}, -{ 7707, 7706}, { 7709, 7708}, { 7711, 7710}, { 7713, 7712}, { 7715, 7714}, { 7717, 7716}, { 7719, 7718}, -{ 7721, 7720}, { 7723, 7722}, { 7725, 7724}, { 7727, 7726}, { 7729, 7728}, { 7731, 7730}, { 7733, 7732}, -{ 7735, 7734}, { 7737, 7736}, { 7739, 7738}, { 7741, 7740}, { 7743, 7742}, { 7745, 7744}, { 7747, 7746}, -{ 7749, 7748}, { 7751, 7750}, { 7753, 7752}, { 7755, 7754}, { 7757, 7756}, { 7759, 7758}, { 7761, 7760}, -{ 7763, 7762}, { 7765, 7764}, { 7767, 7766}, { 7769, 7768}, { 7771, 7770}, { 7773, 7772}, { 7775, 7774}, -{ 7777, 7776}, { 7779, 7778}, { 7781, 7780}, { 7783, 7782}, { 7785, 7784}, { 7787, 7786}, { 7789, 7788}, -{ 7791, 7790}, { 7793, 7792}, { 7795, 7794}, { 7797, 7796}, { 7799, 7798}, { 7801, 7800}, { 7803, 7802}, -{ 7805, 7804}, { 7807, 7806}, { 7809, 7808}, { 7811, 7810}, { 7813, 7812}, { 7815, 7814}, { 7817, 7816}, -{ 7819, 7818}, { 7821, 7820}, { 7823, 7822}, { 7825, 7824}, { 7827, 7826}, { 7829, 7828}, { 7841, 7840}, -{ 7843, 7842}, { 7845, 7844}, { 7847, 7846}, { 7849, 7848}, { 7851, 7850}, { 7853, 7852}, { 7855, 7854}, -{ 7857, 7856}, { 7859, 7858}, { 7861, 7860}, { 7863, 7862}, { 7865, 7864}, { 7867, 7866}, { 7869, 7868}, -{ 7871, 7870}, { 7873, 7872}, { 7875, 7874}, { 7877, 7876}, { 7879, 7878}, { 7881, 7880}, { 7883, 7882}, -{ 7885, 7884}, { 7887, 7886}, { 7889, 7888}, { 7891, 7890}, { 7893, 7892}, { 7895, 7894}, { 7897, 7896}, -{ 7899, 7898}, { 7901, 7900}, { 7903, 7902}, { 7905, 7904}, { 7907, 7906}, { 7909, 7908}, { 7911, 7910}, -{ 7913, 7912}, { 7915, 7914}, { 7917, 7916}, { 7919, 7918}, { 7921, 7920}, { 7923, 7922}, { 7925, 7924}, -{ 7927, 7926}, { 7929, 7928}, { 7936, 7944}, { 7937, 7945}, { 7938, 7946}, { 7939, 7947}, { 7940, 7948}, -{ 7941, 7949}, { 7942, 7950}, { 7943, 7951}, { 7952, 7960}, { 7953, 7961}, { 7954, 7962}, { 7955, 7963}, -{ 7956, 7964}, { 7957, 7965}, { 7968, 7976}, { 7969, 7977}, { 7970, 7978}, { 7971, 7979}, { 7972, 7980}, -{ 7973, 7981}, { 7974, 7982}, { 7975, 7983}, { 7984, 7992}, { 7985, 7993}, { 7986, 7994}, { 7987, 7995}, -{ 7988, 7996}, { 7989, 7997}, { 7990, 7998}, { 7991, 7999}, { 8000, 8008}, { 8001, 8009}, { 8002, 8010}, -{ 8003, 8011}, { 8004, 8012}, { 8005, 8013}, { 8017, 8025}, { 8019, 8027}, { 8021, 8029}, { 8023, 8031}, -{ 8032, 8040}, { 8033, 8041}, { 8034, 8042}, { 8035, 8043}, { 8036, 8044}, { 8037, 8045}, { 8038, 8046}, -{ 8039, 8047}, { 8048, 8122}, { 8049, 8123}, { 8050, 8136}, { 8051, 8137}, { 8052, 8138}, { 8053, 8139}, -{ 8054, 8154}, { 8055, 8155}, { 8056, 8184}, { 8057, 8185}, { 8058, 8170}, { 8059, 8171}, { 8060, 8186}, -{ 8061, 8187}, { 8112, 8120}, { 8113, 8121}, { 8144, 8152}, { 8145, 8153}, { 8160, 8168}, { 8161, 8169}, -{ 8165, 8172}, { 8560, 8544}, { 8561, 8545}, { 8562, 8546}, { 8563, 8547}, { 8564, 8548}, { 8565, 8549}, -{ 8566, 8550}, { 8567, 8551}, { 8568, 8552}, { 8569, 8553}, { 8570, 8554}, { 8571, 8555}, { 8572, 8556}, -{ 8573, 8557}, { 8574, 8558}, { 8575, 8559}, { 9424, 9398}, { 9425, 9399}, { 9426, 9400}, { 9427, 9401}, -{ 9428, 9402}, { 9429, 9403}, { 9430, 9404}, { 9431, 9405}, { 9432, 9406}, { 9433, 9407}, { 9434, 9408}, -{ 9435, 9409}, { 9436, 9410}, { 9437, 9411}, { 9438, 9412}, { 9439, 9413}, { 9440, 9414}, { 9441, 9415}, -{ 9442, 9416}, { 9443, 9417}, { 9444, 9418}, { 9445, 9419}, { 9446, 9420}, { 9447, 9421}, { 9448, 9422}, -{ 9449, 9423}, {65345,65313}, {65346,65314}, {65347,65315}, {65348,65316}, {65349,65317}, {65350,65318}, -{65351,65319}, {65352,65320}, {65353,65321}, {65354,65322}, {65355,65323}, {65356,65324}, {65357,65325}, -{65358,65326}, {65359,65327}, {65360,65328}, {65361,65329}, {65362,65330}, {65363,65331}, {65364,65332}, -{65365,65333}, {65366,65334}, {65367,65335}, {65368,65336}, {65369,65337}, {65370,65338}, {65535, 0}}; - -static const GUnicodePairType UnicodeToLowerTable[] = { -{ 65, 97}, { 66, 98}, { 67, 99}, { 68, 100}, { 69, 101}, { 70, 102}, { 71, 103}, -{ 72, 104}, { 73, 105}, { 74, 106}, { 75, 107}, { 76, 108}, { 77, 109}, { 78, 110}, -{ 79, 111}, { 80, 112}, { 81, 113}, { 82, 114}, { 83, 115}, { 84, 116}, { 85, 117}, -{ 86, 118}, { 87, 119}, { 88, 120}, { 89, 121}, { 90, 122}, { 192, 224}, { 193, 225}, -{ 194, 226}, { 195, 227}, { 196, 228}, { 197, 229}, { 198, 230}, { 199, 231}, { 200, 232}, -{ 201, 233}, { 202, 234}, { 203, 235}, { 204, 236}, { 205, 237}, { 206, 238}, { 207, 239}, -{ 208, 240}, { 209, 241}, { 210, 242}, { 211, 243}, { 212, 244}, { 213, 245}, { 214, 246}, -{ 216, 248}, { 217, 249}, { 218, 250}, { 219, 251}, { 220, 252}, { 221, 253}, { 222, 254}, -{ 256, 257}, { 258, 259}, { 260, 261}, { 262, 263}, { 264, 265}, { 266, 267}, { 268, 269}, -{ 270, 271}, { 272, 273}, { 274, 275}, { 276, 277}, { 278, 279}, { 280, 281}, { 282, 283}, -{ 284, 285}, { 286, 287}, { 288, 289}, { 290, 291}, { 292, 293}, { 294, 295}, { 296, 297}, -{ 298, 299}, { 300, 301}, { 302, 303}, { 304, 105}, { 306, 307}, { 308, 309}, { 310, 311}, { 313, 314}, -{ 315, 316}, { 317, 318}, { 319, 320}, { 321, 322}, { 323, 324}, { 325, 326}, { 327, 328}, -{ 330, 331}, { 332, 333}, { 334, 335}, { 336, 337}, { 338, 339}, { 340, 341}, { 342, 343}, -{ 344, 345}, { 346, 347}, { 348, 349}, { 350, 351}, { 352, 353}, { 354, 355}, { 356, 357}, -{ 358, 359}, { 360, 361}, { 362, 363}, { 364, 365}, { 366, 367}, { 368, 369}, { 370, 371}, -{ 372, 373}, { 374, 375}, { 376, 255}, { 377, 378}, { 379, 380}, { 381, 382}, { 385, 595}, -{ 386, 387}, { 388, 389}, { 390, 596}, { 391, 392}, { 393, 598}, { 394, 599}, { 395, 396}, -{ 398, 477}, { 399, 601}, { 400, 603}, { 401, 402}, { 403, 608}, { 404, 611}, { 406, 617}, -{ 407, 616}, { 408, 409}, { 412, 623}, { 413, 626}, { 415, 629}, { 416, 417}, { 418, 419}, -{ 420, 421}, { 423, 424}, { 425, 643}, { 428, 429}, { 430, 648}, { 431, 432}, { 433, 650}, -{ 434, 651}, { 435, 436}, { 437, 438}, { 439, 658}, { 440, 441}, { 444, 445}, { 452, 454}, -{ 455, 457}, { 458, 460}, { 461, 462}, { 463, 464}, { 465, 466}, { 467, 468}, { 469, 470}, -{ 471, 472}, { 473, 474}, { 475, 476}, { 478, 479}, { 480, 481}, { 482, 483}, { 484, 485}, -{ 486, 487}, { 488, 489}, { 490, 491}, { 492, 493}, { 494, 495}, { 497, 499}, { 500, 501}, -{ 506, 507}, { 508, 509}, { 510, 511}, { 512, 513}, { 514, 515}, { 516, 517}, { 518, 519}, -{ 520, 521}, { 522, 523}, { 524, 525}, { 526, 527}, { 528, 529}, { 530, 531}, { 532, 533}, -{ 534, 535}, { 902, 940}, { 904, 941}, { 905, 942}, { 906, 943}, { 908, 972}, { 910, 973}, -{ 911, 974}, { 913, 945}, { 914, 946}, { 915, 947}, { 916, 948}, { 917, 949}, { 918, 950}, -{ 919, 951}, { 920, 952}, { 921, 953}, { 922, 954}, { 923, 955}, { 924, 956}, { 925, 957}, -{ 926, 958}, { 927, 959}, { 928, 960}, { 929, 961}, { 931, 963}, { 932, 964}, { 933, 965}, -{ 934, 966}, { 935, 967}, { 936, 968}, { 937, 969}, { 938, 970}, { 939, 971}, { 994, 995}, -{ 996, 997}, { 998, 999}, { 1000, 1001}, { 1002, 1003}, { 1004, 1005}, { 1006, 1007}, { 1024, 1104}, { 1025, 1105}, -{ 1026, 1106}, { 1027, 1107}, { 1028, 1108}, { 1029, 1109}, { 1030, 1110}, { 1031, 1111}, { 1032, 1112}, -{ 1033, 1113}, { 1034, 1114}, { 1035, 1115}, { 1036, 1116}, { 1037, 1117}, { 1038, 1118}, { 1039, 1119}, { 1040, 1072}, -{ 1041, 1073}, { 1042, 1074}, { 1043, 1075}, { 1044, 1076}, { 1045, 1077}, { 1046, 1078}, { 1047, 1079}, -{ 1048, 1080}, { 1049, 1081}, { 1050, 1082}, { 1051, 1083}, { 1052, 1084}, { 1053, 1085}, { 1054, 1086}, -{ 1055, 1087}, { 1056, 1088}, { 1057, 1089}, { 1058, 1090}, { 1059, 1091}, { 1060, 1092}, { 1061, 1093}, -{ 1062, 1094}, { 1063, 1095}, { 1064, 1096}, { 1065, 1097}, { 1066, 1098}, { 1067, 1099}, { 1068, 1100}, -{ 1069, 1101}, { 1070, 1102}, { 1071, 1103}, { 1120, 1121}, { 1122, 1123}, { 1124, 1125}, { 1126, 1127}, -{ 1128, 1129}, { 1130, 1131}, { 1132, 1133}, { 1134, 1135}, { 1136, 1137}, { 1138, 1139}, { 1140, 1141}, -{ 1142, 1143}, { 1144, 1145}, { 1146, 1147}, { 1148, 1149}, { 1150, 1151}, { 1152, 1153}, { 1168, 1169}, -{ 1170, 1171}, { 1172, 1173}, { 1174, 1175}, { 1176, 1177}, { 1178, 1179}, { 1180, 1181}, { 1182, 1183}, -{ 1184, 1185}, { 1186, 1187}, { 1188, 1189}, { 1190, 1191}, { 1192, 1193}, { 1194, 1195}, { 1196, 1197}, -{ 1198, 1199}, { 1200, 1201}, { 1202, 1203}, { 1204, 1205}, { 1206, 1207}, { 1208, 1209}, { 1210, 1211}, -{ 1212, 1213}, { 1214, 1215}, { 1217, 1218}, { 1219, 1220}, { 1223, 1224}, { 1227, 1228}, { 1232, 1233}, -{ 1234, 1235}, { 1236, 1237}, { 1238, 1239}, { 1240, 1241}, { 1242, 1243}, { 1244, 1245}, { 1246, 1247}, -{ 1248, 1249}, { 1250, 1251}, { 1252, 1253}, { 1254, 1255}, { 1256, 1257}, { 1258, 1259}, { 1262, 1263}, -{ 1264, 1265}, { 1266, 1267}, { 1268, 1269}, { 1272, 1273}, { 1329, 1377}, { 1330, 1378}, { 1331, 1379}, -{ 1332, 1380}, { 1333, 1381}, { 1334, 1382}, { 1335, 1383}, { 1336, 1384}, { 1337, 1385}, { 1338, 1386}, -{ 1339, 1387}, { 1340, 1388}, { 1341, 1389}, { 1342, 1390}, { 1343, 1391}, { 1344, 1392}, { 1345, 1393}, -{ 1346, 1394}, { 1347, 1395}, { 1348, 1396}, { 1349, 1397}, { 1350, 1398}, { 1351, 1399}, { 1352, 1400}, -{ 1353, 1401}, { 1354, 1402}, { 1355, 1403}, { 1356, 1404}, { 1357, 1405}, { 1358, 1406}, { 1359, 1407}, -{ 1360, 1408}, { 1361, 1409}, { 1362, 1410}, { 1363, 1411}, { 1364, 1412}, { 1365, 1413}, { 1366, 1414}, -{ 4256, 4304}, { 4257, 4305}, { 4258, 4306}, { 4259, 4307}, { 4260, 4308}, { 4261, 4309}, { 4262, 4310}, -{ 4263, 4311}, { 4264, 4312}, { 4265, 4313}, { 4266, 4314}, { 4267, 4315}, { 4268, 4316}, { 4269, 4317}, -{ 4270, 4318}, { 4271, 4319}, { 4272, 4320}, { 4273, 4321}, { 4274, 4322}, { 4275, 4323}, { 4276, 4324}, -{ 4277, 4325}, { 4278, 4326}, { 4279, 4327}, { 4280, 4328}, { 4281, 4329}, { 4282, 4330}, { 4283, 4331}, -{ 4284, 4332}, { 4285, 4333}, { 4286, 4334}, { 4287, 4335}, { 4288, 4336}, { 4289, 4337}, { 4290, 4338}, -{ 4291, 4339}, { 4292, 4340}, { 4293, 4341}, { 7680, 7681}, { 7682, 7683}, { 7684, 7685}, { 7686, 7687}, -{ 7688, 7689}, { 7690, 7691}, { 7692, 7693}, { 7694, 7695}, { 7696, 7697}, { 7698, 7699}, { 7700, 7701}, -{ 7702, 7703}, { 7704, 7705}, { 7706, 7707}, { 7708, 7709}, { 7710, 7711}, { 7712, 7713}, { 7714, 7715}, -{ 7716, 7717}, { 7718, 7719}, { 7720, 7721}, { 7722, 7723}, { 7724, 7725}, { 7726, 7727}, { 7728, 7729}, -{ 7730, 7731}, { 7732, 7733}, { 7734, 7735}, { 7736, 7737}, { 7738, 7739}, { 7740, 7741}, { 7742, 7743}, -{ 7744, 7745}, { 7746, 7747}, { 7748, 7749}, { 7750, 7751}, { 7752, 7753}, { 7754, 7755}, { 7756, 7757}, -{ 7758, 7759}, { 7760, 7761}, { 7762, 7763}, { 7764, 7765}, { 7766, 7767}, { 7768, 7769}, { 7770, 7771}, -{ 7772, 7773}, { 7774, 7775}, { 7776, 7777}, { 7778, 7779}, { 7780, 7781}, { 7782, 7783}, { 7784, 7785}, -{ 7786, 7787}, { 7788, 7789}, { 7790, 7791}, { 7792, 7793}, { 7794, 7795}, { 7796, 7797}, { 7798, 7799}, -{ 7800, 7801}, { 7802, 7803}, { 7804, 7805}, { 7806, 7807}, { 7808, 7809}, { 7810, 7811}, { 7812, 7813}, -{ 7814, 7815}, { 7816, 7817}, { 7818, 7819}, { 7820, 7821}, { 7822, 7823}, { 7824, 7825}, { 7826, 7827}, -{ 7828, 7829}, { 7840, 7841}, { 7842, 7843}, { 7844, 7845}, { 7846, 7847}, { 7848, 7849}, { 7850, 7851}, -{ 7852, 7853}, { 7854, 7855}, { 7856, 7857}, { 7858, 7859}, { 7860, 7861}, { 7862, 7863}, { 7864, 7865}, -{ 7866, 7867}, { 7868, 7869}, { 7870, 7871}, { 7872, 7873}, { 7874, 7875}, { 7876, 7877}, { 7878, 7879}, -{ 7880, 7881}, { 7882, 7883}, { 7884, 7885}, { 7886, 7887}, { 7888, 7889}, { 7890, 7891}, { 7892, 7893}, -{ 7894, 7895}, { 7896, 7897}, { 7898, 7899}, { 7900, 7901}, { 7902, 7903}, { 7904, 7905}, { 7906, 7907}, -{ 7908, 7909}, { 7910, 7911}, { 7912, 7913}, { 7914, 7915}, { 7916, 7917}, { 7918, 7919}, { 7920, 7921}, -{ 7922, 7923}, { 7924, 7925}, { 7926, 7927}, { 7928, 7929}, { 7944, 7936}, { 7945, 7937}, { 7946, 7938}, -{ 7947, 7939}, { 7948, 7940}, { 7949, 7941}, { 7950, 7942}, { 7951, 7943}, { 7960, 7952}, { 7961, 7953}, -{ 7962, 7954}, { 7963, 7955}, { 7964, 7956}, { 7965, 7957}, { 7976, 7968}, { 7977, 7969}, { 7978, 7970}, -{ 7979, 7971}, { 7980, 7972}, { 7981, 7973}, { 7982, 7974}, { 7983, 7975}, { 7992, 7984}, { 7993, 7985}, -{ 7994, 7986}, { 7995, 7987}, { 7996, 7988}, { 7997, 7989}, { 7998, 7990}, { 7999, 7991}, { 8008, 8000}, -{ 8009, 8001}, { 8010, 8002}, { 8011, 8003}, { 8012, 8004}, { 8013, 8005}, { 8025, 8017}, { 8027, 8019}, -{ 8029, 8021}, { 8031, 8023}, { 8040, 8032}, { 8041, 8033}, { 8042, 8034}, { 8043, 8035}, { 8044, 8036}, -{ 8045, 8037}, { 8046, 8038}, { 8047, 8039}, { 8120, 8112}, { 8121, 8113}, { 8122, 8048}, { 8123, 8049}, -{ 8136, 8050}, { 8137, 8051}, { 8138, 8052}, { 8139, 8053}, { 8152, 8144}, { 8153, 8145}, { 8154, 8054}, -{ 8155, 8055}, { 8168, 8160}, { 8169, 8161}, { 8170, 8058}, { 8171, 8059}, { 8172, 8165}, { 8184, 8056}, -{ 8185, 8057}, { 8186, 8060}, { 8187, 8061}, { 8544, 8560}, { 8545, 8561}, { 8546, 8562}, { 8547, 8563}, -{ 8548, 8564}, { 8549, 8565}, { 8550, 8566}, { 8551, 8567}, { 8552, 8568}, { 8553, 8569}, { 8554, 8570}, -{ 8555, 8571}, { 8556, 8572}, { 8557, 8573}, { 8558, 8574}, { 8559, 8575}, { 9398, 9424}, { 9399, 9425}, -{ 9400, 9426}, { 9401, 9427}, { 9402, 9428}, { 9403, 9429}, { 9404, 9430}, { 9405, 9431}, { 9406, 9432}, -{ 9407, 9433}, { 9408, 9434}, { 9409, 9435}, { 9410, 9436}, { 9411, 9437}, { 9412, 9438}, { 9413, 9439}, -{ 9414, 9440}, { 9415, 9441}, { 9416, 9442}, { 9417, 9443}, { 9418, 9444}, { 9419, 9445}, { 9420, 9446}, -{ 9421, 9447}, { 9422, 9448}, { 9423, 9449}, {65313,65345}, {65314,65346}, {65315,65347}, {65316,65348}, -{65317,65349}, {65318,65350}, {65319,65351}, {65320,65352}, {65321,65353}, {65322,65354}, {65323,65355}, -{65324,65356}, {65325,65357}, {65326,65358}, {65327,65359}, {65328,65360}, {65329,65361}, {65330,65362}, -{65331,65363}, {65332,65364}, {65333,65365}, {65334,65366}, {65335,65367}, {65336,65368}, {65337,65369}, -{65338,65370}, {65535, 0}}; - -int OVR_CDECL OVR_towupper(wchar_t charCode) -{ - // Don't use UnicodeUpperBits! It differs from UnicodeToUpperBits. - if (UnicodeCharIs(UnicodeToUpperBits, charCode)) - { - // To protect from memory overrun in case the character is not found - // we use one extra fake element in the table {65536, 0}. - size_t idx = Alg::LowerBoundSliced( - UnicodeToUpperTable, - 0, - sizeof(UnicodeToUpperTable) / sizeof(UnicodeToUpperTable[0]) - 1, - (uint16_t)charCode, - CmpUnicodeKey); - return UnicodeToUpperTable[idx].Value; - } - return charCode; -} - -int OVR_CDECL OVR_towlower(wchar_t charCode) -{ - // Don't use UnicodeLowerBits! It differs from UnicodeToLowerBits. - if (UnicodeCharIs(UnicodeToLowerBits, charCode)) - { - // To protect from memory overrun in case the character is not found - // we use one extra fake element in the table {65536, 0}. - size_t idx = Alg::LowerBoundSliced( - UnicodeToLowerTable, - 0, - sizeof(UnicodeToLowerTable) / sizeof(UnicodeToLowerTable[0]) - 1, - (uint16_t)charCode, - CmpUnicodeKey); - return UnicodeToLowerTable[idx].Value; - } - return charCode; -} - -#endif //OVR_NO_WCTYPE - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_Std.h b/LibOVR/Src/Kernel/OVR_Std.h deleted file mode 100644 index 6a14231..0000000 --- a/LibOVR/Src/Kernel/OVR_Std.h +++ /dev/null @@ -1,638 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Std.h -Content : Standard C function interface -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Std_h -#define OVR_Std_h - -#include "OVR_Types.h" -#include // for va_list args -#include -#include -#include -#include - -#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) -#define OVR_MSVC_SAFESTRING -#include -#endif - -// Wide-char funcs -#include -#include - -namespace OVR { - -// Has the same behavior as itoa aside from also having a dest size argument. -// Return value: Pointer to the resulting null-terminated string, same as parameter str. -#if defined(OVR_OS_MS) -inline char* OVR_CDECL OVR_itoa(int val, char *dest, size_t destsize, int radix) -{ -#if defined(OVR_MSVC_SAFESTRING) - _itoa_s(val, dest, destsize, radix); - return dest; -#else - OVR_UNUSED(destsize); - return itoa(val, dest, radix); -#endif -} -#else // OVR_OS_MS -inline char* OVR_itoa(int val, char* dest, size_t len, int radix) -{ - if (val == 0) - { - if (len > 1) - { - dest[0] = '0'; - dest[1] = '\0'; - } - else if(len > 0) - dest[0] = '\0'; - return dest; - } - - // FIXME: Fix the following code to avoid memory write overruns when len is in sufficient. - int cur = val; - size_t i = 0; - size_t sign = 0; - - if (val < 0) - { - val = -val; - sign = 1; - } - - while ((val != 0) && (i < (len - 1 - sign))) - { - cur = val % radix; - val /= radix; - - if (radix == 16) - { - switch(cur) - { - case 10: - dest[i] = 'a'; - break; - case 11: - dest[i] = 'b'; - break; - case 12: - dest[i] = 'c'; - break; - case 13: - dest[i] = 'd'; - break; - case 14: - dest[i] = 'e'; - break; - case 15: - dest[i] = 'f'; - break; - default: - dest[i] = (char)('0' + cur); - break; - } - } - else - { - dest[i] = (char)('0' + cur); - } - ++i; - } - - if (sign) - { - dest[i++] = '-'; - } - - for (size_t j = 0; j < i / 2; ++j) - { - char tmp = dest[j]; - dest[j] = dest[i - 1 - j]; - dest[i - 1 - j] = tmp; - } - dest[i] = '\0'; - - return dest; -} - -#endif - - -// String functions - -inline size_t OVR_CDECL OVR_strlen(const char* str) -{ - return strlen(str); -} - -inline char* OVR_CDECL OVR_strcpy(char* dest, size_t destsize, const char* src) -{ -#if defined(OVR_MSVC_SAFESTRING) - strcpy_s(dest, destsize, src); - return dest; -#else - // FIXME: This should be a safer implementation - OVR_UNUSED(destsize); - return strcpy(dest, src); -#endif -} - - -// Acts the same as the strlcpy function. -// Copies src to dest, 0-terminating even if it involves truncating the write. -// Returns the required strlen of dest (which is one less than the required size of dest). -// strlcpy is a safer alternative to strcpy and strncpy and provides size information. -// However, it still may result in an incomplete copy. -// -// Example usage: -// char buffer[256]; -// if(OVR_strlcpy(buffer, "hello world", sizeof(buffer)) < sizeof(buffer)) -// { there was enough space } -// else -// { need a larger buffer } -// -size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize); - -// Acts the same as the strlcat function. -// Appends src to dest, 0-terminating even if it involves an incomplete write. -// Doesn't 0-terminate in the case that destsize is 0. -// Returns the required strlen of dest (which is one less than the required size of dest). -// The terminating 0 char of dest is overwritten by the first -// character of src, and a new 0 char is appended to dest. The required capacity -// of the destination is (strlen(src) + strlen(dest) + 1). -// strlcat is a safer alternative to strcat and provides size information. -// However, it still may result in an incomplete copy. -// -// Example usage: -// char buffer[256] = "hello "; -// if(OVR_strlcat(buffer, "world", sizeof(buffer)) < sizeof(buffer)) -// { there was enough space } -// else -// { need a larger buffer } -// -size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize); - - -inline char* OVR_CDECL OVR_strncpy(char* dest, size_t destsize, const char* src, size_t count) -{ -#if defined(OVR_MSVC_SAFESTRING) - strncpy_s(dest, destsize, src, count); - return dest; -#else - // FIXME: This should be a safer implementation - OVR_UNUSED(destsize); - return strncpy(dest, src, count); -#endif -} - -inline char * OVR_CDECL OVR_strcat(char* dest, size_t destsize, const char* src) -{ -#if defined(OVR_MSVC_SAFESTRING) - strcat_s(dest, destsize, src); - return dest; -#else - // FIXME: This should be a safer implementation - OVR_UNUSED(destsize); - return strcat(dest, src); -#endif -} - -inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src) -{ - return strcmp(dest, src); -} - -inline const char* OVR_CDECL OVR_strchr(const char* str, char c) -{ - return strchr(str, c); -} - -inline char* OVR_CDECL OVR_strchr(char* str, char c) -{ - return strchr(str, c); -} - -inline const char* OVR_strrchr(const char* str, char c) -{ - size_t len = OVR_strlen(str); - for (size_t i=len; i>0; i--) - if (str[i]==c) - return str+i; - return 0; -} - -inline const uint8_t* OVR_CDECL OVR_memrchr(const uint8_t* str, size_t size, uint8_t c) -{ - for (intptr_t i = (intptr_t)size - 1; i >= 0; i--) - { - if (str[i] == c) - return str + i; - } - return 0; -} - -inline char* OVR_CDECL OVR_strrchr(char* str, char c) -{ - size_t len = OVR_strlen(str); - for (size_t i=len; i>0; i--) - if (str[i]==c) - return str+i; - return 0; -} - - -double OVR_CDECL OVR_strtod(const char* string, char** tailptr); - -inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix) -{ - return strtol(string, tailptr, radix); -} - -inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix) -{ - return strtoul(string, tailptr, radix); -} - -inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, size_t size) -{ - return strncmp(ws1, ws2, size); -} - -inline uint64_t OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base) -{ -#if defined(OVR_CC_MSVC) - return _strtoui64(nptr, endptr, base); -#else - return strtoull(nptr, endptr, base); -#endif -} - -inline int64_t OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) -{ -#if defined(OVR_CC_MSVC) - return _strtoi64(nptr, endptr, base); -#else - return strtoll(nptr, endptr, base); -#endif -} - - -inline int64_t OVR_CDECL OVR_atoq(const char* string) -{ -#if defined(OVR_CC_MSVC) - return _atoi64(string); -#else - return atoll(string); -#endif -} - -inline uint64_t OVR_CDECL OVR_atouq(const char* string) -{ - return OVR_strtouq(string, NULL, 10); -} - - -// Implemented in OVR_Std.cpp in platform-specific manner. -int OVR_CDECL OVR_stricmp(const char* dest, const char* src); -int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, size_t count); - - -// This is like sprintf but with a destination buffer size argument. However, the behavior is different -// from vsnprintf in that the return value semantics are like sprintf (which returns -1 on capacity overflow) and -// not like snprintf (which returns intended strlen on capacity overflow). -inline size_t OVR_CDECL OVR_sprintf(char *dest, size_t destsize, const char* format, ...) -{ - va_list argList; - va_start(argList,format); - size_t ret; -#if defined(OVR_CC_MSVC) - #if defined(OVR_MSVC_SAFESTRING) - ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); - OVR_ASSERT(ret != -1); - #else - OVR_UNUSED(destsize); - ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character - OVR_ASSERT(ret != -1); - dest[destsize-1] = 0; - #endif -#else - OVR_UNUSED(destsize); - ret = vsprintf(dest, format, argList); - OVR_ASSERT(ret < destsize); -#endif - va_end(argList); - return ret; -} - - -// This is like vsprintf but with a destination buffer size argument. However, the behavior is different -// from vsnprintf in that the return value semantics are like vsprintf (which returns -1 on capacity overflow) and -// not like vsnprintf (which returns intended strlen on capacity overflow). -// Return value: -// On success, the total number of characters written is returned. -// On failure, a negative number is returned. -inline size_t OVR_CDECL OVR_vsprintf(char *dest, size_t destsize, const char * format, va_list argList) -{ - size_t ret; -#if defined(OVR_CC_MSVC) - #if defined(OVR_MSVC_SAFESTRING) - dest[0] = '\0'; - int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); - if (rv == -1) - { - dest[destsize - 1] = '\0'; - ret = destsize - 1; - } - else - ret = (size_t)rv; - #else - OVR_UNUSED(destsize); - int rv = _vsnprintf(dest, destsize - 1, format, argList); - OVR_ASSERT(rv != -1); - ret = (size_t)rv; - dest[destsize-1] = 0; - #endif -#else - // FIXME: This should be a safer implementation - OVR_UNUSED(destsize); - ret = (size_t)vsprintf(dest, format, argList); - OVR_ASSERT(ret < destsize); -#endif - return ret; -} - -// Same behavior as ISO C99 vsnprintf. -// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. -// destsize specifies the capacity of the input buffer. -// -// Example usage: -// void Log(char *dest, size_t destsize, const char * format, ...) -// { -// char buffer[1024]; -// va_list argList; -// va_start(argList,format); -// int result = OVR_vsnprintf(dest, destsize, format, argList); -// assert(result < destsize); // Else we'd have to retry with a dynamically allocated buffer (of size=result+1) and new argList copy. -// va_end(argList); -// } - -inline int OVR_CDECL OVR_vsnprintf(char *dest, size_t destsize, const char * format, va_list argList) -{ - int ret; -#if defined(OVR_CC_MSVC) - OVR_DISABLE_MSVC_WARNING(4996) // 'vsnprintf': This function or variable may be unsafe. - ret = vsnprintf(dest, destsize, format, argList); // Microsoft vsnprintf is non-conforming; it returns -1 if destsize is insufficient. - if (ret < 0) // If there was a format error or if destsize was insufficient... - { - ret = _vscprintf(format, argList); // Get the expected dest strlen. If the return value is still -1 then there was a format error. - - if (destsize) // If we can 0-terminate the output... - { - if (ret < 0) - dest[0] = 0; - else - dest[destsize-1] = 0; - } - } - // Else the string was written OK and ret is its strlen. - OVR_RESTORE_MSVC_WARNING() -#else - ret = vsnprintf(dest, destsize, format, argList); -#endif - return ret; -} - - -// Same behavior as ISO C99 snprintf. -// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. -// destsize specifies the capacity of the input buffer. -// -// Example usage: -// char buffer[16]; -// int result = OVR_snprintf(buffer, sizeof(buffer), "%d", 37); -// if (result >= sizeof(buffer)) // If there was insufficient capacity... -// { -// char* p = new char[result + 1]; // Or char* p = (char*)OVR_ALLOC(result + 1); -// OVR_snprintf(p, (size_t)result, "%d", 37); -// delete[] p; -// } -// -inline int OVR_CDECL OVR_snprintf(char *dest, size_t destsize, const char * format, ...) -{ - va_list argList; - va_start(argList,format); - int ret = OVR_vsnprintf(dest, destsize, format, argList); - va_end(argList); - return ret; -} - - -// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. -// Note: If you are planning on printing a string then it's more efficient to just use OVR_vsnprintf and -// look at the return value and handle the uncommon case that there wasn't enough space. -inline int OVR_CDECL OVR_vscprintf(const char * format, va_list argList) -{ - int ret; -#if defined(OVR_CC_MSVC) - ret = _vscprintf(format, argList); -#else - ret = vsnprintf(NULL, 0, format, argList); -#endif - return ret; -} - - -wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src); -wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count); -wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src); -size_t OVR_CDECL OVR_wcslen(const wchar_t* str); -int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b); -int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b); - -inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) -{ -#if defined(OVR_OS_MS) - #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) - return ::_wcsicoll(a, b); - #else - return ::wcsicoll(a, b); - #endif -#else - // not supported, use regular wcsicmp - return OVR_wcsicmp(a, b); -#endif -} - -inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) -{ -#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) - return wcscoll(a, b); -#else - // not supported, use regular wcscmp - return OVR_wcscmp(a, b); -#endif -} - -#ifndef OVR_NO_WCTYPE - -inline int OVR_CDECL UnicodeCharIs(const uint16_t* table, wchar_t charCode) -{ - unsigned offset = table[charCode >> 8]; - if (offset == 0) return 0; - if (offset == 1) return 1; - return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0; -} - -extern const uint16_t UnicodeAlnumBits[]; -extern const uint16_t UnicodeAlphaBits[]; -extern const uint16_t UnicodeDigitBits[]; -extern const uint16_t UnicodeSpaceBits[]; -extern const uint16_t UnicodeXDigitBits[]; - -// Uncomment if necessary -//extern const uint16_t UnicodeCntrlBits[]; -//extern const uint16_t UnicodeGraphBits[]; -//extern const uint16_t UnicodeLowerBits[]; -//extern const uint16_t UnicodePrintBits[]; -//extern const uint16_t UnicodePunctBits[]; -//extern const uint16_t UnicodeUpperBits[]; - -inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits, charCode); } -inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits, charCode); } -inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits, charCode); } -inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits, charCode); } -inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); } - -// Uncomment if necessary -//inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits, charCode); } -//inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits, charCode); } -//inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits, charCode); } -//inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits, charCode); } -//inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits, charCode); } -//inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits, charCode); } - -int OVR_CDECL OVR_towupper(wchar_t charCode); -int OVR_CDECL OVR_towlower(wchar_t charCode); - -#else // OVR_NO_WCTYPE - -inline int OVR_CDECL OVR_iswspace(wchar_t c) -{ - return iswspace(c); -} - -inline int OVR_CDECL OVR_iswdigit(wchar_t c) -{ - return iswdigit(c); -} - -inline int OVR_CDECL OVR_iswxdigit(wchar_t c) -{ - return iswxdigit(c); -} - -inline int OVR_CDECL OVR_iswalpha(wchar_t c) -{ - return iswalpha(c); -} - -inline int OVR_CDECL OVR_iswalnum(wchar_t c) -{ - return iswalnum(c); -} - -inline wchar_t OVR_CDECL OVR_towlower(wchar_t c) -{ - return (wchar_t)towlower(c); -} - -inline wchar_t OVR_towupper(wchar_t c) -{ - return (wchar_t)towupper(c); -} - -#endif // OVR_NO_WCTYPE - -// ASCII versions of tolower and toupper. Don't use "char" -inline int OVR_CDECL OVR_tolower(int c) -{ - return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; -} - -inline int OVR_CDECL OVR_toupper(int c) -{ - return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; -} - - - -inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr) -{ -#if defined(OVR_OS_OTHER) - OVR_UNUSED(tailptr); - char buffer[64]; - char* tp = NULL; - size_t max = OVR_wcslen(string); - if (max > 63) max = 63; - unsigned char c = 0; - for (size_t i=0; i < max; i++) - { - c = (unsigned char)string[i]; - buffer[i] = ((c) < 128 ? (char)c : '!'); - } - buffer[max] = 0; - return OVR_strtod(buffer, &tp); -#else - return wcstod(string, tailptr); -#endif -} - -inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix) -{ -#if defined(OVR_OS_OTHER) - OVR_UNUSED(tailptr); - char buffer[64]; - char* tp = NULL; - size_t max = OVR_wcslen(string); - if (max > 63) max = 63; - unsigned char c = 0; - for (size_t i=0; i < max; i++) - { - c = (unsigned char)string[i]; - buffer[i] = ((c) < 128 ? (char)c : '!'); - } - buffer[max] = 0; - return strtol(buffer, &tp, radix); -#else - return wcstol(string, tailptr, radix); -#endif -} - -} // OVR - -#endif // OVR_Std_h diff --git a/LibOVR/Src/Kernel/OVR_String.cpp b/LibOVR/Src/Kernel/OVR_String.cpp deleted file mode 100644 index a539992..0000000 --- a/LibOVR/Src/Kernel/OVR_String.cpp +++ /dev/null @@ -1,779 +0,0 @@ -/************************************************************************************ - -Filename : OVR_String.cpp -Content : String UTF8 string implementation with copy-on-write semantics - (thread-safe for assignment but not modification). -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_String.h" - -#include -#include - -#ifdef OVR_OS_QNX -# include -#endif - -namespace OVR { - -#define String_LengthIsSize (size_t(1) << String::Flag_LengthIsSizeShift) - -String::DataDesc String::NullData = {String_LengthIsSize, 1, {0} }; - - -String::String() -{ - pData = &NullData; - pData->AddRef(); -}; - -String::String(const char* pdata) -{ - // Obtain length in bytes; it doesn't matter if _data is UTF8. - size_t size = pdata ? OVR_strlen(pdata) : 0; - pData = AllocDataCopy1(size, 0, pdata, size); -}; - -String::String(const char* pdata1, const char* pdata2, const char* pdata3) -{ - // Obtain length in bytes; it doesn't matter if _data is UTF8. - size_t size1 = pdata1 ? OVR_strlen(pdata1) : 0; - size_t size2 = pdata2 ? OVR_strlen(pdata2) : 0; - size_t size3 = pdata3 ? OVR_strlen(pdata3) : 0; - - DataDesc *pdataDesc = AllocDataCopy2(size1 + size2 + size3, 0, - pdata1, size1, pdata2, size2); - memcpy(pdataDesc->Data + size1 + size2, pdata3, size3); - pData = pdataDesc; -} - -String::String(const char* pdata, size_t size) -{ - OVR_ASSERT((size == 0) || (pdata != 0)); - pData = AllocDataCopy1(size, 0, pdata, size); -}; - - -String::String(const InitStruct& src, size_t size) -{ - pData = AllocData(size, 0); - src.InitString(GetData()->Data, size); -} - -String::String(const String& src) -{ - pData = src.GetData(); - pData->AddRef(); -} - -String::String(const StringBuffer& src) -{ - pData = AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize()); -} - -String::String(const wchar_t* data) -{ - pData = &NullData; - pData->AddRef(); - // Simplified logic for wchar_t constructor. - if (data) - *this = data; -} - - -String::DataDesc* String::AllocData(size_t size, size_t lengthIsSize) -{ - String::DataDesc* pdesc; - - if (size == 0) - { - pdesc = &NullData; - pdesc->AddRef(); - return pdesc; - } - - pdesc = (DataDesc*)OVR_ALLOC(sizeof(DataDesc)+ size); - pdesc->Data[size] = 0; - pdesc->RefCount = 1; - pdesc->Size = size | lengthIsSize; - return pdesc; -} - - -String::DataDesc* String::AllocDataCopy1(size_t size, size_t lengthIsSize, - const char* pdata, size_t copySize) -{ - String::DataDesc* pdesc = AllocData(size, lengthIsSize); - memcpy(pdesc->Data, pdata, copySize); - return pdesc; -} - -String::DataDesc* String::AllocDataCopy2(size_t size, size_t lengthIsSize, - const char* pdata1, size_t copySize1, - const char* pdata2, size_t copySize2) -{ - String::DataDesc* pdesc = AllocData(size, lengthIsSize); - memcpy(pdesc->Data, pdata1, copySize1); - memcpy(pdesc->Data + copySize1, pdata2, copySize2); - return pdesc; -} - - -size_t String::GetLength() const -{ - // Optimize length accesses for non-UTF8 character strings. - DataDesc* pdata = GetData(); - size_t length, size = pdata->GetSize(); - - if (pdata->LengthIsSize()) - return size; - - length = (size_t)UTF8Util::GetLength(pdata->Data, (size_t)size); - - if (length == size) - pdata->Size |= String_LengthIsSize; - - return length; -} - - -//static uint32_t String_CharSearch(const char* buf, ) - - -uint32_t String::GetCharAt(size_t index) const -{ - intptr_t i = (intptr_t) index; - DataDesc* pdata = GetData(); - const char* buf = pdata->Data; - uint32_t c; - - if (pdata->LengthIsSize()) - { - OVR_ASSERT(index < pdata->GetSize()); - buf += i; - return UTF8Util::DecodeNextChar_Advance0(&buf); - } - - c = UTF8Util::GetCharAt(index, buf, pdata->GetSize()); - return c; -} - -uint32_t String::GetFirstCharAt(size_t index, const char** offset) const -{ - DataDesc* pdata = GetData(); - intptr_t i = (intptr_t) index; - const char* buf = pdata->Data; - const char* end = buf + pdata->GetSize(); - uint32_t c; - - do - { - c = UTF8Util::DecodeNextChar_Advance0(&buf); - i--; - - if (buf >= end) - { - // We've hit the end of the string; don't go further. - OVR_ASSERT(i == 0); - return c; - } - } while (i >= 0); - - *offset = buf; - - return c; -} - -uint32_t String::GetNextChar(const char** offset) const -{ - return UTF8Util::DecodeNextChar(offset); -} - - - -void String::AppendChar(uint32_t ch) -{ - DataDesc* pdata = GetData(); - size_t size = pdata->GetSize(); - char buff[8]; - intptr_t encodeSize = 0; - - // Converts ch into UTF8 string and fills it into buff. - UTF8Util::EncodeChar(buff, &encodeSize, ch); - OVR_ASSERT(encodeSize >= 0); - - SetData(AllocDataCopy2(size + (size_t)encodeSize, 0, - pdata->Data, size, buff, (size_t)encodeSize)); - pdata->Release(); -} - - -void String::AppendString(const wchar_t* pstr, intptr_t len) -{ - if (!pstr) - return; - - DataDesc* pdata = GetData(); - size_t oldSize = pdata->GetSize(); - size_t encodeSize = (size_t)UTF8Util::GetEncodeStringSize(pstr, len); - - DataDesc* pnewData = AllocDataCopy1(oldSize + (size_t)encodeSize, 0, - pdata->Data, oldSize); - UTF8Util::EncodeString(pnewData->Data + oldSize, pstr, len); - - SetData(pnewData); - pdata->Release(); -} - - -void String::AppendString(const char* putf8str, intptr_t utf8StrSz) -{ - if (!putf8str || !utf8StrSz) - return; - if (utf8StrSz == -1) - utf8StrSz = (intptr_t)OVR_strlen(putf8str); - - DataDesc* pdata = GetData(); - size_t oldSize = pdata->GetSize(); - - SetData(AllocDataCopy2(oldSize + (size_t)utf8StrSz, 0, - pdata->Data, oldSize, putf8str, (size_t)utf8StrSz)); - pdata->Release(); -} - -void String::AssignString(const InitStruct& src, size_t size) -{ - DataDesc* poldData = GetData(); - DataDesc* pnewData = AllocData(size, 0); - src.InitString(pnewData->Data, size); - SetData(pnewData); - poldData->Release(); -} - -void String::AssignString(const char* putf8str, size_t size) -{ - DataDesc* poldData = GetData(); - SetData(AllocDataCopy1(size, 0, putf8str, size)); - poldData->Release(); -} - -void String::operator = (const char* pstr) -{ - AssignString(pstr, pstr ? OVR_strlen(pstr) : 0); -} - -void String::operator = (const wchar_t* pwstr) -{ - pwstr = pwstr ? pwstr : L""; - - DataDesc* poldData = GetData(); - size_t size = (size_t)UTF8Util::GetEncodeStringSize(pwstr); - - DataDesc* pnewData = AllocData(size, 0); - UTF8Util::EncodeString(pnewData->Data, pwstr); - SetData(pnewData); - poldData->Release(); -} - - -void String::operator = (const String& src) -{ - DataDesc* psdata = src.GetData(); - DataDesc* pdata = GetData(); - - SetData(psdata); - psdata->AddRef(); - pdata->Release(); -} - - -void String::operator = (const StringBuffer& src) -{ - DataDesc* polddata = GetData(); - SetData(AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize())); - polddata->Release(); -} - -void String::operator += (const String& src) -{ - DataDesc *pourData = GetData(), - *psrcData = src.GetData(); - size_t ourSize = pourData->GetSize(), - srcSize = psrcData->GetSize(); - size_t lflag = pourData->GetLengthFlag() & psrcData->GetLengthFlag(); - - SetData(AllocDataCopy2(ourSize + srcSize, lflag, - pourData->Data, ourSize, psrcData->Data, srcSize)); - pourData->Release(); -} - - -String String::operator + (const char* str) const -{ - String tmp1(*this); - tmp1 += (str ? str : ""); - return tmp1; -} - -String String::operator + (const String& src) const -{ - String tmp1(*this); - tmp1 += src; - return tmp1; -} - -void String::Remove(size_t posAt, intptr_t removeLength) -{ - DataDesc* pdata = GetData(); - size_t oldSize = pdata->GetSize(); - // Length indicates the number of characters to remove. - size_t length = GetLength(); - - // If index is past the string, nothing to remove. - if (posAt >= length) - return; - // Otherwise, cap removeLength to the length of the string. - if ((posAt + removeLength) > length) - removeLength = length - posAt; - - // Get the byte position of the UTF8 char at position posAt. - intptr_t bytePos = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize); - intptr_t removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos); - - SetData(AllocDataCopy2(oldSize - removeSize, pdata->GetLengthFlag(), - pdata->Data, bytePos, - pData->Data + bytePos + removeSize, (oldSize - bytePos - removeSize))); - pdata->Release(); -} - - -String String::Substring(size_t start, size_t end) const -{ - size_t length = GetLength(); - if ((start >= length) || (start >= end)) - return String(); - - DataDesc* pdata = GetData(); - - // If size matches, we know the exact index range. - if (pdata->LengthIsSize()) - return String(pdata->Data + start, end - start); - - // Get position of starting character. - intptr_t byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize()); - intptr_t byteSize = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart); - return String(pdata->Data + byteStart, (size_t)byteSize); -} - -void String::Clear() -{ - NullData.AddRef(); - GetData()->Release(); - SetData(&NullData); -} - - -String String::ToUpper() const -{ - uint32_t c; - const char* psource = GetData()->Data; - const char* pend = psource + GetData()->GetSize(); - String str; - intptr_t bufferOffset = 0; - char buffer[512]; - - while(psource < pend) - { - do { - c = UTF8Util::DecodeNextChar_Advance0(&psource); - UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c))); - } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8))); - - // Append string a piece at a time. - str.AppendString(buffer, bufferOffset); - bufferOffset = 0; - } - - return str; -} - -String String::ToLower() const -{ - uint32_t c; - const char* psource = GetData()->Data; - const char* pend = psource + GetData()->GetSize(); - String str; - intptr_t bufferOffset = 0; - char buffer[512]; - - while(psource < pend) - { - do { - c = UTF8Util::DecodeNextChar_Advance0(&psource); - UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c))); - } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8))); - - // Append string a piece at a time. - str.AppendString(buffer, bufferOffset); - bufferOffset = 0; - } - - return str; -} - - - -String& String::Insert(const char* substr, size_t posAt, intptr_t strSize) -{ - DataDesc* poldData = GetData(); - size_t oldSize = poldData->GetSize(); - size_t insertSize = (strSize < 0) ? OVR_strlen(substr) : (size_t)strSize; - size_t byteIndex = (poldData->LengthIsSize()) ? - posAt : (size_t)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize); - - OVR_ASSERT(byteIndex <= oldSize); - - DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0, - poldData->Data, byteIndex, substr, insertSize); - memcpy(pnewData->Data + byteIndex + insertSize, - poldData->Data + byteIndex, oldSize - byteIndex); - SetData(pnewData); - poldData->Release(); - return *this; -} - -/* -String& String::Insert(const uint32_t* substr, size_t posAt, intptr_t len) -{ - for (intptr_t i = 0; i < len; ++i) - { - size_t charw = InsertCharAt(substr[i], posAt); - posAt += charw; - } - return *this; -} -*/ - -size_t String::InsertCharAt(uint32_t c, size_t posAt) -{ - char buf[8]; - intptr_t index = 0; - UTF8Util::EncodeChar(buf, &index, c); - OVR_ASSERT(index >= 0); - buf[(size_t)index] = 0; - - Insert(buf, posAt, index); - return (size_t)index; -} - - -int String::CompareNoCase(const char* a, const char* b) -{ - return OVR_stricmp(a, b); -} - -int String::CompareNoCase(const char* a, const char* b, intptr_t len) -{ - if (len) - { - intptr_t f,l; - intptr_t slen = len; - const char *s = b; - do { - f = (intptr_t)OVR_tolower((int)(*(a++))); - l = (intptr_t)OVR_tolower((int)(*(b++))); - } while (--len && f && (f == l) && *b != 0); - - if (f == l && (len != 0 || *b != 0)) - { - f = (intptr_t)slen; - l = (intptr_t)OVR_strlen(s); - return int(f - l); - } - - return int(f - l); - } - else - return (0-(int)OVR_strlen(b)); -} - -// ***** Implement hash static functions - -// Hash function -size_t String::BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed) -{ - const uint8_t* pdata = (const uint8_t*) pdataIn; - size_t h = seed; - while (size > 0) - { - size--; - h = ((h << 5) + h) ^ (unsigned) pdata[size]; - } - - return h; -} - -// Hash function, case-insensitive -size_t String::BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed) -{ - const uint8_t* pdata = (const uint8_t*) pdataIn; - size_t h = seed; - while (size > 0) - { - size--; - h = ((h << 5) + h) ^ OVR_tolower(pdata[size]); - } - - // Alternative: "sdbm" hash function, suggested at same web page above. - // h = 0; - // for bytes { h = (h << 16) + (h << 6) - hash + *p; } - return h; -} - - - -// ***** String Buffer used for Building Strings - - -#define OVR_SBUFF_DEFAULT_GROW_SIZE 512 -// Constructors / Destructor. -StringBuffer::StringBuffer() - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ -} - -StringBuffer::StringBuffer(size_t growSize) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - SetGrowSize(growSize); -} - -StringBuffer::StringBuffer(const char* data) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - AppendString(data); -} - -StringBuffer::StringBuffer(const char* data, size_t dataSize) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - AppendString(data, dataSize); -} - -StringBuffer::StringBuffer(const String& src) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - AppendString(src.ToCStr(), src.GetSize()); -} - -StringBuffer::StringBuffer(const StringBuffer& src) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - AppendString(src.ToCStr(), src.GetSize()); -} - -StringBuffer::StringBuffer(const wchar_t* data) - : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) -{ - *this = data; -} - -StringBuffer::~StringBuffer() -{ - if (pData) - OVR_FREE(pData); -} -void StringBuffer::SetGrowSize(size_t growSize) -{ - if (growSize <= 16) - GrowSize = 16; - else - { - uint8_t bits = Alg::UpperBit(uint32_t(growSize-1)); - size_t size = (size_t)1 << bits; - GrowSize = size == growSize ? growSize : size; - } -} - -size_t StringBuffer::GetLength() const -{ - size_t length, size = GetSize(); - if (LengthIsSize) - return size; - - length = (size_t)UTF8Util::GetLength(pData, (size_t)GetSize()); - - if (length == GetSize()) - LengthIsSize = true; - return length; -} - -void StringBuffer::Reserve(size_t _size) -{ - if (_size >= BufferSize) // >= because of trailing zero! (!AB) - { - BufferSize = (_size + 1 + GrowSize - 1)& ~(GrowSize-1); - if (!pData) - pData = (char*)OVR_ALLOC(BufferSize); - else - pData = (char*)OVR_REALLOC(pData, BufferSize); - } -} -void StringBuffer::Resize(size_t _size) -{ - Reserve(_size); - LengthIsSize = false; - Size = _size; - if (pData) - pData[Size] = 0; -} - -void StringBuffer::Clear() -{ - Resize(0); - /* - if (pData != pEmptyNullData) - { - OVR_FREE(pHeap, pData); - pData = pEmptyNullData; - Size = BufferSize = 0; - LengthIsSize = false; - } - */ -} -// Appends a character -void StringBuffer::AppendChar(uint32_t ch) -{ - char buff[8]; - size_t origSize = GetSize(); - - // Converts ch into UTF8 string and fills it into buff. Also increments index according to the number of bytes - // in the UTF8 string. - intptr_t srcSize = 0; - UTF8Util::EncodeChar(buff, &srcSize, ch); - OVR_ASSERT(srcSize >= 0); - - size_t size = origSize + srcSize; - Resize(size); - OVR_ASSERT(pData != NULL); - memcpy(pData + origSize, buff, srcSize); -} - -// Append a string -void StringBuffer::AppendString(const wchar_t* pstr, intptr_t len) -{ - if (!pstr || !len) - return; - - intptr_t srcSize = UTF8Util::GetEncodeStringSize(pstr, len); - size_t origSize = GetSize(); - size_t size = srcSize + origSize; - - Resize(size); - OVR_ASSERT(pData != NULL); - UTF8Util::EncodeString(pData + origSize, pstr, len); -} - -void StringBuffer::AppendString(const char* putf8str, intptr_t utf8StrSz) -{ - if (!putf8str || !utf8StrSz) - return; - if (utf8StrSz == -1) - utf8StrSz = (intptr_t)OVR_strlen(putf8str); - - size_t origSize = GetSize(); - size_t size = utf8StrSz + origSize; - - Resize(size); - OVR_ASSERT(pData != NULL); - memcpy(pData + origSize, putf8str, utf8StrSz); -} - -// If pstr is NULL then the StringBuffer is cleared. -void StringBuffer::operator = (const char* pstr) -{ - pstr = pstr ? pstr : ""; - size_t size = OVR_strlen(pstr); - Resize(size); - OVR_ASSERT((pData != NULL) || (size == 0)); - memcpy(pData, pstr, size); -} - -// If pstr is NULL then the StringBuffer is cleared. -void StringBuffer::operator = (const wchar_t* pstr) -{ - pstr = pstr ? pstr : L""; - size_t size = (size_t)UTF8Util::GetEncodeStringSize(pstr); - Resize(size); - OVR_ASSERT((pData != NULL) || (size == 0)); - UTF8Util::EncodeString(pData, pstr); -} - -void StringBuffer::operator = (const String& src) -{ - const size_t size = src.GetSize(); - Resize(size); - OVR_ASSERT((pData != NULL) || (size == 0)); - memcpy(pData, src.ToCStr(), size); -} - -void StringBuffer::operator = (const StringBuffer& src) -{ - Clear(); - AppendString(src.ToCStr(), src.GetSize()); -} - - -// Inserts substr at posAt -void StringBuffer::Insert(const char* substr, size_t posAt, intptr_t len) -{ - size_t oldSize = Size; - size_t insertSize = (len < 0) ? OVR_strlen(substr) : (size_t)len; - size_t byteIndex = LengthIsSize ? posAt : - (size_t)UTF8Util::GetByteIndex(posAt, pData, (intptr_t)Size); - - OVR_ASSERT(byteIndex <= oldSize); - Reserve(oldSize + insertSize); - - OVR_ASSERT(pData != NULL); // pData is unilaterally written to below. - memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1); - memcpy (pData + byteIndex, substr, insertSize); - LengthIsSize = false; - Size = oldSize + insertSize; - pData[Size] = 0; -} - -// Inserts character at posAt -size_t StringBuffer::InsertCharAt(uint32_t c, size_t posAt) -{ - char buf[8]; - intptr_t len = 0; - UTF8Util::EncodeChar(buf, &len, c); - OVR_ASSERT(len >= 0); - buf[(size_t)len] = 0; - - Insert(buf, posAt, len); - return (size_t)len; -} - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_String.h b/LibOVR/Src/Kernel/OVR_String.h deleted file mode 100644 index ecef940..0000000 --- a/LibOVR/Src/Kernel/OVR_String.h +++ /dev/null @@ -1,658 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_String.h -Content : String UTF8 string implementation with copy-on-write semantics - (thread-safe for assignment but not modification). -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_String_h -#define OVR_String_h - -#include "OVR_Types.h" -#include "OVR_Allocator.h" -#include "OVR_UTF8Util.h" -#include "OVR_Atomic.h" -#include "OVR_Std.h" -#include "OVR_Alg.h" - -namespace OVR { - -// ***** Classes - -class String; -class StringBuffer; - - -//----------------------------------------------------------------------------------- -// ***** String Class - -// String is UTF8 based string class with copy-on-write implementation -// for assignment. - -class String -{ -protected: - - enum FlagConstants - { - //Flag_GetLength = 0x7FFFFFFF, - // This flag is set if GetLength() == GetSize() for a string. - // Avoid extra scanning is Substring and indexing logic. - Flag_LengthIsSizeShift = (sizeof(size_t)*8 - 1) - }; - - - // Internal structure to hold string data - struct DataDesc - { - // Number of bytes. Will be the same as the number of chars if the characters - // are ascii, may not be equal to number of chars in case string data is UTF8. - size_t Size; - volatile int32_t RefCount; - char Data[1]; - - void AddRef() - { - AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); - } - // Decrement ref count. This needs to be thread-safe, since - // a different thread could have also decremented the ref count. - // For example, if u start off with a ref count = 2. Now if u - // decrement the ref count and check against 0 in different - // statements, a different thread can also decrement the ref count - // in between our decrement and checking against 0 and will find - // the ref count = 0 and delete the object. This will lead to a crash - // when context switches to our thread and we'll be trying to delete - // an already deleted object. Hence decrementing the ref count and - // checking against 0 needs to made an atomic operation. - void Release() - { - if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) - OVR_FREE(this); - } - - static size_t GetLengthFlagBit() { return size_t(1) << Flag_LengthIsSizeShift; } - size_t GetSize() const { return Size & ~GetLengthFlagBit() ; } - size_t GetLengthFlag() const { return Size & GetLengthFlagBit(); } - bool LengthIsSize() const { return GetLengthFlag() != 0; } - }; - - // Heap type of the string is encoded in the lower bits. - enum HeapType - { - HT_Global = 0, // Heap is global. - HT_Local = 1, // SF::String_loc: Heap is determined based on string's address. - HT_Dynamic = 2, // SF::String_temp: Heap is stored as a part of the class. - HT_Mask = 3 - }; - - union { - DataDesc* pData; - size_t HeapTypeBits; - }; - typedef union { - DataDesc* pData; - size_t HeapTypeBits; - } DataDescUnion; - - inline HeapType GetHeapType() const { return (HeapType) (HeapTypeBits & HT_Mask); } - - inline DataDesc* GetData() const - { - DataDescUnion u; - u.pData = pData; - u.HeapTypeBits = (u.HeapTypeBits & ~(size_t)HT_Mask); - return u.pData; - } - - inline void SetData(DataDesc* pdesc) - { - HeapType ht = GetHeapType(); - pData = pdesc; - OVR_ASSERT((HeapTypeBits & HT_Mask) == 0); - HeapTypeBits |= ht; - } - - - DataDesc* AllocData(size_t size, size_t lengthIsSize); - DataDesc* AllocDataCopy1(size_t size, size_t lengthIsSize, - const char* pdata, size_t copySize); - DataDesc* AllocDataCopy2(size_t size, size_t lengthIsSize, - const char* pdata1, size_t copySize1, - const char* pdata2, size_t copySize2); - - // Special constructor to avoid data initalization when used in derived class. - struct NoConstructor { }; - String(const NoConstructor&) { } - -public: - - // For initializing string with dynamic buffer - struct InitStruct - { - virtual ~InitStruct() { } - virtual void InitString(char* pbuffer, size_t size) const = 0; - }; - - - // Constructors / Destructors. - String(); - String(const char* data); - String(const char* data1, const char* pdata2, const char* pdata3 = 0); - String(const char* data, size_t buflen); - String(const String& src); - String(const StringBuffer& src); - String(const InitStruct& src, size_t size); - explicit String(const wchar_t* data); - - // Destructor (Captain Obvious guarantees!) - ~String() - { - GetData()->Release(); - } - - // Declaration of NullString - static DataDesc NullData; - - - // *** General Functions - - void Clear(); - - // For casting to a pointer to char. - operator const char*() const { return GetData()->Data; } - // Pointer to raw buffer. - const char* ToCStr() const { return GetData()->Data; } - - // Returns number of bytes - size_t GetSize() const { return GetData()->GetSize() ; } - // Tells whether or not the string is empty - bool IsEmpty() const { return GetSize() == 0; } - - // Returns number of characters - size_t GetLength() const; - int GetLengthI() const { return (int)GetLength(); } - - // Returns character at the specified index - uint32_t GetCharAt(size_t index) const; - uint32_t GetFirstCharAt(size_t index, const char** offset) const; - uint32_t GetNextChar(const char** offset) const; - - // Appends a character - void AppendChar(uint32_t ch); - - // Append a string - void AppendString(const wchar_t* pstr, intptr_t len = -1); - void AppendString(const char* putf8str, intptr_t utf8StrSz = -1); - - // Assigned a string with dynamic data (copied through initializer). - void AssignString(const InitStruct& src, size_t size); - // Assigns string with known size. - void AssignString(const char* putf8str, size_t size); - - // Resize the string to the new size -// void Resize(size_t _size); - - // Removes the character at posAt - void Remove(size_t posAt, intptr_t len = 1); - - // Returns a String that's a substring of this. - // -start is the index of the first UTF8 character you want to include. - // -end is the index one past the last UTF8 character you want to include. - String Substring(size_t start, size_t end) const; - - // Case-conversion - String ToUpper() const; - String ToLower() const; - - // Inserts substr at posAt - String& Insert (const char* substr, size_t posAt, intptr_t len = -1); - - // Inserts character at posAt - size_t InsertCharAt(uint32_t c, size_t posAt); - - // Inserts substr at posAt, which is an index of a character (not byte). - // Of size is specified, it is in bytes. -// String& Insert(const uint32_t* substr, size_t posAt, intptr_t size = -1); - - // Get Byte index of the character at position = index - size_t GetByteIndex(size_t index) const { return (size_t)UTF8Util::GetByteIndex(index, GetData()->Data); } - - // Utility: case-insensitive string compare. stricmp() & strnicmp() are not - // ANSI or POSIX, do not seem to appear in Linux. - static int OVR_STDCALL CompareNoCase(const char* a, const char* b); - static int OVR_STDCALL CompareNoCase(const char* a, const char* b, intptr_t len); - - // Hash function, case-insensitive - static size_t OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed = 5381); - - // Hash function, case-sensitive - static size_t OVR_STDCALL BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed = 5381); - - - // ***** File path parsing helper functions. - // Implemented in OVR_String_FilePath.cpp. - - // Absolute paths can star with: - // - protocols: 'file://', 'http://' - // - windows drive: 'c:\' - // - UNC share name: '\\share' - // - unix root '/' - static bool HasAbsolutePath(const char* path); - static bool HasExtension(const char* path); - static bool HasProtocol(const char* path); - - bool HasAbsolutePath() const { return HasAbsolutePath(ToCStr()); } - bool HasExtension() const { return HasExtension(ToCStr()); } - bool HasProtocol() const { return HasProtocol(ToCStr()); } - - String GetProtocol() const; // Returns protocol, if any, with trailing '://'. - String GetPath() const; // Returns path with trailing '/'. - String GetFilename() const; // Returns filename, including extension. - String GetExtension() const; // Returns extension with a dot. - - void StripProtocol(); // Strips front protocol, if any, from the string. - void StripExtension(); // Strips off trailing extension. - - - // Operators - // Assignment - void operator = (const char* str); - void operator = (const wchar_t* str); - void operator = (const String& src); - void operator = (const StringBuffer& src); - - // Addition - void operator += (const String& src); - void operator += (const char* psrc) { AppendString(psrc); } - void operator += (const wchar_t* psrc) { AppendString(psrc); } - void operator += (char ch) { AppendChar(ch); } - String operator + (const char* str) const; - String operator + (const String& src) const; - - // Comparison - bool operator == (const String& str) const - { - return (OVR_strcmp(GetData()->Data, str.GetData()->Data)== 0); - } - - bool operator != (const String& str) const - { - return !operator == (str); - } - - bool operator == (const char* str) const - { - return OVR_strcmp(GetData()->Data, str) == 0; - } - - bool operator != (const char* str) const - { - return !operator == (str); - } - - bool operator < (const char* pstr) const - { - return OVR_strcmp(GetData()->Data, pstr) < 0; - } - - bool operator < (const String& str) const - { - return *this < str.GetData()->Data; - } - - bool operator > (const char* pstr) const - { - return OVR_strcmp(GetData()->Data, pstr) > 0; - } - - bool operator > (const String& str) const - { - return *this > str.GetData()->Data; - } - - int CompareNoCase(const char* pstr) const - { - return CompareNoCase(GetData()->Data, pstr); - } - int CompareNoCase(const String& str) const - { - return CompareNoCase(GetData()->Data, str.ToCStr()); - } - - // Accesses raw bytes - const char& operator [] (int index) const - { - OVR_ASSERT(index >= 0 && (size_t)index < GetSize()); - return GetData()->Data[index]; - } - const char& operator [] (size_t index) const - { - OVR_ASSERT(index < GetSize()); - return GetData()->Data[index]; - } - - - // Case insensitive keys are used to look up insensitive string in hash tables - // for SWF files with version before SWF 7. - struct NoCaseKey - { - const String* pStr; - NoCaseKey(const String &str) : pStr(&str){}; - }; - - bool operator == (const NoCaseKey& strKey) const - { - return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0); - } - bool operator != (const NoCaseKey& strKey) const - { - return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0); - } - - // Hash functor used for strings. - struct HashFunctor - { - size_t operator()(const String& data) const - { - size_t size = data.GetSize(); - return String::BernsteinHashFunction((const char*)data, size); - } - }; - // Case-insensitive hash functor used for strings. Supports additional - // lookup based on NoCaseKey. - struct NoCaseHashFunctor - { - size_t operator()(const String& data) const - { - size_t size = data.GetSize(); - return String::BernsteinHashFunctionCIS((const char*)data, size); - } - size_t operator()(const NoCaseKey& data) const - { - size_t size = data.pStr->GetSize(); - return String::BernsteinHashFunctionCIS((const char*)data.pStr->ToCStr(), size); - } - }; - -}; - - -//----------------------------------------------------------------------------------- -// ***** String Buffer used for Building Strings - -class StringBuffer -{ - char* pData; - size_t Size; - size_t BufferSize; - size_t GrowSize; - mutable bool LengthIsSize; - -public: - - // Constructors / Destructor. - StringBuffer(); - explicit StringBuffer(size_t growSize); - StringBuffer(const char* data); - StringBuffer(const char* data, size_t buflen); - StringBuffer(const String& src); - StringBuffer(const StringBuffer& src); - explicit StringBuffer(const wchar_t* data); - ~StringBuffer(); - - - // Modify grow size used for growing/shrinking the buffer. - size_t GetGrowSize() const { return GrowSize; } - void SetGrowSize(size_t growSize); - - - // *** General Functions - // Does not release memory, just sets Size to 0 - void Clear(); - - // For casting to a pointer to char. - operator const char*() const { return (pData) ? pData : ""; } - // Pointer to raw buffer. - const char* ToCStr() const { return (pData) ? pData : ""; } - - // Returns number of bytes. - size_t GetSize() const { return Size ; } - // Tells whether or not the string is empty. - bool IsEmpty() const { return GetSize() == 0; } - - // Returns number of characters - size_t GetLength() const; - - // Returns character at the specified index - uint32_t GetCharAt(size_t index) const; - uint32_t GetFirstCharAt(size_t index, const char** offset) const; - uint32_t GetNextChar(const char** offset) const; - - - // Resize the string to the new size - void Resize(size_t _size); - void Reserve(size_t _size); - - // Appends a character - void AppendChar(uint32_t ch); - - // Append a string - void AppendString(const wchar_t* pstr, intptr_t len = -1); - void AppendString(const char* putf8str, intptr_t utf8StrSz = -1); - void AppendFormat(const char* format, ...); - - // Assigned a string with dynamic data (copied through initializer). - //void AssignString(const InitStruct& src, size_t size); - - // Inserts substr at posAt - void Insert (const char* substr, size_t posAt, intptr_t len = -1); - // Inserts character at posAt - size_t InsertCharAt(uint32_t c, size_t posAt); - - // Assignment - void operator = (const char* str); - void operator = (const wchar_t* str); - void operator = (const String& src); - void operator = (const StringBuffer& src); - - // Addition - void operator += (const String& src) { AppendString(src.ToCStr(),src.GetSize()); } - void operator += (const char* psrc) { AppendString(psrc); } - void operator += (const wchar_t* psrc) { AppendString(psrc); } - void operator += (char ch) { AppendChar(ch); } - //String operator + (const char* str) const ; - //String operator + (const String& src) const ; - - // Accesses raw bytes - char& operator [] (int index) - { - OVR_ASSERT(((size_t)index) < GetSize()); - return pData[index]; - } - char& operator [] (size_t index) - { - OVR_ASSERT(index < GetSize()); - return pData[index]; - } - - const char& operator [] (int index) const - { - OVR_ASSERT(((size_t)index) < GetSize()); - return pData[index]; - } - const char& operator [] (size_t index) const - { - OVR_ASSERT(index < GetSize()); - return pData[index]; - } -}; - - -// -// Wrapper for string data. The data must have a guaranteed -// lifespan throughout the usage of the wrapper. Not intended for -// cached usage. Not thread safe. -// -class StringDataPtr -{ -public: - StringDataPtr() : pStr(NULL), Size(0) {} - StringDataPtr(const StringDataPtr& p) - : pStr(p.pStr), Size(p.Size) {} - StringDataPtr(const char* pstr, size_t sz) - : pStr(pstr), Size(sz) {} - StringDataPtr(const char* pstr) - : pStr(pstr), Size((pstr != NULL) ? OVR_strlen(pstr) : 0) {} - explicit StringDataPtr(const String& str) - : pStr(str.ToCStr()), Size(str.GetSize()) {} - template - StringDataPtr(const T (&v)[N]) - : pStr(v), Size(N) {} - -public: - const char* ToCStr() const { return pStr; } - size_t GetSize() const { return Size; } - bool IsEmpty() const { return GetSize() == 0; } - - // value is a prefix of this string - // Character's values are not compared. - bool IsPrefix(const StringDataPtr& value) const - { - return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize(); - } - // value is a suffix of this string - // Character's values are not compared. - bool IsSuffix(const StringDataPtr& value) const - { - return ToCStr() <= value.ToCStr() && (End()) == (value.End()); - } - - // Find first character. - // init_ind - initial index. - intptr_t FindChar(char c, size_t init_ind = 0) const - { - for (size_t i = init_ind; i < GetSize(); ++i) - if (pStr[i] == c) - return static_cast(i); - - return -1; - } - - // Find last character. - // init_ind - initial index. - intptr_t FindLastChar(char c, size_t init_ind = ~0) const - { - if (init_ind == (size_t)~0 || init_ind > GetSize()) - init_ind = GetSize(); - else - ++init_ind; - - for (size_t i = init_ind; i > 0; --i) - if (pStr[i - 1] == c) - return static_cast(i - 1); - - return -1; - } - - // Create new object and trim size bytes from the left. - StringDataPtr GetTrimLeft(size_t size) const - { - // Limit trim size to the size of the string. - size = Alg::PMin(GetSize(), size); - - return StringDataPtr(ToCStr() + size, GetSize() - size); - } - // Create new object and trim size bytes from the right. - StringDataPtr GetTrimRight(size_t size) const - { - // Limit trim to the size of the string. - size = Alg::PMin(GetSize(), size); - - return StringDataPtr(ToCStr(), GetSize() - size); - } - - // Create new object, which contains next token. - // Useful for parsing. - StringDataPtr GetNextToken(char separator = ':') const - { - size_t cur_pos = 0; - const char* cur_str = ToCStr(); - - for (; cur_pos < GetSize() && cur_str[cur_pos]; ++cur_pos) - { - if (cur_str[cur_pos] == separator) - { - break; - } - } - - return StringDataPtr(ToCStr(), cur_pos); - } - - // Trim size bytes from the left. - StringDataPtr& TrimLeft(size_t size) - { - // Limit trim size to the size of the string. - size = Alg::PMin(GetSize(), size); - pStr += size; - Size -= size; - - return *this; - } - // Trim size bytes from the right. - StringDataPtr& TrimRight(size_t size) - { - // Limit trim to the size of the string. - size = Alg::PMin(GetSize(), size); - Size -= size; - - return *this; - } - - const char* Begin() const { return ToCStr(); } - const char* End() const { return ToCStr() + GetSize(); } - - // Hash functor used string data pointers - struct HashFunctor - { - size_t operator()(const StringDataPtr& data) const - { - return String::BernsteinHashFunction(data.ToCStr(), data.GetSize()); - } - }; - - bool operator== (const StringDataPtr& data) const - { - return (OVR_strncmp(pStr, data.pStr, data.Size) == 0); - } - -protected: - const char* pStr; - size_t Size; -}; - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_StringHash.h b/LibOVR/Src/Kernel/OVR_StringHash.h deleted file mode 100644 index 410a578..0000000 --- a/LibOVR/Src/Kernel/OVR_StringHash.h +++ /dev/null @@ -1,100 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_StringHash.h -Content : String hash table used when optional case-insensitive - lookup is required. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_StringHash_h -#define OVR_StringHash_h - -#include "OVR_String.h" -#include "OVR_Hash.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// *** StringHash - -// This is a custom string hash table that supports case-insensitive -// searches through special functions such as GetCaseInsensitive, etc. -// This class is used for Flash labels, exports and other case-insensitive tables. - -template > -class StringHash : public Hash -{ -public: - typedef U ValueType; - typedef StringHash SelfType; - typedef Hash BaseType; - -public: - - void operator = (const SelfType& src) { BaseType::operator = (src); } - - bool GetCaseInsensitive(const String& key, U* pvalue) const - { - String::NoCaseKey ikey(key); - return BaseType::GetAlt(ikey, pvalue); - } - // Pointer-returning get variety. - const U* GetCaseInsensitive(const String& key) const - { - String::NoCaseKey ikey(key); - return BaseType::GetAlt(ikey); - } - U* GetCaseInsensitive(const String& key) - { - String::NoCaseKey ikey(key); - return BaseType::GetAlt(ikey); - } - - - typedef typename BaseType::Iterator base_iterator; - - base_iterator FindCaseInsensitive(const String& key) - { - String::NoCaseKey ikey(key); - return BaseType::FindAlt(ikey); - } - - // Set just uses a find and assigns value if found. The key is not modified; - // this behavior is identical to Flash string variable assignment. - void SetCaseInsensitive(const String& key, const U& value) - { - base_iterator it = FindCaseInsensitive(key); - if (it != BaseType::End()) - { - it->Second = value; - } - else - { - BaseType::Add(key, value); - } - } -}; - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp b/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp deleted file mode 100644 index d52b6bb..0000000 --- a/LibOVR/Src/Kernel/OVR_String_FormatUtil.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************************ - -Filename : OVR_String_FormatUtil.cpp -Content : String format functions. -Created : February 27, 2013 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_String.h" -#include "OVR_Log.h" - -namespace OVR { - -void StringBuffer::AppendFormat(const char* format, ...) -{ - va_list argList; - char buffer[512]; - char* bufferUsed = buffer; - char* bufferAllocated = NULL; - - va_start(argList, format); - - #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. - va_list argListSaved; - va_copy(argListSaved, argList); - #endif - - int requiredStrlen = OVR_vsnprintf(bufferUsed, OVR_ARRAY_COUNT(buffer), format, argList); // The large majority of the time this will succeed. - - if(requiredStrlen >= (int)sizeof(buffer)) // If the initial capacity wasn't enough... - { - bufferAllocated = (char*)OVR_ALLOC(sizeof(char) * (requiredStrlen + 1)); - bufferUsed = bufferAllocated; - if(bufferAllocated) - { - #if !defined(OVR_CC_MSVC) - va_end(argList); - va_copy(argList, argListSaved); - #endif - requiredStrlen = OVR_vsnprintf(bufferAllocated, (requiredStrlen + 1), format, argList); - } - } - - if(requiredStrlen < 0) // If there was a printf format error... - { - bufferUsed = NULL; - } - - va_end(argList); - - if(bufferUsed) - AppendString(bufferUsed); - - if(bufferAllocated) - OVR_FREE(bufferAllocated); -} - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp b/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp deleted file mode 100644 index 95f3de9..0000000 --- a/LibOVR/Src/Kernel/OVR_String_PathUtil.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/************************************************************************************ - -Filename : OVR_String_PathUtil.cpp -Content : String filename/url helper function -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_String.h" -#include "OVR_UTF8Util.h" - -namespace OVR { - -//-------------------------------------------------------------------- -// ***** Path-Scanner helper function - -// Scans file path finding filename start and extension start, fills in their addess. -void ScanFilePath(const char* url, const char** pfilename, const char** pext) -{ - const char* urlStart = url; - const char *filename = 0; - const char *lastDot = 0; - - uint32_t charVal = UTF8Util::DecodeNextChar(&url); - - while (charVal != 0) - { - if ((charVal == '/') || (charVal == '\\')) - { - filename = url; - lastDot = 0; - } - else if (charVal == '.') - { - lastDot = url - 1; - } - - charVal = UTF8Util::DecodeNextChar(&url); - } - - if (pfilename) - { - // It was a naked filename - if (urlStart && (*urlStart != '.') && *urlStart) - *pfilename = urlStart; - else - *pfilename = filename; - } - - if (pext) - { - *pext = lastDot; - } -} - -// Scans till the end of protocol. Returns first character past protocol, -// 0 if not found. -// - protocol: 'file://', 'http://' -const char* ScanPathProtocol(const char* url) -{ - uint32_t charVal = UTF8Util::DecodeNextChar(&url); - uint32_t charVal2; - - while (charVal != 0) - { - // Treat a colon followed by a slash as absolute. - if (charVal == ':') - { - charVal2 = UTF8Util::DecodeNextChar(&url); - charVal = UTF8Util::DecodeNextChar(&url); - if ((charVal == '/') && (charVal2 == '\\')) - return url; - } - charVal = UTF8Util::DecodeNextChar(&url); - } - return 0; -} - - -//-------------------------------------------------------------------- -// ***** String Path API implementation - -bool String::HasAbsolutePath(const char* url) -{ - // Absolute paths can star with: - // - protocols: 'file://', 'http://' - // - windows drive: 'c:\' - // - UNC share name: '\\share' - // - unix root '/' - - // On the other hand, relative paths are: - // - directory: 'directory/file' - // - this directory: './file' - // - parent directory: '../file' - // - // For now, we don't parse '.' or '..' out, but instead let it be concatenated - // to string and let the OS figure it out. This, however, is not good for file - // name matching in library/etc, so it should be improved. - - if (!url || !*url) - return true; // Treat empty strings as absolute. - - uint32_t charVal = UTF8Util::DecodeNextChar(&url); - - // Fist character of '/' or '\\' means absolute url. - if ((charVal == '/') || (charVal == '\\')) - return true; - - while (charVal != 0) - { - // Treat a colon followed by a slash as absolute. - if (charVal == ':') - { - charVal = UTF8Util::DecodeNextChar(&url); - // Protocol or windows drive. Absolute. - if ((charVal == '/') || (charVal == '\\')) - return true; - } - else if ((charVal == '/') || (charVal == '\\')) - { - // Not a first character (else 'if' above the loop would have caught it). - // Must be a relative url. - break; - } - - charVal = UTF8Util::DecodeNextChar(&url); - } - - // We get here for relative paths. - return false; -} - - -bool String::HasExtension(const char* path) -{ - const char* ext = 0; - ScanFilePath(path, 0, &ext); - return ext != 0; -} -bool String::HasProtocol(const char* path) -{ - return ScanPathProtocol(path) != 0; -} - - -String String::GetPath() const -{ - const char* filename = 0; - ScanFilePath(ToCStr(), &filename, 0); - - // Technically we can have extra logic somewhere for paths, - // such as enforcing protocol and '/' only based on flags, - // but we keep it simple for now. - return String(ToCStr(), filename ? (filename-ToCStr()) : GetSize()); -} - -String String::GetProtocol() const -{ - const char* protocolEnd = ScanPathProtocol(ToCStr()); - return String(ToCStr(), protocolEnd ? (protocolEnd-ToCStr()) : 0); -} - -String String::GetFilename() const -{ - const char* filename = 0; - ScanFilePath(ToCStr(), &filename, 0); - return String(filename); -} -String String::GetExtension() const -{ - const char* ext = 0; - ScanFilePath(ToCStr(), 0, &ext); - return String(ext); -} - -void String::StripExtension() -{ - const char* ext = 0; - ScanFilePath(ToCStr(), 0, &ext); - if (ext) - { - *this = String(ToCStr(), ext-ToCStr()); - } -} - -void String::StripProtocol() -{ - const char* protocol = ScanPathProtocol(ToCStr()); - if (protocol) - AssignString(protocol, OVR_strlen(protocol)); -} - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_SysFile.cpp b/LibOVR/Src/Kernel/OVR_SysFile.cpp deleted file mode 100644 index 6ef27c7..0000000 --- a/LibOVR/Src/Kernel/OVR_SysFile.cpp +++ /dev/null @@ -1,138 +0,0 @@ -/************************************************************************** - -Filename : OVR_SysFile.cpp -Content : File wrapper class implementation (Win32) - -Created : April 5, 1999 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -**************************************************************************/ - -#define GFILE_CXX - -// Standard C library (Captain Obvious guarantees!) -#include - -#include "OVR_SysFile.h" -#include "OVR_Log.h" - -namespace OVR { - -// This is - a dummy file that fails on all calls. - -class UnopenedFile : public File -{ -public: - UnopenedFile() { } - ~UnopenedFile() { } - - virtual const char* GetFilePath() { return 0; } - - // ** File Information - virtual bool IsValid() { return 0; } - virtual bool IsWritable() { return 0; } - - // Return position / file size - virtual int Tell() { return 0; } - virtual int64_t LTell() { return 0; } - virtual int GetLength() { return 0; } - virtual int64_t LGetLength() { return 0; } - -// virtual bool Stat(FileStats *pfs) { return 0; } - virtual int GetErrorCode() { return Error_FileNotFound; } - - // ** Stream implementation & I/O - virtual int Write(const uint8_t * /*pbuffer*/, int /*numBytes*/) { return -1; } - virtual int Read(uint8_t * /*pbuffer*/, int /*numBytes*/) { return -1; } - virtual int SkipBytes(int /*numBytes*/) { return 0; } - virtual int BytesAvailable() { return 0; } - virtual bool Flush() { return 0; } - virtual int Seek(int /*offset*/, int /*origin*/) { return -1; } - virtual int64_t LSeek(int64_t /*offset*/, int /*origin*/) { return -1; } - - virtual int CopyFromStream(File * /*pstream*/, int /*byteSize*/) { return -1; } - virtual bool Close() { return 0; } -}; - - - -// ***** System File - -// System file is created to access objects on file system directly -// This file can refer directly to path - -// ** Constructor -SysFile::SysFile() : DelegatedFile(0) -{ - pFile = *new UnopenedFile; -} - -Ptr FileFILEOpen(const String& path, int flags, int mode); - -// Opens a file -SysFile::SysFile(const String& path, int flags, int mode) : DelegatedFile(0) -{ - Open(path, flags, mode); -} - - -// ** Open & management -// Will fail if file's already open -bool SysFile::Open(const String& path, int flags, int mode) -{ - pFile = FileFILEOpen(path, flags, mode); - if ((!pFile) || (!pFile->IsValid())) - { - pFile = *new UnopenedFile; - OVR_DEBUG_LOG(("Failed to open file: %s", path.ToCStr())); - return 0; - } - //pFile = *OVR_NEW DelegatedFile(pFile); // MA Testing - if (flags & Open_Buffered) - pFile = *new BufferedFile(pFile); - return 1; -} - - -// ** Overrides - -int SysFile::GetErrorCode() -{ - return pFile ? pFile->GetErrorCode() : Error_FileNotFound; -} - - -// Overrides to provide re-open support -bool SysFile::IsValid() -{ - return pFile && pFile->IsValid(); -} -bool SysFile::Close() -{ - if (IsValid()) - { - DelegatedFile::Close(); - pFile = *new UnopenedFile; - return 1; - } - return 0; -} - -} // OVR diff --git a/LibOVR/Src/Kernel/OVR_SysFile.h b/LibOVR/Src/Kernel/OVR_SysFile.h deleted file mode 100644 index 925c51d..0000000 --- a/LibOVR/Src/Kernel/OVR_SysFile.h +++ /dev/null @@ -1,104 +0,0 @@ -/************************************************************************************ - -PublicHeader: Kernel -Filename : OVR_SysFile.h -Content : Header for all internal file management - functions and structures - to be inherited by OS specific subclasses. -Created : September 19, 2012 -Notes : - -Notes : errno may not be preserved across use of GBaseFile member functions - : Directories cannot be deleted while files opened from them are in use - (For the GetFullName function) - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_SysFile_h -#define OVR_SysFile_h - -#include "OVR_File.h" - -namespace OVR { - -// ***** Declared classes -class SysFile; - -//----------------------------------------------------------------------------------- -// *** File Statistics - -// This class contents are similar to _stat, providing -// creation, modify and other information about the file. -struct FileStat -{ - // No change or create time because they are not available on most systems - int64_t ModifyTime; - int64_t AccessTime; - int64_t FileSize; - - bool operator== (const FileStat& stat) const - { - return ( (ModifyTime == stat.ModifyTime) && - (AccessTime == stat.AccessTime) && - (FileSize == stat.FileSize) ); - } -}; - -//----------------------------------------------------------------------------------- -// *** System File - -// System file is created to access objects on file system directly -// This file can refer directly to path. -// System file can be open & closed several times; however, such use is not recommended -// This class is realy a wrapper around an implementation of File interface for a -// particular platform. - -class SysFile : public DelegatedFile -{ -protected: - SysFile(const SysFile &source) : DelegatedFile () { OVR_UNUSED(source); } -public: - - // ** Constructor - SysFile(); - // Opens a file - SysFile(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite); - - // ** Open & management - bool Open(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite); - - OVR_FORCE_INLINE bool Create(const String& path, int mode = Mode_ReadWrite) - { return Open(path, Open_ReadWrite|Open_Create, mode); } - - // Helper function: obtain file statistics information. In OVR, this is used to detect file changes. - // Return 0 if function failed, most likely because the file doesn't exist. - static bool OVR_CDECL GetFileStat(FileStat* pfileStats, const String& path); - - // ** Overrides - // Overridden to provide re-open support - virtual int GetErrorCode(); - - virtual bool IsValid(); - - virtual bool Close(); -}; - -} // Namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_System.cpp b/LibOVR/Src/Kernel/OVR_System.cpp deleted file mode 100644 index 66c764a..0000000 --- a/LibOVR/Src/Kernel/OVR_System.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/************************************************************************************ - -Filename : OVR_System.cpp -Content : General kernel initialization/cleanup, including that - of the memory allocator. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_System.h" -#include "OVR_Threads.h" -#include "OVR_Timer.h" -#include "../Displays/OVR_Display.h" -#ifdef OVR_OS_WIN32 -#include "../Displays/OVR_Win32_ShimFunctions.h" -#endif - -namespace OVR { - -#ifdef OVR_OS_WIN32 -extern bool anyRiftsInExtendedMode(); -#endif - -// Stack of destroy listeners (push/pop semantics) -static SystemSingletonInternal *SystemShutdownListenerStack = 0; -static Lock stackLock; -static bool DisplayShimInitialized = false; - -void SystemSingletonInternal::PushDestroyCallbacks() -{ - Lock::Locker locker(&stackLock); - - // Push listener onto the stack - NextSingleton = SystemShutdownListenerStack; - SystemShutdownListenerStack = this; -} - -void System::DirectDisplayInitialize() -{ -#ifdef OVR_OS_WIN32 - // Set up display code for Windows - Win32::DisplayShim::GetInstance(); - - // This code will look for the first display. If it's a display - // that's extending the destkop, the code will assume we're in - // compatibility mode. Compatibility mode prevents shim loading - // and renders only to extended Rifts. - // If we find a display and it's application exclusive, - // we load the shim so we can render to it. - // If no display is available, we revert to whatever the - // driver tells us we're in - - bool anyExtendedRifts = anyRiftsInExtendedMode() || Display::InCompatibilityMode( false ); - - DisplayShimInitialized = Win32::DisplayShim::GetInstance().Initialize(anyExtendedRifts); -#endif -} - -bool System::DirectDisplayEnabled() -{ - return DisplayShimInitialized; -} - -// Initializes System core, installing allocator. -void System::Init(Log* log, Allocator *palloc) -{ - if (!Allocator::GetInstance()) - { - Log::SetGlobalLog(log); - Timer::initializeTimerSystem(); - Allocator::setInstance(palloc); - Display::Initialize(); - DirectDisplayInitialize(); - } - else - { - OVR_DEBUG_LOG(("System::Init failed - duplicate call.")); - } -} - -void System::Destroy() -{ - if (Allocator::GetInstance()) - { -#ifdef OVR_OS_WIN32 - Win32::DisplayShim::GetInstance().Shutdown(); -#endif - - // Invoke all of the post-finish callbacks (normal case) - for (SystemSingletonInternal *listener = SystemShutdownListenerStack; listener; listener = listener->NextSingleton) - { - listener->OnThreadDestroy(); - } - -#ifdef OVR_ENABLE_THREADS - // Wait for all threads to finish; this must be done so that memory - // allocator and all destructors finalize correctly. - Thread::FinishAllThreads(); -#endif - - // Invoke all of the post-finish callbacks (normal case) - for (SystemSingletonInternal *next, *listener = SystemShutdownListenerStack; listener; listener = next) - { - next = listener->NextSingleton; - - listener->OnSystemDestroy(); - } - - SystemShutdownListenerStack = 0; - - // Shutdown heap and destroy SysAlloc singleton, if any. - Allocator::GetInstance()->onSystemShutdown(); - Allocator::setInstance(0); - - Timer::shutdownTimerSystem(); - Log::SetGlobalLog(Log::GetDefaultLog()); - } - else - { - OVR_DEBUG_LOG(("System::Destroy failed - System not initialized.")); - } -} - -// Returns 'true' if system was properly initialized. -bool System::IsInitialized() -{ - return Allocator::GetInstance() != 0; -} - - -} // namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_System.h b/LibOVR/Src/Kernel/OVR_System.h deleted file mode 100644 index 9d09911..0000000 --- a/LibOVR/Src/Kernel/OVR_System.h +++ /dev/null @@ -1,174 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_System.h -Content : General kernel initialization/cleanup, including that - of the memory allocator. -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_System_h -#define OVR_System_h - -#include "OVR_Allocator.h" -#include "OVR_Log.h" -#include "OVR_Atomic.h" - -namespace OVR { - - -//----------------------------------------------------------------------------- -// SystemSingleton - -// Subsystems are implemented using the Singleton pattern. -// To avoid code duplication in all the places where Singletons are defined, -// The pattern is defined once here and used everywhere. - -class SystemSingletonInternal -{ - friend class System; - - SystemSingletonInternal* NextSingleton; - - // No copying allowed - OVR_NON_COPYABLE(SystemSingletonInternal); - -protected: - SystemSingletonInternal() : - NextSingleton(0) - { - } - - virtual ~SystemSingletonInternal(){} - - // Call this to register the destroy events - // Destroy callbacks will be called in the reverse order they were registered - // Note: As a rule of thumb, call this at the end of the singleton class constructor. - void PushDestroyCallbacks(); - - // Required: Invoked when the System object is shutting down - // Called after threads are stopped - // Called before Log, Allocator, and Timer subsystems are stopped - // Listeners are called in the opposite order they were registered - virtual void OnSystemDestroy() = 0; - - // Called just before waiting for threads to die - // Listeners are called in the opposite order they were registered - // Useful to start terminating threads at the right time - // Note: The singleton must not delete itself here. - virtual void OnThreadDestroy() {} -}; - -// Singletons derive from this class -template -class SystemSingletonBase : public SystemSingletonInternal -{ - static AtomicPtr SingletonInstance; - static T* SlowGetInstance(); - -protected: - ~SystemSingletonBase() - { - // Make sure the instance gets set to zero on dtor - if (SingletonInstance == this) - SingletonInstance = 0; - } - -public: - static OVR_FORCE_INLINE T* GetInstance() - { - // Fast version - // Note: The singleton instance is stored in an AtomicPtr<> to allow it to be accessed - // atomically from multiple threads without locks. - T* instance = SingletonInstance; - return instance ? instance : SlowGetInstance(); - } -}; - -// For reference, see N3337 14.5.1.3 (Static data members of class templates): -template OVR::AtomicPtr OVR::SystemSingletonBase::SingletonInstance; - -// Place this in the singleton class in the header file -#define OVR_DECLARE_SINGLETON(T) \ - friend class OVR::SystemSingletonBase; \ -private: \ - T(); \ - virtual ~T(); \ - virtual void OnSystemDestroy(); - -// Place this in the singleton class source file -#define OVR_DEFINE_SINGLETON(T) \ - namespace OVR { \ - template<> T* SystemSingletonBase::SlowGetInstance() \ - { \ - static OVR::Lock lock; \ - OVR::Lock::Locker locker(&lock); \ - if (!SingletonInstance) SingletonInstance = new T; \ - return SingletonInstance; \ - } \ - } - - -// ***** System Core Initialization class - -// System initialization must take place before any other OVR_Kernel objects are used; -// this is done my calling System::Init(). Among other things, this is necessary to -// initialize the memory allocator. Similarly, System::Destroy must be -// called before program exist for proper cleanup. Both of these tasks can be achieved by -// simply creating System object first, allowing its constructor/destructor do the work. - -// TBD: Require additional System class for Oculus Rift API? - -class System -{ -public: - // System constructor expects allocator to be specified, if it is being substituted. - System(Log* log = Log::ConfigureDefaultLog(LogMask_Debug), - Allocator* palloc = DefaultAllocator::InitSystemSingleton()) - { - Init(log, palloc); - } - ~System() - { - Destroy(); - } - - static void OVR_CDECL DirectDisplayInitialize(); - static bool OVR_CDECL DirectDisplayEnabled(); - - // Returns 'true' if system was properly initialized. - static bool OVR_CDECL IsInitialized(); - - // Initializes System core. Users can override memory implementation by passing - // a different Allocator here. - static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug), - Allocator *palloc = DefaultAllocator::InitSystemSingleton()); - - // De-initializes System more, finalizing the threading system and destroying - // the global memory allocator. - static void OVR_CDECL Destroy(); -}; - - -} // namespace OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp deleted file mode 100644 index 90ba3cc..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.cpp +++ /dev/null @@ -1,401 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_ThreadCommandQueue.cpp -Content : Command queue for operations executed on a thread -Created : October 29, 2012 - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_ThreadCommandQueue.h" - -namespace OVR { - - -//------------------------------------------------------------------------ -// ***** CircularBuffer - -// CircularBuffer is a FIFO buffer implemented in a single block of memory, -// which allows writing and reading variable-size data chucks. Write fails -// if buffer is full. - -class CircularBuffer -{ - enum { - AlignSize = 16, - AlignMask = AlignSize - 1 - }; - - uint8_t* pBuffer; - size_t Size; - size_t Tail; // Byte offset of next item to be popped. - size_t Head; // Byte offset of where next push will take place. - size_t End; // When Head < Tail, this is used instead of Size. - - inline size_t roundUpSize(size_t size) - { return (size + AlignMask) & ~(size_t)AlignMask; } - -public: - - CircularBuffer(size_t size) - : Size(size), Tail(0), Head(0), End(0) - { - pBuffer = (uint8_t*)OVR_ALLOC_ALIGNED(roundUpSize(size), AlignSize); - } - ~CircularBuffer() - { - // For ThreadCommands, we must consume everything before shutdown. - OVR_ASSERT(IsEmpty()); - OVR_FREE_ALIGNED(pBuffer); - } - - bool IsEmpty() const { return (Head == Tail); } - - // Allocates a state block of specified size and advances pointers, - // returning 0 if buffer is full. - uint8_t* Write(size_t size); - - // Returns a pointer to next available data block; 0 if none available. - uint8_t* ReadBegin() - { return (Head != Tail) ? (pBuffer + Tail) : 0; } - // Consumes data of specified size; this must match size passed to Write. - void ReadEnd(size_t size); -}; - - -// Allocates a state block of specified size and advances pointers, -// returning 0 if buffer is full. -uint8_t* CircularBuffer::Write(size_t size) -{ - uint8_t* p = 0; - - size = roundUpSize(size); - // Since this is circular buffer, always allow at least one item. - OVR_ASSERT(size < Size/2); - - if (Head >= Tail) - { - OVR_ASSERT(End == 0); - - if (size <= (Size - Head)) - { - p = pBuffer + Head; - Head += size; - } - else if (size < Tail) - { - p = pBuffer; - End = Head; - Head = size; - OVR_ASSERT(Head != Tail); - } - } - else - { - OVR_ASSERT(End != 0); - - if ((Tail - Head) > size) - { - p = pBuffer + Head; - Head += size; - OVR_ASSERT(Head != Tail); - } - } - - return p; -} - -void CircularBuffer::ReadEnd(size_t size) -{ - OVR_ASSERT(Head != Tail); - size = roundUpSize(size); - - Tail += size; - if (Tail == End) - { - Tail = End = 0; - } - else if (Tail == Head) - { - OVR_ASSERT(End == 0); - Tail = Head = 0; - } -} - - -//------------------------------------------------------------------------------------- -// ***** ThreadCommand - -ThreadCommand::PopBuffer::~PopBuffer() -{ - if (Size) { - Destruct(toCommand()); - } -} - -void ThreadCommand::PopBuffer::InitFromBuffer(void* data) -{ - ThreadCommand* cmd = (ThreadCommand*)data; - OVR_ASSERT(cmd->Size <= MaxSize); - - if (Size) { - Destruct(toCommand()); - } - Size = cmd->Size; - memcpy(Buffer, (void*)cmd, Size); -} - -void ThreadCommand::PopBuffer::Execute() -{ - ThreadCommand* command = toCommand(); - OVR_ASSERT(command); - command->Execute(); - if (NeedsWait()) { - GetEvent()->PulseEvent(); - } -} - -//------------------------------------------------------------------------------------- - -class ThreadCommandQueueImpl : public NewOverrideBase -{ - typedef ThreadCommand::NotifyEvent NotifyEvent; - friend class ThreadCommandQueue; - -public: - - ThreadCommandQueueImpl(ThreadCommandQueue* queue) : - pQueue(queue), - ExitEnqueued(false), - ExitProcessed(false), - CommandBuffer(2048), - PullThreadId(0) - { - } - ~ThreadCommandQueueImpl(); - - - bool PushCommand(const ThreadCommand& command); - bool PopCommand(ThreadCommand::PopBuffer* popBuffer); - - - // ExitCommand is used by notify us that Thread is shutting down. - struct ExitCommand : public ThreadCommand - { - ThreadCommandQueueImpl* pImpl; - - ExitCommand(ThreadCommandQueueImpl* impl, bool wait) - : ThreadCommand(sizeof(ExitCommand), wait, true), pImpl(impl) { } - - virtual void Execute() const - { - Lock::Locker lock(&pImpl->QueueLock); - pImpl->ExitProcessed = true; - } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct(p, *this); } - }; - - - NotifyEvent* AllocNotifyEvent_NTS() - { - NotifyEvent* p = AvailableEvents.GetFirst(); - - if (!AvailableEvents.IsNull(p)) - p->RemoveNode(); - else - p = new NotifyEvent; - return p; - } - - void FreeNotifyEvent_NTS(NotifyEvent* p) - { - AvailableEvents.PushBack(p); - } - - void FreeNotifyEvents_NTS() - { - while(!AvailableEvents.IsEmpty()) - { - NotifyEvent* p = AvailableEvents.GetFirst(); - p->RemoveNode(); - delete p; - } - } - - ThreadCommandQueue* pQueue; - Lock QueueLock; - volatile bool ExitEnqueued; - volatile bool ExitProcessed; - List AvailableEvents; - List BlockedProducers; - CircularBuffer CommandBuffer; - - // The pull thread id is set to the last thread that pulled commands. - // Since this thread command queue is designed for a single thread, - // reentrant behavior that would cause a dead-lock for messages that - // wait for completion can be avoided by simply comparing the - // thread id of the last pull. - OVR::ThreadId PullThreadId; -}; - -ThreadCommandQueueImpl::~ThreadCommandQueueImpl() -{ - Lock::Locker lock(&QueueLock); - OVR_ASSERT(BlockedProducers.IsEmpty()); - FreeNotifyEvents_NTS(); -} - -bool ThreadCommandQueueImpl::PushCommand(const ThreadCommand& command) -{ - if (command.NeedsWait() && PullThreadId == OVR::GetCurrentThreadId()) - { - command.Execute(); - return true; - } - - ThreadCommand::NotifyEvent* completeEvent = 0; - ThreadCommand::NotifyEvent* queueAvailableEvent = 0; - - // Repeat writing command into buffer until it is available. - for (;;) { - { // Lock Scope - Lock::Locker lock(&QueueLock); - - if (queueAvailableEvent) { - FreeNotifyEvent_NTS(queueAvailableEvent); - queueAvailableEvent = 0; - } - - // Don't allow any commands after PushExitCommand() is called. - if (ExitEnqueued && !command.ExitFlag) { - return false; - } - - bool bufferWasEmpty = CommandBuffer.IsEmpty(); - uint8_t* buffer = CommandBuffer.Write(command.GetSize()); - - if (buffer) { - ThreadCommand* c = command.CopyConstruct(buffer); - - if (c->NeedsWait()) { - completeEvent = c->pEvent = AllocNotifyEvent_NTS(); - } - - // Signal-waker consumer when we add data to buffer. - if (bufferWasEmpty) { - pQueue->OnPushNonEmpty_Locked(); - } - - break; - } - - queueAvailableEvent = AllocNotifyEvent_NTS(); - BlockedProducers.PushBack(queueAvailableEvent); - } // Lock Scope - - queueAvailableEvent->Wait(); - } // Intentional infinite loop - - // Command was enqueued, wait if necessary. - if (completeEvent) { - completeEvent->Wait(); - Lock::Locker lock(&QueueLock); - FreeNotifyEvent_NTS(completeEvent); - } - - return true; -} - - -// Pops the next command from the thread queue, if any is available. -bool ThreadCommandQueueImpl::PopCommand(ThreadCommand::PopBuffer* popBuffer) -{ - PullThreadId = OVR::GetCurrentThreadId(); - - Lock::Locker lock(&QueueLock); - - uint8_t* buffer = CommandBuffer.ReadBegin(); - if (!buffer) - { - // Notify thread while in lock scope, enabling initialization of wait. - pQueue->OnPopEmpty_Locked(); - return false; - } - - popBuffer->InitFromBuffer(buffer); - CommandBuffer.ReadEnd(popBuffer->GetSize()); - - if (!BlockedProducers.IsEmpty()) - { - ThreadCommand::NotifyEvent* queueAvailableEvent = BlockedProducers.GetFirst(); - queueAvailableEvent->RemoveNode(); - queueAvailableEvent->PulseEvent(); - // Event is freed later by waiter. - } - return true; -} - - -//------------------------------------------------------------------------------------- - -ThreadCommandQueue::ThreadCommandQueue() -{ - pImpl = new ThreadCommandQueueImpl(this); -} -ThreadCommandQueue::~ThreadCommandQueue() -{ - delete pImpl; -} - -bool ThreadCommandQueue::PushCommand(const ThreadCommand& command) -{ - return pImpl->PushCommand(command); -} - -bool ThreadCommandQueue::PopCommand(ThreadCommand::PopBuffer* popBuffer) -{ - return pImpl->PopCommand(popBuffer); -} - -void ThreadCommandQueue::PushExitCommand(bool wait) -{ - // Exit is processed in two stages: - // - First, ExitEnqueued flag is set to block further commands from queuing up. - // - Second, the actual exit call is processed on the consumer thread, flushing - // any prior commands. - // IsExiting() only returns true after exit has flushed. - { - Lock::Locker lock(&pImpl->QueueLock); - if (pImpl->ExitEnqueued) - return; - pImpl->ExitEnqueued = true; - } - - PushCommand(ThreadCommandQueueImpl::ExitCommand(pImpl, wait)); -} - -bool ThreadCommandQueue::IsExiting() const -{ - return pImpl->ExitProcessed; -} - - -} // namespace OVR diff --git a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h b/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h deleted file mode 100644 index 9c2a7d3..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadCommandQueue.h +++ /dev/null @@ -1,318 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_ThreadCommandQueue.h -Content : Command queue for operations executed on a thread -Created : October 29, 2012 -Author : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_ThreadCommandQueue_h -#define OVR_ThreadCommandQueue_h - -#include "../Kernel/OVR_Types.h" -#include "../Kernel/OVR_List.h" -#include "../Kernel/OVR_Atomic.h" -#include "../Kernel/OVR_Threads.h" - -namespace OVR { - -class ThreadCommand; -class ThreadCommandQueue; - - -//------------------------------------------------------------------------------------- -// ***** ThreadCommand - -// ThreadCommand is a base class implementation for commands stored in ThreadCommandQueue. -class ThreadCommand -{ -public: - // NotifyEvent is used by ThreadCommandQueue::PushCallAndWait to notify the - // calling (producer) thread when command is completed or queue slot is available. - class NotifyEvent : public ListNode, public NewOverrideBase - { - Event E; - public: - NotifyEvent() { } - - void Wait() { E.Wait(); } - void PulseEvent() { E.PulseEvent(); } - }; - - // ThreadCommand::PopBuffer is temporary storage for a command popped off - // by ThreadCommandQueue::PopCommand. - class PopBuffer - { - enum { MaxSize = 256 }; - - size_t Size; - union { - uint8_t Buffer[MaxSize]; - size_t Align; - }; - - ThreadCommand* toCommand() const { return (ThreadCommand*)Buffer; } - - public: - PopBuffer() : Size(0) { } - ~PopBuffer(); - - void InitFromBuffer(void* data); - - bool HasCommand() const { return Size != 0; } - size_t GetSize() const { return Size; } - bool NeedsWait() const { return toCommand()->NeedsWait(); } - NotifyEvent* GetEvent() const { return toCommand()->pEvent; } - - // Execute the command and also notifies caller to finish waiting, - // if necessary. - void Execute(); - }; - - uint16_t Size; - bool WaitFlag; - bool ExitFlag; // Marks the last exit command. - NotifyEvent* pEvent; - - ThreadCommand(size_t size, bool waitFlag, bool exitFlag = false) - : Size((uint16_t)size), WaitFlag(waitFlag), ExitFlag(exitFlag), pEvent(0) { } - virtual ~ThreadCommand() { } - - bool NeedsWait() const { return WaitFlag; } - size_t GetSize() const { return Size; } - - virtual void Execute() const = 0; - // Copy constructor used for serializing this to memory buffer. - virtual ThreadCommand* CopyConstruct(void* p) const = 0; -}; - - -//------------------------------------------------------------------------------------- - -// CleanType is a template that strips 'const' and '&' modifiers from the argument type; -// for example, typename CleanType::Type is equivalent to A. -template struct CleanType { typedef T Type; }; -template struct CleanType { typedef T Type; }; -template struct CleanType { typedef T Type; }; -template struct CleanType { typedef T Type; }; - -// SelfType is a template that yields the argument type. This helps avoid conflicts with -// automatic template argument deduction for function calls when identical argument -// is already defined. -template struct SelfType { typedef T Type; }; - - - -//------------------------------------------------------------------------------------- -// ThreadCommand specializations for member functions with different number of -// arguments and argument types. - -// Used to return nothing from a ThreadCommand, to avoid problems with 'void'. -struct Void -{ - Void() {} - Void(int) {} -}; - -// ThreadCommand for member function with 0 arguments. -template -class ThreadCommandMF0 : public ThreadCommand -{ - typedef R (C::*FnPtr)(); - C* pClass; - FnPtr pFn; - R* pRet; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)()) : - (void)(pClass->*pFn)(); - } - -public: - ThreadCommandMF0(C* pclass, FnPtr fn, R* ret, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF0), needsWait), - pClass(pclass), pFn(fn), pRet(ret) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct(p, *this); } -}; - - -// ThreadCommand for member function with 1 argument. -template -class ThreadCommandMF1 : public ThreadCommand -{ - typedef R (C::*FnPtr)(A0); - C* pClass; - FnPtr pFn; - R* pRet; - typename CleanType::Type AVal0; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)(AVal0)) : - (void)(pClass->*pFn)(AVal0); - } - -public: - ThreadCommandMF1(C* pclass, FnPtr fn, R* ret, A0 a0, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF1), needsWait), - pClass(pclass), pFn(fn), pRet(ret), AVal0(a0) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct(p, *this); } -}; - -// ThreadCommand for member function with 2 arguments. -template -class ThreadCommandMF2 : public ThreadCommand -{ - typedef R (C::*FnPtr)(A0, A1); - C* pClass; - FnPtr pFn; - R* pRet; - typename CleanType::Type AVal0; - typename CleanType::Type AVal1; - - void executeImpl() const - { - pRet ? (void)(*pRet = (pClass->*pFn)(AVal0, AVal1)) : - (void)(pClass->*pFn)(AVal0, AVal1); - } - -public: - ThreadCommandMF2(C* pclass, FnPtr fn, R* ret, A0 a0, A1 a1, bool needsWait) - : ThreadCommand(sizeof(ThreadCommandMF2), needsWait), - pClass(pclass), pFn(fn), pRet(ret), AVal0(a0), AVal1(a1) { } - - virtual void Execute() const { executeImpl(); } - virtual ThreadCommand* CopyConstruct(void* p) const - { return Construct(p, *this); } -}; - - -//------------------------------------------------------------------------------------- -// ***** ThreadCommandQueue - -// ThreadCommandQueue is a queue of executable function-call commands intended to be -// serviced by a single consumer thread. Commands are added to the queue with PushCall -// and removed with PopCall; they are processed in FIFO order. Multiple producer threads -// are supported and will be blocked if internal data buffer is full. - -class ThreadCommandQueue -{ -public: - - ThreadCommandQueue(); - virtual ~ThreadCommandQueue(); - - - // Pops the next command from the thread queue, if any is available. - // The command should be executed by calling popBuffer->Execute(). - // Returns 'false' if no command is available at the time of the call. - bool PopCommand(ThreadCommand::PopBuffer* popBuffer); - - // Generic implementaion of PushCommand; enqueues a command for execution. - // Returns 'false' if push failed, usually indicating thread shutdown. - bool PushCommand(const ThreadCommand& command); - - // - void PushExitCommand(bool wait); - - // Returns 'true' once ExitCommand has been processed, so the thread can shut down. - bool IsExiting() const; - - - // These two virtual functions serve as notifications for derived - // thread waiting. - virtual void OnPushNonEmpty_Locked() { } - virtual void OnPopEmpty_Locked() { } - - - // *** PushCall with no result - - // Enqueue a member function of 'this' class to be called on consumer thread. - // By default the function returns immediately; set 'wait' argument to 'true' to - // wait for completion. - template - bool PushCall(R (C::*fn)(), bool wait = false) - { return PushCommand(ThreadCommandMF0(static_cast(this), fn, 0, wait)); } - template - bool PushCall(R (C::*fn)(A0), typename SelfType::Type a0, bool wait = false) - { return PushCommand(ThreadCommandMF1(static_cast(this), fn, 0, a0, wait)); } - template - bool PushCall(R (C::*fn)(A0, A1), - typename SelfType::Type a0, typename SelfType::Type a1, bool wait = false) - { return PushCommand(ThreadCommandMF2(static_cast(this), fn, 0, a0, a1, wait)); } - // Enqueue a specified member function call of class C. - // By default the function returns immediately; set 'wait' argument to 'true' to - // wait for completion. - template - bool PushCall(C* p, R (C::*fn)(), bool wait = false) - { return PushCommand(ThreadCommandMF0(p, fn, 0, wait)); } - template - bool PushCall(C* p, R (C::*fn)(A0), typename SelfType::Type a0, bool wait = false) - { return PushCommand(ThreadCommandMF1(p, fn, 0, a0, wait)); } - template - bool PushCall(C* p, R (C::*fn)(A0, A1), - typename SelfType::Type a0, typename SelfType::Type a1, bool wait = false) - { return PushCommand(ThreadCommandMF2(p, fn, 0, a0, a1, wait)); } - - - // *** PushCall with Result - - // Enqueue a member function of 'this' class call and wait for call to complete - // on consumer thread before returning. - template - bool PushCallAndWaitResult(R (C::*fn)(), R* ret) - { return PushCommand(ThreadCommandMF0(static_cast(this), fn, ret, true)); } - template - bool PushCallAndWaitResult(R (C::*fn)(A0), R* ret, typename SelfType::Type a0) - { return PushCommand(ThreadCommandMF1(static_cast(this), fn, ret, a0, true)); } - template - bool PushCallAndWaitResult(R (C::*fn)(A0, A1), R* ret, - typename SelfType::Type a0, typename SelfType::Type a1) - { return PushCommand(ThreadCommandMF2(static_cast(this), fn, ret, a0, a1, true)); } - // Enqueue a member function call for class C and wait for the call to complete - // on consumer thread before returning. - template - bool PushCallAndWaitResult(C* p, R (C::*fn)(), R* ret) - { return PushCommand(ThreadCommandMF0(p, fn, ret, true)); } - template - bool PushCallAndWaitResult(C* p, R (C::*fn)(A0), R* ret, typename SelfType::Type a0) - { return PushCommand(ThreadCommandMF1(p, fn, ret, a0, true)); } - template - bool PushCallAndWaitResult(C* p, R (C::*fn)(A0, A1), R* ret, - typename SelfType::Type a0, typename SelfType::Type a1) - { return PushCommand(ThreadCommandMF2(p, fn, ret, a0, a1, true)); } - -private: - class ThreadCommandQueueImpl* pImpl; -}; - - -} // namespace OVR - -#endif // OVR_ThreadCommandQueue_h diff --git a/LibOVR/Src/Kernel/OVR_Threads.h b/LibOVR/Src/Kernel/OVR_Threads.h deleted file mode 100644 index e159157..0000000 --- a/LibOVR/Src/Kernel/OVR_Threads.h +++ /dev/null @@ -1,434 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_Threads.h -Content : Contains thread-related (safe) functionality -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ -#ifndef OVR_Threads_h -#define OVR_Threads_h - -#include "OVR_Types.h" -#include "OVR_Atomic.h" -#include "OVR_RefCount.h" -#include "OVR_Array.h" - -// Defines the infinite wait delay timeout -#define OVR_WAIT_INFINITE 0xFFFFFFFF - -// To be defined in the project configuration options -#ifdef OVR_ENABLE_THREADS - - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ****** Declared classes - -// Declared with thread support only -class Mutex; -class WaitCondition; -class Event; -// Implementation forward declarations -class MutexImpl; -class WaitConditionImpl; - - - -//----------------------------------------------------------------------------------- -// ***** Mutex - -// Mutex class represents a system Mutex synchronization object that provides access -// serialization between different threads, allowing one thread mutually exclusive access -// to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition. - -class Mutex -{ - friend class WaitConditionImpl; - friend class MutexImpl; - - MutexImpl *pImpl; - -public: - // Constructor/destructor - Mutex(bool recursive = 1); - ~Mutex(); - - // Locking functions - void DoLock(); - bool TryLock(); - void Unlock(); - - // Returns 1 if the mutes is currently locked by another thread - // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. - bool IsLockedByAnotherThread(); - - // Locker class; Used for automatic locking of a mutex withing scope - class Locker - { - public: - Mutex *pMutex; - Locker(Mutex *pmutex) - { pMutex = pmutex; pMutex->DoLock(); } - ~Locker() - { pMutex->Unlock(); } - }; -}; - - -//----------------------------------------------------------------------------------- -// ***** WaitCondition - -/* - WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor. - Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that - call Notify() or NotifyAll(). - - The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then - starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same - resource, this ensures that any condition checked for while the mutex was locked does not change before - the wait on the condition is actually initiated. -*/ - -class WaitCondition -{ - friend class WaitConditionImpl; - // Internal implementation structure - WaitConditionImpl *pImpl; - -public: - // Constructor/destructor - WaitCondition(); - ~WaitCondition(); - - // Release mutex and wait for condition. The mutex is re-aquired after the wait. - // Delay is specified in milliseconds (1/1000 of a second). - bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE); - - // Notify a condition, releasing at one object waiting - void Notify(); - // Notify a condition, releasing all objects waiting - void NotifyAll(); -}; - - -//----------------------------------------------------------------------------------- -// ***** Event - -// Event is a wait-able synchronization object similar to Windows event. -// Event can be waited on until it's signaled by another thread calling -// either SetEvent or PulseEvent. - -class Event -{ - // Event state, its mutex and the wait condition - volatile bool State; - volatile bool Temporary; - mutable Mutex StateMutex; - WaitCondition StateWaitCondition; - - void updateState(bool newState, bool newTemp, bool mustNotify); - -public: - Event(bool setInitially = 0) : State(setInitially), Temporary(false) { } - ~Event() { } - - // Wait on an event condition until it is set - // Delay is specified in milliseconds (1/1000 of a second). - bool Wait(unsigned delay = OVR_WAIT_INFINITE); - - // Set an event, releasing objects waiting on it - void SetEvent() - { updateState(true, false, true); } - - // Reset an event, un-signaling it - void ResetEvent() - { updateState(false, false, false); } - - // Set and then reset an event once a waiter is released. - // If threads are already waiting, they will be notified and released - // If threads are not waiting, the event is set until the first thread comes in - void PulseEvent() - { updateState(true, true, true); } -}; - - -//----------------------------------------------------------------------------------- -// ***** Thread class - -// ThreadHandle is a handle to a thread, which on some platforms (e.g. Windows) is -// different from ThreadId. On Unix platforms, a ThreadHandle is the same as a -// ThreadId and is pthread_t. -typedef void* ThreadHandle; - -// ThreadId uniquely identifies a thread; returned by Windows GetCurrentThreadId(), -// Unix pthread_self() and Thread::GetThreadId. -typedef void* ThreadId; - - -// *** Thread flags - -// Indicates that the thread is has been started, i.e. Start method has been called, and threads -// OnExit() method has not yet been called/returned. -#define OVR_THREAD_STARTED 0x01 -// This flag is set once the thread has ran, and finished. -#define OVR_THREAD_FINISHED 0x02 -// This flag is set temporarily if this thread was started suspended. It is used internally. -#define OVR_THREAD_START_SUSPENDED 0x08 -// This flag is used to ask a thread to exit. Message driven threads will usually check this flag -// and finish once it is set. -#define OVR_THREAD_EXIT 0x10 - - -class Thread : public RefCountBase -{ // NOTE: Waitable must be the first base since it implements RefCountImpl. -public: - // *** Callback functions, can be used instead of overriding Run - - // Run function prototypes. - // Thread function and user handle passed to it, executed by the default - // Thread::Run implementation if not null. - typedef int (*ThreadFn)(Thread *pthread, void* h); - - // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried - ThreadFn ThreadFunction; - // User handle passes to a thread - void* UserHandle; - - // Thread state to start a thread with - enum ThreadState - { - NotRunning = 0, - Running = 1, - Suspended = 2 - }; - - // Thread priority - enum ThreadPriority - { - CriticalPriority, - HighestPriority, - AboveNormalPriority, - NormalPriority, - BelowNormalPriority, - LowestPriority, - IdlePriority, - }; - - // Thread constructor parameters - struct CreateParams - { - CreateParams(ThreadFn func = 0, void* hand = 0, size_t ssize = 128 * 1024, - int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority) - : threadFunction(func), userHandle(hand), stackSize(ssize), - processor(proc), initialState(state), priority(prior) {} - ThreadFn threadFunction; // Thread function - void* userHandle; // User handle passes to a thread - size_t stackSize; // Thread stack size - int processor; // Thread hardware processor - ThreadState initialState; // - ThreadPriority priority; // Thread priority - }; - - - // *** Constructors - - // A default constructor always creates a thread in NotRunning state, because - // the derived class has not yet been initialized. The derived class can call Start explicitly. - // "processor" parameter specifies which hardware processor this thread will be run on. - // -1 means OS decides this. Implemented only on Win32 - Thread(size_t stackSize = 128 * 1024, int processor = -1); - // Constructors that initialize the thread with a pointer to function. - // An option to start a thread is available, but it should not be used if classes are derived from Thread. - // "processor" parameter specifies which hardware processor this thread will be run on. - // -1 means OS decides this. Implemented only on Win32 - Thread(ThreadFn threadFunction, void* userHandle = 0, size_t stackSize = 128 * 1024, - int processor = -1, ThreadState initialState = NotRunning); - // Constructors that initialize the thread with a create parameters structure. - explicit Thread(const CreateParams& params); - - // Destructor. - virtual ~Thread(); - - // Waits for all Threads to finish; should be called only from the root - // application thread. Once this function returns, we know that all other - // thread's references to Thread object have been released. - static void OVR_CDECL FinishAllThreads(); - - - // *** Overridable Run function for thread processing - - // - returning from this method will end the execution of the thread - // - return value is usually 0 for success - virtual int Run(); - // Called after return/exit function - virtual void OnExit(); - - - // *** Thread management - - // Starts the thread if its not already running - // - internally sets up the threading and calls Run() - // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing - // - returns the exit code - virtual bool Start(ThreadState initialState = Running); - - // Quits with an exit code - virtual void Exit(int exitCode=0); - - // Suspend the thread until resumed - // Returns 1 for success, 0 for failure. - bool Suspend(); - // Resumes currently suspended thread - // Returns 1 for success, 0 for failure. - bool Resume(); - - // Static function to return a pointer to the current thread - //static Thread* GetThread(); - - - // *** Thread status query functions - - bool GetExitFlag() const; - void SetExitFlag(bool exitFlag); - - // Determines whether the thread was running and is now finished - bool IsFinished() const; - // Determines if the thread is currently suspended - bool IsSuspended() const; - // Returns current thread state - ThreadState GetThreadState() const; - - // Wait for thread to finish for a maxmimum number of milliseconds - // For maxWaitMs = 0 it simply polls and then returns if the thread is not finished - // For maxWaitMs < 0 it will wait forever - bool Join(int maxWaitMs = -1) const; - - // Returns the number of available CPUs on the system - static int GetCPUCount(); - - // Returns the thread exit code. Exit code is initialized to 0, - // and set to the return value if Run function after the thread is finished. - inline int GetExitCode() const { return ExitCode; } - // Returns an OS handle -#if defined(OVR_OS_MS) - void* GetOSHandle() const { return ThreadHandle; } -#else - pthread_t GetOSHandle() const { return ThreadHandle; } -#endif - -#if defined(OVR_OS_MS) - ThreadId GetThreadId() const { return IdValue; } -#else - ThreadId GetThreadId() const { return (ThreadId)GetOSHandle(); } -#endif - - // Returns the platform-specific equivalent const that corresponds to the given ThreadPriority. - static int GetOSPriority(ThreadPriority); - static ThreadPriority GetOVRPriority(int osPriority); // May return a value outside the ThreadPriority enum range in unusual cases. - - // Gets this instance's priority. - ThreadPriority GetPriority(); - - // Gets the current thread's priority. - static ThreadPriority GetCurrentPriority(); - - // Sets this instance's thread's priority. - // Some platforms (e.g. Unix) don't let you set thread priorities unless you have root privileges/ - bool SetPriority(ThreadPriority); - - // Sets the current thread's priority. - static bool SetCurrentPriority(ThreadPriority); - - // *** Sleep - - // Sleep secs seconds - static bool Sleep(unsigned secs); - // Sleep msecs milliseconds - static bool MSleep(unsigned msecs); - - - // *** Debugging functionality - virtual void SetThreadName(const char* name); - static void SetThreadName(const char* name, ThreadId threadId); - static void SetCurrentThreadName(const char* name); - - static void GetThreadName(char* name, size_t nameCapacity, ThreadId threadId); - static void GetCurrentThreadName(char* name, size_t nameCapacity); - -private: -#if defined(OVR_OS_WIN32) - friend unsigned WINAPI Thread_Win32StartFn(void *phandle); -#elif defined(OVR_OS_MS) // Any other Microsoft OS... - friend DWORD WINAPI Thread_Win32StartFn(void *phandle); -#else - friend void *Thread_PthreadStartFn(void * phandle); - - static int InitAttr; - static pthread_attr_t Attr; -#endif - -protected: - // Thread state flags - AtomicInt ThreadFlags; - AtomicInt SuspendCount; - size_t StackSize; - - // Hardware processor which this thread is running on. - int Processor; - ThreadPriority Priority; - -#if defined(OVR_OS_MS) - void* ThreadHandle; - volatile ThreadId IdValue; - - // System-specific cleanup function called from destructor - void CleanupSystemThread(); - -#else - pthread_t ThreadHandle; -#endif - - // Exit code of the thread, as returned by Run. - int ExitCode; - - // Internal run function. - int PRun(); - // Finishes the thread and releases internal reference to it. - void FinishAndRelease(); - - void Init(const CreateParams& params); - - // Protected copy constructor - Thread(const Thread &source) : RefCountBase() { OVR_UNUSED(source); } - -}; - -// Returns the unique Id of a thread it is called on, intended for -// comparison purposes. -ThreadId GetCurrentThreadId(); - - -} // OVR - -#endif // OVR_ENABLE_THREADS -#endif // OVR_Threads_h diff --git a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp b/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp deleted file mode 100644 index 760e489..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadsPthread.cpp +++ /dev/null @@ -1,984 +0,0 @@ -/************************************************************************************ - -Filename : OVR_ThreadsPthread.cpp -Content : -Created : -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Threads.h" -#include "OVR_Hash.h" - -#ifdef OVR_ENABLE_THREADS - -#include "OVR_Timer.h" -#include "OVR_Log.h" - -#include -#include -#include -#include -#include -#include - -#if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) - #include - #include - #if !defined(OVR_OS_MAC) - #include - #endif -#endif - - - -namespace OVR { - -// ***** Mutex implementation - - -// *** Internal Mutex implementation structure - -class MutexImpl : public NewOverrideBase -{ - // System mutex or semaphore - pthread_mutex_t SMutex; - bool Recursive; - unsigned LockCount; - pthread_t LockedBy; - - friend class WaitConditionImpl; - -public: - // Constructor/destructor - MutexImpl(Mutex* pmutex, bool recursive = 1); - ~MutexImpl(); - - // Locking functions - void DoLock(); - bool TryLock(); - void Unlock(Mutex* pmutex); - // Returns 1 if the mutes is currently locked - bool IsLockedByAnotherThread(Mutex* pmutex); - bool IsSignaled() const; -}; - -pthread_mutexattr_t Lock::RecursiveAttr; -bool Lock::RecursiveAttrInit = 0; - -// *** Constructor/destructor -MutexImpl::MutexImpl(Mutex* pmutex, bool recursive) -{ - OVR_UNUSED(pmutex); - Recursive = recursive; - LockCount = 0; - - if (Recursive) - { - if (!Lock::RecursiveAttrInit) - { - pthread_mutexattr_init(&Lock::RecursiveAttr); - pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE); - Lock::RecursiveAttrInit = 1; - } - - pthread_mutex_init(&SMutex, &Lock::RecursiveAttr); - } - else - pthread_mutex_init(&SMutex, 0); -} - -MutexImpl::~MutexImpl() -{ - pthread_mutex_destroy(&SMutex); -} - - -// Lock and try lock -void MutexImpl::DoLock() -{ - while (pthread_mutex_lock(&SMutex)) - ; - LockCount++; - LockedBy = pthread_self(); -} - -bool MutexImpl::TryLock() -{ - if (!pthread_mutex_trylock(&SMutex)) - { - LockCount++; - LockedBy = pthread_self(); - return 1; - } - - return 0; -} - -void MutexImpl::Unlock(Mutex* pmutex) -{ - OVR_UNUSED(pmutex); - OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0); - - //unsigned lockCount; - LockCount--; - //lockCount = LockCount; - - pthread_mutex_unlock(&SMutex); -} - -bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex) -{ - OVR_UNUSED(pmutex); - // There could be multiple interpretations of IsLocked with respect to current thread - if (LockCount == 0) - return 0; - if (pthread_self() != LockedBy) - return 1; - return 0; -} - -bool MutexImpl::IsSignaled() const -{ - // An mutex is signaled if it is not locked ANYWHERE - // Note that this is different from IsLockedByAnotherThread function, - // that takes current thread into account - return LockCount == 0; -} - - -// *** Actual Mutex class implementation - -Mutex::Mutex(bool recursive) -{ - // NOTE: RefCount mode already thread-safe for all waitables. - pImpl = new MutexImpl(this, recursive); -} - -Mutex::~Mutex() -{ - delete pImpl; -} - -// Lock and try lock -void Mutex::DoLock() -{ - pImpl->DoLock(); -} -bool Mutex::TryLock() -{ - return pImpl->TryLock(); -} -void Mutex::Unlock() -{ - pImpl->Unlock(this); -} -bool Mutex::IsLockedByAnotherThread() -{ - return pImpl->IsLockedByAnotherThread(this); -} - - - -//----------------------------------------------------------------------------------- -// ***** Event - -bool Event::Wait(unsigned delay) -{ - Mutex::Locker lock(&StateMutex); - - // Do the correct amount of waiting - if (delay == OVR_WAIT_INFINITE) - { - while(!State) - StateWaitCondition.Wait(&StateMutex); - } - else if (delay) - { - if (!State) - StateWaitCondition.Wait(&StateMutex, delay); - } - - bool state = State; - // Take care of temporary 'pulsing' of a state - if (Temporary) - { - Temporary = false; - State = false; - } - return state; -} - -void Event::updateState(bool newState, bool newTemp, bool mustNotify) -{ - Mutex::Locker lock(&StateMutex); - State = newState; - Temporary = newTemp; - if (mustNotify) - StateWaitCondition.NotifyAll(); -} - - - -// ***** Wait Condition Implementation - -// Internal implementation class -class WaitConditionImpl : public NewOverrideBase -{ - pthread_mutex_t SMutex; - pthread_cond_t Condv; - -public: - - // Constructor/destructor - WaitConditionImpl(); - ~WaitConditionImpl(); - - // Release mutex and wait for condition. The mutex is re-aqured after the wait. - bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE); - - // Notify a condition, releasing at one object waiting - void Notify(); - // Notify a condition, releasing all objects waiting - void NotifyAll(); -}; - - -WaitConditionImpl::WaitConditionImpl() -{ - pthread_mutex_init(&SMutex, 0); - pthread_cond_init(&Condv, 0); -} - -WaitConditionImpl::~WaitConditionImpl() -{ - pthread_mutex_destroy(&SMutex); - pthread_cond_destroy(&Condv); -} - -bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay) -{ - bool result = 1; - unsigned lockCount = pmutex->pImpl->LockCount; - - // Mutex must have been locked - if (lockCount == 0) - return 0; - - pthread_mutex_lock(&SMutex); - - // Finally, release a mutex or semaphore - if (pmutex->pImpl->Recursive) - { - // Release the recursive mutex N times - pmutex->pImpl->LockCount = 0; - for(unsigned i=0; ipImpl->SMutex); - } - else - { - pmutex->pImpl->LockCount = 0; - pthread_mutex_unlock(&pmutex->pImpl->SMutex); - } - - // Note that there is a gap here between mutex.Unlock() and Wait(). - // The other mutex protects this gap. - - if (delay == OVR_WAIT_INFINITE) - pthread_cond_wait(&Condv,&SMutex); - else - { - timespec ts; - - struct timeval tv; - gettimeofday(&tv, 0); - - ts.tv_sec = tv.tv_sec + (delay / 1000); - ts.tv_nsec = (tv.tv_usec + (delay % 1000) * 1000) * 1000; - - if (ts.tv_nsec > 999999999) - { - ts.tv_sec++; - ts.tv_nsec -= 1000000000; - } - int r = pthread_cond_timedwait(&Condv,&SMutex, &ts); - OVR_ASSERT(r == 0 || r == ETIMEDOUT); - if (r) - result = 0; - } - - pthread_mutex_unlock(&SMutex); - - // Re-aquire the mutex - for(unsigned i=0; iDoLock(); - - // Return the result - return result; -} - -// Notify a condition, releasing the least object in a queue -void WaitConditionImpl::Notify() -{ - pthread_mutex_lock(&SMutex); - pthread_cond_signal(&Condv); - pthread_mutex_unlock(&SMutex); -} - -// Notify a condition, releasing all objects waiting -void WaitConditionImpl::NotifyAll() -{ - pthread_mutex_lock(&SMutex); - pthread_cond_broadcast(&Condv); - pthread_mutex_unlock(&SMutex); -} - - - -// *** Actual implementation of WaitCondition - -WaitCondition::WaitCondition() -{ - pImpl = new WaitConditionImpl; -} -WaitCondition::~WaitCondition() -{ - delete pImpl; -} - -bool WaitCondition::Wait(Mutex *pmutex, unsigned delay) -{ - return pImpl->Wait(pmutex, delay); -} -// Notification -void WaitCondition::Notify() -{ - pImpl->Notify(); -} -void WaitCondition::NotifyAll() -{ - pImpl->NotifyAll(); -} - - -// ***** Current thread - -// Per-thread variable -/* -static __thread Thread* pCurrentThread = 0; - -// Static function to return a pointer to the current thread -void Thread::InitCurrentThread(Thread *pthread) -{ - pCurrentThread = pthread; -} - -// Static function to return a pointer to the current thread -Thread* Thread::GetThread() -{ - return pCurrentThread; -} -*/ - - -// *** Thread constructors. - -Thread::Thread(UPInt stackSize, int processor) -{ - // NOTE: RefCount mode already thread-safe for all Waitable objects. - CreateParams params; - params.stackSize = stackSize; - params.processor = processor; - Init(params); -} - -Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, UPInt stackSize, - int processor, Thread::ThreadState initialState) -{ - CreateParams params(threadFunction, userHandle, stackSize, processor, initialState); - Init(params); -} - -Thread::Thread(const CreateParams& params) -{ - Init(params); -} - -void Thread::Init(const CreateParams& params) -{ - // Clear the variables - ThreadFlags = 0; - ThreadHandle = 0; - ExitCode = 0; - SuspendCount = 0; - StackSize = params.stackSize; - Processor = params.processor; - Priority = params.priority; - - // Clear Function pointers - ThreadFunction = params.threadFunction; - UserHandle = params.userHandle; - if (params.initialState != NotRunning) - Start(params.initialState); -} - -Thread::~Thread() -{ - // Thread should not running while object is being destroyed, - // this would indicate ref-counting issue. - //OVR_ASSERT(IsRunning() == 0); - - // Clean up thread. - ThreadHandle = 0; -} - - - -// *** Overridable User functions. - -// Default Run implementation -int Thread::Run() -{ - // Call pointer to function, if available. - return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0; -} -void Thread::OnExit() -{ -} - - -// Finishes the thread and releases internal reference to it. -void Thread::FinishAndRelease() -{ - // Note: thread must be US. - ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED); - ThreadFlags |= OVR_THREAD_FINISHED; - - // Release our reference; this is equivalent to 'delete this' - // from the point of view of our thread. - Release(); -} - - - -// *** ThreadList - used to track all created threads - -class ThreadList : public NewOverrideBase -{ - //------------------------------------------------------------------------ - struct ThreadHashOp - { - size_t operator()(const Thread* ptr) - { - return (((size_t)ptr) >> 6) ^ (size_t)ptr; - } - }; - - HashSet ThreadSet; - Mutex ThreadMutex; - WaitCondition ThreadsEmpty; - // Track the root thread that created us. - pthread_t RootThreadId; - - static ThreadList* volatile pRunningThreads; - - void addThread(Thread *pthread) - { - Mutex::Locker lock(&ThreadMutex); - ThreadSet.Add(pthread); - } - - void removeThread(Thread *pthread) - { - Mutex::Locker lock(&ThreadMutex); - ThreadSet.Remove(pthread); - if (ThreadSet.GetSize() == 0) - ThreadsEmpty.Notify(); - } - - void finishAllThreads() - { - // Only original root thread can call this. - OVR_ASSERT(pthread_self() == RootThreadId); - - Mutex::Locker lock(&ThreadMutex); - while (ThreadSet.GetSize() != 0) - ThreadsEmpty.Wait(&ThreadMutex); - } - -public: - - ThreadList() - { - RootThreadId = pthread_self(); - } - ~ThreadList() { } - - - static void AddRunningThread(Thread *pthread) - { - // Non-atomic creation ok since only the root thread - if (!pRunningThreads) - { - pRunningThreads = new ThreadList; - OVR_ASSERT(pRunningThreads); - } - pRunningThreads->addThread(pthread); - } - - // NOTE: 'pthread' might be a dead pointer when this is - // called so it should not be accessed; it is only used - // for removal. - static void RemoveRunningThread(Thread *pthread) - { - OVR_ASSERT(pRunningThreads); - pRunningThreads->removeThread(pthread); - } - - static void FinishAllThreads() - { - // This is ok because only root thread can wait for other thread finish. - if (pRunningThreads) - { - pRunningThreads->finishAllThreads(); - delete pRunningThreads; - pRunningThreads = 0; - } - } -}; - -// By default, we have no thread list. -ThreadList* volatile ThreadList::pRunningThreads = 0; - - -// FinishAllThreads - exposed publicly in Thread. -void Thread::FinishAllThreads() -{ - ThreadList::FinishAllThreads(); -} - -// *** Run override - -int Thread::PRun() -{ - // Suspend us on start, if requested - if (ThreadFlags & OVR_THREAD_START_SUSPENDED) - { - Suspend(); - ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED; - } - - // Call the virtual run function - ExitCode = Run(); - return ExitCode; -} - - - - -// *** User overridables - -bool Thread::GetExitFlag() const -{ - return (ThreadFlags & OVR_THREAD_EXIT) != 0; -} - -void Thread::SetExitFlag(bool exitFlag) -{ - // The below is atomic since ThreadFlags is AtomicInt. - if (exitFlag) - ThreadFlags |= OVR_THREAD_EXIT; - else - ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT; -} - - -// Determines whether the thread was running and is now finished -bool Thread::IsFinished() const -{ - return (ThreadFlags & OVR_THREAD_FINISHED) != 0; -} -// Determines whether the thread is suspended -bool Thread::IsSuspended() const -{ - return SuspendCount > 0; -} -// Returns current thread state -Thread::ThreadState Thread::GetThreadState() const -{ - if (IsSuspended()) - return Suspended; - if (ThreadFlags & OVR_THREAD_STARTED) - return Running; - return NotRunning; -} - -// Join thread -bool Thread::Join(int maxWaitMs) const -{ - // If polling, - if (maxWaitMs == 0) - { - // Just return if finished - return IsFinished(); - } - // If waiting forever, - else if (maxWaitMs > 0) - { - UInt32 t0 = Timer::GetTicksMs(); - - while (!IsFinished()) - { - UInt32 t1 = Timer::GetTicksMs(); - - // If the wait has expired, - int delta = (int)(t1 - t0); - if (delta >= maxWaitMs) - { - return false; - } - - Thread::MSleep(10); - } - - return true; - } - else - { - while (!IsFinished()) - { - pthread_join(ThreadHandle, NULL); - } - } - - return true; -} - -/* -static const char* mapsched_policy(int policy) -{ - switch(policy) - { - case SCHED_OTHER: - return "SCHED_OTHER"; - case SCHED_RR: - return "SCHED_RR"; - case SCHED_FIFO: - return "SCHED_FIFO"; - - } - return "UNKNOWN"; -} - int policy; - sched_param sparam; - pthread_getschedparam(pthread_self(), &policy, &sparam); - int max_prior = sched_get_priority_max(policy); - int min_prior = sched_get_priority_min(policy); - printf(" !!!! policy: %s, priority: %d, max priority: %d, min priority: %d\n", mapsched_policy(policy), sparam.sched_priority, max_prior, min_prior); -#include -*/ -// ***** Thread management - -// The actual first function called on thread start -void* Thread_PthreadStartFn(void* phandle) -{ - Thread* pthread = (Thread*)phandle; - int result = pthread->PRun(); - // Signal the thread as done and release it atomically. - pthread->FinishAndRelease(); - // At this point Thread object might be dead; however we can still pass - // it to RemoveRunningThread since it is only used as a key there. - ThreadList::RemoveRunningThread(pthread); - return reinterpret_cast(result); -} - -int Thread::InitAttr = 0; -pthread_attr_t Thread::Attr; - -/* static */ -int Thread::GetOSPriority(ThreadPriority p) -{ - OVR_UNUSED(p); - return -1; -} - -/* static */ -Thread::ThreadPriority Thread::GetOVRPriority(int osPriority) -{ - #if defined(OVR_OS_LINUX) - return (ThreadPriority)(Thread::NormalPriority - osPriority); // This works for both SCHED_OTHER, SCHED_RR, and SCHED_FIFO. - #else - // Apple priorities are such that the min is a value less than the max. - static int minPriority = sched_get_priority_min(SCHED_FIFO); // We don't have a means to pass a policy type to this function. - static int maxPriority = sched_get_priority_max(SCHED_FIFO); - - return (ThreadPriority)(Thread::NormalPriority - (osPriority - ((minPriority + maxPriority) / 2))); - #endif -} - - -Thread::ThreadPriority Thread::GetPriority() -{ - int policy; - sched_param param; - - int result = pthread_getschedparam(ThreadHandle, &policy, ¶m); - - if(result == 0) - { - #if !defined(OVR_OS_LINUX) - if(policy == SCHED_OTHER) - { - return Thread::NormalPriority; //SCHED_OTHER allows only normal priority on BSD-style Unix and Mac OS X. - } - #endif - - return GetOVRPriority(param.sched_priority); - } - - return Thread::NormalPriority; -} - -/* static */ -Thread::ThreadPriority Thread::GetCurrentPriority() -{ - int policy; - sched_param param; - pthread_t currentThreadId = pthread_self(); - - int result = pthread_getschedparam(currentThreadId, &policy, ¶m); - - if(result == 0) - { - #if !defined(OVR_OS_LINUX) - if(policy == SCHED_OTHER) - { - return Thread::NormalPriority; //SCHED_OTHER allows only normal priority on BSD-style Unix and Mac OS X. - } - #endif - - return GetOVRPriority(param.sched_priority); - } - - return Thread::NormalPriority; -} - - -bool Thread::SetPriority(ThreadPriority) -{ - // We currently fail. To do: add code to support this via pthread_getschedparam/pthread_attr_setschedparam - // This won't work unless using SCHED_FIFO or SCHED_RR anyway, which require root privileges. - return false; -} - -/* static */ -bool Thread::SetCurrentPriority(ThreadPriority) -{ - // We currently fail. To do: add code to support this via pthread_getschedparam/pthread_attr_setschedparam - // This won't work unless using SCHED_FIFO or SCHED_RR anyway, which require root privileges. - return false; -} - -bool Thread::Start(ThreadState initialState) -{ - if (initialState == NotRunning) - return 0; - if (GetThreadState() != NotRunning) - { - OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this)); - return 0; - } - - if (!InitAttr) - { - pthread_attr_init(&Attr); - pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&Attr, 128 * 1024); - sched_param sparam; - sparam.sched_priority = Thread::GetOSPriority(NormalPriority); - pthread_attr_setschedparam(&Attr, &sparam); - InitAttr = 1; - } - - ExitCode = 0; - SuspendCount = 0; - ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED; - - // AddRef to us until the thread is finished - AddRef(); - ThreadList::AddRunningThread(this); - - int result; - if (StackSize != 128 * 1024 || Priority != NormalPriority) - { - pthread_attr_t attr; - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setstacksize(&attr, StackSize); - sched_param sparam; - sparam.sched_priority = Thread::GetOSPriority(Priority); - pthread_attr_setschedparam(&attr, &sparam); - result = pthread_create(&ThreadHandle, &attr, Thread_PthreadStartFn, this); - pthread_attr_destroy(&attr); - } - else - result = pthread_create(&ThreadHandle, &Attr, Thread_PthreadStartFn, this); - - if (result) - { - ThreadFlags = 0; - Release(); - ThreadList::RemoveRunningThread(this); - return 0; - } - return 1; -} - - -// Suspend the thread until resumed -bool Thread::Suspend() -{ - OVR_DEBUG_LOG(("Thread::Suspend - cannot suspend threads on this system")); - return 0; -} - -// Resumes currently suspended thread -bool Thread::Resume() -{ - return 0; -} - - -// Quits with an exit code -void Thread::Exit(int exitCode) -{ - // Can only exist the current thread - // if (GetThread() != this) - // return; - - // Call the virtual OnExit function - OnExit(); - - // Signal this thread object as done and release it's references. - FinishAndRelease(); - ThreadList::RemoveRunningThread(this); - - pthread_exit(reinterpret_cast(exitCode)); -} - -ThreadId GetCurrentThreadId() -{ - return (void*)pthread_self(); -} - -// *** Sleep functions - -/* static */ -bool Thread::Sleep(unsigned secs) -{ - sleep(secs); - return 1; -} -/* static */ -bool Thread::MSleep(unsigned msecs) -{ - usleep(msecs*1000); - return 1; -} - -/* static */ -int Thread::GetCPUCount() -{ - #if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) - // http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man3/sysctlbyname.3.html - int cpuCount = 0; - size_t len = sizeof(cpuCount); - - if(sysctlbyname("hw.logicalcpu", &cpuCount, &len, NULL, 0) != 0) - cpuCount = 1; - - return cpuCount; - - #else // Linux, Android - - // Alternative: read /proc/cpuinfo - #ifdef _SC_NPROCESSORS_ONLN - return (int)sysconf(_SC_NPROCESSORS_ONLN); - #else - return 1; - #endif - #endif -} - - -void Thread::SetThreadName( const char* name ) -{ - #if defined (OVR_OS_APPLE) - if(ThreadHandle == pthread_self()) - pthread_setname_np(name); - // Else there's nothing we can do. - #else - if(ThreadHandle != 0) - pthread_setname_np(ThreadHandle, name); - // Else we can possibly save this name and set it later when the thread starts. - #endif -} - - -void Thread::SetThreadName(const char* name, ThreadId threadId) -{ - #if defined (OVR_OS_APPLE) - if(pthread_equal((pthread_t)threadId, pthread_self())) - pthread_setname_np(name); - // Else there's no way to set the name of another thread. - #else - pthread_setname_np((pthread_t)threadId, name); - #endif -} - - -void Thread::SetCurrentThreadName(const char* name) -{ - #if defined (OVR_OS_APPLE) - pthread_setname_np(name); - #else - pthread_setname_np(pthread_self(), name); - #endif -} - - -void Thread::GetThreadName(char* name, size_t nameCapacity, ThreadId threadId) -{ - name[0] = 0; - pthread_getname_np((pthread_t)threadId, name, nameCapacity); -} - - -void Thread::GetCurrentThreadName(char* name, size_t nameCapacity) -{ - name[0] = 0; - pthread_getname_np(pthread_self(), name, nameCapacity); -} - - -} // namespace OVR - -#endif // OVR_ENABLE_THREADS diff --git a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp b/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp deleted file mode 100644 index 4786435..0000000 --- a/LibOVR/Src/Kernel/OVR_ThreadsWinAPI.cpp +++ /dev/null @@ -1,1146 +0,0 @@ -/************************************************************************************ - -Filename : OVR_ThreadsWinAPI.cpp -Platform : WinAPI -Content : Windows specific thread-related (safe) functionality -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Threads.h" -#include "OVR_Hash.h" -#include "OVR_Log.h" -#include "OVR_Timer.h" - -#ifdef OVR_ENABLE_THREADS - -// For _beginthreadex / _endtheadex -#include - -namespace OVR { - - -//----------------------------------------------------------------------------------- -// *** Internal Mutex implementation class - -class MutexImpl : public NewOverrideBase -{ - // System mutex or semaphore - HANDLE hMutexOrSemaphore; - bool Recursive; - volatile unsigned LockCount; - - friend class WaitConditionImpl; - -public: - // Constructor/destructor - MutexImpl(bool recursive = 1); - ~MutexImpl(); - - // Locking functions - void DoLock(); - bool TryLock(); - void Unlock(Mutex* pmutex); - // Returns 1 if the mutes is currently locked - bool IsLockedByAnotherThread(Mutex* pmutex); -}; - -// *** Constructor/destructor -MutexImpl::MutexImpl(bool recursive) -{ - Recursive = recursive; - LockCount = 0; -#if defined(OVR_OS_WIN32) // Older versions of Windows don't support CreateSemaphoreEx, so stick with CreateSemaphore for portability. - hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphore(NULL, 1, 1, NULL); -#else - // No CreateSemaphore() call, so emulate it. - hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphoreEx(NULL, 1, 1, NULL, 0, SEMAPHORE_ALL_ACCESS); -#endif -} -MutexImpl::~MutexImpl() -{ - CloseHandle(hMutexOrSemaphore); -} - - -// Lock and try lock -void MutexImpl::DoLock() -{ - if (::WaitForSingleObject(hMutexOrSemaphore, INFINITE) != WAIT_OBJECT_0) - return; - LockCount++; -} - -bool MutexImpl::TryLock() -{ - DWORD ret; - if ((ret=::WaitForSingleObject(hMutexOrSemaphore, 0)) != WAIT_OBJECT_0) - return 0; - LockCount++; - return 1; -} - -void MutexImpl::Unlock(Mutex* pmutex) -{ - OVR_UNUSED(pmutex); - - unsigned lockCount; - LockCount--; - lockCount = LockCount; - - // Release mutex - if ((Recursive ? ReleaseMutex(hMutexOrSemaphore) : - ReleaseSemaphore(hMutexOrSemaphore, 1, NULL)) != 0) - { - // This used to call Wait handlers if lockCount == 0. - } -} - -bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex) -{ - // There could be multiple interpretations of IsLocked with respect to current thread - if (LockCount == 0) - return 0; - if (!TryLock()) - return 1; - Unlock(pmutex); - return 0; -} - -/* -bool MutexImpl::IsSignaled() const -{ - // An mutex is signaled if it is not locked ANYWHERE - // Note that this is different from IsLockedByAnotherThread function, - // that takes current thread into account - return LockCount == 0; -} -*/ - - -// *** Actual Mutex class implementation - -Mutex::Mutex(bool recursive) -{ - pImpl = new MutexImpl(recursive); -} -Mutex::~Mutex() -{ - delete pImpl; -} - -// Lock and try lock -void Mutex::DoLock() -{ - pImpl->DoLock(); -} -bool Mutex::TryLock() -{ - return pImpl->TryLock(); -} -void Mutex::Unlock() -{ - pImpl->Unlock(this); -} -bool Mutex::IsLockedByAnotherThread() -{ - return pImpl->IsLockedByAnotherThread(this); -} - -//----------------------------------------------------------------------------------- -// ***** Event - -bool Event::Wait(unsigned delay) -{ - Mutex::Locker lock(&StateMutex); - - // Do the correct amount of waiting - if (delay == OVR_WAIT_INFINITE) - { - while(!State) - StateWaitCondition.Wait(&StateMutex); - } - else if (delay) - { - if (!State) - StateWaitCondition.Wait(&StateMutex, delay); - } - - bool state = State; - // Take care of temporary 'pulsing' of a state - if (Temporary) - { - Temporary = false; - State = false; - } - return state; -} - -void Event::updateState(bool newState, bool newTemp, bool mustNotify) -{ - Mutex::Locker lock(&StateMutex); - State = newState; - Temporary = newTemp; - if (mustNotify) - StateWaitCondition.NotifyAll(); -} - - -//----------------------------------------------------------------------------------- -// ***** Win32 Wait Condition Implementation - -// Internal implementation class -class WaitConditionImpl : public NewOverrideBase -{ - // Event pool entries for extra events - struct EventPoolEntry : public NewOverrideBase - { - HANDLE hEvent; - EventPoolEntry *pNext; - EventPoolEntry *pPrev; - }; - - Lock WaitQueueLoc; - // Stores free events that can be used later - EventPoolEntry * pFreeEventList; - - // A queue of waiting objects to be signaled - EventPoolEntry* pQueueHead; - EventPoolEntry* pQueueTail; - - // Allocation functions for free events - EventPoolEntry* GetNewEvent(); - void ReleaseEvent(EventPoolEntry* pevent); - - // Queue operations - void QueuePush(EventPoolEntry* pentry); - EventPoolEntry* QueuePop(); - void QueueFindAndRemove(EventPoolEntry* pentry); - -public: - - // Constructor/destructor - WaitConditionImpl(); - ~WaitConditionImpl(); - - // Release mutex and wait for condition. The mutex is re-acqured after the wait. - bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE); - - // Notify a condition, releasing at one object waiting - void Notify(); - // Notify a condition, releasing all objects waiting - void NotifyAll(); -}; - - - -WaitConditionImpl::WaitConditionImpl() -{ - pFreeEventList = 0; - pQueueHead = - pQueueTail = 0; -} - -WaitConditionImpl::~WaitConditionImpl() -{ - // Free all the resources - EventPoolEntry* p = pFreeEventList; - EventPoolEntry* pentry; - - while(p) - { - // Move to next - pentry = p; - p = p->pNext; - // Delete old - ::CloseHandle(pentry->hEvent); - delete pentry; - } - // Shouldn't we also consider the queue? - - // To be safe - pFreeEventList = 0; - pQueueHead = - pQueueTail = 0; -} - - -// Allocation functions for free events -WaitConditionImpl::EventPoolEntry* WaitConditionImpl::GetNewEvent() -{ - EventPoolEntry* pentry; - - // If there are any free nodes, use them - if (pFreeEventList) - { - pentry = pFreeEventList; - pFreeEventList = pFreeEventList->pNext; - } - else - { - // Allocate a new node - pentry = new EventPoolEntry; - pentry->pNext = 0; - pentry->pPrev = 0; - // Non-signaled manual event - pentry->hEvent = ::CreateEvent(NULL, TRUE, 0, NULL); - } - - return pentry; -} - -void WaitConditionImpl::ReleaseEvent(EventPoolEntry* pevent) -{ - // Mark event as non-signaled - ::ResetEvent(pevent->hEvent); - // And add it to free pool - pevent->pNext = pFreeEventList; - pevent->pPrev = 0; - pFreeEventList = pevent; -} - -// Queue operations -void WaitConditionImpl::QueuePush(EventPoolEntry* pentry) -{ - // Items already exist? Just add to tail - if (pQueueTail) - { - pentry->pPrev = pQueueTail; - pQueueTail->pNext = pentry; - pentry->pNext = 0; - pQueueTail = pentry; - } - else - { - // No items in queue - pentry->pNext = - pentry->pPrev = 0; - pQueueHead = - pQueueTail = pentry; - } -} - -WaitConditionImpl::EventPoolEntry* WaitConditionImpl::QueuePop() -{ - EventPoolEntry* pentry = pQueueHead; - - // No items, null pointer - if (pentry) - { - // More items after this one? just grab the first item - if (pQueueHead->pNext) - { - pQueueHead = pentry->pNext; - pQueueHead->pPrev = 0; - } - else - { - // Last item left - pQueueTail = - pQueueHead = 0; - } - } - return pentry; -} - -void WaitConditionImpl::QueueFindAndRemove(EventPoolEntry* pentry) -{ - // Do an exhaustive search looking for an entry - EventPoolEntry* p = pQueueHead; - - while(p) - { - // Entry found? Remove. - if (p == pentry) - { - - // Remove the node form the list - // Prev link - if (pentry->pPrev) - pentry->pPrev->pNext = pentry->pNext; - else - pQueueHead = pentry->pNext; - // Next link - if (pentry->pNext) - pentry->pNext->pPrev = pentry->pPrev; - else - pQueueTail = pentry->pPrev; - // Done - return; - } - - // Move to next item - p = p->pNext; - } -} - - -bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay) -{ - bool result = 0; - unsigned i; - unsigned lockCount = pmutex->pImpl->LockCount; - EventPoolEntry* pentry; - - // Mutex must have been locked - if (lockCount == 0) - return 0; - - // Add an object to the wait queue - WaitQueueLoc.DoLock(); - QueuePush(pentry = GetNewEvent()); - WaitQueueLoc.Unlock(); - - // Finally, release a mutex or semaphore - if (pmutex->pImpl->Recursive) - { - // Release the recursive mutex N times - pmutex->pImpl->LockCount = 0; - for(i=0; ipImpl->hMutexOrSemaphore); - } - else - { - pmutex->pImpl->LockCount = 0; - ::ReleaseSemaphore(pmutex->pImpl->hMutexOrSemaphore, 1, NULL); - } - - // Note that there is a gap here between mutex.Unlock() and Wait(). However, - // if notify() comes in at this point in the other thread it will set our - // corresponding event so wait will just fall through, as expected. - - // Block and wait on the event - DWORD waitResult = ::WaitForSingleObject(pentry->hEvent, - (delay == OVR_WAIT_INFINITE) ? INFINITE : delay); - /* -repeat_wait: - DWORD waitResult = - - ::MsgWaitForMultipleObjects(1, &pentry->hEvent, FALSE, - (delay == OVR_WAIT_INFINITE) ? INFINITE : delay, - QS_ALLINPUT); - */ - - WaitQueueLoc.DoLock(); - switch(waitResult) - { - case WAIT_ABANDONED: - case WAIT_OBJECT_0: - result = 1; - // Wait was successful, therefore the event entry should already be removed - // So just add entry back to a free list - ReleaseEvent(pentry); - break; - /* - case WAIT_OBJECT_0 + 1: - // Messages in WINDOWS queue - { - MSG msg; - PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE); - WaitQueueLoc.Unlock(); - goto repeat_wait; - } - break; */ - default: - // Timeout, our entry should still be in a queue - QueueFindAndRemove(pentry); - ReleaseEvent(pentry); - } - WaitQueueLoc.Unlock(); - - // Re-aquire the mutex - for(i=0; iDoLock(); - - // Return the result - return result; -} - -// Notify a condition, releasing the least object in a queue -void WaitConditionImpl::Notify() -{ - Lock::Locker lock(&WaitQueueLoc); - - // Pop last entry & signal it - EventPoolEntry* pentry = QueuePop(); - if (pentry) - ::SetEvent(pentry->hEvent); -} - -// Notify a condition, releasing all objects waiting -void WaitConditionImpl::NotifyAll() -{ - Lock::Locker lock(&WaitQueueLoc); - - // Pop and signal all events - // NOTE : There is no need to release the events, it's the waiters job to do so - EventPoolEntry* pentry = QueuePop(); - while (pentry) - { - ::SetEvent(pentry->hEvent); - pentry = QueuePop(); - } -} - - - -// *** Actual implementation of WaitCondition - -WaitCondition::WaitCondition() -{ - pImpl = new WaitConditionImpl; -} -WaitCondition::~WaitCondition() -{ - delete pImpl; -} - -// Wait without a mutex -bool WaitCondition::Wait(Mutex *pmutex, unsigned delay) -{ - return pImpl->Wait(pmutex, delay); -} -// Notification -void WaitCondition::Notify() -{ - pImpl->Notify(); -} -void WaitCondition::NotifyAll() -{ - pImpl->NotifyAll(); -} - - - -//----------------------------------------------------------------------------------- -// ***** Thread Class - -// Per-thread variable -// MA: Don't use TLS for now - portability issues with DLLs, etc. -/* -#if !defined(OVR_CC_MSVC) || (OVR_CC_MSVC < 1300) -__declspec(thread) Thread* pCurrentThread = 0; -#else -#pragma data_seg(".tls$") -__declspec(thread) Thread* pCurrentThread = 0; -#pragma data_seg(".rwdata") -#endif -*/ - -// *** Thread constructors. - -Thread::Thread(size_t stackSize, int processor) -{ - CreateParams params; - params.stackSize = stackSize; - params.processor = processor; - Init(params); -} - -Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, size_t stackSize, - int processor, Thread::ThreadState initialState) -{ - CreateParams params(threadFunction, userHandle, stackSize, processor, initialState); - Init(params); -} - -Thread::Thread(const CreateParams& params) -{ - Init(params); -} -void Thread::Init(const CreateParams& params) -{ - // Clear the variables - ThreadFlags = 0; - ThreadHandle = 0; - IdValue = 0; - ExitCode = 0; - SuspendCount = 0; - StackSize = params.stackSize; - Processor = params.processor; - Priority = params.priority; - - // Clear Function pointers - ThreadFunction = params.threadFunction; - UserHandle = params.userHandle; - if (params.initialState != NotRunning) - Start(params.initialState); - -} - -Thread::~Thread() -{ - // Thread should not running while object is being destroyed, - // this would indicate ref-counting issue. - //OVR_ASSERT(IsRunning() == 0); - - // Clean up thread. - CleanupSystemThread(); - ThreadHandle = 0; -} - - -// *** Overridable User functions. - -// Default Run implementation -int Thread::Run() -{ - if (!ThreadFunction) - return 0; - - int ret = ThreadFunction(this, UserHandle); - - return ret; -} - -void Thread::OnExit() -{ -} - -// Finishes the thread and releases internal reference to it. -void Thread::FinishAndRelease() -{ - // Note: thread must be US. - ThreadFlags &= (uint32_t)~(OVR_THREAD_STARTED); - ThreadFlags |= OVR_THREAD_FINISHED; - - // Release our reference; this is equivalent to 'delete this' - // from the point of view of our thread. - Release(); -} - - -// *** ThreadList - used to tack all created threads - -class ThreadList : public NewOverrideBase -{ - //------------------------------------------------------------------------ - struct ThreadHashOp - { - size_t operator()(const Thread* ptr) - { - return (((size_t)ptr) >> 6) ^ (size_t)ptr; - } - }; - - HashSet ThreadSet; - Mutex ThreadMutex; - WaitCondition ThreadsEmpty; - // Track the root thread that created us. - ThreadId RootThreadId; - - static ThreadList* volatile pRunningThreads; - - void addThread(Thread *pthread) - { - Mutex::Locker lock(&ThreadMutex); - ThreadSet.Add(pthread); - } - - void removeThread(Thread *pthread) - { - Mutex::Locker lock(&ThreadMutex); - ThreadSet.Remove(pthread); - if (ThreadSet.GetSize() == 0) - ThreadsEmpty.Notify(); - } - - void finishAllThreads() - { - // Only original root thread can call this. - OVR_ASSERT(GetCurrentThreadId() == RootThreadId); - - Mutex::Locker lock(&ThreadMutex); - while (ThreadSet.GetSize() != 0) - ThreadsEmpty.Wait(&ThreadMutex); - } - -public: - - ThreadList() - { - RootThreadId = GetCurrentThreadId(); - } - ~ThreadList() { } - - - static void AddRunningThread(Thread *pthread) - { - // Non-atomic creation ok since only the root thread - if (!pRunningThreads) - { - pRunningThreads = new ThreadList; - OVR_ASSERT(pRunningThreads); - } - pRunningThreads->addThread(pthread); - } - - // NOTE: 'pthread' might be a dead pointer when this is - // called so it should not be accessed; it is only used - // for removal. - static void RemoveRunningThread(Thread *pthread) - { - OVR_ASSERT(pRunningThreads); - pRunningThreads->removeThread(pthread); - } - - static void FinishAllThreads() - { - // This is ok because only root thread can wait for other thread finish. - if (pRunningThreads) - { - pRunningThreads->finishAllThreads(); - delete pRunningThreads; - pRunningThreads = 0; - } - } -}; - -// By default, we have no thread list. -ThreadList* volatile ThreadList::pRunningThreads = 0; - - -// FinishAllThreads - exposed publicly in Thread. -void Thread::FinishAllThreads() -{ - ThreadList::FinishAllThreads(); -} - - -// *** Run override - -int Thread::PRun() -{ - // Suspend us on start, if requested - if (ThreadFlags & OVR_THREAD_START_SUSPENDED) - { - Suspend(); - ThreadFlags &= (uint32_t)~OVR_THREAD_START_SUSPENDED; - } - - // Call the virtual run function - ExitCode = Run(); - - return ExitCode; -} - - - -/* MA: Don't use TLS for now. - -// Static function to return a pointer to the current thread -void Thread::InitCurrentThread(Thread *pthread) -{ - pCurrentThread = pthread; -} - -// Static function to return a pointer to the current thread -Thread* Thread::GetThread() -{ - return pCurrentThread; -} -*/ - - -// *** User overridables - -bool Thread::GetExitFlag() const -{ - return (ThreadFlags & OVR_THREAD_EXIT) != 0; -} - -void Thread::SetExitFlag(bool exitFlag) -{ - // The below is atomic since ThreadFlags is AtomicInt. - if (exitFlag) - ThreadFlags |= OVR_THREAD_EXIT; - else - ThreadFlags &= (uint32_t) ~OVR_THREAD_EXIT; -} - - -// Determines whether the thread was running and is now finished -bool Thread::IsFinished() const -{ - return (ThreadFlags & OVR_THREAD_FINISHED) != 0; -} -// Determines whether the thread is suspended -bool Thread::IsSuspended() const -{ - return SuspendCount > 0; -} -// Returns current thread state -Thread::ThreadState Thread::GetThreadState() const -{ - if (IsSuspended()) - return Suspended; - if (ThreadFlags & OVR_THREAD_STARTED) - return Running; - return NotRunning; -} -// Join thread -bool Thread::Join(int maxWaitMs) const -{ - // If polling, - if (maxWaitMs == 0) - { - // Just return if finished - return IsFinished(); - } - // If waiting forever, - else if (maxWaitMs > 0) - { - // Try waiting once - WaitForSingleObject(ThreadHandle, maxWaitMs); - - // Return if the wait succeeded - return IsFinished(); - } - - // While not finished, - while (!IsFinished()) - { - // Wait for the thread handle to signal - WaitForSingleObject(ThreadHandle, INFINITE); - } - - return true; -} - - -// ***** Thread management -/* static */ -int Thread::GetOSPriority(ThreadPriority p) -{ - switch(p) - { - // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14. - case Thread::CriticalPriority: return THREAD_PRIORITY_TIME_CRITICAL; // 15 - case Thread::HighestPriority: return THREAD_PRIORITY_HIGHEST; // 2 - case Thread::AboveNormalPriority: return THREAD_PRIORITY_ABOVE_NORMAL; // 1 - case Thread::NormalPriority: return THREAD_PRIORITY_NORMAL; // 0 - case Thread::BelowNormalPriority: return THREAD_PRIORITY_BELOW_NORMAL; // -1 - case Thread::LowestPriority: return THREAD_PRIORITY_LOWEST; // -2 - case Thread::IdlePriority: return THREAD_PRIORITY_IDLE; // -15 - } - return THREAD_PRIORITY_NORMAL; -} - -/* static */ -Thread::ThreadPriority Thread::GetOVRPriority(int osPriority) -{ - // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14. - // As a result, it's possible for those cases that an unknown/invalid ThreadPriority enum be returned. However, - // in practice we don't expect to be using such processes. - - // The ThreadPriority types aren't linearly distributed, so we need to check for some values explicitly. - if(osPriority == THREAD_PRIORITY_TIME_CRITICAL) - return Thread::CriticalPriority; - if(osPriority == THREAD_PRIORITY_IDLE) - return Thread::IdlePriority; - return (ThreadPriority)(Thread::NormalPriority - osPriority); -} - -Thread::ThreadPriority Thread::GetPriority() -{ - int osPriority = ::GetThreadPriority(ThreadHandle); - - if(osPriority != THREAD_PRIORITY_ERROR_RETURN) - { - return GetOVRPriority(osPriority); - } - - return NormalPriority; -} - -/* static */ -Thread::ThreadPriority Thread::GetCurrentPriority() -{ - int osPriority = ::GetThreadPriority(::GetCurrentThread()); - - if(osPriority != THREAD_PRIORITY_ERROR_RETURN) - { - return GetOVRPriority(osPriority); - } - - return NormalPriority; -} - -bool Thread::SetPriority(ThreadPriority p) -{ - BOOL ret = ::SetThreadPriority(ThreadHandle, Thread::GetOSPriority(p)); - return (ret != FALSE); -} - -/* static */ -bool Thread::SetCurrentPriority(ThreadPriority p) -{ - BOOL ret = ::SetThreadPriority(::GetCurrentThread(), Thread::GetOSPriority(p)); - return (ret != FALSE); -} - - - -// The actual first function called on thread start -#if defined(OVR_OS_WIN32) -unsigned WINAPI Thread_Win32StartFn(void * phandle) -#else // Other Micorosft OSs... -DWORD WINAPI Thread_Win32StartFn(void *phandle) -#endif -{ - Thread * pthread = (Thread*)phandle; - if (pthread->Processor != -1) - { - DWORD_PTR ret = SetThreadAffinityMask(GetCurrentThread(), (DWORD)pthread->Processor); - if (ret == 0) - OVR_DEBUG_LOG(("Could not set hardware processor for the thread")); - } - BOOL ret = ::SetThreadPriority(GetCurrentThread(), Thread::GetOSPriority(pthread->Priority)); - if (ret == 0) - OVR_DEBUG_LOG(("Could not set thread priority")); - OVR_UNUSED(ret); - - // Ensure that ThreadId is assigned once thread is running, in case - // beginthread hasn't filled it in yet. - pthread->IdValue = (ThreadId)::GetCurrentThreadId(); - - DWORD result = pthread->PRun(); - // Signal the thread as done and release it atomically. - pthread->FinishAndRelease(); - // At this point Thread object might be dead; however we can still pass - // it to RemoveRunningThread since it is only used as a key there. - ThreadList::RemoveRunningThread(pthread); - return (unsigned) result; -} - -bool Thread::Start(ThreadState initialState) -{ - if (initialState == NotRunning) - return 0; - if (GetThreadState() != NotRunning) - { - OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this)); - return 0; - } - - // Free old thread handle before creating the new one - CleanupSystemThread(); - - // AddRef to us until the thread is finished. - AddRef(); - ThreadList::AddRunningThread(this); - - ExitCode = 0; - SuspendCount = 0; - ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED; -#if defined(OVR_OS_WIN32) - ThreadHandle = (HANDLE) _beginthreadex(0, (unsigned)StackSize, - Thread_Win32StartFn, this, 0, (unsigned*)&IdValue); -#else // Other Micorosft OSs... - DWORD TheThreadId; - ThreadHandle = CreateThread(0, (unsigned)StackSize, - Thread_Win32StartFn, this, 0, &TheThreadId); - IdValue = (ThreadId)TheThreadId; -#endif - - // Failed? Fail the function - if (ThreadHandle == 0) - { - ThreadFlags = 0; - Release(); - ThreadList::RemoveRunningThread(this); - return 0; - } - return 1; -} - - -// Suspend the thread until resumed -bool Thread::Suspend() -{ - // Can't suspend a thread that wasn't started - if (!(ThreadFlags & OVR_THREAD_STARTED)) - return 0; - - if (::SuspendThread(ThreadHandle) != 0xFFFFFFFF) - { - SuspendCount++; - return 1; - } - return 0; -} - -// Resumes currently suspended thread -bool Thread::Resume() -{ - // Can't suspend a thread that wasn't started - if (!(ThreadFlags & OVR_THREAD_STARTED)) - return 0; - - // Decrement count, and resume thread if it is 0 - int32_t oldCount = SuspendCount.ExchangeAdd_Acquire(-1); - if (oldCount >= 1) - { - if (oldCount == 1) - { - if (::ResumeThread(ThreadHandle) != 0xFFFFFFFF) - { - return 1; - } - } - else - { - return 1; - } - } - return 0; -} - - -// Quits with an exit code -void Thread::Exit(int exitCode) -{ - // Can only exist the current thread. - // MA: Don't use TLS for now. - //if (GetThread() != this) - // return; - - // Call the virtual OnExit function. - OnExit(); - - // Signal this thread object as done and release it's references. - FinishAndRelease(); - ThreadList::RemoveRunningThread(this); - - // Call the exit function. -#if defined(OVR_OS_WIN32) // _endthreadex doesn't exist on other Microsoft OSs and instead we need to call ExitThread directly. - _endthreadex((unsigned)exitCode); -#else - ExitThread((unsigned)exitCode); -#endif -} - - -void Thread::CleanupSystemThread() -{ - if (ThreadHandle != 0) - { - ::CloseHandle(ThreadHandle); - ThreadHandle = 0; - } -} - -// *** Sleep functions -// static -bool Thread::Sleep(unsigned secs) -{ - ::Sleep(secs*1000); - return 1; -} - -// static -bool Thread::MSleep(unsigned msecs) -{ - ::Sleep(msecs); - return 1; -} - - - -void Thread::SetThreadName( const char* name ) -{ - if(IdValue) - SetThreadName(name, IdValue); - // Else we don't know what thread to name. We can save the name and wait until the thread is created. -} - - -void Thread::SetThreadName(const char* name, ThreadId threadId) -{ - #if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING) - // http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx - #pragma pack(push,8) - struct THREADNAME_INFO { - DWORD dwType; // Must be 0x1000 - LPCSTR szName; // Pointer to name (in user address space) - DWORD dwThreadID; // Thread ID (-1 for caller thread) - DWORD dwFlags; // Reserved for future use; must be zero - }; - #pragma pack(pop) - - THREADNAME_INFO info = { 0x1000, name, (DWORD)threadId, 0 }; - - __try - { - RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), reinterpret_cast(&info)); - } - __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER ) - { - return; - } - #endif // OVR_BUILD_SHIPPING -} - - -void Thread::SetCurrentThreadName( const char* name ) -{ - SetThreadName(name, (ThreadId)::GetCurrentThreadId()); -} - - -void Thread::GetThreadName(char* name, size_t /*nameCapacity*/, ThreadId /*threadId*/) -{ - // Not possible on Windows. - name[0] = 0; -} - - -void Thread::GetCurrentThreadName(char* name, size_t /*nameCapacity*/) -{ - // Not possible on Windows. - name[0] = 0; -} - - -// static -int Thread::GetCPUCount() -{ - SYSTEM_INFO sysInfo; - - #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) // GetNativeSystemInfo requires WinXP+ and a corresponding SDK (0x0501) or later. - GetNativeSystemInfo(&sysInfo); - #else - GetSystemInfo(&sysInfo); - #endif - - return (int) sysInfo.dwNumberOfProcessors; -} - -// Returns the unique Id of a thread it is called on, intended for -// comparison purposes. -ThreadId GetCurrentThreadId() -{ - return (ThreadId)::GetCurrentThreadId(); -} - -} // OVR - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Timer.cpp b/LibOVR/Src/Kernel/OVR_Timer.cpp deleted file mode 100644 index 3a75ec2..0000000 --- a/LibOVR/Src/Kernel/OVR_Timer.cpp +++ /dev/null @@ -1,551 +0,0 @@ -/************************************************************************************ - -Filename : OVR_Timer.cpp -Content : Provides static functions for precise timing -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Timer.h" -#include "OVR_Log.h" - -#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) -#define WIN32_LEAN_AND_MEAN -#include -#include -#elif defined(OVR_OS_ANDROID) -#include -#include -#elif defined(OVR_OS_MAC) -#include -#else -#include -#include -#include -#endif - - -#if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) - #ifndef NTSTATUS - #define NTSTATUS DWORD - #endif - - typedef NTSTATUS (NTAPI* NtQueryTimerResolutionType)(PULONG MaximumTime, PULONG MinimumTime, PULONG CurrentTime); - NtQueryTimerResolutionType pNtQueryTimerResolution; -#endif - - - -#if defined(OVR_OS_MS) && !defined(OVR_OS_WIN32) // Non-desktop Microsoft platforms... - -// Add this alias here because we're not going to include OVR_CAPI.cpp -extern "C" { - double ovr_GetTimeInSeconds() - { - return Timer::GetSeconds(); - } -} - -#endif - - - - -namespace OVR { - -// For recorded data playback -bool Timer::useFakeSeconds = false; -double Timer::FakeSeconds = 0; - - - - -//------------------------------------------------------------------------ -// *** Android Specific Timer - -#if defined(OVR_OS_ANDROID) // To consider: This implementation can also work on most Linux distributions - -//------------------------------------------------------------------------ -// *** Timer - Platform Independent functions - -// Returns global high-resolution application timer in seconds. -double Timer::GetSeconds() -{ - if(useFakeSeconds) - return FakeSeconds; - - // Choreographer vsync timestamp is based on. - struct timespec tp; - const int status = clock_gettime(CLOCK_MONOTONIC, &tp); - -#ifdef OVR_BUILD_DEBUG - if (status != 0) - { - OVR_DEBUG_LOG(("clock_gettime status=%i", status )); - } -#else - OVR_UNUSED(status); -#endif - - return (double)tp.tv_sec; -} - - - -uint64_t Timer::GetTicksNanos() -{ - if (useFakeSeconds) - return (uint64_t) (FakeSeconds * NanosPerSecond); - - // Choreographer vsync timestamp is based on. - struct timespec tp; - const int status = clock_gettime(CLOCK_MONOTONIC, &tp); - -#ifdef OVR_BUILD_DEBUG - if (status != 0) - { - OVR_DEBUG_LOG(("clock_gettime status=%i", status )); - } -#else - OVR_UNUSED(status); -#endif - - const uint64_t result = (uint64_t)tp.tv_sec * (uint64_t)(1000 * 1000 * 1000) + uint64_t(tp.tv_nsec); - return result; -} - - -void Timer::initializeTimerSystem() -{ - // Empty for this platform. -} - -void Timer::shutdownTimerSystem() -{ - // Empty for this platform. -} - - - - - -//------------------------------------------------------------------------ -// *** Win32 Specific Timer - -#elif defined (OVR_OS_MS) - - -// This helper class implements high-resolution wrapper that combines timeGetTime() output -// with QueryPerformanceCounter. timeGetTime() is lower precision but drives the high bits, -// as it's tied to the system clock. -struct PerformanceTimer -{ - PerformanceTimer() - : UsingVistaOrLater(false), - TimeCS(), - OldMMTimeMs(0), - MMTimeWrapCounter(0), - PerfFrequency(0), - PerfFrequencyInverse(0), - PerfFrequencyInverseNanos(0), - PerfMinusTicksDeltaNanos(0), - LastResultNanos(0) - { } - - enum { - MMTimerResolutionNanos = 1000000 - }; - - void Initialize(); - void Shutdown(); - - uint64_t GetTimeSeconds(); - double GetTimeSecondsDouble(); - uint64_t GetTimeNanos(); - - UINT64 getFrequency() - { - if (PerfFrequency == 0) - { - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - PerfFrequency = freq.QuadPart; - PerfFrequencyInverse = 1.0 / (double)PerfFrequency; - PerfFrequencyInverseNanos = 1000000000.0 / (double)PerfFrequency; - } - return PerfFrequency; - } - - double GetFrequencyInverse() - { - OVR_ASSERT(PerfFrequencyInverse != 0.0); // Assert that the frequency has been initialized. - return PerfFrequencyInverse; - } - - bool UsingVistaOrLater; - - CRITICAL_SECTION TimeCS; - // timeGetTime() support with wrap. - uint32_t OldMMTimeMs; - uint32_t MMTimeWrapCounter; - // Cached performance frequency result. - uint64_t PerfFrequency; // cycles per second, typically a large value like 3000000, but usually not the same as the CPU clock rate. - double PerfFrequencyInverse; // seconds per cycle (will be a small fractional value). - double PerfFrequencyInverseNanos; // nanoseconds per cycle. - - // Computed as (perfCounterNanos - ticksCounterNanos) initially, - // and used to adjust timing. - uint64_t PerfMinusTicksDeltaNanos; - // Last returned value in nanoseconds, to ensure we don't back-step in time. - uint64_t LastResultNanos; -}; - -static PerformanceTimer Win32_PerfTimer; - - -void PerformanceTimer::Initialize() -{ - #if defined(OVR_OS_WIN32) // Desktop Windows only - // The following has the effect of setting the NT timer resolution (NtSetTimerResolution) to 1 millisecond. - MMRESULT mmr = timeBeginPeriod(1); - OVR_ASSERT(TIMERR_NOERROR == mmr); - OVR_UNUSED(mmr); - #endif - - InitializeCriticalSection(&TimeCS); - MMTimeWrapCounter = 0; - getFrequency(); - - #if defined(OVR_OS_WIN32) // Desktop Windows only - // Set Vista flag. On Vista, we can just use QPC() without all the extra work - OSVERSIONINFOEX ver; - ZeroMemory(&ver, sizeof(OSVERSIONINFOEX)); - ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - ver.dwMajorVersion = 6; // Vista+ - - DWORDLONG condMask = 0; - VER_SET_CONDITION(condMask, VER_MAJORVERSION, VER_GREATER_EQUAL); - - // VerifyVersionInfo returns true if the OS meets the conditions set above - UsingVistaOrLater = VerifyVersionInfo(&ver, VER_MAJORVERSION, condMask) != 0; - #else - UsingVistaOrLater = true; - #endif - - OVR_DEBUG_LOG(("PerformanceTimer UsingVistaOrLater = %d", (int)UsingVistaOrLater)); - - #if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) - HMODULE hNtDll = LoadLibrary(L"NtDll.dll"); - if (hNtDll) - { - pNtQueryTimerResolution = (NtQueryTimerResolutionType)GetProcAddress(hNtDll, "NtQueryTimerResolution"); - //pNtSetTimerResolution = (NtSetTimerResolutionType)GetProcAddress(hNtDll, "NtSetTimerResolution"); - - if(pNtQueryTimerResolution) - { - ULONG MinimumResolution; // in 100-ns units - ULONG MaximumResolution; - ULONG ActualResolution; - pNtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &ActualResolution); - OVR_DEBUG_LOG(("NtQueryTimerResolution = Min %ld us, Max %ld us, Current %ld us", MinimumResolution / 10, MaximumResolution / 10, ActualResolution / 10)); - } - - FreeLibrary(hNtDll); - } - #endif -} - -void PerformanceTimer::Shutdown() -{ - DeleteCriticalSection(&TimeCS); - - #if defined(OVR_OS_WIN32) // Desktop Windows only - MMRESULT mmr = timeEndPeriod(1); - OVR_ASSERT(TIMERR_NOERROR == mmr); - OVR_UNUSED(mmr); - #endif -} - - -uint64_t PerformanceTimer::GetTimeSeconds() -{ - if (UsingVistaOrLater) - { - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - OVR_ASSERT(PerfFrequencyInverse != 0); // Initialize should have been called earlier. - return (uint64_t)(li.QuadPart * PerfFrequencyInverse); - } - - return (uint64_t)(GetTimeNanos() * .0000000001); -} - - -double PerformanceTimer::GetTimeSecondsDouble() -{ - if (UsingVistaOrLater) - { - LARGE_INTEGER li; - QueryPerformanceCounter(&li); - OVR_ASSERT(PerfFrequencyInverse != 0); - return (li.QuadPart * PerfFrequencyInverse); - } - - return (GetTimeNanos() * .0000000001); -} - - -uint64_t PerformanceTimer::GetTimeNanos() -{ - uint64_t resultNanos; - LARGE_INTEGER li; - - OVR_ASSERT(PerfFrequencyInverseNanos != 0); // Initialize should have been called earlier. - - if (UsingVistaOrLater) // Includes non-desktop platforms - { - // Then we can use QPC() directly without all that extra work - QueryPerformanceCounter(&li); - resultNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); - } - else - { - // On Win32 QueryPerformanceFrequency is unreliable due to SMP and - // performance levels, so use this logic to detect wrapping and track - // high bits. - ::EnterCriticalSection(&TimeCS); - - // Get raw value and perf counter "At the same time". - QueryPerformanceCounter(&li); - - DWORD mmTimeMs = timeGetTime(); - if (OldMMTimeMs > mmTimeMs) - MMTimeWrapCounter++; - OldMMTimeMs = mmTimeMs; - - // Normalize to nanoseconds. - uint64_t perfCounterNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); - uint64_t mmCounterNanos = ((uint64_t(MMTimeWrapCounter) << 32) | mmTimeMs) * 1000000; - if (PerfMinusTicksDeltaNanos == 0) - PerfMinusTicksDeltaNanos = perfCounterNanos - mmCounterNanos; - - // Compute result before snapping. - // - // On first call, this evaluates to: - // resultNanos = mmCounterNanos. - // Next call, assuming no wrap: - // resultNanos = prev_mmCounterNanos + (perfCounterNanos - prev_perfCounterNanos). - // After wrap, this would be: - // resultNanos = snapped(prev_mmCounterNanos +/- 1ms) + (perfCounterNanos - prev_perfCounterNanos). - // - resultNanos = perfCounterNanos - PerfMinusTicksDeltaNanos; - - // Snap the range so that resultNanos never moves further apart then its target resolution. - // It's better to allow more slack on the high side as timeGetTime() may be updated at sporadically - // larger then 1 ms intervals even when 1 ms resolution is requested. - if (resultNanos > (mmCounterNanos + MMTimerResolutionNanos*2)) - { - resultNanos = mmCounterNanos + MMTimerResolutionNanos*2; - if (resultNanos < LastResultNanos) - resultNanos = LastResultNanos; - PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; - } - else if (resultNanos < (mmCounterNanos - MMTimerResolutionNanos)) - { - resultNanos = mmCounterNanos - MMTimerResolutionNanos; - if (resultNanos < LastResultNanos) - resultNanos = LastResultNanos; - PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; - } - - LastResultNanos = resultNanos; - ::LeaveCriticalSection(&TimeCS); - } - - //Tom's addition, to keep precision - //static uint64_t initial_time = 0; - //if (!initial_time) initial_time = resultNanos; - //resultNanos -= initial_time; - // FIXME: This cannot be used for cross-process timestamps - - return resultNanos; -} - - -//------------------------------------------------------------------------ -// *** Timer - Platform Independent functions - -// Returns global high-resolution application timer in seconds. -double Timer::GetSeconds() -{ - if(useFakeSeconds) - return FakeSeconds; - - return Win32_PerfTimer.GetTimeSecondsDouble(); -} - - - -// Delegate to PerformanceTimer. -uint64_t Timer::GetTicksNanos() -{ - if (useFakeSeconds) - return (uint64_t) (FakeSeconds * NanosPerSecond); - - return Win32_PerfTimer.GetTimeNanos(); -} -void Timer::initializeTimerSystem() -{ - Win32_PerfTimer.Initialize(); -} -void Timer::shutdownTimerSystem() -{ - Win32_PerfTimer.Shutdown(); -} - - - -#elif defined(OVR_OS_MAC) - - -double Timer::TimeConvertFactorNanos = 0.0; -double Timer::TimeConvertFactorSeconds = 0.0; - - -//------------------------------------------------------------------------ -// *** Standard OS Timer - -// Returns global high-resolution application timer in seconds. -double Timer::GetSeconds() -{ - if(useFakeSeconds) - return FakeSeconds; - - OVR_ASSERT(TimeConvertFactorNanos != 0.0); - return (double)mach_absolute_time() * TimeConvertFactorNanos; -} - - -uint64_t Timer::GetTicksNanos() -{ - if (useFakeSeconds) - return (uint64_t) (FakeSeconds * NanosPerSecond); - - OVR_ASSERT(TimeConvertFactorSeconds != 0.0); - return (uint64_t)(mach_absolute_time() * TimeConvertFactorSeconds); -} - -void Timer::initializeTimerSystem() -{ - mach_timebase_info_data_t timeBase; - mach_timebase_info(&timeBase); - TimeConvertFactorSeconds = ((double)timeBase.numer / (double)timeBase.denom); - TimeConvertFactorNanos = TimeConvertFactorSeconds / 1000000000.0; -} - -void Timer::shutdownTimerSystem() -{ - // Empty for this platform. -} - - -#else // Posix platforms (e.g. Linux, BSD Unix) - - -bool Timer::MonotonicClockAvailable = false; - - -// Returns global high-resolution application timer in seconds. -double Timer::GetSeconds() -{ - if(useFakeSeconds) - return FakeSeconds; - - // http://linux/die/netman3/clock_gettime - #if defined(CLOCK_MONOTONIC) // If we can use clock_gettime, which has nanosecond precision... - if(MonotonicClockAvailable) - { - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); // Better to use CLOCK_MONOTONIC than CLOCK_REALTIME. - return static_cast(ts.tv_sec) + static_cast(ts.tv_nsec) / 1E9; - } - #endif - - // We cannot use rdtsc because its frequency changes at runtime. - struct timeval tv; - gettimeofday(&tv, 0); - - return static_cast(tv.tv_sec) + static_cast(tv.tv_usec) / 1E6; -} - - -uint64_t Timer::GetTicksNanos() -{ - if (useFakeSeconds) - return (uint64_t) (FakeSeconds * NanosPerSecond); - - #if defined(CLOCK_MONOTONIC) // If we can use clock_gettime, which has nanosecond precision... - if(MonotonicClockAvailable) - { - timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return ((uint64_t)ts.tv_sec * 1000000000ULL) + (uint64_t)ts.tv_nsec; - } - #endif - - - // We cannot use rdtsc because its frequency changes at runtime. - uint64_t result; - - // Return microseconds. - struct timeval tv; - - gettimeofday(&tv, 0); - - result = (uint64_t)tv.tv_sec * 1000000; - result += tv.tv_usec; - - return result * 1000; -} - - -void Timer::initializeTimerSystem() -{ - #if defined(CLOCK_MONOTONIC) - timespec ts; // We could also check for the availability of CLOCK_MONOTONIC with sysconf(_SC_MONOTONIC_CLOCK) - int result = clock_gettime(CLOCK_MONOTONIC, &ts); - MonotonicClockAvailable = (result == 0); - #endif -} - -void Timer::shutdownTimerSystem() -{ - // Empty for this platform. -} - - - -#endif // OS-specific - - - -} // OVR - diff --git a/LibOVR/Src/Kernel/OVR_Timer.h b/LibOVR/Src/Kernel/OVR_Timer.h deleted file mode 100644 index 6c8dbb7..0000000 --- a/LibOVR/Src/Kernel/OVR_Timer.h +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR -Filename : OVR_Timer.h -Content : Provides static functions for precise timing -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Timer_h -#define OVR_Timer_h - -#include "OVR_Types.h" - -namespace OVR { - -//----------------------------------------------------------------------------------- -// ***** Timer - -// Timer class defines a family of static functions used for application -// timing and profiling. - -class Timer -{ -public: - enum { - MsPerSecond = 1000, // Milliseconds in one second. - MksPerSecond = 1000 * 1000, // Microseconds in one second. - NanosPerSecond = 1000 * 1000 * 1000, // Nanoseconds in one second. - }; - - // ***** Timing APIs for Application - - // These APIs should be used to guide animation and other program functions - // that require precision. - - // Returns global high-resolution application timer in seconds. - static double OVR_STDCALL GetSeconds(); - - // Returns time in Nanoseconds, using highest possible system resolution. - static uint64_t OVR_STDCALL GetTicksNanos(); - - // Kept for compatibility. - // Returns ticks in milliseconds, as a 32-bit number. May wrap around every 49.2 days. - // Use either time difference of two values of GetTicks to avoid wrap-around. - static uint32_t OVR_STDCALL GetTicksMs() - { return uint32_t(GetTicksNanos() / 1000000); } - - // for recorded data playback - static void SetFakeSeconds(double fakeSeconds, bool enable = true) - { - FakeSeconds = fakeSeconds; - useFakeSeconds = enable; - } - -private: - friend class System; - // System called during program startup/shutdown. - static void initializeTimerSystem(); - static void shutdownTimerSystem(); - - // for recorded data playback - static double FakeSeconds; - static bool useFakeSeconds; - - #if defined(OVR_OS_ANDROID) - // Android-specific data - #elif defined (OVR_OS_MS) - // Microsoft-specific data - #elif defined(OVR_OS_MAC) - static double TimeConvertFactorNanos; // Conversion factor for GetTicksNanos - static double TimeConvertFactorSeconds; // Conversion factor for GetSeconds. - #else - static bool MonotonicClockAvailable; // True if clock_gettime supports CLOCK_MONOTONIC - #endif -}; - - -} // OVR::Timer - -#endif diff --git a/LibOVR/Src/Kernel/OVR_Types.h b/LibOVR/Src/Kernel/OVR_Types.h deleted file mode 100644 index d42d131..0000000 --- a/LibOVR/Src/Kernel/OVR_Types.h +++ /dev/null @@ -1,909 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_Types.h -Content : Standard library defines and simple types -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Types_H -#define OVR_Types_H - -#include "OVR_Compiler.h" - - -// Unsupported compiler configurations -#if _MSC_VER == 0x1600 -# if _MSC_FULL_VER < 160040219 -# error "Oculus does not support VS2010 without SP1 installed: It will crash in Release mode" -# endif -#endif - - -//----------------------------------------------------------------------------------- -// ****** Operating system identification -// -// Try to use the most generic version of these defines as possible in order to achieve -// the simplest portable code. For example, instead of using #if (defined(OVR_OS_IPHONE) || defined(OVR_OS_MAC)), -// consider using #if defined(OVR_OS_APPLE). -// -// Type definitions exist for the following operating systems: (OVR_OS_x) -// -// WIN32 - Win32 and Win64 (Windows XP and later) Does not include Microsoft phone and console platforms, despite that Microsoft's _WIN32 may be defined by the compiler for them. -// WIN64 - Win64 (Windows XP and later) -// MAC - Mac OS X (may be defined in addition to BSD) -// LINUX - Linux -// BSD - BSD Unix -// ANDROID - Android (may be defined in addition to LINUX) -// IPHONE - iPhone -// MS_MOBILE - Microsoft mobile OS. -// -// Meta platforms -// MS - Any OS by Microsoft (e.g. Win32, Win64, phone, console) -// APPLE - Any OS by Apple (e.g. iOS, OS X) -// UNIX - Linux, BSD, Mac OS X. -// MOBILE - iOS, Android, Microsoft phone -// CONSOLE - Console platforms -// - -#if (defined(__APPLE__) && (defined(__GNUC__) ||\ - defined(__xlC__) || defined(__xlc__))) || defined(__MACOS__) -# if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || defined(__IPHONE_OS_VERSION_MIN_REQUIRED)) -# define OVR_OS_IPHONE -# else -# define OVR_OS_DARWIN -# define OVR_OS_MAC -# define OVR_OS_BSD -# endif -#elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) -# define OVR_OS_WIN64 -# define OVR_OS_WIN32 // Defined for compatibility and because the Win64 API supports the Win32 API. -#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) -# define OVR_OS_WIN32 -#elif defined(ANDROID) || defined(__ANDROID__) -# define OVR_OS_ANDROID -# define OVR_OS_LINUX -#elif defined(__linux__) || defined(__linux) -# define OVR_OS_LINUX -#elif defined(_BSD_) || defined(__FreeBSD__) -# define OVR_OS_BSD -#else -# define OVR_OS_OTHER -#endif - -#if !defined(OVR_OS_MS_MOBILE) -# if (defined(_M_ARM) || defined(_M_IX86) || defined(_M_AMD64)) && !defined(OVR_OS_WIN32) && !defined(OVR_OS_CONSOLE) -# define OVR_OS_MS_MOBILE -# endif -#endif - -#if !defined(OVR_OS_MS) -# if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) || defined(OVR_OS_MS_MOBILE) -# define OVR_OS_MS -# endif -#endif - -#if !defined(OVR_OS_APPLE) -# if defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) -# define OVR_OS_APPLE -# endif -#endif - -#if !defined(OVR_OS_UNIX) -# if defined(OVR_OS_ANDROID) || defined(OVR_OS_BSD) || defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) -# define OVR_OS_UNIX -# endif -#endif - -#if !defined(OVR_OS_MOBILE) -# if defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) || defined(OVR_OS_MS_MOBILE) -# define OVR_OS_MOBILE -# endif -#endif - - - - -//----------------------------------------------------------------------------------- -// ***** CPU Architecture -// -// The following CPUs are defined: (OVR_CPU_x) -// -// X86 - x86 (IA-32) -// X86_64 - x86_64 (amd64) -// PPC - PowerPC -// PPC64 - PowerPC64 -// MIPS - MIPS -// OTHER - CPU for which no special support is present or needed - - -#if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(_M_AMD64) -# define OVR_CPU_X86_64 -# define OVR_64BIT_POINTERS -#elif defined(__i386__) || defined(OVR_OS_WIN32) -# define OVR_CPU_X86 -#elif defined(__powerpc64__) -# define OVR_CPU_PPC64 -#elif defined(__ppc__) -# define OVR_CPU_PPC -#elif defined(__mips__) || defined(__MIPSEL__) -# define OVR_CPU_MIPS -#elif defined(__arm__) -# define OVR_CPU_ARM -#else -# define OVR_CPU_OTHER -#endif - -//----------------------------------------------------------------------------------- -// ***** Co-Processor Architecture -// -// The following co-processors are defined: (OVR_CPU_x) -// -// SSE - Available on all modern x86 processors. -// Altivec - Available on all modern ppc processors. -// Neon - Available on some armv7+ processors. - -#if defined(__SSE__) || defined(_M_IX86) || defined(_M_AMD64) // _M_IX86 and _M_AMD64 are Microsoft identifiers for Intel-based platforms. -# define OVR_CPU_SSE -#endif // __SSE__ - -#if defined( __ALTIVEC__ ) -# define OVR_CPU_ALTIVEC -#endif // __ALTIVEC__ - -#if defined(__ARM_NEON__) -# define OVR_CPU_ARM_NEON -#endif // __ARM_NEON__ - - -//----------------------------------------------------------------------------------- -// ***** Compiler Warnings - -// Disable MSVC warnings -#if defined(OVR_CC_MSVC) -# pragma warning(disable : 4127) // Inconsistent dll linkage -# pragma warning(disable : 4530) // Exception handling -# if (OVR_CC_MSVC<1300) -# pragma warning(disable : 4514) // Unreferenced inline function has been removed -# pragma warning(disable : 4710) // Function not inlined -# pragma warning(disable : 4714) // _force_inline not inlined -# pragma warning(disable : 4786) // Debug variable name longer than 255 chars -# endif // (OVR_CC_MSVC<1300) -#endif // (OVR_CC_MSVC) - - - -// *** Linux Unicode - must come before Standard Includes - -#ifdef OVR_OS_LINUX -// Use glibc unicode functions on linux. -# ifndef _GNU_SOURCE -# define _GNU_SOURCE -# endif -#endif - -//----------------------------------------------------------------------------------- -// ***** Standard Includes -// -#include -#include -#include - - -// MSVC Based Memory Leak checking - for now -#if defined(OVR_CC_MSVC) && defined(OVR_BUILD_DEBUG) -# define _CRTDBG_MAP_ALLOC -# include -# include -#endif - - -//----------------------------------------------------------------------------------- -// ***** int8_t, int16_t, etc. - -#if defined(OVR_CC_MSVC) && (OVR_CC_VER <= 1500) // VS2008 and earlier - typedef signed char int8_t; - typedef unsigned char uint8_t; - typedef signed short int16_t; - typedef unsigned short uint16_t; - typedef signed int int32_t; - typedef unsigned int uint32_t; - typedef signed __int64 int64_t; - typedef unsigned __int64 uint64_t; -#else - #include -#endif - - -//----------------------------------------------------------------------------------- -// ***** Type definitions for Common Systems - -namespace OVR { - -typedef char Char; - -// Pointer-sized integer -typedef size_t UPInt; -typedef ptrdiff_t SPInt; - - -#if defined(OVR_OS_MS) - -typedef char SByte; // 8 bit Integer (Byte) -typedef unsigned char UByte; -typedef short SInt16; // 16 bit Integer (Word) -typedef unsigned short UInt16; -typedef long SInt32; // 32 bit Integer -typedef unsigned long UInt32; -typedef __int64 SInt64; // 64 bit Integer (QWord) -typedef unsigned __int64 UInt64; - - -#elif defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) || defined(OVR_CC_GNU) - -typedef int SByte __attribute__((__mode__ (__QI__))); -typedef unsigned int UByte __attribute__((__mode__ (__QI__))); -typedef int SInt16 __attribute__((__mode__ (__HI__))); -typedef unsigned int UInt16 __attribute__((__mode__ (__HI__))); -typedef int SInt32 __attribute__((__mode__ (__SI__))); -typedef unsigned int UInt32 __attribute__((__mode__ (__SI__))); -typedef int SInt64 __attribute__((__mode__ (__DI__))); -typedef unsigned int UInt64 __attribute__((__mode__ (__DI__))); - -#else - -#include -typedef int8_t SByte; -typedef uint8_t UByte; -typedef int16_t SInt16; -typedef uint16_t UInt16; -typedef int32_t SInt32; -typedef uint32_t UInt32; -typedef int64_t SInt64; -typedef uint64_t UInt64; - -#endif - - -//osx PID is a signed int32 (already defined to pid_t in OSX framework) -//linux PID is a signed int32 (already defined) -//win32 PID is an unsigned int64 -#ifdef OVR_OS_WIN32 -//process ID representation -typedef unsigned long pid_t; -#endif - -struct OVR_GUID -{ - uint32_t Data1; - uint16_t Data2; - uint16_t Data3; - uint8_t Data4[8]; -}; - - - -} // OVR - - - -//----------------------------------------------------------------------------------- -// ****** Standard C/C++ Library -// -// Identifies which standard library is currently being used. -// -// LIBSTDCPP - GNU libstdc++, used by GCC. -// LIBCPP - LLVM libc++, typically used by clang and GCC. -// DINKUMWARE - Used by Microsoft and various non-Microsoft compilers (e.g. Sony clang). - -#if !defined(OVR_STDLIB_LIBSTDCPP) - #if defined(__GLIBCXX__) - #define OVR_STDLIB_LIBSTDCPP 1 - #endif -#endif - -#if !defined(OVR_STDLIB_LIBCPP) - #if defined(__clang__) - #if defined(__cplusplus) && __has_include(<__config>) - #define OVR_STDLIB_LIBCPP 1 - #endif - #endif -#endif - -#if !defined(OVR_STDLIB_DINKUMWARE) - #if defined(_YVALS) // Dinkumware globally #defines _YVALS from the #includes above. - #define OVR_STDLIB_DINKUMWARE 1 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** Macro Definitions -// -// We define the following: -// -// OVR_BYTE_ORDER - Defined to either OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN -// OVR_FORCE_INLINE - Forces inline expansion of function -// OVR_ASM - Assembly language prefix -// OVR_STR - Prefixes string with L"" if building unicode -// -// OVR_STDCALL - Use stdcall calling convention (Pascal arg order) -// OVR_CDECL - Use cdecl calling convention (C argument order) -// OVR_FASTCALL - Use fastcall calling convention (registers) -// - -// Byte order constants, OVR_BYTE_ORDER is defined to be one of these. -#define OVR_LITTLE_ENDIAN 1 -#define OVR_BIG_ENDIAN 2 - - -#if defined(OVR_OS_MS) - - // ***** Windows and non-desktop platforms - - // Byte order - #define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN - - // Calling convention - goes after function return type but before function name - #ifdef __cplusplus_cli - # define OVR_FASTCALL __stdcall - #else - # define OVR_FASTCALL __fastcall - #endif - - #define OVR_STDCALL __stdcall - #define OVR_CDECL __cdecl - - - // Assembly macros - #if defined(OVR_CC_MSVC) - # define OVR_ASM _asm - #else - # define OVR_ASM asm - #endif // (OVR_CC_MSVC) - - #ifdef UNICODE - # define OVR_STR(str) L##str - #else - # define OVR_STR(str) str - #endif // UNICODE - -#else - - // **** Standard systems - - #if (defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN))|| \ - (defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)) - # define OVR_BYTE_ORDER OVR_BIG_ENDIAN - #elif (defined(__ARMEB__) || defined(OVR_CPU_PPC) || defined(OVR_CPU_PPC64)) - # define OVR_BYTE_ORDER OVR_BIG_ENDIAN - #else - # define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN - #endif - - // Assembly macros - #define OVR_ASM __asm__ - #define OVR_ASM_PROC(procname) OVR_ASM - #define OVR_ASM_END OVR_ASM - - // Calling convention - goes after function return type but before function name - #define OVR_FASTCALL - #define OVR_STDCALL - #define OVR_CDECL - -#endif // defined(OVR_OS_WIN32) - - -//----------------------------------------------------------------------------------- -// ***** OVR_PTR_SIZE -// -// Specifies the byte size of pointers (same as sizeof void*). - -#if !defined(OVR_PTR_SIZE) - #if defined(__WORDSIZE) - #define OVR_PTR_SIZE ((__WORDSIZE) / 8) - #elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || defined(__ia64__) || defined(__arch64__) || defined(__64BIT__) || defined(__Ptr_Is_64) - #define OVR_PTR_SIZE 8 - #elif defined(__CC_ARM) && (__sizeof_ptr == 8) - #define OVR_PTR_SIZE 8 - #else - #define OVR_PTR_SIZE 4 - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_WORD_SIZE -// -// Specifies the byte size of a machine word/register. Not necessarily the same as -// the size of pointers, but usually >= the size of pointers. - -#if !defined(OVR_WORD_SIZE) - #define OVR_WORD_SIZE OVR_PTR_SIZE // For our currently supported platforms these are equal. -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_FORCE_INLINE -// -// Force inline substitute - goes before function declaration -// Example usage: -// OVR_FORCE_INLINE void Test(); - -#if !defined(OVR_FORCE_INLINE) - #if defined(OVR_CC_MSVC) - #define OVR_FORCE_INLINE __forceinline - #elif defined(OVR_CC_GNU) - #define OVR_FORCE_INLINE __attribute__((always_inline)) inline - #else - #define OVR_FORCE_INLINE inline - #endif // OVR_CC_MSVC -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_NO_INLINE -// -// Cannot be used with inline or OVR_FORCE_INLINE. -// Example usage: -// OVR_NO_INLINE void Test(); - -#if !defined(OVR_NO_INLINE) - #if defined(OVR_CC_MSVC) && (_MSC_VER >= 1500) // VS2008+ - #define OVR_NO_INLINE __declspec(noinline) - #elif !defined(OVR_CC_MSVC) - #define OVR_NO_INLINE __attribute__((noinline)) - #endif -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_STRINGIZE -// -// Converts a preprocessor symbol to a string. -// -// Example usage: -// printf("Line: %s", OVR_STRINGIZE(__LINE__)); -// -#if !defined(OVR_STRINGIFY) - #define OVR_STRINGIZEIMPL(x) #x - #define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x) -#endif - - -// ----------------------------------------------------------------------------------- -// ***** OVR_JOIN -// -// Joins two preprocessing symbols together. Supports the case when either or the -// the symbols are macros themselves. -// -// Example usage: -// char OVR_JOIN(unique_, __LINE__); // Results in (e.g.) char unique_123; -// -#if !defined(OVR_JOIN) - #define OVR_JOIN(a, b) OVR_JOIN1(a, b) - #define OVR_JOIN1(a, b) OVR_JOIN2(a, b) - #define OVR_JOIN2(a, b) a##b -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_OFFSETOF -// -// Portable implementation of offsetof for structs and classes. offsetof and GCC's -// __builtin_offsetof work only with POD types (standard-layout types under C++11), -// despite that it can safely work with a number of types that aren't POD. This -// version works with more types without generating compiler warnings or errors. -// Returns the offset as a size_t, as per offsetof. -// -// Example usage: -// struct Test{ int i; float f; }; -// size_t fPos = OVR_OFFSETOF(Test, f); - -#if defined(OVR_CC_GNU) - #define OVR_OFFSETOF(class_, member_) ((size_t)(((uintptr_t)&reinterpret_cast((((class_*)65536)->member_))) - 65536)) -#else - #define OVR_OFFSETOF(class_, member_) offsetof(class_, member_) -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_SIZEOF_MEMBER -// -// Implements a portable way to determine the size of struct or class data member. -// C++11 allows this directly via sizeof (see OVR_CPP_NO_EXTENDED_SIZEOF), and this -// macro exists to handle pre-C++11 compilers. -// Returns the offset as a size_t, as per sizeof. -// -// Example usage: -// struct Test{ int i; float f; }; -// size_t fSize = OVR_SIZEOF_MEMBER(Test, f); -// -#if defined(OVR_CPP_NO_EXTENDED_SIZEOF) - #define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(((class_*)0)->member_)) -#else - #define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(class_::member_)) -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_DEBUG_BREAK, OVR_DEBUG_CODE, -// OVR_ASSERT, OVR_ASSERT_M, OVR_ASSERT_AND_UNUSED -// -// Macros have effect only in debug builds. -// -// Example OVR_DEBUG_BREAK usage (note the lack of parentheses): -// #define MY_ASSERT(expression) do { if (!(expression)) { OVR_DEBUG_BREAK; } } while(0) -// -// Example OVR_DEBUG_CODE usage: -// OVR_DEBUG_CODE(printf("debug test\n");) -// or -// OVR_DEBUG_CODE(printf("debug test\n")); -// -// Example OVR_ASSERT usage: -// OVR_ASSERT(count < 100); -// OVR_ASSERT_M(count < 100, "count is too high"); -// -#if defined(OVR_BUILD_DEBUG) - // Causes a debugger breakpoint in debug builds. Has no effect in release builds. - // Microsoft Win32 specific debugging support - #if defined(OVR_CC_MSVC) - #define OVR_DEBUG_BREAK __debugbreak() - #elif defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) - #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - #define OVR_DEBUG_BREAK do { OVR_ASM("int $3\n\t"); } while(0) - #else - #define OVR_DEBUG_BREAK __builtin_trap() - #endif - #else - #define OVR_DEBUG_BREAK do { *((int *) 0) = 1; } while(0) - #endif - - // The expresssion is defined only in debug builds. It is defined away in release builds. - #define OVR_DEBUG_CODE(c) c - - // In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, - // if true then no action. Has no effect in release builds. - #if defined(__clang_analyzer__) // During static analysis, make it so the analyzer thinks that failed asserts result in program exit. Reduced false positives. - #include - #define OVR_ASSERT_M(p, message) do { if (!(p)) { OVR_DEBUG_BREAK; exit(0); } } while(0) - #define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; exit(0); } } while(0) - #else - // void OVR_ASSERT_M(bool expression, const char message); - // Note: The expresion below is expanded into all usage of this assertion macro. - // We should try to minimize the size of the expanded code to the extent possible. - #define OVR_ASSERT_M(p, message) do \ - { \ - if (!(p)) \ - { \ - intptr_t ovrAssertUserParam; \ - OVRAssertionHandler ovrAssertUserHandler = OVR::GetAssertionHandler(&ovrAssertUserParam); \ - \ - if(ovrAssertUserHandler && !OVRIsDebuggerPresent()) \ - { \ - ovrAssertUserHandler(ovrAssertUserParam, "Assertion failure", message); \ - } \ - else \ - { \ - OVR_DEBUG_BREAK; \ - } \ - } \ - } while(0) - - // void OVR_ASSERT(bool expression); - #define OVR_ASSERT(p) OVR_ASSERT_M((p), (#p)) - #endif - - // Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. - // Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); - #define OVR_ASSERT_AND_UNUSED(expression, value) OVR_ASSERT(expression); OVR_UNUSED(value) - -#else - - // The expresssion is defined only in debug builds. It is defined away in release builds. - #define OVR_DEBUG_CODE(c) - - // Causes a debugger breakpoint in debug builds. Has no effect in release builds. - #define OVR_DEBUG_BREAK ((void)0) - - // In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, - // if true then no action. Has no effect in release builds. - #define OVR_ASSERT(p) ((void)0) - #define OVR_ASSERT_M(p, m) ((void)0) - - // Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. - // Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); - #define OVR_ASSERT_AND_UNUSED(expression, value) OVR_UNUSED(value) - -#endif // OVR_BUILD_DEBUG - - - -// Assert handler -// The user of this library can override the default assertion handler and provide their own. -namespace OVR -{ - // The return value meaning is reserved for future definition and currently has no effect. - typedef intptr_t (*OVRAssertionHandler)(intptr_t userParameter, const char* title, const char* message); - - // Returns the current assertion handler. - OVRAssertionHandler GetAssertionHandler(intptr_t* userParameter = NULL); - - // Sets the current assertion handler. - // The default assertion handler if none is set simply issues a debug break. - // Example usage: - // intptr_t CustomAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message)) { - // MessageBox(title, message); - // OVR_DEBUG_BREAK; - // } - void SetAssertionHandler(OVRAssertionHandler assertionHandler, intptr_t userParameter = 0); - - // Implements the default assertion handler. - intptr_t DefaultAssertionHandler(intptr_t userParameter, const char* title, const char* message); - - // Currently defined in OVR_DebugHelp.cpp - bool OVRIsDebuggerPresent(); -} - - -// ------------------------------------------------------------------------ -// ***** static_assert -// -// Portable support for C++11 static_assert. -// Acts as if the following were declared: -// void static_assert(bool const_expression, const char* msg); -// -// Example usage: -// static_assert(sizeof(int32_t) == 4, "int32_t expected to be 4 bytes."); - -#if defined(OVR_CPP_NO_STATIC_ASSERT) // If the compiler doesn't provide it intrinsically... - #if !defined(OVR_SA_UNUSED) - #if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) - #define OVR_SA_UNUSED __attribute__((unused)) - #else - #define OVR_SA_UNUSED - #endif - #define OVR_SA_PASTE(a,b) a##b - #define OVR_SA_HELP(a,b) OVR_SA_PASTE(a,b) - #endif - - #if defined(__COUNTER__) - #define static_assert(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __COUNTER__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED - #else - #define static_assert(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED - #endif -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_COMPILER_ASSERT -// -// Compile-time assert; produces compiler error if condition is false. -// The expression must be a compile-time constant expression. -// This macro is deprecated in favor of static_assert, which provides better -// compiler output and works in a broader range of contexts. -// -// Example usage: -// OVR_COMPILER_ASSERT(sizeof(int32_t == 4)); - -#if !defined(OVR_COMPILER_ASSERT) - #define OVR_COMPILER_ASSERT(expression) static_assert(expression, #expression) - #define OVR_COMPILER_ASSERT_M(expression, msg) static_assert(expression, msg) -#endif - - -// ***** OVR_PROCESSOR_PAUSE -// -// Yields the processor for other hyperthreads, usually for the purpose of implementing spins and spin locks. -// -// Example usage: -// while(!finished()) -// OVR_PROCESSOR_PAUSE(); - -#if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) - #if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) - #define OVR_PROCESSOR_PAUSE() asm volatile("pause" ::: "memory") // Consumes 38-40 clocks on current Intel x86 and x64 hardware. - #elif defined(OVR_CC_MSVC) - #include - #pragma intrinsic(_mm_pause) // Maps to asm pause. - #define OVR_PROCESSOR_PAUSE _mm_pause - #else - #define OVR_PROCESSOR_PAUSE() - #endif -#else - #define OVR_PROCESSOR_PAUSE() -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_ARRAY_COUNT -// -// Returns the element count of a C array. -// -// Example usage: -// float itemArray[16]; -// for(size_t i = 0; i < OVR_ARRAY_COUNT(itemArray); i++) { ... } - -#if defined(OVR_CPP_NO_CONSTEXPR) - #ifndef OVR_ARRAY_COUNT - #define OVR_ARRAY_COUNT(x) (sizeof(x) / sizeof(x[0])) - #endif -#else - // Smarter C++11 version which knows the difference between arrays and pointers. - template - char (&OVRArrayCountHelper(T (&x)[N]))[N]; - #define OVR_ARRAY_COUNT(x) (sizeof(OVRArrayCountHelper(x))) -#endif - - -// ------------------------------------------------------------------------ -// ***** OVR_CURRENT_FUNCTION -// -// Portable wrapper for __PRETTY_FUNCTION__, C99 __func__, __FUNCTION__. -// This represents the most expressive version available. -// Acts as if the following were declared: -// static const char OVR_CURRENT_FUNCTION[] = "function-name"; -// -// Example usage: -// void Test() { printf("%s", OVR_CURRENT_FUNCTION); } - -#if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) || (defined(__ICC) && (__ICC >= 600)) // GCC, clang, Intel - #define OVR_CURRENT_FUNCTION __PRETTY_FUNCTION__ -#elif defined(__FUNCSIG__) // VC++ - #define OVR_CURRENT_FUNCTION __FUNCSIG__ -#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) // C99 compilers - #define OVR_CURRENT_FUNCTION __func__ -#else - #define OVR_CURRENT_FUNCTION __FUNCTION__ -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_DEPRECATED / OVR_DEPRECATED_MSG -// -// Portably annotates a function or struct as deprecated. -// Note that clang supports __deprecated_enum_msg, which may be useful to support. -// -// Example usage: -// OVR_DEPRECATED void Test(); // Use on the function declaration, as opposed to definition. -// -// struct OVR_DEPRECATED Test{ ... }; -// -// OVR_DEPRECATED_MSG("Test is deprecated") -// void Test(); - -#if !defined(OVR_DEPRECATED) - #if defined(OVR_CC_MSVC) && (OVR_CC_VERSION > 1400) // VS2005+ - #define OVR_DEPRECATED __declspec(deprecated) - #define OVR_DEPRECATED_MSG(msg) __declspec(deprecated(msg)) - #elif defined(OVR_CC_CLANG) && OVR_CC_HAS_FEATURE(attribute_deprecated_with_message) - #define OVR_DEPRECATED __declspec(deprecated) - #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) - #elif defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 405) - #define OVR_DEPRECATED __declspec(deprecated) - #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) - #elif !defined(OVR_CC_MSVC) - #define OVR_DEPRECATED __attribute__((deprecated)) - #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated)) - #else - #define OVR_DEPRECATED - #define OVR_DEPRECATED_MSG(msg) - #endif -#endif - - -//----------------------------------------------------------------------------------- -// ***** OVR_UNUSED - Unused Argument handling -// Macro to quiet compiler warnings about unused parameters/variables. -// -// Example usage: -// void Test() { -// int x = SomeFunction(); -// OVR_UNUSED(x); -// } -// - -#if defined(OVR_CC_GNU) -# define OVR_UNUSED(a) do {__typeof__ (&a) __attribute__ ((unused)) __tmp = &a; } while(0) -#else -# define OVR_UNUSED(a) (a) -#endif - -#define OVR_UNUSED1(a1) OVR_UNUSED(a1) -#define OVR_UNUSED2(a1,a2) OVR_UNUSED(a1); OVR_UNUSED(a2) -#define OVR_UNUSED3(a1,a2,a3) OVR_UNUSED2(a1,a2); OVR_UNUSED(a3) -#define OVR_UNUSED4(a1,a2,a3,a4) OVR_UNUSED3(a1,a2,a3); OVR_UNUSED(a4) -#define OVR_UNUSED5(a1,a2,a3,a4,a5) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED(a5) -#define OVR_UNUSED6(a1,a2,a3,a4,a5,a6) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED2(a5,a6) -#define OVR_UNUSED7(a1,a2,a3,a4,a5,a6,a7) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED3(a5,a6,a7) -#define OVR_UNUSED8(a1,a2,a3,a4,a5,a6,a7,a8) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED4(a5,a6,a7,a8) -#define OVR_UNUSED9(a1,a2,a3,a4,a5,a6,a7,a8,a9) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED5(a5,a6,a7,a8,a9) - - -//----------------------------------------------------------------------------------- -// ***** Configuration Macros -// -// Expands to the current build type as a const char string literal. -// Acts as the following declaration: const char OVR_BUILD_STRING[]; - -#ifdef OVR_BUILD_DEBUG -# define OVR_BUILD_STRING "Debug" -#else -# define OVR_BUILD_STRING "Release" -#endif - - -//// Enables SF Debugging information -//# define OVR_BUILD_DEBUG - -// OVR_DEBUG_STATEMENT injects a statement only in debug builds. -// OVR_DEBUG_SELECT injects first argument in debug builds, second argument otherwise. -#ifdef OVR_BUILD_DEBUG -#define OVR_DEBUG_STATEMENT(s) s -#define OVR_DEBUG_SELECT(d, nd) d -#else -#define OVR_DEBUG_STATEMENT(s) -#define OVR_DEBUG_SELECT(d, nd) nd -#endif - - -#define OVR_ENABLE_THREADS -// -// Prevents OVR from defining new within -// type macros, so developers can override -// new using the #define new new(...) trick -// - used with OVR_DEFINE_NEW macro -//# define OVR_BUILD_DEFINE_NEW -// - - -//----------------------------------------------------------------------------------- -// ***** Find normal allocations -// -// Our allocations are all supposed to go through the OVR System Allocator, so that -// they can be run through a game's own preferred allocator. Occasionally we will -// accidentally introduce new code that doesn't adhere to this contract. And it -// then becomes difficult to track down these normal allocations. This piece of -// code makes it easy to check for normal allocations by asserting whenever they -// happen in our code. - -//#define OVR_FIND_NORMAL_ALLOCATIONS -#ifdef OVR_FIND_NORMAL_ALLOCATIONS - -inline void* operator new (size_t size, const char* filename, int line) -{ - void* ptr = new char[size]; - OVR_ASSERT(false); - return ptr; -} - -#define new new(__FILE__, __LINE__) - -#endif // OVR_FIND_NORMAL_ALLOCATIONS - - -#include "OVR_Nullptr.h" - - - - -#endif // OVR_Types_h diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp b/LibOVR/Src/Kernel/OVR_UTF8Util.cpp deleted file mode 100644 index 68e58ea..0000000 --- a/LibOVR/Src/Kernel/OVR_UTF8Util.cpp +++ /dev/null @@ -1,556 +0,0 @@ -/************************************************************************** - -Filename : OVR_UTF8Util.cpp -Content : UTF8 Unicode character encoding/decoding support -Created : September 19, 2012 -Notes : -Notes : Much useful info at "UTF-8 and Unicode FAQ" - http://www.cl.cam.ac.uk/~mgk25/unicode.html - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_UTF8Util.h" - -namespace OVR { namespace UTF8Util { - -intptr_t OVR_STDCALL GetLength(const char* buf, intptr_t buflen) -{ - const char* p = buf; - intptr_t length = 0; - - if (buflen != -1) - { - while (p - buf < buflen) - { - // We should be able to have ASStrings with 0 in the middle. - UTF8Util::DecodeNextChar_Advance0(&p); - length++; - } - } - else - { - while (UTF8Util::DecodeNextChar_Advance0(&p)) - length++; - } - - return length; -} - -uint32_t OVR_STDCALL GetCharAt(intptr_t index, const char* putf8str, intptr_t length) -{ - const char* buf = putf8str; - uint32_t c = 0; - - if (length != -1) - { - while (buf - putf8str < length) - { - c = UTF8Util::DecodeNextChar_Advance0(&buf); - if (index == 0) - return c; - index--; - } - - return c; - } - - do - { - c = UTF8Util::DecodeNextChar_Advance0(&buf); - index--; - - if (c == 0) - { - // We've hit the end of the string; don't go further. - OVR_ASSERT(index == 0); - return c; - } - } while (index >= 0); - - return c; -} - -intptr_t OVR_STDCALL GetByteIndex(intptr_t index, const char *putf8str, intptr_t length) -{ - const char* buf = putf8str; - - if (length != -1) - { - while ((buf - putf8str) < length && index > 0) - { - UTF8Util::DecodeNextChar_Advance0(&buf); - index--; - } - - return buf-putf8str; - } - - while (index > 0) - { - uint32_t c = UTF8Util::DecodeNextChar_Advance0(&buf); - index--; - - if (c == 0) - return buf-putf8str; - }; - - return buf-putf8str; -} - -int OVR_STDCALL GetEncodeCharSize(uint32_t ucs_character) -{ - if (ucs_character <= 0x7F) - return 1; - else if (ucs_character <= 0x7FF) - return 2; - else if (ucs_character <= 0xFFFF) - return 3; - else if (ucs_character <= 0x1FFFFF) - return 4; - else if (ucs_character <= 0x3FFFFFF) - return 5; - else if (ucs_character <= 0x7FFFFFFF) - return 6; - else - return 0; -} - -uint32_t OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer) -{ - uint32_t uc; - char c; - - // Security considerations: - // - // Changed, this is now only the case for DecodeNextChar: - // - If we hit a zero byte, we want to return 0 without stepping - // the buffer pointer past the 0. th - // - // If we hit an "overlong sequence"; i.e. a character encoded - // in a longer multibyte string than is necessary, then we - // need to discard the character. This is so attackers can't - // disguise dangerous characters or character sequences -- - // there is only one valid encoding for each character. - // - // If we decode characters { 0xD800 .. 0xDFFF } or { 0xFFFE, - // 0xFFFF } then we ignore them; they are not valid in UTF-8. - - // This isn't actually an invalid character; it's a valid char that - // looks like an inverted question mark. -#define INVALID_CHAR 0x0FFFD - -#define FIRST_BYTE(mask, shift) \ - uc = (c & (mask)) << (shift); - -#define NEXT_BYTE(shift) \ - c = **putf8Buffer; \ - if (c == 0) return 0; /* end of buffer, do not advance */ \ - if ((c & 0xC0) != 0x80) return INVALID_CHAR; /* standard check */ \ - (*putf8Buffer)++; \ - uc |= (c & 0x3F) << shift; - - c = **putf8Buffer; - (*putf8Buffer)++; - if (c == 0) - return 0; // End of buffer. - - if ((c & 0x80) == 0) return (uint32_t) c; // Conventional 7-bit ASCII. - - // Multi-byte sequences. - if ((c & 0xE0) == 0xC0) - { - // Two-byte sequence. - FIRST_BYTE(0x1F, 6); - NEXT_BYTE(0); - if (uc < 0x80) return INVALID_CHAR; // overlong - return uc; - } - else if ((c & 0xF0) == 0xE0) - { - // Three-byte sequence. - FIRST_BYTE(0x0F, 12); - NEXT_BYTE(6); - NEXT_BYTE(0); - if (uc < 0x800) return INVALID_CHAR; // overlong - // Not valid ISO 10646, but Flash requires these to work - // see AS3 test e15_5_3_2_3 for String.fromCharCode().charCodeAt(0) - // if (uc >= 0x0D800 && uc <= 0x0DFFF) return INVALID_CHAR; - // if (uc == 0x0FFFE || uc == 0x0FFFF) return INVALID_CHAR; // not valid ISO 10646 - return uc; - } - else if ((c & 0xF8) == 0xF0) - { - // Four-byte sequence. - FIRST_BYTE(0x07, 18); - NEXT_BYTE(12); - NEXT_BYTE(6); - NEXT_BYTE(0); - if (uc < 0x010000) return INVALID_CHAR; // overlong - return uc; - } - else if ((c & 0xFC) == 0xF8) - { - // Five-byte sequence. - FIRST_BYTE(0x03, 24); - NEXT_BYTE(18); - NEXT_BYTE(12); - NEXT_BYTE(6); - NEXT_BYTE(0); - if (uc < 0x0200000) return INVALID_CHAR; // overlong - return uc; - } - else if ((c & 0xFE) == 0xFC) - { - // Six-byte sequence. - FIRST_BYTE(0x01, 30); - NEXT_BYTE(24); - NEXT_BYTE(18); - NEXT_BYTE(12); - NEXT_BYTE(6); - NEXT_BYTE(0); - if (uc < 0x04000000) return INVALID_CHAR; // overlong - return uc; - } - else - { - // Invalid. - return INVALID_CHAR; - } -} - - -void OVR_STDCALL EncodeChar(char* pbuffer, intptr_t* pindex, uint32_t ucs_character) -{ - if (ucs_character <= 0x7F) - { - // Plain single-byte ASCII. - pbuffer[(*pindex)++] = (char) ucs_character; - } - else if (ucs_character <= 0x7FF) - { - // Two bytes. - pbuffer[(*pindex)++] = 0xC0 | (char)(ucs_character >> 6); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else if (ucs_character <= 0xFFFF) - { - // Three bytes. - pbuffer[(*pindex)++] = 0xE0 | (char)(ucs_character >> 12); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else if (ucs_character <= 0x1FFFFF) - { - // Four bytes. - pbuffer[(*pindex)++] = 0xF0 | (char)(ucs_character >> 18); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else if (ucs_character <= 0x3FFFFFF) - { - // Five bytes. - pbuffer[(*pindex)++] = 0xF8 | (char)(ucs_character >> 24); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else if (ucs_character <= 0x7FFFFFFF) - { - // Six bytes. - pbuffer[(*pindex)++] = 0xFC | (char)(ucs_character >> 30); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 24) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); - pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); - } - else - { - // Invalid char; don't encode anything. - } -} - -intptr_t OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, intptr_t length) -{ - intptr_t len = 0; - if (length != -1) - for (int i = 0; i < length; i++) - { - len += GetEncodeCharSize(pchar[i]); - } - else - for (int i = 0;; i++) - { - if (pchar[i] == 0) - return len; - len += GetEncodeCharSize(pchar[i]); - } - return len; -} - -void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, intptr_t length) -{ - intptr_t ofs = 0; - if (length != -1) - { - for (int i = 0; i < length; i++) - { - EncodeChar(pbuff, &ofs, pchar[i]); - } - } - else - { - for (int i = 0;; i++) - { - if (pchar[i] == 0) - break; - EncodeChar(pbuff, &ofs, pchar[i]); - } - } - pbuff[ofs] = 0; -} - -size_t OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, intptr_t bytesLen) -{ - wchar_t *pbegin = pbuff; - if (bytesLen == -1) - { - while (1) - { - uint32_t ch = DecodeNextChar_Advance0(&putf8str); - if (ch == 0) - break; - else if (ch >= 0xFFFF) - ch = 0xFFFD; - *pbuff++ = wchar_t(ch); - } - } - else - { - const char* p = putf8str; - while ((p - putf8str) < bytesLen) - { - uint32_t ch = DecodeNextChar_Advance0(&p); - if (ch >= 0xFFFF) - ch = 0xFFFD; - *pbuff++ = wchar_t(ch); - } - } - - *pbuff = 0; - return pbuff - pbegin; -} - - -#ifdef UTF8_UNIT_TEST - -// Compile this test case with something like: -// -// gcc utf8.cpp -g -I.. -DUTF8_UNIT_TEST -lstdc++ -o utf8_test -// -// or -// -// cl utf8.cpp -Zi -Od -DUTF8_UNIT_TEST -I.. -// -// If possible, try running the test program with the first arg -// pointing at the file: -// -// http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt -// -// and examine the results by eye to make sure they are acceptable to -// you. - - -#include "base/utility.h" -#include - - -bool check_equal(const char* utf8_in, const uint32_t* ucs_in) -{ - for (;;) - { - uint32_t next_ucs = *ucs_in++; - uint32_t next_ucs_from_utf8 = utf8::decode_next_unicode_character(&utf8_in); - if (next_ucs != next_ucs_from_utf8) - { - return false; - } - if (next_ucs == 0) - { - OVR_ASSERT(next_ucs_from_utf8 == 0); - break; - } - } - - return true; -} - - -void log_ascii(const char* line) -{ - for (;;) - { - unsigned char c = (unsigned char) *line++; - if (c == 0) - { - // End of line. - return; - } - else if (c != '\n' - && (c < 32 || c > 127)) - { - // Non-printable as plain ASCII. - printf("<0x%02X>", (int) c); - } - else - { - printf("%c", c); - } - } -} - - -void log_ucs(const uint32_t* line) -{ - for (;;) - { - uint32_t uc = *line++; - if (uc == 0) - { - // End of line. - return; - } - else if (uc != '\n' - && (uc < 32 || uc > 127)) - { - // Non-printable as plain ASCII. - printf("", uc); - } - else - { - printf("%c", (char) uc); - } - } -} - - -// Simple canned test. -int main(int argc, const char* argv[]) -{ - { - const char* test8 = "Ignacio Castaño"; - const uint32_t test32[] = - { - 0x49, 0x67, 0x6E, 0x61, 0x63, - 0x69, 0x6F, 0x20, 0x43, 0x61, - 0x73, 0x74, 0x61, 0xF1, 0x6F, - 0x00 - }; - - OVR_ASSERT(check_equal(test8, test32)); - } - - // If user passed an arg, try reading the file as UTF-8 encoded text. - if (argc > 1) - { - const char* filename = argv[1]; - FILE* fp = fopen(filename, "rb"); - if (fp == NULL) - { - printf("Can't open file '%s'\n", filename); - return 1; - } - - // Read lines from the file, encode/decode them, and highlight discrepancies. - const int LINE_SIZE = 200; // max line size - char line_buffer_utf8[LINE_SIZE]; - char reencoded_utf8[6 * LINE_SIZE]; - uint32_t line_buffer_ucs[LINE_SIZE]; - - int byte_counter = 0; - for (;;) - { - int c = fgetc(fp); - if (c == EOF) - { - // Done. - break; - } - line_buffer_utf8[byte_counter++] = c; - if (c == '\n' || byte_counter >= LINE_SIZE - 2) - { - // End of line. Process the line. - line_buffer_utf8[byte_counter++] = 0; // terminate. - - // Decode into UCS. - const char* p = line_buffer_utf8; - uint32_t* q = line_buffer_ucs; - for (;;) - { - uint32_t uc = UTF8Util::DecodeNextChar(&p); - *q++ = uc; - - OVR_ASSERT(q < line_buffer_ucs + LINE_SIZE); - OVR_ASSERT(p < line_buffer_utf8 + LINE_SIZE); - - if (uc == 0) break; - } - - // Encode back into UTF-8. - q = line_buffer_ucs; - int index = 0; - for (;;) - { - uint32_t uc = *q++; - OVR_ASSERT(index < LINE_SIZE * 6 - 6); - int last_index = index; - UTF8Util::EncodeChar(reencoded_utf8, &index, uc); - OVR_ASSERT(index <= last_index + 6); - if (uc == 0) break; - } - - // This can be useful for debugging. -#if 0 - // Show the UCS and the re-encoded UTF-8. - log_ucs(line_buffer_ucs); - log_ascii(reencoded_utf8); -#endif // 0 - - OVR_ASSERT(check_equal(line_buffer_utf8, line_buffer_ucs)); - OVR_ASSERT(check_equal(reencoded_utf8, line_buffer_ucs)); - - // Start next line. - byte_counter = 0; - } - } - - fclose(fp); - } - - return 0; -} - - -#endif // UTF8_UNIT_TEST - -}} // namespace UTF8Util::OVR - diff --git a/LibOVR/Src/Kernel/OVR_UTF8Util.h b/LibOVR/Src/Kernel/OVR_UTF8Util.h deleted file mode 100644 index 3b640f0..0000000 --- a/LibOVR/Src/Kernel/OVR_UTF8Util.h +++ /dev/null @@ -1,99 +0,0 @@ -/************************************************************************************ - -PublicHeader: OVR_Kernel.h -Filename : OVR_UTF8Util.h -Content : UTF8 Unicode character encoding/decoding support -Created : September 19, 2012 -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_UTF8Util_h -#define OVR_UTF8Util_h - -#include "OVR_Types.h" - -namespace OVR { namespace UTF8Util { - -//----------------------------------------------------------------------------------- - -// *** UTF8 string length and indexing. - -// Determines the length of UTF8 string in characters. -// If source length is specified (in bytes), null 0 character is counted properly. -intptr_t OVR_STDCALL GetLength(const char* putf8str, intptr_t length = -1); - -// Gets a decoded UTF8 character at index; you can access up to the index returned -// by GetLength. 0 will be returned for out of bounds access. -uint32_t OVR_STDCALL GetCharAt(intptr_t index, const char* putf8str, intptr_t length = -1); - -// Converts UTF8 character index into byte offset. -// -1 is returned if index was out of bounds. -intptr_t OVR_STDCALL GetByteIndex(intptr_t index, const char* putf8str, intptr_t length = -1); - - -// *** 16-bit Unicode string Encoding/Decoding routines. - -// Determines the number of bytes necessary to encode a string. -// Does not count the terminating 0 (null) character. -intptr_t OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, intptr_t length = -1); - -// Encodes a unicode (UCS-2 only) string into a buffer. The size of buffer must be at -// least GetEncodeStringSize() + 1. -void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, intptr_t length = -1); - -// Decode UTF8 into a wchar_t buffer. Must have GetLength()+1 characters available. -// Characters over 0xFFFF are replaced with 0xFFFD. -// Returns the length of resulting string (number of characters) -size_t OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, intptr_t bytesLen = -1); - - -// *** Individual character Encoding/Decoding. - -// Determined the number of bytes necessary to encode a UCS character. -int OVR_STDCALL GetEncodeCharSize(uint32_t ucsCharacter); - -// Encodes the given UCS character into the given UTF-8 buffer. -// Writes the data starting at buffer[offset], and -// increments offset by the number of bytes written. -// May write up to 6 bytes, so make sure there's room in the buffer -void OVR_STDCALL EncodeChar(char* pbuffer, intptr_t* poffset, uint32_t ucsCharacter); - -// Return the next Unicode character in the UTF-8 encoded buffer. -// Invalid UTF-8 sequences produce a U+FFFD character as output. -// Advances *utf8_buffer past the character returned. Pointer advance -// occurs even if the terminating 0 character is hit, since that allows -// strings with middle '\0' characters to be supported. -uint32_t OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer); - -// Safer version of DecodeNextChar, which doesn't advance pointer if -// null character is hit. -inline uint32_t DecodeNextChar(const char** putf8Buffer) -{ - uint32_t ch = DecodeNextChar_Advance0(putf8Buffer); - if (ch == 0) - (*putf8Buffer)--; - return ch; -} - - -}} // OVR::UTF8Util - -#endif diff --git a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c b/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c deleted file mode 100644 index 142faf1..0000000 --- a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.c +++ /dev/null @@ -1,2955 +0,0 @@ -/* This file was generated by the MIG utility with: - mig /usr/include/mach/mach_exc.defs - We pre-generate them instead of generate them at compile-time because we - need to rename some of the functions to append _OVR so we don't get conflicts - with any other versions of these functions the application may have. -*/ - -/* Begin mach_excUser.c */ - -#define __MIG_check__Reply__mach_exc_subsystem__ 1 -#define __NDR_convert__Reply__mach_exc_subsystem__ 1 -#define __NDR_convert__mig_reply_error_subsystem__ 1 - -#include "OVR_mach_exc_OSX.h" - -#if defined(__cplusplus) - extern "C" { -#endif - -#ifndef mig_internal -#define mig_internal static __inline__ -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#if !defined(__MigTypeCheck) && defined(TypeCheck) -#define __MigTypeCheck TypeCheck /* Legacy setting */ -#endif /* !defined(__MigTypeCheck) */ - -#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) -#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ -#endif /* !defined(__MigKernelSpecificCode) */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#if !defined(_WALIGN_) -#define _WALIGN_(x) (((x) + 3) & ~3) -#endif /* !defined(_WALIGN_) */ - -#if !defined(_WALIGNSZ_) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#endif /* !defined(_WALIGNSZ_) */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 0 -#endif /* UseStaticTemplates */ - -#ifndef __MachMsgErrorWithTimeout -#define __MachMsgErrorWithTimeout(_R_) { \ - switch (_R_) { \ - case MACH_SEND_INVALID_DATA: \ - case MACH_SEND_INVALID_DEST: \ - case MACH_SEND_INVALID_HEADER: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ - break; \ - case MACH_SEND_TIMED_OUT: \ - case MACH_RCV_TIMED_OUT: \ - default: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ - } \ -} -#endif /* __MachMsgErrorWithTimeout */ - -#ifndef __MachMsgErrorWithoutTimeout -#define __MachMsgErrorWithoutTimeout(_R_) { \ - switch (_R_) { \ - case MACH_SEND_INVALID_DATA: \ - case MACH_SEND_INVALID_DEST: \ - case MACH_SEND_INVALID_HEADER: \ - mig_put_reply_port(InP->Head.msgh_reply_port); \ - break; \ - default: \ - mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ - } \ -} -#endif /* __MachMsgErrorWithoutTimeout */ - -#ifndef __DeclareSendRpc -#define __DeclareSendRpc(_NUM_, _NAME_) -#endif /* __DeclareSendRpc */ - -#ifndef __BeforeSendRpc -#define __BeforeSendRpc(_NUM_, _NAME_) -#endif /* __BeforeSendRpc */ - -#ifndef __AfterSendRpc -#define __AfterSendRpc(_NUM_, _NAME_) -#endif /* __AfterSendRpc */ - -#ifndef __DeclareSendSimple -#define __DeclareSendSimple(_NUM_, _NAME_) -#endif /* __DeclareSendSimple */ - -#ifndef __BeforeSendSimple -#define __BeforeSendSimple(_NUM_, _NAME_) -#endif /* __BeforeSendSimple */ - -#ifndef __AfterSendSimple -#define __AfterSendSimple(_NUM_, _NAME_) -#endif /* __AfterSendSimple */ - -#ifndef msgh_request_port - #define msgh_request_port msgh_remote_port -#endif - -#ifndef msgh_reply_port - #define msgh_reply_port msgh_local_port -#endif - - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__mach_exc_subsystem__ -#if !defined(__MIG_check__Reply__mach_exception_raise_t__defined) -#define __MIG_check__Reply__mach_exception_raise_t__defined -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined -#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(a, f) \ - __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined */ - - - - - -mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_t_OVR(__Reply__mach_exception_raise_t *Out0P) -{ - - typedef __Reply__mach_exception_raise_t __Reply; - if (Out0P->Head.msgh_id != 2505) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - - #if __MigTypeCheck - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (Out0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Reply))) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined */ - { - return Out0P->RetCode; - } -} -#endif /* !defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ -#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine mach_exception_raise_OVR */ -mig_external kern_return_t mach_exception_raise_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt -) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_msg_trailer_t trailer; - } Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - unsigned int msgh_size; - - #ifdef __MIG_check__Reply__mach_exception_raise_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Reply__mach_exception_raise_t__defined */ - - __DeclareSendRpc(2405, "mach_exception_raise_OVR") - - #if UseStaticTemplates - const static mach_msg_port_descriptor_t threadTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 19, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; - #endif /* UseStaticTemplates */ - - #if UseStaticTemplates - const static mach_msg_port_descriptor_t taskTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 19, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; - #endif /* UseStaticTemplates */ - - InP->msgh_body.msgh_descriptor_count = 2; - #if UseStaticTemplates - InP->thread = threadTemplate; - InP->thread.name = thread; - #else /* UseStaticTemplates */ - InP->thread.name = thread; - InP->thread.disposition = 19; - InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; - #endif /* UseStaticTemplates */ - - #if UseStaticTemplates - InP->task = taskTemplate; - InP->task.name = task; - #else /* UseStaticTemplates */ - InP->task.name = task; - InP->task.disposition = 19; - InP->task.type = MACH_MSG_PORT_DESCRIPTOR; - #endif /* UseStaticTemplates */ - - InP->NDR = NDR_record; - - InP->exception = exception; - - if (codeCnt > 2) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); - - InP->codeCnt = codeCnt; - - msgh_size = (mach_msg_size_t)(sizeof(Request) - 16) + ((8 * codeCnt)); - InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = exception_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 2405; - - __BeforeSendRpc(2405, "mach_exception_raise_OVR") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(2405, "mach_exception_raise_OVR") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - - #if defined(__MIG_check__Reply__mach_exception_raise_t__defined) - check_result = __MIG_check__Reply__mach_exception_raise_t_OVR((__Reply__mach_exception_raise_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } - #endif /* defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__mach_exc_subsystem__ -#if !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) -#define __MIG_check__Reply__mach_exception_raise_state_t__defined -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined -#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(a, f) \ - __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__thread_state_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__int_rep__natural_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) -#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__thread_state_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__char_rep__natural_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) -#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - - - - -#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__thread_state_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__float_rep__natural_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) -#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - - - - -mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_t_OVR(__Reply__mach_exception_raise_state_t *Out0P) -{ - - typedef __Reply__mach_exception_raise_state_t __Reply; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - - if (Out0P->Head.msgh_id != 2506) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - - #if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 576)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { - #ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); - #endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(&Out0P->new_stateCnt, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined */ - #if __MigTypeCheck - if ( Out0P->new_stateCnt > 144 ) - return MIG_TYPE_ERROR; - if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 576)) / 4 != Out0P->new_stateCnt) || - (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 576) + Out0P->new_stateCnt * 4)) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined */ - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.int_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if 0 || \ - defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ - 0 - if (Out0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined) - __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.char_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if 0 || \ - defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ - 0 - if (Out0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined) - __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.float_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ -#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine mach_exception_raise_state_OVR */ -mig_external kern_return_t mach_exception_raise_state_OVR -( - mach_port_t exception_port, - exception_type_t exception, - const mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - const thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - mach_msg_trailer_t trailer; - } Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - unsigned int msgh_size; - unsigned int msgh_size_delta; - - - #ifdef __MIG_check__Reply__mach_exception_raise_state_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Reply__mach_exception_raise_state_t__defined */ - - __DeclareSendRpc(2406, "mach_exception_raise_state_OVR") - - InP->NDR = NDR_record; - - InP->exception = exception; - - if (codeCnt > 2) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); - - InP->codeCnt = codeCnt; - - msgh_size_delta = (8 * codeCnt); - msgh_size = (mach_msg_size_t)(sizeof(Request) - 592) + msgh_size_delta; - InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); - - InP->flavor = *flavor; - - if (old_stateCnt > 144) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); - - InP->old_stateCnt = old_stateCnt; - - msgh_size += (4 * old_stateCnt); - InP = &Mess.In; - InP->Head.msgh_bits = - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = exception_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 2406; - - __BeforeSendRpc(2406, "mach_exception_raise_state_OVR") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(2406, "mach_exception_raise_state_OVR") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - - #if defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) - check_result = __MIG_check__Reply__mach_exception_raise_state_t_OVR((__Reply__mach_exception_raise_state_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } - #endif /* defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ - - *flavor = Out0P->flavor; - - if (Out0P->new_stateCnt > 144) { - (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 144); - *new_stateCnt = Out0P->new_stateCnt; - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); - - *new_stateCnt = Out0P->new_stateCnt; - - return KERN_SUCCESS; -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Reply__mach_exc_subsystem__ -#if !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) -#define __MIG_check__Reply__mach_exception_raise_state_identity_t__defined -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined -#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(a, f) \ - __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) -#elif defined(__NDR_convert__int_rep__kern_return_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(a, f) \ - __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__thread_state_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__int_rep__natural_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) -#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - - -#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined -#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined */ - - - -#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - - -#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__thread_state_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__char_rep__natural_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) -#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - - - - -#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - - -#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__thread_state_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__float_rep__natural_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) -#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined -#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - - - - -mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_identity_t(__Reply__mach_exception_raise_state_identity_t *Out0P) -{ - - typedef __Reply__mach_exception_raise_state_identity_t __Reply; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - - if (Out0P->Head.msgh_id != 2507) { - if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) - { return MIG_SERVER_DIED; } - else - { return MIG_REPLY_MISMATCH; } - } - - #if __MigTypeCheck - msgh_size = Out0P->Head.msgh_size; - - if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 576)) && - (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || - Out0P->RetCode == KERN_SUCCESS))) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - if (Out0P->RetCode != KERN_SUCCESS) { - #ifdef __NDR_convert__mig_reply_error_t__defined - __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); - #endif /* __NDR_convert__mig_reply_error_t__defined */ - return ((mig_reply_error_t *)Out0P)->RetCode; - } - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(&Out0P->new_stateCnt, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined */ - #if __MigTypeCheck - if ( Out0P->new_stateCnt > 144 ) - return MIG_TYPE_ERROR; - if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 576)) / 4 != Out0P->new_stateCnt) || - (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 576) + Out0P->new_stateCnt * 4)) - { return MIG_TYPE_ERROR ; } - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ - defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined) - if (Out0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined */ - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) - __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.int_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if 0 || \ - defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ - 0 - if (Out0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) - __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.char_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if 0 || \ - defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ - 0 - if (Out0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) - __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.float_rep, Out0P->new_stateCnt); - #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ -#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine mach_exception_raise_state_identity_OVR */ -mig_external kern_return_t mach_exception_raise_state_identity_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - mach_msg_trailer_t trailer; - } Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply; - #ifdef __MigPackStructs - #pragma pack() - #endif - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - union { - Request In; - Reply Out; - } Mess; - - Request *InP = &Mess.In; - Reply *Out0P = &Mess.Out; - - mach_msg_return_t msg_result; - unsigned int msgh_size; - unsigned int msgh_size_delta; - - - #ifdef __MIG_check__Reply__mach_exception_raise_state_identity_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Reply__mach_exception_raise_state_identity_t__defined */ - - __DeclareSendRpc(2407, "mach_exception_raise_state_identity_OVR") - - #if UseStaticTemplates - const static mach_msg_port_descriptor_t threadTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 19, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; - #endif /* UseStaticTemplates */ - - #if UseStaticTemplates - const static mach_msg_port_descriptor_t taskTemplate = { - /* name = */ MACH_PORT_NULL, - /* pad1 = */ 0, - /* pad2 = */ 0, - /* disp = */ 19, - /* type = */ MACH_MSG_PORT_DESCRIPTOR, - }; - #endif /* UseStaticTemplates */ - - InP->msgh_body.msgh_descriptor_count = 2; - #if UseStaticTemplates - InP->thread = threadTemplate; - InP->thread.name = thread; - #else /* UseStaticTemplates */ - InP->thread.name = thread; - InP->thread.disposition = 19; - InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; - #endif /* UseStaticTemplates */ - - #if UseStaticTemplates - InP->task = taskTemplate; - InP->task.name = task; - #else /* UseStaticTemplates */ - InP->task.name = task; - InP->task.disposition = 19; - InP->task.type = MACH_MSG_PORT_DESCRIPTOR; - #endif /* UseStaticTemplates */ - - InP->NDR = NDR_record; - - InP->exception = exception; - - if (codeCnt > 2) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); - - InP->codeCnt = codeCnt; - - msgh_size_delta = (8 * codeCnt); - msgh_size = (mach_msg_size_t)(sizeof(Request) - 592) + msgh_size_delta; - InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); - - InP->flavor = *flavor; - - if (old_stateCnt > 144) { - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); - - InP->old_stateCnt = old_stateCnt; - - msgh_size += (4 * old_stateCnt); - InP = &Mess.In; - InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| - MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); - /* msgh_size passed as argument */ - InP->Head.msgh_request_port = exception_port; - InP->Head.msgh_reply_port = mig_get_reply_port(); - InP->Head.msgh_id = 2407; - - __BeforeSendRpc(2407, "mach_exception_raise_state_identity_OVR") - msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); - __AfterSendRpc(2407, "mach_exception_raise_state_identity_OVR") - if (msg_result != MACH_MSG_SUCCESS) { - __MachMsgErrorWithoutTimeout(msg_result); - { return msg_result; } - } - - - #if defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) - check_result = __MIG_check__Reply__mach_exception_raise_state_identity_t((__Reply__mach_exception_raise_state_identity_t *)Out0P); - if (check_result != MACH_MSG_SUCCESS) - { return check_result; } - #endif /* defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ - - *flavor = Out0P->flavor; - - if (Out0P->new_stateCnt > 144) { - (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 144); - *new_stateCnt = Out0P->new_stateCnt; - { return MIG_ARRAY_TOO_LARGE; } - } - (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); - - *new_stateCnt = Out0P->new_stateCnt; - - return KERN_SUCCESS; -} - -#if defined(__cplusplus) - } /* extern "C" */ -#endif - -/* End mach_excUser.c */ - - - - -/* Begin mach_excServer.c */ - -/* Module mach_exc */ - -#define __MIG_check__Request__mach_exc_subsystem__ 1 -#define __NDR_convert__Request__mach_exc_subsystem__ 1 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#if defined(__cplusplus) - extern "C" { -#endif - -#ifndef mig_internal -#define mig_internal static __inline__ -#endif /* mig_internal */ - -#ifndef mig_external -#define mig_external -#endif /* mig_external */ - -#if !defined(__MigTypeCheck) && defined(TypeCheck) -#define __MigTypeCheck TypeCheck /* Legacy setting */ -#endif /* !defined(__MigTypeCheck) */ - -#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) -#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ -#endif /* !defined(__MigKernelSpecificCode) */ - -#ifndef LimitCheck -#define LimitCheck 0 -#endif /* LimitCheck */ - -#ifndef min -#define min(a,b) ( ((a) < (b))? (a): (b) ) -#endif /* min */ - -#if !defined(_WALIGN_) -#define _WALIGN_(x) (((x) + 3) & ~3) -#endif /* !defined(_WALIGN_) */ - -#if !defined(_WALIGNSZ_) -#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) -#endif /* !defined(_WALIGNSZ_) */ - -#ifndef UseStaticTemplates -#define UseStaticTemplates 0 -#endif /* UseStaticTemplates */ - -#ifndef __DeclareRcvRpc -#define __DeclareRcvRpc(_NUM_, _NAME_) -#endif /* __DeclareRcvRpc */ - -#ifndef __BeforeRcvRpc -#define __BeforeRcvRpc(_NUM_, _NAME_) -#endif /* __BeforeRcvRpc */ - -#ifndef __AfterRcvRpc -#define __AfterRcvRpc(_NUM_, _NAME_) -#endif /* __AfterRcvRpc */ - -#ifndef __DeclareRcvSimple -#define __DeclareRcvSimple(_NUM_, _NAME_) -#endif /* __DeclareRcvSimple */ - -#ifndef __BeforeRcvSimple -#define __BeforeRcvSimple(_NUM_, _NAME_) -#endif /* __BeforeRcvSimple */ - -#ifndef __AfterRcvSimple -#define __AfterRcvSimple(_NUM_, _NAME_) -#endif /* __AfterRcvSimple */ - -#define novalue void - -#ifndef msgh_request_port - #define msgh_request_port msgh_local_port -#endif -#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) -#ifndef msgh_reply_port - #define msgh_reply_port msgh_remote_port -#endif -#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) - -#define MIG_RETURN_ERROR(X, code) {\ - ((mig_reply_error_t *)X)->RetCode = code;\ - ((mig_reply_error_t *)X)->NDR = NDR_record;\ - return;\ - } - -/* typedefs for all requests */ - -#ifndef __Request__mach_exc_subsystem__defined -#define __Request__mach_exc_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - } __Request__mach_exception_raise_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } __Request__mach_exception_raise_state_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } __Request__mach_exception_raise_state_identity_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__mach_exc_subsystem__defined */ - -/* typedefs for all replies */ - -#ifndef __Reply__mach_exc_subsystem__defined -#define __Reply__mach_exc_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_exception_raise_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply__mach_exception_raise_state_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply__mach_exception_raise_state_identity_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__mach_exc_subsystem__defined */ - - -/* union of all replies */ - -#ifndef __ReplyUnion__catch_mach_exc_subsystem__defined -#define __ReplyUnion__catch_mach_exc_subsystem__defined -union __ReplyUnion__catch_mach_exc_subsystem { - __Reply__mach_exception_raise_t Reply_mach_exception_raise; - __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; - __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; -}; -#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ -/* Forward Declarations */ - - -mig_internal novalue _Xmach_exception_raise_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xmach_exception_raise_state_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -mig_internal novalue _Xmach_exception_raise_state_identity_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__mach_exc_subsystem__ -#if !defined(__MIG_check__Request__mach_exception_raise_t__defined) -#define __MIG_check__Request__mach_exception_raise_t__defined -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__int_rep__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__char_rep__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__float_rep__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined */ - - -mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) -{ - const size_t sizeofRequest = sizeof(__Request__mach_exception_raise_t); - - typedef __Request__mach_exception_raise_t __Request; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - msgh_size = In0P->Head.msgh_size; - if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->msgh_body.msgh_descriptor_count != 2) || - (msgh_size < (mach_msg_size_t)(sizeofRequest - 16)) || (msgh_size > (mach_msg_size_t)sizeofRequest)) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->thread.disposition != 17) - return MIG_TYPE_ERROR; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->task.disposition != 17) - return MIG_TYPE_ERROR; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ - #if __MigTypeCheck - if ( In0P->codeCnt > 2 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 16)) / 8 != In0P->codeCnt) || - (msgh_size != (mach_msg_size_t)(sizeofRequest - 16) + (8 * In0P->codeCnt))) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined) || \ - 0 - if (In0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined) || \ - 0 - if (In0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ -#endif /* __MIG_check__Request__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine catch_mach_exception_raise_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t catch_mach_exception_raise_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt -); - -/* Routine _Xmach_exception_raise_OVR */ -mig_internal novalue _Xmach_exception_raise_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - mach_msg_trailer_t trailer; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - typedef __Request__mach_exception_raise_t __Request; - typedef __Reply__mach_exception_raise_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Reply *OutP = (Reply *) OutHeadP; - #ifdef __MIG_check__Request__mach_exception_raise_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Request__mach_exception_raise_t__defined */ - - __DeclareRcvRpc(2405, "mach_exception_raise_OVR") - __BeforeRcvRpc(2405, "mach_exception_raise_OVR") - - #if defined(__MIG_check__Request__mach_exception_raise_t__defined) - check_result = __MIG_check__Request__mach_exception_raise_t_OVR((__Request *)In0P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } - #endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ - - OutP->RetCode = catch_mach_exception_raise_OVR(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); - - OutP->NDR = NDR_record; - - - __AfterRcvRpc(2405, "mach_exception_raise_OVR") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__mach_exc_subsystem__ -#if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) -#define __MIG_check__Request__mach_exception_raise_state_t__defined -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__int_rep__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__thread_state_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__int_rep__natural_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) -#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__char_rep__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__thread_state_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__char_rep__natural_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) -#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__float_rep__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#if defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__thread_state_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__float_rep__natural_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) -#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined */ - - -mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) -{ - - typedef __Request__mach_exception_raise_state_t __Request; - __Request *In1P; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - unsigned int msgh_size_delta; - - #if __MigTypeCheck - msgh_size = In0P->Head.msgh_size; - if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 592)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ - msgh_size_delta = (8 * In0P->codeCnt); - #if __MigTypeCheck - if ( In0P->codeCnt > 2 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 592)) / 8 < In0P->codeCnt) || - (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 592) + (8 * In0P->codeCnt))) - return MIG_BAD_ARGUMENTS; - msgh_size -= msgh_size_delta; - #endif /* __MigTypeCheck */ - - *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ - #if __MigTypeCheck - if ( In1P->old_stateCnt > 144 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 592)) / 4 != In1P->old_stateCnt) || - (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 592) + (4 * In1P->old_stateCnt))) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.int_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined) || \ - 0 || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ - 0 - if (In0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.char_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined) || \ - 0 || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ - 0 - if (In0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.float_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ -#endif /* __MIG_check__Request__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine mach_exception_raise_state_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t catch_mach_exception_raise_state_OVR -( - mach_port_t exception_port, - exception_type_t exception, - const mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - const thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -/* Routine _Xmach_exception_raise_state_OVR */ -mig_internal novalue _Xmach_exception_raise_state_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - mach_msg_trailer_t trailer; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - typedef __Request__mach_exception_raise_state_t __Request; - typedef __Reply__mach_exception_raise_state_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Request *In1P; - Reply *OutP = (Reply *) OutHeadP; - #ifdef __MIG_check__Request__mach_exception_raise_state_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ - - __DeclareRcvRpc(2406, "mach_exception_raise_state_OVR") - __BeforeRcvRpc(2406, "mach_exception_raise_state_OVR") - - #if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) - check_result = __MIG_check__Request__mach_exception_raise_state_t_OVR((__Request *)In0P, (__Request **)&In1P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } - #endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ - - OutP->new_stateCnt = 144; - - OutP->RetCode = catch_mach_exception_raise_state_OVR(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->flavor = In1P->flavor; - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 576) + (((4 * OutP->new_stateCnt))); - - __AfterRcvRpc(2406, "mach_exception_raise_state_OVR") -} - -#if ( __MigTypeCheck || __NDR_convert__ ) -#if __MIG_check__Request__mach_exc_subsystem__ -#if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) -#define __MIG_check__Request__mach_exception_raise_state_identity_t__defined -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__exception_type_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__int_rep__int64_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__int_rep__mach_exc__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__int__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__int((int *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__int_rep__int32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__int_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__thread_state_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__int_rep__natural_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) -#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__int_rep__uint32_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - -#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined -#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined -#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(a, f) \ - __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__exception_type_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__char_rep__int64_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__char_rep__mach_exc__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__int__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__int((int *)(a), f) -#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__char_rep__int32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__char_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - -#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__thread_state_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__char_rep__natural_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) -#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__char_rep__uint32_t__defined) -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__exception_type_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) -#elif defined(__NDR_convert__float_rep__int64_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ - __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#if defined(__NDR_convert__float_rep__mach_exc__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__int__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__int((int *)(a), f) -#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) -#elif defined(__NDR_convert__float_rep__int32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ - __NDR_convert__float_rep__int32_t((int32_t *)(a), f) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - -#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__thread_state_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) -#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) -#elif defined(__NDR_convert__float_rep__natural_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) -#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) -#elif defined(__NDR_convert__float_rep__uint32_t__defined) -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined -#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ - __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) -#endif /* defined(__NDR_convert__*__defined) */ -#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - - -mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) -{ - const size_t sizeofRequest = sizeof(__Request__mach_exception_raise_state_identity_t); - - typedef __Request__mach_exception_raise_state_identity_t __Request; - __Request *In1P; - #if __MigTypeCheck - unsigned int msgh_size; - #endif /* __MigTypeCheck */ - unsigned int msgh_size_delta; - - #if __MigTypeCheck - msgh_size = In0P->Head.msgh_size; - if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || - (In0P->msgh_body.msgh_descriptor_count != 2) || - (msgh_size < (mach_msg_size_t)(sizeofRequest - 592)) || (msgh_size > (mach_msg_size_t)sizeofRequest)) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->thread.disposition != 17) - return MIG_TYPE_ERROR; - #endif /* __MigTypeCheck */ - - #if __MigTypeCheck - if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || - In0P->task.disposition != 17) - return MIG_TYPE_ERROR; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ - msgh_size_delta = (8 * In0P->codeCnt); - #if __MigTypeCheck - if ( In0P->codeCnt > 2 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 592)) / 8 < In0P->codeCnt) || - (msgh_size < (mach_msg_size_t)(sizeofRequest - 592) + (8 * In0P->codeCnt))) - return MIG_BAD_ARGUMENTS; - msgh_size -= msgh_size_delta; - #endif /* __MigTypeCheck */ - - *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ - #if __MigTypeCheck - if ( In1P->old_stateCnt > 144 ) - return MIG_BAD_ARGUMENTS; - if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 592)) / 4 != In1P->old_stateCnt) || - (msgh_size != (mach_msg_size_t)(sizeofRequest - 592) + (4 * In1P->old_stateCnt))) - return MIG_BAD_ARGUMENTS; - #endif /* __MigTypeCheck */ - - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ - defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) - if (In0P->NDR.int_rep != NDR_record.int_rep) { - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.int_rep); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) - __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.int_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__int_rep...) */ - - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ - 0 || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ - 0 - if (In0P->NDR.char_rep != NDR_record.char_rep) { - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.char_rep); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) - __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.char_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__char_rep...) */ - - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ - 0 || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ - defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ - 0 - if (In0P->NDR.float_rep != NDR_record.float_rep) { - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.float_rep); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ - #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) - __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.float_rep, In1P->old_stateCnt); - #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ - } - #endif /* defined(__NDR_convert__float_rep...) */ - - return MACH_MSG_SUCCESS; -} -#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ -#endif /* __MIG_check__Request__mach_exc_subsystem__ */ -#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ - - -/* Routine catch_mach_exception_raise_state_identity_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t catch_mach_exception_raise_state_identity_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -/* Routine mach_exception_raise_state_identity_OVR */ -mig_internal novalue _Xmach_exception_raise_state_identity_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - - #ifdef __MigPackStructs - #pragma pack(4) - #endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - mach_msg_trailer_t trailer; - } Request; - #ifdef __MigPackStructs - #pragma pack() - #endif - typedef __Request__mach_exception_raise_state_identity_t __Request; - typedef __Reply__mach_exception_raise_state_identity_t Reply; - - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - Request *In0P = (Request *) InHeadP; - Request *In1P; - Reply *OutP = (Reply *) OutHeadP; - #ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined - kern_return_t check_result; - #endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ - - __DeclareRcvRpc(2407, "mach_exception_raise_state_identity_OVR") - __BeforeRcvRpc(2407, "mach_exception_raise_state_identity_OVR") - - #if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) - check_result = __MIG_check__Request__mach_exception_raise_state_identity_t_OVR((__Request *)In0P, (__Request **)&In1P); - if (check_result != MACH_MSG_SUCCESS) - { MIG_RETURN_ERROR(OutP, check_result); } - #endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ - - OutP->new_stateCnt = 144; - - OutP->RetCode = catch_mach_exception_raise_state_identity_OVR(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); - if (OutP->RetCode != KERN_SUCCESS) { - MIG_RETURN_ERROR(OutP, OutP->RetCode); - } - - OutP->NDR = NDR_record; - - - OutP->flavor = In1P->flavor; - OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 576) + (((4 * OutP->new_stateCnt))); - - __AfterRcvRpc(2407, "mach_exception_raise_state_identity_OVR") -} - - -#ifdef mig_external - mig_external -#else - extern -#endif /* mig_external */ - boolean_t mach_exc_server_OVR(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); - -#ifdef mig_external - mig_external -#else - extern -#endif /* mig_external */ - mig_routine_t mach_exc_server_routine_OVR(mach_msg_header_t *InHeadP); - - -/* Description of this subsystem, for use in direct RPC */ -const struct catch_mach_exc_subsystem_OVR { - mig_server_routine_t server; /* Server routine */ - mach_msg_id_t start; /* Min routine number */ - mach_msg_id_t end; /* Max routine number + 1 */ - unsigned int maxsize; /* Max msg size */ - vm_address_t reserved; /* Reserved */ - struct routine_descriptor /*Array of routine descriptors */ - routine[3]; -} catch_mach_exc_subsystem_OVR = { - mach_exc_server_routine_OVR, - 2405, - 2408, - (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), - (vm_address_t)0, - { - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_exception_raise_OVR, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_exception_raise_state_OVR, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, - { (mig_impl_routine_t) 0, - (mig_stub_routine_t) _Xmach_exception_raise_state_identity_OVR, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, - } -}; - -mig_external boolean_t mach_exc_server_OVR - (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) -{ - /* - * typedef struct { - * mach_msg_header_t Head; - * NDR_record_t NDR; - * kern_return_t RetCode; - * } mig_reply_error_t; - */ - - register mig_routine_t routine; - - OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); - OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; - /* Minimal size: routine() will update it if different */ - OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); - OutHeadP->msgh_local_port = MACH_PORT_NULL; - OutHeadP->msgh_id = InHeadP->msgh_id + 100; - - if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || - ((routine = catch_mach_exc_subsystem_OVR.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) - { - ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; - ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; - return FALSE; - } - (*routine) (InHeadP, OutHeadP); - return TRUE; -} - -mig_external mig_routine_t mach_exc_server_routine_OVR - (mach_msg_header_t *InHeadP) -{ - register int msgh_id; - - msgh_id = InHeadP->msgh_id - 2405; - - if ((msgh_id > 2) || (msgh_id < 0)) - return 0; - - return catch_mach_exc_subsystem_OVR.routine[msgh_id].stub_routine; -} - -#if defined(__cplusplus) - } /* extern "C" */ -#endif -/* End mach_excServer.c */ - - - diff --git a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.h b/LibOVR/Src/Kernel/OVR_mach_exc_OSX.h deleted file mode 100644 index 4a1bcf0..0000000 --- a/LibOVR/Src/Kernel/OVR_mach_exc_OSX.h +++ /dev/null @@ -1,277 +0,0 @@ -#ifndef _mach_exc_user_ -#define _mach_exc_user_ - -/* Module mach_exc */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef AUTOTEST -#ifndef FUNCTION_PTR_T -#define FUNCTION_PTR_T -typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); -typedef struct { - char *name; - function_ptr_t function; -} function_table_entry; -typedef function_table_entry *function_table_t; -#endif /* FUNCTION_PTR_T */ -#endif /* AUTOTEST */ - -#ifndef mach_exc_MSG_COUNT -#define mach_exc_MSG_COUNT 3 -#endif /* mach_exc_MSG_COUNT */ - -#include -#include -#include -#include - -#ifdef __BeforeMigUserHeader -__BeforeMigUserHeader -#endif /* __BeforeMigUserHeader */ - -#include -__BEGIN_DECLS - -#if defined(__cplusplus) - extern "C" { -#endif - -/* Routine mach_exception_raise_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t mach_exception_raise_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt -); - -/* Routine mach_exception_raise_state_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t mach_exception_raise_state_OVR -( - mach_port_t exception_port, - exception_type_t exception, - const mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - const thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -/* Routine mach_exception_raise_state_identity_OVR */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -kern_return_t mach_exception_raise_state_identity_OVR -( - mach_port_t exception_port, - mach_port_t thread, - mach_port_t task, - exception_type_t exception, - mach_exception_data_t code, - mach_msg_type_number_t codeCnt, - int *flavor, - thread_state_t old_state, - mach_msg_type_number_t old_stateCnt, - thread_state_t new_state, - mach_msg_type_number_t *new_stateCnt -); - -__END_DECLS - -/********************** Caution **************************/ -/* The following data types should be used to calculate */ -/* maximum message sizes only. The actual message may be */ -/* smaller, and the position of the arguments within the */ -/* message layout may vary from what is presented here. */ -/* For example, if any of the arguments are variable- */ -/* sized, and less than the maximum is sent, the data */ -/* will be packed tight in the actual message to reduce */ -/* the presence of holes. */ -/********************** Caution **************************/ - -/* typedefs for all requests */ - -#ifndef __Request__mach_exc_subsystem__defined -#define __Request__mach_exc_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - } __Request__mach_exception_raise_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } __Request__mach_exception_raise_state_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t thread; - mach_msg_port_descriptor_t task; - /* end of the kernel processed data */ - NDR_record_t NDR; - exception_type_t exception; - mach_msg_type_number_t codeCnt; - int64_t code[2]; - int flavor; - mach_msg_type_number_t old_stateCnt; - natural_t old_state[144]; - } __Request__mach_exception_raise_state_identity_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__mach_exc_subsystem__defined */ - -/* union of all requests */ - -#ifndef __RequestUnion__mach_exc_subsystem__defined -#define __RequestUnion__mach_exc_subsystem__defined -union __RequestUnion__mach_exc_subsystem { - __Request__mach_exception_raise_t Request_mach_exception_raise; - __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; - __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; -}; -#endif /* !__RequestUnion__mach_exc_subsystem__defined */ -/* typedefs for all replies */ - -#ifndef __Reply__mach_exc_subsystem__defined -#define __Reply__mach_exc_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - } __Reply__mach_exception_raise_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply__mach_exception_raise_state_t; -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif - typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int flavor; - mach_msg_type_number_t new_stateCnt; - natural_t new_state[144]; - } __Reply__mach_exception_raise_state_identity_t; -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__mach_exc_subsystem__defined */ - -/* union of all replies */ - -#ifndef __ReplyUnion__mach_exc_subsystem__defined -#define __ReplyUnion__mach_exc_subsystem__defined -union __ReplyUnion__mach_exc_subsystem { - __Reply__mach_exception_raise_t Reply_mach_exception_raise; - __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; - __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; -}; -#endif /* !__RequestUnion__mach_exc_subsystem__defined */ - -#ifndef subsystem_to_name_map_mach_exc -#define subsystem_to_name_map_mach_exc \ - { "mach_exception_raise_OVR", 2405 },\ - { "mach_exception_raise_state_OVR", 2406 },\ - { "mach_exception_raise_state_identity_OVR", 2407 } -#endif - -#ifdef __AfterMigUserHeader -__AfterMigUserHeader -#endif /* __AfterMigUserHeader */ - - -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ -boolean_t mach_exc_server_OVR( - mach_msg_header_t *InHeadP, - mach_msg_header_t *OutHeadP); - - -#if defined(__cplusplus) - } // extern"C" -#endif - - -#endif /* _mach_exc_user_ */ diff --git a/LibOVR/Src/Net/OVR_BitStream.cpp b/LibOVR/Src/Net/OVR_BitStream.cpp index b565f22..054f871 100644 --- a/LibOVR/Src/Net/OVR_BitStream.cpp +++ b/LibOVR/Src/Net/OVR_BitStream.cpp @@ -107,6 +107,18 @@ BitStream::BitStream( char* _data, const unsigned int lengthInBytes, bool _copyD data = ( unsigned char* ) _data; } +void BitStream::WrapBuffer(unsigned char* _data, const unsigned int lengthInBytes) +{ + if (copyData && numberOfBitsAllocated > (BITSTREAM_STACK_ALLOCATION_SIZE << 3)) + OVR_FREE(data); // Use realloc and free so we are more efficient than delete and new for resizing + + numberOfBitsUsed = lengthInBytes << 3; + readOffset = 0; + copyData = false; + numberOfBitsAllocated = lengthInBytes << 3; + data = (unsigned char*)_data; +} + // Use this if you pass a pointer copy to the constructor (_copyData==false) and want to overallocate to prevent reallocation void BitStream::SetNumberOfBitsAllocated( const BitSize_t lengthInBits ) { @@ -183,8 +195,9 @@ void BitStream::Write( BitStream *bitStream, BitSize_t numberOfBits ) numberOfBitsUsed+=BYTES_TO_BITS(numBytes); } - while (numberOfBits-->0 && bitStream->readOffset + 1 <= bitStream->numberOfBitsUsed) + while (numberOfBits > 0 && bitStream->readOffset + 1 <= bitStream->numberOfBitsUsed) { + --numberOfBits; numberOfBitsMod8 = numberOfBitsUsed & 7; if ( numberOfBitsMod8 == 0 ) { @@ -974,14 +987,8 @@ void BitStream::AssertCopyData( void ) } bool BitStream::IsNetworkOrderInternal(void) { -#if defined(_PS3) || defined(__PS3__) || defined(SN_TARGET_PS3) - return true; -#elif defined(SN_TARGET_PSP2) - return false; -#else - static unsigned long htonlValue = htonl(12345); - return htonlValue == 12345; -#endif + static unsigned long htonlValue = htonl(12345); + return htonlValue == 12345; } void BitStream::ReverseBytes(unsigned char *inByteArray, unsigned char *inOutByteArray, const unsigned int length) { diff --git a/LibOVR/Src/Net/OVR_BitStream.h b/LibOVR/Src/Net/OVR_BitStream.h index b1ddc8f..4e2d2ef 100644 --- a/LibOVR/Src/Net/OVR_BitStream.h +++ b/LibOVR/Src/Net/OVR_BitStream.h @@ -29,9 +29,13 @@ limitations under the License. #define OVR_Bitstream_h #include -#include "../Kernel/OVR_Types.h" -#include "../Kernel/OVR_Std.h" -#include "../Kernel/OVR_String.h" +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_Std.h" +#include "Kernel/OVR_String.h" + +#if defined(OVR_CC_MSVC) +#pragma warning(push) +#endif namespace OVR { namespace Net { @@ -76,6 +80,9 @@ public: /// Resets the bitstream for reuse. void Reset( void ); + // Releases the current data and points the bitstream at the provided buffer + void WrapBuffer(unsigned char* data, const unsigned int lengthInBytes); + /// \brief Bidirectional serialize/deserialize any integral type to/from a bitstream. /// \details Undefine __BITSTREAM_NATIVE_END if you need endian swapping. /// \param[in] writeToBitstream true to write from your data to this bitstream. False to read from this bitstream and write to your data @@ -1741,4 +1748,8 @@ BitStream& operator>>(BitStream& in, templateType& c) }} // OVR::Net +#if defined(OVR_CC_MSVC) +#pragma warning(pop) +#endif + #endif diff --git a/LibOVR/Src/Net/OVR_NetworkTypes.h b/LibOVR/Src/Net/OVR_NetworkTypes.h index 401f53a..c807bd0 100644 --- a/LibOVR/Src/Net/OVR_NetworkTypes.h +++ b/LibOVR/Src/Net/OVR_NetworkTypes.h @@ -28,7 +28,7 @@ limitations under the License. #ifndef OVR_NetworkTypes_h #define OVR_NetworkTypes_h -#include "../Kernel/OVR_Types.h" +#include "Kernel/OVR_Types.h" namespace OVR { namespace Net { diff --git a/LibOVR/Src/Net/OVR_PacketizedTCPSocket.h b/LibOVR/Src/Net/OVR_PacketizedTCPSocket.h index 8052bd3..e4bd3f3 100644 --- a/LibOVR/Src/Net/OVR_PacketizedTCPSocket.h +++ b/LibOVR/Src/Net/OVR_PacketizedTCPSocket.h @@ -29,8 +29,8 @@ limitations under the License. #define OVR_PacketizedTCPSocket_h #include "OVR_Socket.h" -#include "../Kernel/OVR_Allocator.h" -#include "../Kernel/OVR_Atomic.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Atomic.h" #ifdef OVR_OS_WIN32 #include "OVR_Win32_Socket.h" diff --git a/LibOVR/Src/Net/OVR_RPC1.cpp b/LibOVR/Src/Net/OVR_RPC1.cpp index 12afb09..b6137a5 100644 --- a/LibOVR/Src/Net/OVR_RPC1.cpp +++ b/LibOVR/Src/Net/OVR_RPC1.cpp @@ -26,7 +26,7 @@ limitations under the License. #include "OVR_RPC1.h" #include "OVR_BitStream.h" -#include "../Kernel/OVR_Threads.h" // Thread::MSleep +#include "Kernel/OVR_Threads.h" // Thread::MSleep #include "OVR_MessageIDTypes.h" namespace OVR { namespace Net { namespace Plugins { @@ -54,13 +54,12 @@ RPC1::RPC1() RPC1::~RPC1() { - slotHash.Clear(); delete blockingReturnValue; } -void RPC1::RegisterSlot(OVR::String sharedIdentifier, OVR::Observer* rpcSlotObserver ) +void RPC1::RegisterSlot(OVR::String sharedIdentifier, OVR::CallbackListener* rpcSlotObserver) { - slotHash.AddObserverToSubject(sharedIdentifier, rpcSlotObserver); + slotHash.AddListener(sharedIdentifier, rpcSlotObserver); } bool RPC1::RegisterBlockingFunction(OVR::String uniqueID, RPCDelegate blockingFunction) @@ -235,18 +234,15 @@ void RPC1::OnReceive(ReceivePayload *pPayload, ListenerReceiveResult *lrrOut) OVR::String sharedIdentifier; bsIn.Read(sharedIdentifier); - Observer *o = slotHash.GetSubject(sharedIdentifier); + CallbackEmitter* o = slotHash.GetKey(sharedIdentifier); if (o) { bsIn.AlignReadToByteBoundary(); - if (o) - { - OVR::Net::BitStream serializedParameters(bsIn.GetData() + bsIn.GetReadOffset()/8, bsIn.GetNumberOfUnreadBits()/8, false); + OVR::Net::BitStream serializedParameters(bsIn.GetData() + bsIn.GetReadOffset()/8, bsIn.GetNumberOfUnreadBits()/8, false); - o->Call(&serializedParameters, pPayload); - } + o->Call(&serializedParameters, pPayload); } } } diff --git a/LibOVR/Src/Net/OVR_RPC1.h b/LibOVR/Src/Net/OVR_RPC1.h index 6104ccf..6af2155 100644 --- a/LibOVR/Src/Net/OVR_RPC1.h +++ b/LibOVR/Src/Net/OVR_RPC1.h @@ -29,12 +29,12 @@ limitations under the License. #define OVR_Net_RPC_h #include "OVR_NetworkPlugin.h" -#include "../Kernel/OVR_Hash.h" -#include "../Kernel/OVR_String.h" +#include "Kernel/OVR_Hash.h" +#include "Kernel/OVR_String.h" #include "OVR_BitStream.h" -#include "../Kernel/OVR_Threads.h" -#include "../Kernel/OVR_Delegates.h" -#include "../Kernel//OVR_Observer.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_Delegates.h" +#include "Kernel/OVR_Callbacks.h" namespace OVR { namespace Net { namespace Plugins { @@ -55,7 +55,7 @@ public: /// \param[in] sharedIdentifier A string to identify the slot. Recommended to be the same as the name of the function. /// \param[in] functionPtr Pointer to the function. /// \param[in] callPriority Slots are called by order of the highest callPriority first. For slots with the same priority, they are called in the order they are registered - void RegisterSlot(OVR::String sharedIdentifier, OVR::Observer *rpcSlotObserver); + void RegisterSlot(OVR::String sharedIdentifier, CallbackListener* rpcSlotListener); /// \brief Same as \a RegisterFunction, but is called with CallBlocking() instead of Call() and returns a value to the caller bool RegisterBlockingFunction(OVR::String uniqueID, RPCDelegate blockingFunction); @@ -88,7 +88,8 @@ protected: virtual void OnConnected(Connection* conn); Hash< String, RPCDelegate, String::HashFunctor > registeredBlockingFunctions; - ObserverHash< RPCSlot > slotHash; + + CallbackHash< RPCSlot > slotHash; // Synchronization for RPC caller Lock singleRPCLock; diff --git a/LibOVR/Src/Net/OVR_Session.cpp b/LibOVR/Src/Net/OVR_Session.cpp index 508f0c9..4049c6c 100644 --- a/LibOVR/Src/Net/OVR_Session.cpp +++ b/LibOVR/Src/Net/OVR_Session.cpp @@ -26,36 +26,95 @@ limitations under the License. #include "OVR_Session.h" #include "OVR_PacketizedTCPSocket.h" -#include "../Kernel/OVR_Log.h" -#include "../Service/Service_NetSessionCommon.h" +#include "Kernel/OVR_Log.h" +#include "Service/Service_NetSessionCommon.h" namespace OVR { namespace Net { +// The SDK version requested by the user. +SDKVersion RuntimeSDKVersion; + + //----------------------------------------------------------------------------- // Protocol -static const char* OfficialHelloString = "OculusVR_Hello"; +static const char* OfficialHelloString = "OculusVR_Hello"; static const char* OfficialAuthorizedString = "OculusVR_Authorized"; -void RPC_C2S_Hello::Generate(Net::BitStream* bs) +bool RPC_C2S_Hello::Serialize(bool writeToBitstream, Net::BitStream* bs) +{ + bs->Serialize(writeToBitstream, HelloString); + bs->Serialize(writeToBitstream, MajorVersion); + bs->Serialize(writeToBitstream, MinorVersion); + if (!bs->Serialize(writeToBitstream, PatchVersion)) + return false; + + // If an older client is connecting to us, + if (!writeToBitstream && (MajorVersion * 100) + (MinorVersion * 10) + PatchVersion < 121) + { + // The following was version code was added to RPC version 1.2 + // without bumping it up to 1.3 and introducing an incompatibility. + // We can do this because an older server will not read this additional data. + return true; + } + + bs->Serialize(writeToBitstream, CodeVersion.ProductVersion); + bs->Serialize(writeToBitstream, CodeVersion.MajorVersion); + bs->Serialize(writeToBitstream, CodeVersion.MinorVersion); + bs->Serialize(writeToBitstream, CodeVersion.RequestedMinorVersion); + bs->Serialize(writeToBitstream, CodeVersion.PatchVersion); + bs->Serialize(writeToBitstream, CodeVersion.BuildNumber); + return bs->Serialize(writeToBitstream, CodeVersion.FeatureVersion); +} + +void RPC_C2S_Hello::ClientGenerate(Net::BitStream* bs) { RPC_C2S_Hello hello; - hello.HelloString = OfficialHelloString; + hello.HelloString = OfficialHelloString; hello.MajorVersion = RPCVersion_Major; hello.MinorVersion = RPCVersion_Minor; hello.PatchVersion = RPCVersion_Patch; - hello.Serialize(bs); + OVR_ASSERT(OVR::Net::RuntimeSDKVersion.ProductVersion != UINT16_MAX); + hello.CodeVersion = OVR::Net::RuntimeSDKVersion; // This should have been set to a value earlier in the first steps of ovr initialization. + hello.Serialize(true, bs); } -bool RPC_C2S_Hello::Validate() +bool RPC_C2S_Hello::ServerValidate() { + // Server checks the protocol version return MajorVersion == RPCVersion_Major && MinorVersion <= RPCVersion_Minor && HelloString.CompareNoCase(OfficialHelloString) == 0; } -void RPC_S2C_Authorization::Generate(Net::BitStream* bs, String errorString) +bool RPC_S2C_Authorization::Serialize(bool writeToBitstream, Net::BitStream* bs) +{ + bs->Serialize(writeToBitstream, AuthString); + bs->Serialize(writeToBitstream, MajorVersion); + bs->Serialize(writeToBitstream, MinorVersion); + if (!bs->Serialize(writeToBitstream, PatchVersion)) + return false; + + // If an older client is connecting to us, + if (!writeToBitstream && (MajorVersion * 100) + (MinorVersion * 10) + PatchVersion < 121) + { + // The following was version code was added to RPC version 1.2 + // without bumping it up to 1.3 and introducing an incompatibility. + // We can do this because an older server will not read this additional data. + return true; + } + + bs->Serialize(writeToBitstream, CodeVersion.ProductVersion); + bs->Serialize(writeToBitstream, CodeVersion.MajorVersion); + bs->Serialize(writeToBitstream, CodeVersion.MinorVersion); + bs->Serialize(writeToBitstream, CodeVersion.RequestedMinorVersion); + bs->Serialize(writeToBitstream, CodeVersion.PatchVersion); + bs->Serialize(writeToBitstream, CodeVersion.BuildNumber); + return bs->Serialize(writeToBitstream, CodeVersion.FeatureVersion); +} + +void RPC_S2C_Authorization::ServerGenerate(Net::BitStream* bs, String errorString) { RPC_S2C_Authorization auth; if (errorString.IsEmpty()) @@ -69,15 +128,32 @@ void RPC_S2C_Authorization::Generate(Net::BitStream* bs, String errorString) auth.MajorVersion = RPCVersion_Major; auth.MinorVersion = RPCVersion_Minor; auth.PatchVersion = RPCVersion_Patch; - auth.Serialize(bs); + // Leave CurrentSDKVersion as it is. + auth.Serialize(true, bs); } -bool RPC_S2C_Authorization::Validate() +bool RPC_S2C_Authorization::ClientValidate() { return AuthString.CompareNoCase(OfficialAuthorizedString) == 0; } +//----------------------------------------------------------------------------- +// SingleProcess + +static bool SingleProcess = false; + +void Session::SetSingleProcess(bool enable) +{ + SingleProcess = enable; +} + +bool Session::IsSingleProcess() +{ + return SingleProcess; +} + + //----------------------------------------------------------------------------- // Session @@ -111,29 +187,25 @@ void Session::Shutdown() SessionResult Session::Listen(ListenerDescription* pListenerDescription) { - if (pListenerDescription->Transport == TransportType_PacketizedTCP) - { - BerkleyListenerDescription* bld = (BerkleyListenerDescription*)pListenerDescription; - TCPSocket* tcpSocket = (TCPSocket*)bld->BoundSocketToListenWith.GetPtr(); + if (pListenerDescription->Transport == TransportType_PacketizedTCP) + { + BerkleyListenerDescription* bld = (BerkleyListenerDescription*)pListenerDescription; + TCPSocket* tcpSocket = (TCPSocket*)bld->BoundSocketToListenWith.GetPtr(); if (tcpSocket->Listen() < 0) { return SessionResult_ListenFailure; } - Lock::Locker locker(&SocketListenersLock); + Lock::Locker locker(&SocketListenersLock); SocketListeners.PushBack(tcpSocket); - } - else if (pListenerDescription->Transport == TransportType_Loopback) - { - HasLoopbackListener = true; - } + } else { OVR_ASSERT(false); } - return SessionResult_OK; + return SessionResult_OK; } SessionResult Session::Connect(ConnectParameters *cp) @@ -153,6 +225,28 @@ SessionResult Session::Connect(ConnectParameters *cp) return SessionResult_AlreadyConnected; } + // If we are already connected, don't create a duplicate connection + if (FullConnections.GetSizeI() > 0) + { + return SessionResult_AlreadyConnected; + } + + // If we are already connecting, don't create a duplicate connection + const int count = AllConnections.GetSizeI(); + for (int i = 0; i < count; ++i) + { + Connection* arrayItem = AllConnections[i].GetPtr(); + + OVR_ASSERT(arrayItem); + if (arrayItem) { + if (arrayItem->State == Client_ConnectedWait + || arrayItem->State == Client_Connecting) + { + return SessionResult_ConnectInProgress; + } + } + } + TCPSocketBase* tcpSock = (TCPSocketBase*)cp2->BoundSocketToConnectWith.GetPtr(); int ret = tcpSock->Connect(&cp2->RemoteAddress); @@ -174,7 +268,6 @@ SessionResult Session::Connect(ConnectParameters *cp) c->SetState(Client_Connecting); AllConnections.PushBack(c); - } if (cp2->Blocking) @@ -182,11 +275,12 @@ SessionResult Session::Connect(ConnectParameters *cp) c->WaitOnConnecting(); } - if (c->State == State_Connected) + EConnectionState state = c->State; + if (state == State_Connected) { return SessionResult_OK; } - else if (c->State == Client_Connecting) + else if (state == Client_Connecting) { return SessionResult_ConnectInProgress; } @@ -195,49 +289,33 @@ SessionResult Session::Connect(ConnectParameters *cp) return SessionResult_ConnectFailure; } } - else if (cp->Transport == TransportType_Loopback) - { - if (HasLoopbackListener) - { - Ptr c = AllocConnection(cp->Transport); - if (!c) - { - return SessionResult_ConnectFailure; - } - - c->Transport = cp->Transport; - c->SetState(State_Connected); - - { - Lock::Locker locker(&ConnectionsLock); - AllConnections.PushBack(c); - } - - invokeSessionEvent(&SessionListener::OnConnectionRequestAccepted, c); - } - else - { - OVR_ASSERT(false); - } - } else { OVR_ASSERT(false); } - return SessionResult_OK; + return SessionResult_OK; } +static Session* SingleProcessServer = nullptr; + SessionResult Session::ListenPTCP(OVR::Net::BerkleyBindParameters *bbp) { - Ptr listenSocket = *new OVR::Net::PacketizedTCPSocket(); + if (Session::IsSingleProcess()) + { + // Do not actually listen on a socket. + SingleProcessServer = this; + return SessionResult_OK; + } + + Ptr listenSocket = *new OVR::Net::PacketizedTCPSocket(); if (listenSocket->Bind(bbp) == INVALID_SOCKET) { return SessionResult_BindFailure; } - BerkleyListenerDescription bld; - bld.BoundSocketToListenWith = listenSocket.GetPtr(); + BerkleyListenerDescription bld; + bld.BoundSocketToListenWith = listenSocket.GetPtr(); bld.Transport = TransportType_PacketizedTCP; return Listen(&bld); @@ -245,16 +323,46 @@ SessionResult Session::ListenPTCP(OVR::Net::BerkleyBindParameters *bbp) SessionResult Session::ConnectPTCP(OVR::Net::BerkleyBindParameters* bbp, SockAddr* remoteAddress, bool blocking) { + if (Session::IsSingleProcess()) + { + OVR_ASSERT(SingleProcessServer); // ListenPTCP() must be called before ConnectPTCP() + + SingleProcessServer->SingleTargetSession = this; + SingleTargetSession = SingleProcessServer; + + Ptr s = *new PacketizedTCPSocket; + SockAddr sa; + sa.Set("::1", 10101, SOCK_STREAM); + + Ptr newConnection = AllocConnection(TransportType_PacketizedTCP); + if (!newConnection) + { + return SessionResult_ConnectFailure; + } + + PacketizedTCPConnection* c = (PacketizedTCPConnection*)newConnection.GetPtr(); + c->pSocket = s; + c->Address = &sa; + c->Transport = TransportType_PacketizedTCP; + c->SetState(Client_Connecting); + AllConnections.PushBack(c); + + SingleTargetSession->TCP_OnAccept(s, &sa, INVALID_SOCKET); + TCP_OnConnected(s); + + return SessionResult_OK; + } + ConnectParametersBerkleySocket cp(NULL, remoteAddress, blocking, TransportType_PacketizedTCP); Ptr connectSocket = *new PacketizedTCPSocket(); - cp.BoundSocketToConnectWith = connectSocket.GetPtr(); + cp.BoundSocketToConnectWith = connectSocket.GetPtr(); if (connectSocket->Bind(bbp) == INVALID_SOCKET) { return SessionResult_BindFailure; } - return Connect(&cp); + return Connect(&cp); } Ptr Session::findConnectionBySockAddr(SockAddr* address) @@ -280,47 +388,26 @@ Ptr Session::findConnectionBySockAddr(SockAddr* address int Session::Send(SendParameters *payload) { - if (payload->pConnection->Transport == TransportType_Loopback) - { - Lock::Locker locker(&SessionListenersLock); - - const int count = SessionListeners.GetSizeI(); - for (int i = 0; i < count; ++i) - { - SessionListener* sl = SessionListeners[i]; - - // FIXME: This looks like it needs to be reviewed at some point.. - ReceivePayload rp; - rp.Bytes = payload->Bytes; - rp.pConnection = payload->pConnection; - rp.pData = (uint8_t*)payload->pData; // FIXME - ListenerReceiveResult lrr = LRR_CONTINUE; - sl->OnReceive(&rp, &lrr); - if (lrr == LRR_RETURN) - { - return payload->Bytes; - } - else if (lrr == LRR_BREAK) - { - break; - } - } - - return payload->Bytes; - } - else if (payload->pConnection->Transport == TransportType_PacketizedTCP) - { - PacketizedTCPConnection* conn = (PacketizedTCPConnection*)payload->pConnection.GetPtr(); - - return conn->pSocket->Send(payload->pData, payload->Bytes); - } - else + if (payload->pConnection->Transport == TransportType_PacketizedTCP) { - OVR_ASSERT(false); + if (Session::IsSingleProcess()) + { + OVR_ASSERT(SingleTargetSession->AllConnections.GetSizeI() > 0); + PacketizedTCPConnection* conn = (PacketizedTCPConnection*)SingleTargetSession->AllConnections[0].GetPtr(); + SingleTargetSession->TCP_OnRecv(conn->pSocket, (uint8_t*)payload->pData, payload->Bytes); + return payload->Bytes; + } + else + { + PacketizedTCPConnection* conn = (PacketizedTCPConnection*)payload->pConnection.GetPtr(); + return conn->pSocket->Send(payload->pData, payload->Bytes); + } } + OVR_ASSERT(false); // Should not reach here return 0; } + void Session::Broadcast(BroadcastParameters *payload) { SendParameters sp; @@ -338,21 +425,29 @@ void Session::Broadcast(BroadcastParameters *payload) } } } -// DO NOT CALL Poll() FROM MULTIPLE THREADS due to allBlockingTcpSockets being a member + +// DO NOT CALL Poll() FROM MULTIPLE THREADS due to AllBlockingTcpSockets being a member void Session::Poll(bool listeners) { - allBlockingTcpSockets.Clear(); + if (Net::Session::IsSingleProcess()) + { + // Spend a lot of time sleeping in single process mode + Thread::MSleep(100); + return; + } - if (listeners) - { - Lock::Locker locker(&SocketListenersLock); + AllBlockingTcpSockets.Clear(); + + if (listeners) + { + Lock::Locker locker(&SocketListenersLock); const int listenerCount = SocketListeners.GetSizeI(); for (int i = 0; i < listenerCount; ++i) - { - allBlockingTcpSockets.PushBack(SocketListeners[i]); - } - } + { + AllBlockingTcpSockets.PushBack(SocketListeners[i]); + } + } { Lock::Locker locker(&ConnectionsLock); @@ -366,7 +461,7 @@ void Session::Poll(bool listeners) { PacketizedTCPConnection* ptcp = (PacketizedTCPConnection*)arrayItem; - allBlockingTcpSockets.PushBack(ptcp->pSocket); + AllBlockingTcpSockets.PushBack(ptcp->pSocket); } else { @@ -375,15 +470,15 @@ void Session::Poll(bool listeners) } } - const int count = allBlockingTcpSockets.GetSizeI(); - if (count > 0) - { + const int count = AllBlockingTcpSockets.GetSizeI(); + if (count > 0) + { TCPSocketPollState state; // Add all the sockets for polling, for (int i = 0; i < count; ++i) { - Net::TCPSocket* sock = allBlockingTcpSockets[i].GetPtr(); + Net::TCPSocket* sock = AllBlockingTcpSockets[i].GetPtr(); // If socket handle is invalid, if (sock->GetSocketHandle() == INVALID_SOCKET) @@ -399,20 +494,20 @@ void Session::Poll(bool listeners) } // If polling returns with an event, - if (state.Poll(allBlockingTcpSockets[0]->GetBlockingTimeoutUsec(), allBlockingTcpSockets[0]->GetBlockingTimeoutSec())) + if (state.Poll(AllBlockingTcpSockets[0]->GetBlockingTimeoutUsec(), AllBlockingTcpSockets[0]->GetBlockingTimeoutSec())) { // Handle any events for each socket for (int i = 0; i < count; ++i) { - state.HandleEvent(allBlockingTcpSockets[i], this); + state.HandleEvent(AllBlockingTcpSockets[i], this); } } - } + } } void Session::AddSessionListener(SessionListener* se) { - Lock::Locker locker(&SessionListenersLock); + Lock::Locker locker(&SessionListenersLock); const int count = SessionListeners.GetSizeI(); for (int i = 0; i < count; ++i) @@ -425,36 +520,35 @@ void Session::AddSessionListener(SessionListener* se) } SessionListeners.PushBack(se); - se->OnAddedToSession(this); + se->OnAddedToSession(this); } void Session::RemoveSessionListener(SessionListener* se) { - Lock::Locker locker(&SessionListenersLock); + Lock::Locker locker(&SessionListenersLock); const int count = SessionListeners.GetSizeI(); - for (int i = 0; i < count; ++i) - { + for (int i = 0; i < count; ++i) + { if (SessionListeners[i] == se) - { + { se->OnRemovedFromSession(this); SessionListeners.RemoveAtUnordered(i); break; - } - } + } + } } -SInt32 Session::GetActiveSocketsCount() + +int Session::GetActiveSocketsCount() { - Lock::Locker locker1(&SocketListenersLock); - Lock::Locker locker2(&ConnectionsLock); - return SocketListeners.GetSize() + AllConnections.GetSize()>0; + return SocketListeners.GetSizeI() + AllConnections.GetSizeI(); } + Ptr Session::AllocConnection(TransportType transport) { switch (transport) { - case TransportType_Loopback: return *new Connection(); case TransportType_TCP: return *new TCPConnection(); case TransportType_PacketizedTCP: return *new PacketizedTCPConnection(); default: @@ -511,14 +605,14 @@ int Session::invokeSessionListeners(ReceivePayload* rp) void Session::TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead) { - // KevinJ: 9/2/2014 Fix deadlock - Watchdog calls Broadcast(), which locks ConnectionsLock(). - // Lock::Locker locker(&ConnectionsLock); + // KevinJ: 9/2/2014 Fix deadlock - Watchdog calls Broadcast(), which locks ConnectionsLock(). + // Lock::Locker locker(&ConnectionsLock); // Look for the connection in the full connection list first int connIndex; - ConnectionsLock.DoLock(); + ConnectionsLock.DoLock(); Ptr conn = findConnectionBySocket(AllConnections, pSocket, &connIndex); - ConnectionsLock.Unlock(); + ConnectionsLock.Unlock(); if (conn) { if (conn->State == State_Connected) @@ -537,8 +631,8 @@ void Session::TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead) BitStream bsIn((char*)pData, bytesRead, false); RPC_S2C_Authorization auth; - if (!auth.Deserialize(&bsIn) || - !auth.Validate()) + if (!auth.Serialize(false, &bsIn) || + !auth.ClientValidate()) { LogError("{ERR-001} [Session] REJECTED: OVRService did not authorize us: %s", auth.AuthString.ToCStr()); @@ -551,16 +645,18 @@ void Session::TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead) conn->RemoteMajorVersion = auth.MajorVersion; conn->RemoteMinorVersion = auth.MinorVersion; conn->RemotePatchVersion = auth.PatchVersion; + conn->RemoteCodeVersion = auth.CodeVersion; // Mark as connected conn->SetState(State_Connected); - ConnectionsLock.DoLock(); - int connIndex2; - if (findConnectionBySocket(AllConnections, pSocket, &connIndex2)==conn && findConnectionBySocket(FullConnections, pSocket, &connIndex2)==NULL) - { - FullConnections.PushBack(conn); - } - ConnectionsLock.Unlock(); + ConnectionsLock.DoLock(); + int connIndex2; + if (findConnectionBySocket(AllConnections, pSocket, &connIndex2)==conn && findConnectionBySocket(FullConnections, pSocket, &connIndex2)==NULL) + { + FullConnections.PushBack(conn); + HaveFullConnections.store(true, std::memory_order_relaxed); + } + ConnectionsLock.Unlock(); invokeSessionEvent(&SessionListener::OnConnectionRequestAccepted, conn); } } @@ -570,41 +666,59 @@ void Session::TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead) BitStream bsIn((char*)pData, bytesRead, false); RPC_C2S_Hello hello; - if (!hello.Deserialize(&bsIn) || - !hello.Validate()) + if (!hello.Serialize(false, &bsIn) || + !hello.ServerValidate()) { - LogError("{ERR-002} [Session] REJECTED: Rift application is using an incompatible version %d.%d.%d (my version=%d.%d.%d)", - hello.MajorVersion, hello.MinorVersion, hello.PatchVersion, - RPCVersion_Major, RPCVersion_Minor, RPCVersion_Patch); + LogError("{ERR-002} [Session] REJECTED: Rift application is using an incompatible version %d.%d.%d, feature version %d (my version=%d.%d.%d, feature version %d)", + hello.MajorVersion, hello.MinorVersion, hello.PatchVersion, hello.CodeVersion.FeatureVersion, + RPCVersion_Major, RPCVersion_Minor, RPCVersion_Patch, OVR_FEATURE_VERSION); conn->SetState(State_Zombie); // Send auth response BitStream bsOut; - RPC_S2C_Authorization::Generate(&bsOut, "Incompatible protocol version. Please make sure your OVRService and SDK are both up to date."); - conn->pSocket->Send(bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); + RPC_S2C_Authorization::ServerGenerate(&bsOut, "Incompatible protocol version. Please make sure your OVRService and SDK are both up to date."); + + SendParameters sp; + sp.Bytes = bsOut.GetNumberOfBytesUsed(); + sp.pData = bsOut.GetData(); + sp.pConnection = conn; + Send(&sp); } else { + if (hello.CodeVersion.FeatureVersion != OVR_FEATURE_VERSION) + { + LogError("[Session] WARNING: Rift application is using a different feature version than the server (server version = %d, app version = %d)", + OVR_FEATURE_VERSION, hello.CodeVersion.FeatureVersion); + } + // Read remote version conn->RemoteMajorVersion = hello.MajorVersion; conn->RemoteMinorVersion = hello.MinorVersion; conn->RemotePatchVersion = hello.PatchVersion; + conn->RemoteCodeVersion = hello.CodeVersion; // Send auth response BitStream bsOut; - RPC_S2C_Authorization::Generate(&bsOut); - conn->pSocket->Send(bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); + RPC_S2C_Authorization::ServerGenerate(&bsOut); + + SendParameters sp; + sp.Bytes = bsOut.GetNumberOfBytesUsed(); + sp.pData = bsOut.GetData(); + sp.pConnection = conn; + Send(&sp); // Mark as connected conn->SetState(State_Connected); - ConnectionsLock.DoLock(); - int connIndex2; - if (findConnectionBySocket(AllConnections, pSocket, &connIndex2)==conn && findConnectionBySocket(FullConnections, pSocket, &connIndex2)==NULL) - { - FullConnections.PushBack(conn); - } - ConnectionsLock.Unlock(); + ConnectionsLock.DoLock(); + int connIndex2; + if (findConnectionBySocket(AllConnections, pSocket, &connIndex2)==conn && findConnectionBySocket(FullConnections, pSocket, &connIndex2)==NULL) + { + FullConnections.PushBack(conn); + HaveFullConnections.store(true, std::memory_order_relaxed); + } + ConnectionsLock.Unlock(); invokeSessionEvent(&SessionListener::OnNewIncomingConnection, conn); } @@ -618,10 +732,10 @@ void Session::TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead) void Session::TCP_OnClosed(TCPSocket* s) { - Lock::Locker locker(&ConnectionsLock); + Lock::Locker locker(&ConnectionsLock); // If found in the full connection list, - int connIndex; + int connIndex = 0; Ptr conn = findConnectionBySocket(AllConnections, s, &connIndex); if (conn) { @@ -631,6 +745,10 @@ void Session::TCP_OnClosed(TCPSocket* s) if (findConnectionBySocket(FullConnections, s, &connIndex)) { FullConnections.RemoveAtUnordered(connIndex); + if (FullConnections.GetSizeI() < 1) + { + HaveFullConnections.store(false, std::memory_order_relaxed); + } } // Generate an appropriate event for the current state @@ -659,23 +777,23 @@ void Session::TCP_OnClosed(TCPSocket* s) void Session::TCP_OnAccept(TCPSocket* pListener, SockAddr* pSockAddr, SocketHandle newSock) { OVR_UNUSED(pListener); - OVR_ASSERT(pListener->Transport == TransportType_PacketizedTCP); + Ptr newSocket = *new PacketizedTCPSocket(newSock, false); + OVR_ASSERT(pListener->Transport == TransportType_PacketizedTCP); - Ptr newSocket = *new PacketizedTCPSocket(newSock, false); // If pSockAddr is not localhost, then close newSock - if (pSockAddr->IsLocalhost()==false) + if (!pSockAddr->IsLocalhost()) { newSocket->Close(); return; } - if (newSocket) - { - Ptr b = AllocConnection(TransportType_PacketizedTCP); - Ptr c = (PacketizedTCPConnection*)b.GetPtr(); - c->pSocket = newSocket; - c->Address = *pSockAddr; + if (newSocket) + { + Ptr b = AllocConnection(TransportType_PacketizedTCP); + Ptr c = (PacketizedTCPConnection*)b.GetPtr(); + c->pSocket = newSocket; + c->Address = *pSockAddr; c->State = Server_ConnectedWait; { @@ -684,7 +802,7 @@ void Session::TCP_OnAccept(TCPSocket* pListener, SockAddr* pSockAddr, SocketHand } // Server does not send the first packet. It waits for the client to send its version - } + } } void Session::TCP_OnConnected(TCPSocket *s) @@ -697,13 +815,18 @@ void Session::TCP_OnConnected(TCPSocket *s) { OVR_ASSERT(conn->State == Client_Connecting); + // Just update state but do not generate any notifications yet + conn->SetState(Client_ConnectedWait); + // Send hello message BitStream bsOut; - RPC_C2S_Hello::Generate(&bsOut); - conn->pSocket->Send(bsOut.GetData(), bsOut.GetNumberOfBytesUsed()); + RPC_C2S_Hello::ClientGenerate(&bsOut); - // Just update state but do not generate any notifications yet - conn->State = Client_ConnectedWait; + SendParameters sp; + sp.Bytes = bsOut.GetNumberOfBytesUsed(); + sp.pData = bsOut.GetData(); + sp.pConnection = conn; + Send(&sp); } } diff --git a/LibOVR/Src/Net/OVR_Session.h b/LibOVR/Src/Net/OVR_Session.h old mode 100644 new mode 100755 index b6ef07b..3f329f9 --- a/LibOVR/Src/Net/OVR_Session.h +++ b/LibOVR/Src/Net/OVR_Session.h @@ -28,12 +28,16 @@ limitations under the License. #ifndef OVR_Session_h #define OVR_Session_h +#include + +#include #include "OVR_Socket.h" #include "OVR_PacketizedTCPSocket.h" -#include "../Kernel/OVR_Array.h" -#include "../Kernel/OVR_Threads.h" -#include "../Kernel/OVR_Atomic.h" -#include "../Kernel/OVR_RefCount.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_RefCount.h" +#include + namespace OVR { namespace Net { @@ -45,48 +49,82 @@ class Session; // // Please update changelog below: // 1.0.0 - [SDK 0.4.0] Initial version (July 21, 2014) -// 1.1.0 - Add Get/SetDriverMode_1, HMDCountUpdate_1 -// Version mismatch results (July 28, 2014) +// 1.1.0 - [SDK 0.4.1] Add Get/SetDriverMode_1, HMDCountUpdate_1 Version mismatch results (July 28, 2014) +// 1.2.0 - [SDK 0.4.4] +// 1.2.1 - [SDK 0.5.0] Added DyLib model and SDKVersion +// 1.3.0 - [SDK 0.5.0] Multiple shared memory regions for different objects //----------------------------------------------------------------------------- static const uint16_t RPCVersion_Major = 1; // MAJOR version when you make incompatible API changes, -static const uint16_t RPCVersion_Minor = 2; // MINOR version when you add functionality in a backwards-compatible manner, and +static const uint16_t RPCVersion_Minor = 3; // MINOR version when you add functionality in a backwards-compatible manner, and static const uint16_t RPCVersion_Patch = 0; // PATCH version when you make backwards-compatible bug fixes. +#define OVR_FEATURE_VERSION 0 + + +struct SDKVersion +{ + uint16_t ProductVersion; // CAPI DLL product number, 0 before first consumer release + uint16_t MajorVersion; // CAPI DLL version major number + uint16_t MinorVersion; // CAPI DLL version minor number + uint16_t RequestedMinorVersion; // Number provided by game in ovr_Initialize() arguments + uint16_t PatchVersion; // CAPI DLL version patch number + uint16_t BuildNumber; // Number increments per build + uint16_t FeatureVersion; // CAPI DLL feature version number + + SDKVersion() + { + Reset(); + } + + void Reset() + { + ProductVersion = MajorVersion = MinorVersion = UINT16_MAX; + RequestedMinorVersion = PatchVersion = BuildNumber = UINT16_MAX; + FeatureVersion = UINT16_MAX; + } + + void SetCurrent() + { + ProductVersion = OVR_PRODUCT_VERSION; + MajorVersion = OVR_MAJOR_VERSION; + MinorVersion = OVR_MINOR_VERSION; + RequestedMinorVersion = OVR_MINOR_VERSION; + PatchVersion = OVR_PATCH_VERSION; + BuildNumber = OVR_BUILD_NUMBER; + FeatureVersion = OVR_FEATURE_VERSION; + } +}; + +// This is the version that the OVR_CAPI client passes on to the server. It's a global variable +// because it needs to be initialized in ovr_Initialize but read in the OVR_Session module. +// This variable exists as a global in the server but it has no meaning. +extern SDKVersion RuntimeSDKVersion; + + // Client starts communication by sending its version number. struct RPC_C2S_Hello { RPC_C2S_Hello() : MajorVersion(0), MinorVersion(0), - PatchVersion(0) + PatchVersion(0), + CodeVersion() { + CodeVersion.SetCurrent(); } String HelloString; - // Client version info + // Client protocol version info uint16_t MajorVersion, MinorVersion, PatchVersion; - void Serialize(Net::BitStream* bs) - { - bs->Write(HelloString); - bs->Write(MajorVersion); - bs->Write(MinorVersion); - bs->Write(PatchVersion); - } - - bool Deserialize(Net::BitStream* bs) - { - bs->Read(HelloString); - bs->Read(MajorVersion); - bs->Read(MinorVersion); - return bs->Read(PatchVersion); - } - - static void Generate(Net::BitStream* bs); + // Client runtime code version info + SDKVersion CodeVersion; - bool Validate(); + bool Serialize(bool writeToBitstream, Net::BitStream* bs); + static void ClientGenerate(Net::BitStream* bs); + bool ServerValidate(); }; // Server responds with an authorization accepted message, including the server's version number @@ -95,8 +133,10 @@ struct RPC_S2C_Authorization RPC_S2C_Authorization() : MajorVersion(0), MinorVersion(0), - PatchVersion(0) + PatchVersion(0), + CodeVersion() { + CodeVersion.SetCurrent(); } String AuthString; @@ -104,25 +144,13 @@ struct RPC_S2C_Authorization // Server version info uint16_t MajorVersion, MinorVersion, PatchVersion; - void Serialize(Net::BitStream* bs) - { - bs->Write(AuthString); - bs->Write(MajorVersion); - bs->Write(MinorVersion); - bs->Write(PatchVersion); - } + // The SDK version that the server was built with. + // There's no concept of the server requesting an SDK version like the client does. + SDKVersion CodeVersion; - bool Deserialize(Net::BitStream* bs) - { - bs->Read(AuthString); - bs->Read(MajorVersion); - bs->Read(MinorVersion); - return bs->Read(PatchVersion); - } - - static void Generate(Net::BitStream* bs, String errorString = ""); - - bool Validate(); + bool Serialize(bool writeToBitstream, Net::BitStream* bs); + static void ServerGenerate(Net::BitStream* bs, String errorString = ""); + bool ClientValidate(); }; @@ -130,10 +158,10 @@ struct RPC_S2C_Authorization // Result of a session function enum SessionResult { - SessionResult_OK, - SessionResult_BindFailure, - SessionResult_ListenFailure, - SessionResult_ConnectFailure, + SessionResult_OK, + SessionResult_BindFailure, + SessionResult_ListenFailure, + SessionResult_ConnectFailure, SessionResult_ConnectInProgress, SessionResult_AlreadyConnected, }; @@ -166,10 +194,11 @@ public: State(State_Zombie), RemoteMajorVersion(0), RemoteMinorVersion(0), - RemotePatchVersion(0) + RemotePatchVersion(0), + RemoteCodeVersion() { } - virtual ~Connection() // Allow delete from base + virtual ~Connection() // Allow delete from base { } @@ -180,9 +209,10 @@ public: EConnectionState State; // Version number read from remote host just before connection completes - int RemoteMajorVersion; + int RemoteMajorVersion; // RPC version int RemoteMinorVersion; int RemotePatchVersion; + SDKVersion RemoteCodeVersion; }; @@ -192,42 +222,44 @@ class NetworkConnection : public Connection { protected: NetworkConnection() - { - } + { + } virtual ~NetworkConnection() { } public: - virtual void SetState(EConnectionState s) + // Thread-safe interface to set or wait on a connection state change. + // All modifications of the connection state should go through this function, + // on the client side. + void SetState(EConnectionState s) { + Mutex::Locker locker(&StateMutex); + if (s != State) { - Mutex::Locker locker(&StateMutex); + State = s; - if (s != State) + if (State != Client_Connecting && + State != Client_ConnectedWait) { - State = s; - - if (State != Client_Connecting) - { - ConnectingWait.NotifyAll(); - } + ConnectingWait.NotifyAll(); } } } + // Call this function to wait for the state to change to a connected state. void WaitOnConnecting() { Mutex::Locker locker(&StateMutex); - while (State == Client_Connecting) + while (State == Client_Connecting || State == Client_ConnectedWait) { ConnectingWait.Wait(&StateMutex); } } - SockAddr Address; + SockAddr Address; Mutex StateMutex; WaitCondition ConnectingWait; }; @@ -246,7 +278,7 @@ public: } public: - Ptr pSocket; + Ptr pSocket; }; @@ -255,7 +287,7 @@ public: class PacketizedTCPConnection : public TCPConnection { public: - PacketizedTCPConnection() + PacketizedTCPConnection() { Transport = TransportType_PacketizedTCP; } @@ -284,16 +316,16 @@ public: class BerkleyListenerDescription : public ListenerDescription { public: - static const int DefaultMaxIncomingConnections = 64; - static const int DefaultMaxConnections = 128; + static const int DefaultMaxIncomingConnections = 64; + static const int DefaultMaxConnections = 128; - BerkleyListenerDescription() : - MaxIncomingConnections(DefaultMaxIncomingConnections), - MaxConnections(DefaultMaxConnections) - { - } + BerkleyListenerDescription() : + MaxIncomingConnections(DefaultMaxIncomingConnections), + MaxConnections(DefaultMaxConnections) + { + } - Ptr BoundSocketToListenWith; + Ptr BoundSocketToListenWith; int MaxIncomingConnections; int MaxConnections; }; @@ -303,9 +335,9 @@ public: // Receive payload struct ReceivePayload { - Connection* pConnection; // Source connection - uint8_t* pData; // Pointer to data received - int Bytes; // Number of bytes of data received + Connection* pConnection; // Source connection + uint8_t* pData; // Pointer to data received + int Bytes; // Number of bytes of data received }; //----------------------------------------------------------------------------- @@ -335,22 +367,22 @@ public: class SendParameters { public: - SendParameters() : - pData(NULL), - Bytes(0) - { - } - SendParameters(Ptr _pConnection, const void* _pData, int _bytes) : - pConnection(_pConnection), - pData(_pData), - Bytes(_bytes) - { - } + SendParameters() : + pData(NULL), + Bytes(0) + { + } + SendParameters(Ptr _pConnection, const void* _pData, int _bytes) : + pConnection(_pConnection), + pData(_pData), + Bytes(_bytes) + { + } public: - Ptr pConnection; // Connection to use - const void* pData; // Pointer to data to send - int Bytes; // Number of bytes of data received + Ptr pConnection; // Connection to use + const void* pData; // Pointer to data to send + int Bytes; // Number of bytes of data received }; @@ -359,18 +391,18 @@ public: struct ConnectParameters { public: - ConnectParameters() : - Transport(TransportType_None) - { - } + ConnectParameters() : + Transport(TransportType_None) + { + } - TransportType Transport; + TransportType Transport; }; struct ConnectParametersBerkleySocket : public ConnectParameters { - SockAddr RemoteAddress; - Ptr BoundSocketToConnectWith; + SockAddr RemoteAddress; + Ptr BoundSocketToConnectWith; bool Blocking; ConnectParametersBerkleySocket(BerkleySocket* s, SockAddr* addr, bool blocking, @@ -388,11 +420,11 @@ struct ConnectParametersBerkleySocket : public ConnectParameters // Listener receive result enum ListenerReceiveResult { - /// The SessionListener used this message and it shouldn't be given to the user. - LRR_RETURN = 0, + /// The SessionListener used this message and it shouldn't be given to the user. + LRR_RETURN = 0, - /// The SessionListener is going to hold on to this message. Do not deallocate it but do not pass it to other plugins either. - LRR_BREAK, + /// The SessionListener is going to hold on to this message. Do not deallocate it but do not pass it to other plugins either. + LRR_BREAK, /// This message will be processed by other SessionListeners, and at last by the user. LRR_CONTINUE, @@ -406,15 +438,15 @@ enum ListenerReceiveResult class SessionListener { public: - virtual ~SessionListener(){} + virtual ~SessionListener(){} - // Data events + // Data events virtual void OnReceive(ReceivePayload* pPayload, ListenerReceiveResult* lrrOut) { OVR_UNUSED2(pPayload, lrrOut); } - // Connection was closed + // Connection was closed virtual void OnDisconnected(Connection* conn) = 0; - // Connection was created (some data was exchanged to verify protocol compatibility too) + // Connection was created (some data was exchanged to verify protocol compatibility too) virtual void OnConnected(Connection* conn) = 0; // Server accepted client @@ -430,7 +462,7 @@ public: // Disconnected during initial handshake virtual void OnHandshakeAttemptFailed(Connection* conn) { OnConnectionAttemptFailed(conn); } - // Other + // Other virtual void OnAddedToSession(Session* session) { OVR_UNUSED(session); } virtual void OnRemovedFromSession(Session* session) { OVR_UNUSED(session); } }; @@ -442,32 +474,27 @@ public: // Interface for network events such as listening on a socket, sending data, connecting, and disconnecting. Works independently of the transport medium and also implements loopback class Session : public SocketEvent_TCP, public NewOverrideBase { - // Implement a policy to avoid releasing memory backing allBlockingTcpSockets - struct ArrayNoShrinkPolicy : ArrayDefaultPolicy - { - bool NeverShrinking() const { return 1; } - }; - public: Session() : - HasLoopbackListener(false) + HaveFullConnections(false) { } virtual ~Session() { // Ensure memory backing the sockets array is released - allBlockingTcpSockets.ClearAndRelease(); + AllBlockingTcpSockets.ClearAndRelease(); } - virtual SessionResult Listen(ListenerDescription* pListenerDescription); - virtual SessionResult Connect(ConnectParameters* cp); - virtual int Send(SendParameters* payload); + virtual SessionResult Listen(ListenerDescription* pListenerDescription); + virtual SessionResult Connect(ConnectParameters* cp); + virtual int Send(SendParameters* payload); virtual void Broadcast(BroadcastParameters* payload); - // DO NOT CALL Poll() FROM MULTIPLE THREADS due to allBlockingTcpSockets being a member + // DO NOT CALL Poll() FROM MULTIPLE THREADS due to AllBlockingTcpSockets being a member virtual void Poll(bool listeners = true); - virtual void AddSessionListener(SessionListener* se); - virtual void RemoveSessionListener(SessionListener* se); - virtual SInt32 GetActiveSocketsCount(); + virtual void AddSessionListener(SessionListener* se); + virtual void RemoveSessionListener(SessionListener* se); + // GetActiveSocketsCount() is not thread-safe: Socket count may change at any time. + virtual int GetActiveSocketsCount(); // Packetized TCP convenience functions virtual SessionResult ListenPTCP(BerkleyBindParameters* bbp); @@ -476,7 +503,15 @@ public: // Closes all the sockets; useful for interrupting the socket polling during shutdown void Shutdown(); + // Returns true if there is at least one successful connection + // WARNING: This function may not be in sync across threads, but it IS atomic + bool ConnectionSuccessful() const + { + return HaveFullConnections.load(std::memory_order_relaxed); + } + // Get count of successful connections (past handshake point) + // WARNING: This function is not thread-safe int GetConnectionCount() const { return FullConnections.GetSizeI(); @@ -484,15 +519,16 @@ public: Ptr GetConnectionAtIndex(int index); protected: - virtual Ptr AllocConnection(TransportType transportType); + virtual Ptr AllocConnection(TransportType transportType); Lock SocketListenersLock, ConnectionsLock, SessionListenersLock; - bool HasLoopbackListener; // Has loopback listener installed? - Array< Ptr > SocketListeners; // List of active sockets + Array< Ptr > SocketListeners; // List of active sockets Array< Ptr > AllConnections; // List of active connections stuck at the versioning handshake Array< Ptr > FullConnections; // List of active connections past the versioning handshake Array< SessionListener* > SessionListeners; // List of session listeners - Array< Ptr< Net::TCPSocket >, ArrayNoShrinkPolicy > allBlockingTcpSockets; // Preallocated blocking sockets array + Array< Ptr< Net::TCPSocket > > AllBlockingTcpSockets; // Preallocated blocking sockets array + + std::atomic HaveFullConnections; // Tools Ptr findConnectionBySocket(Array< Ptr >& connectionArray, Socket* s, int *connectionIndex = NULL); // Call with ConnectionsLock held @@ -500,11 +536,18 @@ protected: int invokeSessionListeners(ReceivePayload*); void invokeSessionEvent(void(SessionListener::*f)(Connection*), Connection* pConnection); - // TCP - virtual void TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead); - virtual void TCP_OnClosed(TCPSocket* pSocket); - virtual void TCP_OnAccept(TCPSocket* pListener, SockAddr* pSockAddr, SocketHandle newSock); - virtual void TCP_OnConnected(TCPSocket* pSocket); + // TCP + virtual void TCP_OnRecv(Socket* pSocket, uint8_t* pData, int bytesRead); + virtual void TCP_OnClosed(TCPSocket* pSocket); + virtual void TCP_OnAccept(TCPSocket* pListener, SockAddr* pSockAddr, SocketHandle newSock); + virtual void TCP_OnConnected(TCPSocket* pSocket); + +public: + static void SetSingleProcess(bool enable); + static bool IsSingleProcess(); + +protected: + Session* SingleTargetSession; // Target for SingleProcess mode }; diff --git a/LibOVR/Src/Net/OVR_Socket.h b/LibOVR/Src/Net/OVR_Socket.h index b02e038..df6407f 100644 --- a/LibOVR/Src/Net/OVR_Socket.h +++ b/LibOVR/Src/Net/OVR_Socket.h @@ -28,18 +28,17 @@ limitations under the License. #ifndef OVR_Socket_h #define OVR_Socket_h -#include "../Kernel/OVR_Types.h" -#include "../Kernel/OVR_Timer.h" -#include "../Kernel/OVR_Allocator.h" -#include "../Kernel/OVR_RefCount.h" -#include "../Kernel/OVR_String.h" +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_Timer.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_RefCount.h" +#include "Kernel/OVR_String.h" // OS-specific socket headers #if defined(OVR_OS_WIN32) #include #include -#define WIN32_LEAN_AND_MEAN -#include +#include "Kernel/OVR_Win32_IncludeWindows.h" #else # include # include @@ -72,7 +71,6 @@ static const int SOCKET_ERROR = -1; enum TransportType { TransportType_None, // No transport (useful placeholder for invalid states) - TransportType_Loopback, // Loopback transport: Class talks to itself TransportType_TCP, // TCP/IPv4/v6 TransportType_UDP, // UDP/IPv4/v6 TransportType_PacketizedTCP // Packetized TCP: Message framing is automatic diff --git a/LibOVR/Src/Net/OVR_Unix_Socket.cpp b/LibOVR/Src/Net/OVR_Unix_Socket.cpp index 6f2a678..7477ee7 100644 --- a/LibOVR/Src/Net/OVR_Unix_Socket.cpp +++ b/LibOVR/Src/Net/OVR_Unix_Socket.cpp @@ -25,10 +25,10 @@ limitations under the License. ************************************************************************************/ #include "OVR_Unix_Socket.h" -#include "../Kernel/OVR_Std.h" -#include "../Kernel/OVR_Allocator.h" -#include "../Kernel/OVR_Threads.h" // Thread::MSleep -#include "../Kernel/OVR_Log.h" +#include "Kernel/OVR_Std.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Threads.h" // Thread::MSleep +#include "Kernel/OVR_Log.h" #include @@ -409,10 +409,14 @@ TCPSocket::TCPSocket(SocketHandle boundHandle, bool isListenSocket) TheSocket = boundHandle; IsListenSocket = isListenSocket; IsConnecting = false; - SetSocketOptions(TheSocket); - // The actual socket is always non-blocking - _Ioctlsocket(TheSocket, 1); + if (TheSocket != INVALID_SOCKET) + { + SetSocketOptions(TheSocket); + + // The actual socket is always non-blocking + _Ioctlsocket(TheSocket, 1); + } } TCPSocket::~TCPSocket() diff --git a/LibOVR/Src/Net/OVR_Win32_Socket.cpp b/LibOVR/Src/Net/OVR_Win32_Socket.cpp index edc6ade..3cd2ada 100644 --- a/LibOVR/Src/Net/OVR_Win32_Socket.cpp +++ b/LibOVR/Src/Net/OVR_Win32_Socket.cpp @@ -1,608 +1,618 @@ -/************************************************************************************ - -Filename : OVR_Win32_Socket.cpp -Content : Windows-specific socket-based networking implementation -Created : June 10, 2014 -Authors : Kevin Jenkins - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "OVR_Win32_Socket.h" -#include "../Kernel/OVR_Std.h" -#include "../Kernel/OVR_Allocator.h" -#include "../Kernel/OVR_Threads.h" // Thread::MSleep -#include "../Kernel/OVR_Log.h" - -#include - -namespace OVR { namespace Net { - - -//----------------------------------------------------------------------------- -// WSAStartupSingleton - -class WSAStartupSingleton -{ -public: - static void AddRef(void); - static void Deref(void); - -protected: - static int RefCount; -}; - - -// Local data -int WSAStartupSingleton::RefCount = 0; - - -// Implementation -void WSAStartupSingleton::AddRef() -{ - if (++RefCount == 1) - { - WSADATA winsockInfo; - const int errCode = WSAStartup(MAKEWORD(2, 2), &winsockInfo); - OVR_ASSERT(errCode == 0); - - // If an error code is returned - if (errCode != 0) - { - LogError("{ERR-007w} [Socket] Unable to initialize Winsock %d", errCode); - } - } -} - -void WSAStartupSingleton::Deref() -{ - OVR_ASSERT(RefCount > 0); - - if (RefCount > 0) - { - if (--RefCount == 0) - { - WSACleanup(); - RefCount = 0; - } - } -} - - -//----------------------------------------------------------------------------- -// BerkleySocket - -void BerkleySocket::Close() -{ - if (TheSocket != INVALID_SOCKET) - { - closesocket(TheSocket); - TheSocket = INVALID_SOCKET; - } -} - -int32_t BerkleySocket::GetSockname(SockAddr *pSockAddrOut) -{ - struct sockaddr_in6 sa; - memset(&sa,0,sizeof(sa)); - int size = sizeof(sa); - int32_t i = getsockname(TheSocket, (sockaddr*) &sa, &size); - if (i>=0) - { - pSockAddrOut->Set(&sa); - } - return i; -} - - -//----------------------------------------------------------------------------- -// BitStream overloads for SockAddr - -BitStream& operator<<(BitStream& out, SockAddr& in) -{ - out.WriteBits((const unsigned char*) &in.Addr6, sizeof(in.Addr6)*8, true); - return out; -} - -BitStream& operator>>(BitStream& in, SockAddr& out) -{ - bool success = in.ReadBits((unsigned char*) &out.Addr6, sizeof(out.Addr6)*8, true); - OVR_ASSERT(success); - OVR_UNUSED(success); - return in; -} - - -//----------------------------------------------------------------------------- -// SockAddr - -SockAddr::SockAddr() -{ - WSAStartupSingleton::AddRef(); - - // Zero out the address to squelch static analysis tools - ZeroMemory(&Addr6, sizeof(Addr6)); -} - -SockAddr::SockAddr(SockAddr* address) -{ - WSAStartupSingleton::AddRef(); - Set(&address->Addr6); -} - -SockAddr::SockAddr(sockaddr_storage* storage) -{ - WSAStartupSingleton::AddRef(); - Set(storage); -} - -SockAddr::SockAddr(sockaddr_in6* address) -{ - WSAStartupSingleton::AddRef(); - Set(address); -} - -SockAddr::SockAddr(const char* hostAddress, uint16_t port, int sockType) -{ - WSAStartupSingleton::AddRef(); - Set(hostAddress, port, sockType); -} - -void SockAddr::Set(const sockaddr_storage* storage) -{ - memcpy(&Addr6, storage, sizeof(Addr6)); -} - -void SockAddr::Set(const sockaddr_in6* address) -{ - memcpy(&Addr6, address, sizeof(Addr6)); -} - -void SockAddr::Set(const char* hostAddress, uint16_t port, int sockType) -{ - memset(&Addr6, 0, sizeof(Addr6)); - - struct addrinfo hints; - - // make sure the struct is empty - memset(&hints, 0, sizeof (addrinfo)); - - hints.ai_socktype = sockType; // SOCK_DGRAM or SOCK_STREAM - hints.ai_flags = AI_PASSIVE; // fill in my IP for me - hints.ai_family = AF_UNSPEC ; - - // FIXME See OVR_Unix_Socket implementation and man pages for getaddrinfo. - // ai_protocol is expecting to be either IPPROTO_UDP and IPPROTO_TCP. - // But this has been working on windows so I'm leaving it be for - // now instead of introducing another variable. - hints.ai_protocol = IPPROTO_IPV6; - - struct addrinfo* servinfo = NULL; // will point to the results - - char portStr[32]; - OVR_itoa(port, portStr, sizeof(portStr), 10); - int errcode = getaddrinfo(hostAddress, portStr, &hints, &servinfo); - - if (0 != errcode) - { - OVR::LogError("{ERR-008w} getaddrinfo error: %s", gai_strerror(errcode)); - } - - OVR_ASSERT(servinfo); - - if (servinfo) - { - memcpy(&Addr6, servinfo->ai_addr, sizeof(Addr6)); - - freeaddrinfo(servinfo); - } -} - -uint16_t SockAddr::GetPort() -{ - return htons(Addr6.sin6_port); -} - -String SockAddr::ToString(bool writePort, char portDelineator) const -{ - char dest[INET6_ADDRSTRLEN + 1]; - - int ret = getnameinfo((struct sockaddr*)&Addr6, - sizeof(struct sockaddr_in6), - dest, - INET6_ADDRSTRLEN, - NULL, - 0, - NI_NUMERICHOST); - if (ret != 0) - { - dest[0] = '\0'; - } - - if (writePort) - { - unsigned char ch[2]; - ch[0]=portDelineator; - ch[1]=0; - OVR_strcat(dest, 16, (const char*) ch); - OVR_itoa(ntohs(Addr6.sin6_port), dest+strlen(dest), 16, 10); - } - - return String(dest); -} -bool SockAddr::IsLocalhost() const -{ - static const unsigned char localhost_bytes[] = - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; - - return memcmp(Addr6.sin6_addr.s6_addr, localhost_bytes, 16) == 0; -} -bool SockAddr::operator==( const SockAddr& right ) const -{ - return memcmp(&Addr6, &right.Addr6, sizeof(Addr6)) == 0; -} - -bool SockAddr::operator!=( const SockAddr& right ) const -{ - return !(*this == right); -} - -bool SockAddr::operator>( const SockAddr& right ) const -{ - return memcmp(&Addr6, &right.Addr6, sizeof(Addr6)) > 0; -} - -bool SockAddr::operator<( const SockAddr& right ) const -{ - return memcmp(&Addr6, &right.Addr6, sizeof(Addr6)) < 0; -} - -static bool SetSocketOptions(SocketHandle sock) -{ - int result = 0; - int sock_opt; - - // This doubles the max throughput rate - sock_opt = 1024 * 256; - result |= setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)& sock_opt, sizeof (sock_opt)); - - // Immediate hard close. Don't linger the socket, or recreating the socket quickly on Vista fails. - sock_opt = 0; - result |= setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)& sock_opt, sizeof (sock_opt)); - - // This doesn't make much difference: 10% maybe - sock_opt = 1024 * 16; - result |= setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)& sock_opt, sizeof (sock_opt)); - - // If all the setsockopt() returned 0 there were no failures, so return true for success, else false - return result == 0; -} - -void _Ioctlsocket(SocketHandle sock, unsigned long nonblocking) -{ - ioctlsocket(sock, FIONBIO, &nonblocking); -} - -static SocketHandle BindShared(int ai_family, int ai_socktype, BerkleyBindParameters* pBindParameters) -{ - SocketHandle sock; - - struct addrinfo hints; - memset(&hints, 0, sizeof (addrinfo)); // make sure the struct is empty - hints.ai_family = ai_family; - hints.ai_socktype = ai_socktype; - hints.ai_flags = AI_PASSIVE; // fill in my IP for me - struct addrinfo *servinfo=0, *aip; // will point to the results - char portStr[32]; - OVR_itoa(pBindParameters->Port, portStr, sizeof(portStr), 10); - - int errcode = 0; - if (!pBindParameters->Address.IsEmpty()) - errcode = getaddrinfo(pBindParameters->Address.ToCStr(), portStr, &hints, &servinfo); - else - errcode = getaddrinfo(0, portStr, &hints, &servinfo); - - if (0 != errcode) - { - OVR::LogError("{ERR-020w} getaddrinfo error: %s", gai_strerror(errcode)); - } - - for (aip = servinfo; aip != NULL; aip = aip->ai_next) - { - // Open socket. The address type depends on what - // getaddrinfo() gave us. - sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); - if (sock != INVALID_SOCKET) - { - if (bind(sock, aip->ai_addr, (int)aip->ai_addrlen) != SOCKET_ERROR) - { - // The actual socket is always non-blocking - // I control blocking or not using WSAEventSelect - _Ioctlsocket(sock, 1); - freeaddrinfo(servinfo); - return sock; - } - - closesocket(sock); - } - } - - if (servinfo) { freeaddrinfo(servinfo); } - return INVALID_SOCKET; -} - - -//----------------------------------------------------------------------------- -// UDPSocket - -UDPSocket::UDPSocket() -{ - WSAStartupSingleton::AddRef(); - RecvBuf = new uint8_t[RecvBufSize]; -} - -UDPSocket::~UDPSocket() -{ - WSAStartupSingleton::Deref(); - delete[] RecvBuf; -} - -SocketHandle UDPSocket::Bind(BerkleyBindParameters *pBindParameters) -{ - SocketHandle s = BindShared(AF_INET6, SOCK_DGRAM, pBindParameters); - if (s == INVALID_SOCKET) - return s; - - Close(); - TheSocket = s; - SetSocketOptions(TheSocket); - - return TheSocket; -} - -void UDPSocket::OnRecv(SocketEvent_UDP* eventHandler, uint8_t* pData, int bytesRead, SockAddr* address) -{ - eventHandler->UDP_OnRecv(this, pData, bytesRead, address); -} - -int UDPSocket::Send(const void* pData, int bytes, SockAddr* address) -{ - return sendto(TheSocket, (const char*)pData, bytes, 0, (const sockaddr*)&address->Addr6, sizeof(address->Addr6)); -} - -void UDPSocket::Poll(SocketEvent_UDP *eventHandler) -{ - struct sockaddr_storage win32_addr; - socklen_t fromlen; - int bytesRead; - - // FIXME: Implement blocking poll wait for UDP - - // While some bytes are read, - while (fromlen = sizeof(win32_addr), // Must set fromlen each time - bytesRead = recvfrom(TheSocket, (char*)RecvBuf, RecvBufSize, 0, (sockaddr*)&win32_addr, &fromlen), - bytesRead > 0) - { - SockAddr address(&win32_addr); // Wrap address - - OnRecv(eventHandler, RecvBuf, bytesRead, &address); - } -} - - -//----------------------------------------------------------------------------- -// TCPSocket - -TCPSocket::TCPSocket() -{ - IsConnecting = false; - IsListenSocket = false; - WSAStartupSingleton::AddRef(); -} -TCPSocket::TCPSocket(SocketHandle boundHandle, bool isListenSocket) -{ - TheSocket = boundHandle; - IsListenSocket = isListenSocket; - IsConnecting = false; - WSAStartupSingleton::AddRef(); - SetSocketOptions(TheSocket); - - // The actual socket is always non-blocking - _Ioctlsocket(TheSocket, 1); -} - -TCPSocket::~TCPSocket() -{ - WSAStartupSingleton::Deref(); -} - -void TCPSocket::OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, int bytesRead) -{ - eventHandler->TCP_OnRecv(this, pData, bytesRead); -} - -SocketHandle TCPSocket::Bind(BerkleyBindParameters* pBindParameters) -{ - SocketHandle s = BindShared(AF_INET6, SOCK_STREAM, pBindParameters); - if (s == INVALID_SOCKET) - return s; - - Close(); - - SetBlockingTimeout(pBindParameters->blockingTimeout); - TheSocket = s; - - SetSocketOptions(TheSocket); - - return TheSocket; -} - -int TCPSocket::Listen() -{ - if (IsListenSocket) - { - return 0; - } - - int i = listen(TheSocket, SOMAXCONN); - if (i >= 0) - { - IsListenSocket = true; - } - - return i; -} - -int TCPSocket::Connect(SockAddr* address) -{ - int retval; - - retval = connect(TheSocket, (struct sockaddr *) &address->Addr6, sizeof(address->Addr6)); - if (retval < 0) - { - DWORD dwIOError = WSAGetLastError(); - if (dwIOError == WSAEWOULDBLOCK) - { - IsConnecting = true; - return 0; - } - - printf( "TCPSocket::Connect failed:Error code - %d\n", dwIOError ); - } - - return retval; -} - -int TCPSocket::Send(const void* pData, int bytes) -{ - if (bytes <= 0) - { - return 0; - } - else - { - return send(TheSocket, (const char*)pData, bytes, 0); - } -} - - -//// TCPSocketPollState - -TCPSocketPollState::TCPSocketPollState() -{ - FD_ZERO(&readFD); - FD_ZERO(&exceptionFD); - FD_ZERO(&writeFD); - largestDescriptor = INVALID_SOCKET; -} - -bool TCPSocketPollState::IsValid() const -{ - return largestDescriptor != INVALID_SOCKET; -} - -void TCPSocketPollState::Add(TCPSocket* tcpSocket) -{ - if (!tcpSocket) - { - return; - } - - SocketHandle handle = tcpSocket->GetSocketHandle(); - - if (largestDescriptor == INVALID_SOCKET || - largestDescriptor < handle) - { - largestDescriptor = handle; - } - - FD_SET(handle, &readFD); - FD_SET(handle, &exceptionFD); - - if (tcpSocket->IsConnecting) - { - FD_SET(handle, &writeFD); - } -} - -bool TCPSocketPollState::Poll(long usec, long seconds) -{ - timeval tv; - tv.tv_sec = seconds; - tv.tv_usec = usec; - - return (int)select((int)largestDescriptor + 1, &readFD, &writeFD, &exceptionFD, &tv) > 0; -} - -void TCPSocketPollState::HandleEvent(TCPSocket* tcpSocket, SocketEvent_TCP* eventHandler) -{ - if (!tcpSocket || !eventHandler) - { - return; - } - - SocketHandle handle = tcpSocket->GetSocketHandle(); - - if (tcpSocket->IsConnecting && FD_ISSET(handle, &writeFD)) - { - tcpSocket->IsConnecting = false; - eventHandler->TCP_OnConnected(tcpSocket); - } - - if (FD_ISSET(handle, &readFD)) - { - if (!tcpSocket->IsListenSocket) - { - static const int BUFF_SIZE = 8096; - char data[BUFF_SIZE]; - - int bytesRead = recv(handle, data, BUFF_SIZE, 0); - if (bytesRead > 0) - { - tcpSocket->OnRecv(eventHandler, (uint8_t*)data, bytesRead); - } - else // Disconnection event: - { - tcpSocket->IsConnecting = false; - eventHandler->TCP_OnClosed(tcpSocket); - } - } - else - { - struct sockaddr_storage sockAddr; - socklen_t sockAddrSize = sizeof(sockAddr); - - SocketHandle newSock = accept(handle, (sockaddr*)&sockAddr, (socklen_t*)&sockAddrSize); - if (newSock != INVALID_SOCKET) - { - SockAddr sa(&sockAddr); - eventHandler->TCP_OnAccept(tcpSocket, &sa, newSock); - } - } - } - - if (FD_ISSET(handle, &exceptionFD)) - { - tcpSocket->IsConnecting = false; - eventHandler->TCP_OnClosed(tcpSocket); - } -} - - -}} // namespace OVR::Net +/************************************************************************************ + +Filename : OVR_Win32_Socket.cpp +Content : Windows-specific socket-based networking implementation +Created : June 10, 2014 +Authors : Kevin Jenkins + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Win32_Socket.h" +#include "Kernel/OVR_Std.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_Threads.h" // Thread::MSleep +#include "Kernel/OVR_Log.h" + +#include +#pragma comment(lib, "ws2_32.lib") + +namespace OVR { namespace Net { + + +//----------------------------------------------------------------------------- +// WSAStartupSingleton + +class WSAStartupSingleton +{ +public: + static void AddRef(void); + static void Deref(void); + +protected: + static int RefCount; +}; + + +// Local data +int WSAStartupSingleton::RefCount = 0; + + +// Implementation +void WSAStartupSingleton::AddRef() +{ + if (++RefCount == 1) + { + WSADATA winsockInfo; + const int errCode = WSAStartup(MAKEWORD(2, 2), &winsockInfo); + OVR_ASSERT(errCode == 0); + + // If an error code is returned + if (errCode != 0) + { + LogError("{ERR-007w} [Socket] Unable to initialize Winsock %d", errCode); + } + } +} + +void WSAStartupSingleton::Deref() +{ + OVR_ASSERT(RefCount > 0); + + if (RefCount > 0) + { + if (--RefCount == 0) + { + WSACleanup(); + RefCount = 0; + } + } +} + + +//----------------------------------------------------------------------------- +// BerkleySocket + +void BerkleySocket::Close() +{ + if (TheSocket != INVALID_SOCKET) + { + closesocket(TheSocket); + TheSocket = INVALID_SOCKET; + } +} + +int32_t BerkleySocket::GetSockname(SockAddr *pSockAddrOut) +{ + struct sockaddr_in6 sa; + memset(&sa,0,sizeof(sa)); + int size = sizeof(sa); + int32_t i = getsockname(TheSocket, (sockaddr*) &sa, &size); + if (i>=0) + { + pSockAddrOut->Set(&sa); + } + return i; +} + + +//----------------------------------------------------------------------------- +// BitStream overloads for SockAddr + +BitStream& operator<<(BitStream& out, SockAddr& in) +{ + out.WriteBits((const unsigned char*) &in.Addr6, sizeof(in.Addr6)*8, true); + return out; +} + +BitStream& operator>>(BitStream& in, SockAddr& out) +{ + bool success = in.ReadBits((unsigned char*) &out.Addr6, sizeof(out.Addr6)*8, true); + OVR_ASSERT(success); + OVR_UNUSED(success); + return in; +} + + +//----------------------------------------------------------------------------- +// SockAddr + +SockAddr::SockAddr() +{ + WSAStartupSingleton::AddRef(); + + // Zero out the address to squelch static analysis tools + ZeroMemory(&Addr6, sizeof(Addr6)); +} + +SockAddr::SockAddr(SockAddr* address) +{ + WSAStartupSingleton::AddRef(); + Set(&address->Addr6); +} + +SockAddr::SockAddr(sockaddr_storage* storage) +{ + WSAStartupSingleton::AddRef(); + Set(storage); +} + +SockAddr::SockAddr(sockaddr_in6* address) +{ + WSAStartupSingleton::AddRef(); + Set(address); +} + +SockAddr::SockAddr(const char* hostAddress, uint16_t port, int sockType) +{ + WSAStartupSingleton::AddRef(); + Set(hostAddress, port, sockType); +} + +void SockAddr::Set(const sockaddr_storage* storage) +{ + memcpy(&Addr6, storage, sizeof(Addr6)); +} + +void SockAddr::Set(const sockaddr_in6* address) +{ + memcpy(&Addr6, address, sizeof(Addr6)); +} + +void SockAddr::Set(const char* hostAddress, uint16_t port, int sockType) +{ + memset(&Addr6, 0, sizeof(Addr6)); + + struct addrinfo hints; + + // make sure the struct is empty + memset(&hints, 0, sizeof (addrinfo)); + + hints.ai_socktype = sockType; // SOCK_DGRAM or SOCK_STREAM + hints.ai_flags = AI_PASSIVE; // fill in my IP for me + hints.ai_family = AF_UNSPEC ; + + // FIXME See OVR_Unix_Socket implementation and man pages for getaddrinfo. + // ai_protocol is expecting to be either IPPROTO_UDP and IPPROTO_TCP. + // But this has been working on windows so I'm leaving it be for + // now instead of introducing another variable. + hints.ai_protocol = IPPROTO_IPV6; + + struct addrinfo* servinfo = NULL; // will point to the results + + char portStr[32]; + OVR_itoa(port, portStr, sizeof(portStr), 10); + int errcode = getaddrinfo(hostAddress, portStr, &hints, &servinfo); + + if (0 != errcode) + { + OVR::LogError("{ERR-008w} getaddrinfo error: %s", gai_strerror(errcode)); + } + + OVR_ASSERT(servinfo); + + if (servinfo) + { + memcpy(&Addr6, servinfo->ai_addr, sizeof(Addr6)); + + freeaddrinfo(servinfo); + } +} + +uint16_t SockAddr::GetPort() +{ + return htons(Addr6.sin6_port); +} + +String SockAddr::ToString(bool writePort, char portDelineator) const +{ + char dest[INET6_ADDRSTRLEN + 1]; + + int ret = getnameinfo((struct sockaddr*)&Addr6, + sizeof(struct sockaddr_in6), + dest, + INET6_ADDRSTRLEN, + NULL, + 0, + NI_NUMERICHOST); + if (ret != 0) + { + dest[0] = '\0'; + } + + if (writePort) + { + unsigned char ch[2]; + ch[0]=portDelineator; + ch[1]=0; + OVR_strcat(dest, 16, (const char*) ch); + OVR_itoa(ntohs(Addr6.sin6_port), dest+strlen(dest), 16, 10); + } + + return String(dest); +} +bool SockAddr::IsLocalhost() const +{ + static const unsigned char localhost_bytes[] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; + + return memcmp(Addr6.sin6_addr.s6_addr, localhost_bytes, 16) == 0; +} +bool SockAddr::operator==( const SockAddr& right ) const +{ + return memcmp(&Addr6, &right.Addr6, sizeof(Addr6)) == 0; +} + +bool SockAddr::operator!=( const SockAddr& right ) const +{ + return !(*this == right); +} + +bool SockAddr::operator>( const SockAddr& right ) const +{ + return memcmp(&Addr6, &right.Addr6, sizeof(Addr6)) > 0; +} + +bool SockAddr::operator<( const SockAddr& right ) const +{ + return memcmp(&Addr6, &right.Addr6, sizeof(Addr6)) < 0; +} + +static bool SetSocketOptions(SocketHandle sock) +{ + int result = 0; + int sock_opt; + + // This doubles the max throughput rate + sock_opt = 1024 * 256; + result |= setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)& sock_opt, sizeof (sock_opt)); + + // Immediate hard close. Don't linger the socket, or recreating the socket quickly on Vista fails. + sock_opt = 0; + result |= setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)& sock_opt, sizeof (sock_opt)); + + // This doesn't make much difference: 10% maybe + sock_opt = 1024 * 16; + result |= setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)& sock_opt, sizeof (sock_opt)); + + // If all the setsockopt() returned 0 there were no failures, so return true for success, else false + return result == 0; +} + +void _Ioctlsocket(SocketHandle sock, unsigned long nonblocking) +{ + ioctlsocket(sock, FIONBIO, &nonblocking); +} + +static SocketHandle BindShared(int ai_family, int ai_socktype, BerkleyBindParameters* pBindParameters) +{ + SocketHandle sock; + + struct addrinfo hints; + memset(&hints, 0, sizeof (addrinfo)); // make sure the struct is empty + hints.ai_family = ai_family; + hints.ai_socktype = ai_socktype; + hints.ai_flags = AI_PASSIVE; // fill in my IP for me + struct addrinfo *servinfo=0, *aip; // will point to the results + char portStr[32]; + OVR_itoa(pBindParameters->Port, portStr, sizeof(portStr), 10); + + int errcode = 0; + if (!pBindParameters->Address.IsEmpty()) + errcode = getaddrinfo(pBindParameters->Address.ToCStr(), portStr, &hints, &servinfo); + else + errcode = getaddrinfo(0, portStr, &hints, &servinfo); + + if (0 != errcode) + { + OVR::LogError("{ERR-020w} getaddrinfo error: %s", gai_strerror(errcode)); + } + + for (aip = servinfo; aip != NULL; aip = aip->ai_next) + { + // Open socket. The address type depends on what + // getaddrinfo() gave us. + sock = socket(aip->ai_family, aip->ai_socktype, aip->ai_protocol); + if (sock != INVALID_SOCKET) + { + if (bind(sock, aip->ai_addr, (int)aip->ai_addrlen) != SOCKET_ERROR) + { + // The actual socket is always non-blocking + // I control blocking or not using WSAEventSelect + _Ioctlsocket(sock, 1); + freeaddrinfo(servinfo); + return sock; + } + + closesocket(sock); + } + } + + if (servinfo) { freeaddrinfo(servinfo); } + return INVALID_SOCKET; +} + + +//----------------------------------------------------------------------------- +// UDPSocket + +UDPSocket::UDPSocket() +{ + WSAStartupSingleton::AddRef(); + RecvBuf = new uint8_t[RecvBufSize]; +} + +UDPSocket::~UDPSocket() +{ + WSAStartupSingleton::Deref(); + delete[] RecvBuf; +} + +SocketHandle UDPSocket::Bind(BerkleyBindParameters *pBindParameters) +{ + SocketHandle s = BindShared(AF_INET6, SOCK_DGRAM, pBindParameters); + if (s == INVALID_SOCKET) + return s; + + Close(); + TheSocket = s; + SetSocketOptions(TheSocket); + + return TheSocket; +} + +void UDPSocket::OnRecv(SocketEvent_UDP* eventHandler, uint8_t* pData, int bytesRead, SockAddr* address) +{ + eventHandler->UDP_OnRecv(this, pData, bytesRead, address); +} + +int UDPSocket::Send(const void* pData, int bytes, SockAddr* address) +{ + return sendto(TheSocket, (const char*)pData, bytes, 0, (const sockaddr*)&address->Addr6, sizeof(address->Addr6)); +} + +void UDPSocket::Poll(SocketEvent_UDP *eventHandler) +{ + struct sockaddr_storage win32_addr; + socklen_t fromlen; + int bytesRead; + + // FIXME: Implement blocking poll wait for UDP + + // While some bytes are read, + while (fromlen = sizeof(win32_addr), // Must set fromlen each time + bytesRead = recvfrom(TheSocket, (char*)RecvBuf, RecvBufSize, 0, (sockaddr*)&win32_addr, &fromlen), + bytesRead > 0) + { + SockAddr address(&win32_addr); // Wrap address + + OnRecv(eventHandler, RecvBuf, bytesRead, &address); + } +} + + +//----------------------------------------------------------------------------- +// TCPSocket + +TCPSocket::TCPSocket() +{ + IsConnecting = false; + IsListenSocket = false; + WSAStartupSingleton::AddRef(); +} + +TCPSocket::TCPSocket(SocketHandle boundHandle, bool isListenSocket) +{ + TheSocket = boundHandle; + IsListenSocket = isListenSocket; + IsConnecting = false; + WSAStartupSingleton::AddRef(); + + if (TheSocket != INVALID_SOCKET) + { + SetSocketOptions(TheSocket); + + // The actual socket is always non-blocking + _Ioctlsocket(TheSocket, 1); + } +} + +TCPSocket::~TCPSocket() +{ + WSAStartupSingleton::Deref(); +} + +void TCPSocket::OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, int bytesRead) +{ + eventHandler->TCP_OnRecv(this, pData, bytesRead); +} + +SocketHandle TCPSocket::Bind(BerkleyBindParameters* pBindParameters) +{ + SocketHandle s = BindShared(AF_INET6, SOCK_STREAM, pBindParameters); + if (s == INVALID_SOCKET) + return s; + + Close(); + + SetBlockingTimeout(pBindParameters->blockingTimeout); + TheSocket = s; + + SetSocketOptions(TheSocket); + + return TheSocket; +} + +int TCPSocket::Listen() +{ + if (IsListenSocket) + { + return 0; + } + + int i = listen(TheSocket, SOMAXCONN); + if (i >= 0) + { + IsListenSocket = true; + } + + return i; +} + +int TCPSocket::Connect(SockAddr* address) +{ + int retval; + + retval = connect(TheSocket, (struct sockaddr *) &address->Addr6, sizeof(address->Addr6)); + if (retval < 0) + { + DWORD dwIOError = WSAGetLastError(); + if (dwIOError == WSAEWOULDBLOCK) + { + IsConnecting = true; + return 0; + } + + LogError("[TCPSocket] ERROR: Connect failed. Error code - %d", (int)dwIOError); + } + + return retval; +} + +int TCPSocket::Send(const void* pData, int bytes) +{ + if (bytes <= 0) + { + return 0; + } + else + { + return send(TheSocket, (const char*)pData, bytes, 0); + } +} + + +//// TCPSocketPollState + +TCPSocketPollState::TCPSocketPollState() +{ + memset(&readFD, 0, sizeof(readFD)); + memset(&exceptionFD, 0, sizeof(exceptionFD)); + memset(&writeFD, 0, sizeof(writeFD)); + + FD_ZERO(&readFD); + FD_ZERO(&exceptionFD); + FD_ZERO(&writeFD); + largestDescriptor = INVALID_SOCKET; +} + +bool TCPSocketPollState::IsValid() const +{ + return largestDescriptor != INVALID_SOCKET; +} + +void TCPSocketPollState::Add(TCPSocket* tcpSocket) +{ + if (!tcpSocket) + { + return; + } + + SocketHandle handle = tcpSocket->GetSocketHandle(); + + if (largestDescriptor == INVALID_SOCKET || + largestDescriptor < handle) + { + largestDescriptor = handle; + } + + FD_SET(handle, &readFD); + FD_SET(handle, &exceptionFD); + + if (tcpSocket->IsConnecting) + { + FD_SET(handle, &writeFD); + } +} + +bool TCPSocketPollState::Poll(long usec, long seconds) +{ + timeval tv; + tv.tv_sec = seconds; + tv.tv_usec = usec; + + return (int)select((int)largestDescriptor + 1, &readFD, &writeFD, &exceptionFD, &tv) > 0; +} + +void TCPSocketPollState::HandleEvent(TCPSocket* tcpSocket, SocketEvent_TCP* eventHandler) +{ + if (!tcpSocket || !eventHandler) + { + return; + } + + SocketHandle handle = tcpSocket->GetSocketHandle(); + + if (tcpSocket->IsConnecting && FD_ISSET(handle, &writeFD)) + { + tcpSocket->IsConnecting = false; + eventHandler->TCP_OnConnected(tcpSocket); + } + + if (FD_ISSET(handle, &readFD)) + { + if (!tcpSocket->IsListenSocket) + { + static const int BUFF_SIZE = 8096; + char data[BUFF_SIZE]; + + int bytesRead = recv(handle, data, BUFF_SIZE, 0); + if (bytesRead > 0) + { + tcpSocket->OnRecv(eventHandler, (uint8_t*)data, bytesRead); + } + else // Disconnection event: + { + tcpSocket->IsConnecting = false; + eventHandler->TCP_OnClosed(tcpSocket); + } + } + else + { + struct sockaddr_storage sockAddr; + socklen_t sockAddrSize = sizeof(sockAddr); + + SocketHandle newSock = accept(handle, (sockaddr*)&sockAddr, (socklen_t*)&sockAddrSize); + if (newSock != INVALID_SOCKET) + { + SockAddr sa(&sockAddr); + eventHandler->TCP_OnAccept(tcpSocket, &sa, newSock); + } + } + } + + if (FD_ISSET(handle, &exceptionFD)) + { + tcpSocket->IsConnecting = false; + eventHandler->TCP_OnClosed(tcpSocket); + } +} + + +}} // namespace OVR::Net diff --git a/LibOVR/Src/Net/OVR_Win32_Socket.h b/LibOVR/Src/Net/OVR_Win32_Socket.h index ac66869..ed0a624 100644 --- a/LibOVR/Src/Net/OVR_Win32_Socket.h +++ b/LibOVR/Src/Net/OVR_Win32_Socket.h @@ -1,151 +1,150 @@ -/************************************************************************************ - -PublicHeader: n/a -Filename : OVR_Win32_Socket.h -Content : Windows-specific socket-based networking implementation -Created : June 10, 2014 -Authors : Kevin Jenkins - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_Win32_Socket_h -#define OVR_Win32_Socket_h - -#include "OVR_Socket.h" -#include "OVR_BitStream.h" - -#include -#include -#define WIN32_LEAN_AND_MEAN -#include -#include - -namespace OVR { namespace Net { - - -//----------------------------------------------------------------------------- -// SockAddr - -// Abstraction for IPV6 socket address, with various convenience functions -class SockAddr -{ -public: - SockAddr(); - SockAddr(SockAddr* sa); - SockAddr(sockaddr_storage* sa); - SockAddr(sockaddr_in6* sa); - SockAddr(const char* hostAddress, uint16_t port, int sockType); - -public: - void Set(const sockaddr_storage* sa); - void Set(const sockaddr_in6* sa); - void Set(const char* hostAddress, uint16_t port, int sockType); // SOCK_DGRAM or SOCK_STREAM - - uint16_t GetPort(); - - String ToString(bool writePort, char portDelineator) const; - bool IsLocalhost() const; - - void Serialize(BitStream* bs); - bool Deserialize(BitStream); - - bool operator==( const SockAddr& right ) const; - bool operator!=( const SockAddr& right ) const; - bool operator >( const SockAddr& right ) const; - bool operator <( const SockAddr& right ) const; - -public: - sockaddr_in6 Addr6; -}; - - -//----------------------------------------------------------------------------- -// UDP Socket - -// Windows version of TCP socket -class UDPSocket : public UDPSocketBase -{ -public: - UDPSocket(); - virtual ~UDPSocket(); - -public: - virtual SocketHandle Bind(BerkleyBindParameters* pBindParameters); - virtual int Send(const void* pData, int bytes, SockAddr* address); - virtual void Poll(SocketEvent_UDP* eventHandler); - -protected: - static const int RecvBufSize = 1048576; - uint8_t* RecvBuf; - - virtual void OnRecv(SocketEvent_UDP* eventHandler, uint8_t* pData, - int bytesRead, SockAddr* address); -}; - - -//----------------------------------------------------------------------------- -// TCP Socket - -// Windows version of TCP socket -class TCPSocket : public TCPSocketBase -{ - friend class TCPSocketPollState; - -public: - TCPSocket(); - TCPSocket(SocketHandle boundHandle, bool isListenSocket); - virtual ~TCPSocket(); - -public: - virtual SocketHandle Bind(BerkleyBindParameters* pBindParameters); - virtual int Listen(); - virtual int Connect(SockAddr* address); - virtual int Send(const void* pData, int bytes); - -protected: - virtual void OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, - int bytesRead); - -public: - bool IsConnecting; // Is in the process of connecting? -}; - - -//----------------------------------------------------------------------------- -// TCPSocketPollState - -// Polls multiple blocking TCP sockets at once -class TCPSocketPollState -{ - fd_set readFD, exceptionFD, writeFD; - SocketHandle largestDescriptor; - -public: - TCPSocketPollState(); - bool IsValid() const; - void Add(TCPSocket* tcpSocket); - bool Poll(long usec = 30000, long seconds = 0); - void HandleEvent(TCPSocket* tcpSocket, SocketEvent_TCP* eventHandler); -}; - - -}} // OVR::Net - -#endif +/************************************************************************************ + +PublicHeader: n/a +Filename : OVR_Win32_Socket.h +Content : Windows-specific socket-based networking implementation +Created : June 10, 2014 +Authors : Kevin Jenkins + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Win32_Socket_h +#define OVR_Win32_Socket_h + +#include "OVR_Socket.h" +#include "OVR_BitStream.h" + +#include +#include +#include "Kernel/OVR_Win32_IncludeWindows.h" +#include + +namespace OVR { namespace Net { + + +//----------------------------------------------------------------------------- +// SockAddr + +// Abstraction for IPV6 socket address, with various convenience functions +class SockAddr +{ +public: + SockAddr(); + SockAddr(SockAddr* sa); + SockAddr(sockaddr_storage* sa); + SockAddr(sockaddr_in6* sa); + SockAddr(const char* hostAddress, uint16_t port, int sockType); + +public: + void Set(const sockaddr_storage* sa); + void Set(const sockaddr_in6* sa); + void Set(const char* hostAddress, uint16_t port, int sockType); // SOCK_DGRAM or SOCK_STREAM + + uint16_t GetPort(); + + String ToString(bool writePort, char portDelineator) const; + bool IsLocalhost() const; + + void Serialize(BitStream* bs); + bool Deserialize(BitStream); + + bool operator==( const SockAddr& right ) const; + bool operator!=( const SockAddr& right ) const; + bool operator >( const SockAddr& right ) const; + bool operator <( const SockAddr& right ) const; + +public: + sockaddr_in6 Addr6; +}; + + +//----------------------------------------------------------------------------- +// UDP Socket + +// Windows version of TCP socket +class UDPSocket : public UDPSocketBase +{ +public: + UDPSocket(); + virtual ~UDPSocket(); + +public: + virtual SocketHandle Bind(BerkleyBindParameters* pBindParameters); + virtual int Send(const void* pData, int bytes, SockAddr* address); + virtual void Poll(SocketEvent_UDP* eventHandler); + +protected: + static const int RecvBufSize = 1048576; + uint8_t* RecvBuf; + + virtual void OnRecv(SocketEvent_UDP* eventHandler, uint8_t* pData, + int bytesRead, SockAddr* address); +}; + + +//----------------------------------------------------------------------------- +// TCP Socket + +// Windows version of TCP socket +class TCPSocket : public TCPSocketBase +{ + friend class TCPSocketPollState; + +public: + TCPSocket(); + TCPSocket(SocketHandle boundHandle, bool isListenSocket); + virtual ~TCPSocket(); + +public: + virtual SocketHandle Bind(BerkleyBindParameters* pBindParameters); + virtual int Listen(); + virtual int Connect(SockAddr* address); + virtual int Send(const void* pData, int bytes); + +protected: + virtual void OnRecv(SocketEvent_TCP* eventHandler, uint8_t* pData, + int bytesRead); + +public: + bool IsConnecting; // Is in the process of connecting? +}; + + +//----------------------------------------------------------------------------- +// TCPSocketPollState + +// Polls multiple blocking TCP sockets at once +class TCPSocketPollState +{ + fd_set readFD, exceptionFD, writeFD; + SocketHandle largestDescriptor; + +public: + TCPSocketPollState(); + bool IsValid() const; + void Add(TCPSocket* tcpSocket); + bool Poll(long usec = 30000, long seconds = 0); + void HandleEvent(TCPSocket* tcpSocket, SocketEvent_TCP* eventHandler); +}; + + +}} // OVR::Net + +#endif diff --git a/LibOVR/Src/OVR_CAPI.cpp b/LibOVR/Src/OVR_CAPI.cpp old mode 100644 new mode 100755 index bfc0527..d451ad8 --- a/LibOVR/Src/OVR_CAPI.cpp +++ b/LibOVR/Src/OVR_CAPI.cpp @@ -25,67 +25,84 @@ limitations under the License. ************************************************************************************/ #include "OVR_CAPI.h" +#include "OVR_Version.h" + + #include "Kernel/OVR_Timer.h" -#include "Kernel/OVR_Math.h" #include "Kernel/OVR_System.h" +#include "Kernel/OVR_DebugHelp.h" +#include "Extras/OVR_Math.h" #include "OVR_Stereo.h" #include "OVR_Profile.h" -#include "../Include/OVR_Version.h" #include "CAPI/CAPI_HMDState.h" -#include "CAPI/CAPI_FrameTimeManager.h" +#include "Net/OVR_Session.h" #include "Service/Service_NetClient.h" -#ifdef OVR_SINGLE_PROCESS +#ifdef OVR_PRIVATE_FILE #include "Service/Service_NetServer.h" #endif -#ifdef OVR_OS_WIN32 +#include "Displays/OVR_Display.h" + +#if defined(OVR_OS_WIN32) #include "Displays/OVR_Win32_ShimFunctions.h" +#include #endif +// Forward decl to keep the callback static + +// Note: Removed CaptureHmdDescTrace from non-Win32 due to build warning. +#if !defined(OVR_OS_MAC) && !defined(OVR_OS_LINUX) +static bool CaptureHmdDescTrace(const OVR::CAPI::HMDState *state); +#endif +#define TRACE_STATE_CAPTURE_FUNC OVR::CAPI::HMDState::EnumerateHMDStateList(CaptureHmdDescTrace) +#include "Tracing/Tracing.h" + +#if !defined(OVR_OS_MAC) && !defined(OVR_OS_LINUX) +// EnumerateHMDStateList callback for tracing state capture +static bool CaptureHmdDescTrace(const OVR::CAPI::HMDState* state) +{ + TraceHmdDesc(*state->pHmdDesc); + OVR_UNUSED(state); // Avoid potential compiler warnings. + return true; +} +#endif + +// Produce an invalid tracking state that will not mess up the application too badly. +static ovrTrackingState GetNullTrackingState() +{ + ovrTrackingState nullState = ovrTrackingState(); + nullState.HeadPose.ThePose.Orientation.w = 1.f; // Provide valid quaternions for head pose. + return nullState; +} + +// Produce a null frame timing structure that will not break the calling application. +static ovrFrameTiming GetNullFrameTiming() +{ + ovrFrameTiming nullTiming = ovrFrameTiming(); + nullTiming.DeltaSeconds = 0.013f; // Provide nominal value + return nullTiming; +} + using namespace OVR; using namespace OVR::Util::Render; -using namespace OVR::Tracking; +using namespace OVR::Vision; //------------------------------------------------------------------------------------- // Math namespace OVR { -// ***** FovPort - -// C-interop support: FovPort <-> ovrFovPort -FovPort::FovPort(const ovrFovPort &src) - : UpTan(src.UpTan), DownTan(src.DownTan), LeftTan(src.LeftTan), RightTan(src.RightTan) -{ } - -FovPort::operator ovrFovPort () const -{ - ovrFovPort result; - result.LeftTan = LeftTan; - result.RightTan = RightTan; - result.UpTan = UpTan; - result.DownTan = DownTan; - return result; -} - -// Converts Fov Tan angle units to [-1,1] render target NDC space -Vector2f FovPort::TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle) -{ - ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(*this); - return tanEyeAngle * eyeToSourceNDC.Scale + eyeToSourceNDC.Offset; -} - // ***** SensorDataType SensorDataType::SensorDataType(const ovrSensorData& s) { - Acceleration = s.Accelerometer; - RotationRate = s.Gyro; - MagneticField = s.Magnetometer; - Temperature = s.Temperature; + Acceleration = s.Accelerometer; + RotationRate = s.Gyro; + MagneticField = s.Magnetometer; + Temperature = s.Temperature; AbsoluteTimeSeconds = s.TimeInSeconds; } @@ -93,39 +110,35 @@ SensorDataType::operator ovrSensorData () const { ovrSensorData result; result.Accelerometer = Acceleration; - result.Gyro = RotationRate; - result.Magnetometer = MagneticField; - result.Temperature = Temperature; - result.TimeInSeconds = (float) AbsoluteTimeSeconds; + result.Gyro = RotationRate; + result.Magnetometer = MagneticField; + result.Temperature = Temperature; + result.TimeInSeconds = (float)AbsoluteTimeSeconds; return result; } + + // ***** SensorState TrackingState::TrackingState(const ovrTrackingState& s) { - HeadPose = s.HeadPose; - CameraPose = s.CameraPose; + HeadPose = s.HeadPose; + CameraPose = s.CameraPose; LeveledCameraPose = s.LeveledCameraPose; - RawSensorData = s.RawSensorData; - StatusFlags = s.StatusFlags; - LastVisionProcessingTime = s.LastVisionProcessingTime; - LastVisionFrameLatency = s.LastVisionFrameLatency; - LastCameraFrameCounter = s.LastCameraFrameCounter; + RawSensorData = s.RawSensorData; + StatusFlags = s.StatusFlags; } TrackingState::operator ovrTrackingState() const { ovrTrackingState result; - result.HeadPose = HeadPose; - result.CameraPose = CameraPose; + result.HeadPose = HeadPose; + result.CameraPose = CameraPose; result.LeveledCameraPose = LeveledCameraPose; - result.RawSensorData = RawSensorData; - result.StatusFlags = StatusFlags; - result.LastVisionProcessingTime = LastVisionProcessingTime; - result.LastVisionFrameLatency = LastVisionFrameLatency; - result.LastCameraFrameCounter = LastCameraFrameCounter; + result.RawSensorData = RawSensorData; + result.StatusFlags = StatusFlags; return result; } @@ -136,182 +149,210 @@ TrackingState::operator ovrTrackingState() const using namespace OVR::CAPI; -#ifdef __cplusplus -extern "C" { -#endif - -// Used to generate projection from ovrEyeDesc::Fov -OVR_EXPORT ovrMatrix4f ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, ovrBool rightHanded) +// Helper function to validate the HMD object provided by the API user. +static HMDState* GetHMDStateFromOvrHmd(ovrHmd hmddesc) { - return CreateProjection(rightHanded ? true : false, fov, znear, zfar); + if (!hmddesc || !hmddesc->Handle) + return nullptr; + + return (HMDState*)hmddesc->Handle; } -OVR_EXPORT ovrMatrix4f ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale, - float orthoDistance, float hmdToEyeViewOffsetX) +OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds() { + return Timer::GetSeconds(); +} - float orthoHorizontalOffset = hmdToEyeViewOffsetX / orthoDistance; - - // Current projection maps real-world vector (x,y,1) to the RT. - // We want to find the projection that maps the range [-FovPixels/2,FovPixels/2] to - // the physical [-orthoHalfFov,orthoHalfFov] - // Note moving the offset from M[0][2]+M[1][2] to M[0][3]+M[1][3] - this means - // we don't have to feed in Z=1 all the time. - // The horizontal offset math is a little hinky because the destination is - // actually [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset] - // So we need to first map [-FovPixels/2,FovPixels/2] to - // [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]: - // x1 = x0 * orthoHalfFov/(FovPixels/2) + orthoHorizontalOffset; - // = x0 * 2*orthoHalfFov/FovPixels + orthoHorizontalOffset; - // But then we need the same mapping as the existing projection matrix, i.e. - // x2 = x1 * Projection.M[0][0] + Projection.M[0][2]; - // = x0 * (2*orthoHalfFov/FovPixels + orthoHorizontalOffset) * Projection.M[0][0] + Projection.M[0][2]; - // = x0 * Projection.M[0][0]*2*orthoHalfFov/FovPixels + - // orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]; - // So in the new projection matrix we need to scale by Projection.M[0][0]*2*orthoHalfFov/FovPixels and - // offset by orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]. - - Matrix4f ortho; - ortho.M[0][0] = projection.M[0][0] * orthoScale.x; - ortho.M[0][1] = 0.0f; - ortho.M[0][2] = 0.0f; - ortho.M[0][3] = -projection.M[0][2] + ( orthoHorizontalOffset * projection.M[0][0] ); - - ortho.M[1][0] = 0.0f; - ortho.M[1][1] = -projection.M[1][1] * orthoScale.y; // Note sign flip (text rendering uses Y=down). - ortho.M[1][2] = 0.0f; - ortho.M[1][3] = -projection.M[1][2]; - - /* - if ( fabsf ( zNear - zFar ) < 0.001f ) - { - ortho.M[2][0] = 0.0f; - ortho.M[2][1] = 0.0f; - ortho.M[2][2] = 0.0f; - ortho.M[2][3] = zFar; - } - else - { - ortho.M[2][0] = 0.0f; - ortho.M[2][1] = 0.0f; - ortho.M[2][2] = zFar / (zNear - zFar); - ortho.M[2][3] = (zFar * zNear) / (zNear - zFar); - } - */ - // MA: Undo effect of sign - ortho.M[2][0] = 0.0f; - ortho.M[2][1] = 0.0f; - //ortho.M[2][2] = projection.M[2][2] * projection.M[3][2] * -1.0f; // reverse right-handedness - ortho.M[2][2] = 0.0f; - ortho.M[2][3] = 0.0f; - //projection.M[2][3]; +//------------------------------------------------------------------------------------- - // No perspective correction for ortho. - ortho.M[3][0] = 0.0f; - ortho.M[3][1] = 0.0f; - ortho.M[3][2] = 0.0f; - ortho.M[3][3] = 1.0f; +// 1. Init/shutdown. - return ortho; -} +static ovrBool CAPI_ovrInitializeCalled = ovrFalse; +static OVR::Service::NetClient* CAPI_pNetClient = nullptr; -OVR_EXPORT double ovr_GetTimeInSeconds() +ovrBool ovr_InitializeRenderingShim() { - return Timer::GetSeconds(); + OVR::Display::Initialize(); + + return OVR::Display::GetDirectDisplayInitialized(); } -// Waits until the specified absolute time. -OVR_EXPORT double ovr_WaitTillTime(double absTime) +OVR_PUBLIC_FUNCTION(ovrBool) ovr_InitializeRenderingShimVersion(int requestedMinorVersion) { - double initialTime = ovr_GetTimeInSeconds(); - double newTime = initialTime; + // We ignore the patch and build versions here, as they aren't relevant to compatibility. + // And we don't store them away here, as we do that in ovr_Initialize() instead. - while(newTime < absTime) + if (requestedMinorVersion > OVR_MINOR_VERSION) + return ovrFalse; + + return ovr_InitializeRenderingShim(); +} + +// Write out to the log where the current running module is located on disk. +static void LogLocationOfThisModule() +{ +#if defined (OVR_OS_WIN32) + // Log out the DLL file path on startup. { - for (int j = 0; j < 5; j++) - OVR_PROCESSOR_PAUSE(); + bool success = false; + + HMODULE hModule = nullptr; + GetModuleHandleEx( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + (LPCTSTR)&ovr_Initialize, + &hModule); + if (hModule) + { + wchar_t filename[_MAX_PATH]; + DWORD len = GetModuleFileNameW(hModule, filename, OVR_ARRAY_COUNT(filename)); + if (len > 0 && filename[0]) + { + success = true; + LogText("[CAPI] LibOVR module is located at %ws\n", filename); + } + } - newTime = ovr_GetTimeInSeconds(); + if (!success) + { + LogError("[CAPI] WARNING: Unable to find LibOVR module."); + } } - - // How long we waited - return newTime - initialTime; +#endif // OVR_OS_WIN32 } +// These defaults are also in OVR_CAPIShim.c +static const ovrInitParams DefaultParams = { + ovrInit_RequestVersion, // Flags + OVR_MINOR_VERSION, // RequestedMinorVersion + 0, // LogCallback + 0 // ConnectionTimeoutSeconds +}; -//------------------------------------------------------------------------------------- +// Precondition: params is not null +OVR_PUBLIC_FUNCTION(ovrBool) ovr_Initialize(ovrInitParams const* params) +{ + // TBD: Should we check if the version requested changed and fail here? + if (CAPI_ovrInitializeCalled) // If already initialized... + return ovrTrue; -// 1. Init/shutdown. + TraceInit(); + TraceCall(0); -static ovrBool CAPI_SystemInitCalled = 0; -static ovrBool CAPI_ovrInitializeCalled = 0; + if (!params) + { + params = &DefaultParams; + } -static OVR::Service::NetClient* CAPI_pNetClient = 0; + bool DebugMode = (params->Flags & ovrInit_Debug) != 0; -OVR_EXPORT ovrBool ovr_InitializeRenderingShim() -{ - OVR::System::DirectDisplayInitialize(); - return OVR::System::DirectDisplayEnabled(); -} +#if defined(OVR_BUILD_DEBUG) + // If no debug setting is provided, + if (!(params->Flags & (ovrInit_Debug | ovrInit_ForceNoDebug))) + { + DebugMode = true; + } +#endif -OVR_EXPORT ovrBool ovr_Initialize() -{ - if (CAPI_ovrInitializeCalled) - return 1; + // We ignore the requested patch version and build version, as they are not currently relevant to + // the library compatibility. Our test for minor version compatibility is currently simple: we support + // only older or equal minor versions, and don't change our behavior if the requested minor version + // is older than than OVR_MINOR_VERSION. - // We must set up the system for the plugin to work - if (!OVR::System::IsInitialized()) + if ((params->Flags & ovrInit_RequestVersion) != 0 && + (params->RequestedMinorVersion > OVR_MINOR_VERSION)) { - OVR::System::Init(OVR::Log::ConfigureDefaultLog(OVR::LogMask_All)); - CAPI_SystemInitCalled = 1; + goto Abort; } - if (!OVR::System::DirectDisplayEnabled() && !OVR::Display::InCompatibilityMode(false)) +#if defined(OVR_OS_WIN32) + // Older than Windows 7 SP1? + if (!IsWindows7SP1OrGreater()) { + MessageBoxA(nullptr, "This software depends on features available starting with \nWindows 7 Service Pack 1, and it cannot start.", "LibOVR: Cannot start", 0); OVR_ASSERT(false); - return 0; + goto Abort; } +#endif // OVR_OS_WIN32 - CAPI_pNetClient = NetClient::GetInstance(); + OVR::Net::RuntimeSDKVersion.SetCurrent(); // Fill in the constant parts of this struct. + OVR::Net::RuntimeSDKVersion.RequestedMinorVersion = (uint16_t)params->RequestedMinorVersion; -#ifdef OVR_SINGLE_PROCESS + // Initialize display subsystem regardless of Allocator initialization. + OVR::Display::Initialize(); - // If the server could not start running, - if (Service::NetServer::GetInstance()->IsInitialized()) + // We must set up the system for the plugin to work + if (!OVR::System::IsInitialized()) { - CAPI_pNetClient->Connect(true); + // TBD: Base this on registry setting? + Allocator::SetLeakTracking(DebugMode); + + OVR::Log* logger = OVR::Log::ConfigureDefaultLog(OVR::LogMask_All); + + // Set the CAPI logger callback + logger->SetCAPICallback(params->LogCallback); + + OVR::System::Init(logger); } - else + + if (!OVR::Display::GetDirectDisplayInitialized() && !OVR::Display::InCompatibilityMode(true)) { - // This normally will happen if the OVRService is running in the background, - // or another SingleProcess-mode app is running in the background. - // In this case, it's using the hardware and we should not also attempt to use - // the hardware. - LogError("{ERR-079} [LibOVR] Server is already running"); + OVR_ASSERT(false); + goto Abort; } -#else - CAPI_pNetClient->Connect(true); -#endif + CAPI_pNetClient = NetClient::GetInstance(); + + // Store off the initialization parameters from ovr_Initialize() + CAPI_pNetClient->ApplyParameters(params); + + // Mark as initialized regardless of whether or not we can connect to the server. CAPI_ovrInitializeCalled = 1; - return 1; + // Log the location of the module after most of the bring-up, as the game + // could do almost anything in response to a log message callback. + LogLocationOfThisModule(); + + // If unable to connect to server and we are not in a debug mode, + if (!CAPI_pNetClient->Connect(true) && !DebugMode) + { + // Then it's a failure when the server is unreachable. + // This means that a DebugHMD cannot be created unless the ovrInit_Debug flag is set. + goto Abort; + } + + // everything is okay + TraceReturn(0); + return ovrTrue; + +Abort: + // clean up and return failure + TraceReturn(0); + TraceFini(); + return ovrFalse; } -OVR_EXPORT void ovr_Shutdown() + +OVR_PUBLIC_FUNCTION(void) ovr_Shutdown() { - // We should clean up the system to be complete - if (OVR::System::IsInitialized() && CAPI_SystemInitCalled) + if (CAPI_ovrInitializeCalled) + { + OVR::Display::Shutdown(); + TraceCall(0); + TraceFini(); + CAPI_ovrInitializeCalled = 0; + } + + if (OVR::System::IsInitialized()) { OVR::System::Destroy(); } - CAPI_SystemInitCalled = 0; - CAPI_ovrInitializeCalled = 0; + OVR::Net::RuntimeSDKVersion.Reset(); + CAPI_pNetClient = nullptr; // Not strictly necessary, but useful for debugging and cleanliness. } @@ -324,10 +365,10 @@ OVR_EXPORT void ovr_Shutdown() // probably check this. // -OVR_EXPORT int ovrHmd_Detect() +OVR_PUBLIC_FUNCTION(int) ovrHmd_Detect() { if (!CAPI_ovrInitializeCalled) - return 0; + return -2; return CAPI_pNetClient->Hmd_Detect(); } @@ -337,7 +378,7 @@ OVR_EXPORT int ovrHmd_Detect() // a relatively light-weight handle that would reference the device going forward and would // survive future ovrHmd_Detect calls. That is once ovrHMD is returned, index is no longer // necessary and can be changed by a ovrHmd_Detect call. -OVR_EXPORT ovrHmd ovrHmd_Create(int index) +OVR_PUBLIC_FUNCTION(ovrHmd) ovrHmd_Create(int index) { if (!CAPI_ovrInitializeCalled) return 0; @@ -351,18 +392,35 @@ OVR_EXPORT ovrHmd ovrHmd_Create(int index) while (!CAPI_pNetClient->Hmd_Create(index, &netInfo) || netInfo.NetId == InvalidVirtualHmdId) { - // If two seconds elapse and still no HMD detected, - if (Timer::GetSeconds() - t0 > 2.) + double waitTime = 2.0; // Default wait time + + if (NetClient::GetInstance()->IsConnected(false, false)) { - if (!NetClient::GetInstance()->IsConnected(false, false)) + NetClient::GetInstance()->SetLastError("No HMD Detected"); + + // If in single process mode, + if (Net::Session::IsSingleProcess()) { - NetClient::GetInstance()->SetLastError("Not connected to service"); + // Wait 8 seconds for HMD to be detected, as this is a single process + // build and we expect that the operator has the system set up properly. + waitTime = 8.0; } else { - NetClient::GetInstance()->SetLastError("No HMD Detected"); + // Wait 1/2 second for HMD to be detected. + waitTime = 0.5; } + } + else + { + NetClient::GetInstance()->SetLastError("Not connected to service"); + // Wait the default amount of time for the service to start up. + } + + // If two seconds elapse and still no HMD detected, + if (Timer::GetSeconds() - t0 > waitTime) + { return 0; } } @@ -380,24 +438,26 @@ OVR_EXPORT ovrHmd ovrHmd_Create(int index) // Reset frame timing so that FrameTimeManager values are properly initialized in AppRendered mode. ovrHmd_ResetFrameTiming(hmds->pHmdDesc, 0); + TraceHmdDesc(*hmds->pHmdDesc); + return hmds->pHmdDesc; } -OVR_EXPORT ovrBool ovrHmd_AttachToWindow( ovrHmd hmd, void* window, - const ovrRecti* destMirrorRect, - const ovrRecti* sourceRenderTargetRect ) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_AttachToWindow(ovrHmd hmddesc, void* window, + const ovrRecti* destMirrorRect, + const ovrRecti* sourceRenderTargetRect) { - OVR_UNUSED( destMirrorRect ); - OVR_UNUSED( sourceRenderTargetRect ); + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return ovrFalse; + + OVR_UNUSED3(destMirrorRect, sourceRenderTargetRect, hmds); if (!CAPI_ovrInitializeCalled) - return false; + return ovrFalse; - if (!hmd || !hmd->Handle) - return false; #ifndef OVR_OS_MAC - HMDState* hmds = (HMDState*)hmd->Handle; CAPI_pNetClient->Hmd_AttachToWindow(hmds->GetNetId(), window); hmds->pWindow = window; #endif @@ -408,27 +468,27 @@ OVR_EXPORT ovrBool ovrHmd_AttachToWindow( ovrHmd hmd, void* window, OVR_UNUSED(window); #endif - return true; + return ovrTrue; } -OVR_EXPORT ovrHmd ovrHmd_CreateDebug(ovrHmdType type) +OVR_PUBLIC_FUNCTION(ovrHmd) ovrHmd_CreateDebug(ovrHmdType type) { if (!CAPI_ovrInitializeCalled) return 0; - HMDState* hmds = HMDState::CreateHMDState(type); + HMDState* hmds = HMDState::CreateDebugHMDState(type); + if (!hmds) + return nullptr; return hmds->pHmdDesc; } -OVR_EXPORT void ovrHmd_Destroy(ovrHmd hmddesc) +OVR_PUBLIC_FUNCTION(void) ovrHmd_Destroy(ovrHmd hmddesc) { - if (!hmddesc || !hmddesc->Handle) + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) return; - - // TBD: Any extra shutdown? - HMDState* hmds = (HMDState*)hmddesc->Handle; - + { // Thread checker in its own scope, to avoid access after 'delete'. // Essentially just checks that no other RenderAPI function is executing. ThreadChecker::Scope checkScope(&hmds->RenderAPIThreadChecker, "ovrHmd_Destroy"); @@ -448,20 +508,16 @@ OVR_EXPORT void ovrHmd_Destroy(ovrHmd hmddesc) } -OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmddesc) +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetLastError(ovrHmd hmddesc) { if (!CAPI_ovrInitializeCalled) - { return "System initialize not called"; - } VirtualHmdId netId = InvalidVirtualHmdId; - if (hmddesc && hmddesc->Handle) - { - HMDState* p = (HMDState*)hmddesc->Handle; - netId = p->GetNetId(); - } + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (hmds) + netId = hmds->GetNetId(); return CAPI_pNetClient->Hmd_GetLastError(netId); } @@ -470,7 +526,7 @@ OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmddesc) // Returns version string representing libOVR version. Static, so // string remains valid for app lifespan -OVR_EXPORT const char* ovr_GetVersionString() +OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString() { static const char* version = OVR_VERSION_LIBOVR_PFX OVR_VERSION_STRING; return version + sizeof(OVR_VERSION_LIBOVR_PFX) - 1; @@ -483,21 +539,24 @@ OVR_EXPORT const char* ovr_GetVersionString() // Returns capability bits that are enabled at this time; described by ovrHmdCapBits. // Note that this value is different font ovrHmdDesc::Caps, which describes what // capabilities are available. -OVR_EXPORT unsigned int ovrHmd_GetEnabledCaps(ovrHmd hmddesc) +OVR_PUBLIC_FUNCTION(unsigned int) ovrHmd_GetEnabledCaps(ovrHmd hmddesc) { - HMDState* p = (HMDState*)hmddesc->Handle; - return p ? p->EnabledHmdCaps : 0; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return 0; + + return hmds->EnabledHmdCaps; } // Modifies capability bits described by ovrHmdCapBits that can be modified, // such as ovrHmdCap_LowPersistance. -OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmddesc, unsigned int capsBits) +OVR_PUBLIC_FUNCTION(void) ovrHmd_SetEnabledCaps(ovrHmd hmddesc, unsigned int capsBits) { - HMDState* p = (HMDState*)hmddesc->Handle; - if (p) - { - p->SetEnabledHmdCaps(capsBits); - } + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return; + + hmds->SetEnabledHmdCaps(capsBits); } @@ -516,62 +575,50 @@ OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmddesc, unsigned int capsBits) // functions that have different rules (all frame access functions // must be on render thread) -OVR_EXPORT ovrBool ovrHmd_ConfigureTracking(ovrHmd hmddesc, unsigned int supportedCaps, - unsigned int requiredCaps) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ConfigureTracking(ovrHmd hmddesc, unsigned int supportedCaps, + unsigned int requiredCaps) { - if (hmddesc) - { - HMDState* p = (HMDState*)hmddesc->Handle; - return p->ConfigureTracking(supportedCaps, requiredCaps); - } + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return ovrFalse; - return 0; + return hmds->ConfigureTracking(supportedCaps, requiredCaps) ? ovrTrue : ovrFalse; } -OVR_EXPORT void ovrHmd_RecenterPose(ovrHmd hmddesc) + +OVR_PUBLIC_FUNCTION(void) ovrHmd_RecenterPose(ovrHmd hmddesc) { - if (hmddesc) - { - HMDState* p = (HMDState*)hmddesc->Handle; - p->TheSensorStateReader.RecenterPose(); - } + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return; + + hmds->RecenterPose(); } -OVR_EXPORT ovrTrackingState ovrHmd_GetTrackingState(ovrHmd hmddesc, double absTime) +OVR_PUBLIC_FUNCTION(ovrTrackingState) ovrHmd_GetTrackingState(ovrHmd hmddesc, double absTime) { - ovrTrackingState result; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return GetNullTrackingState(); - if (hmddesc) - { - HMDState* p = (HMDState*)hmddesc->Handle; - result = p->PredictedTrackingState(absTime); + return hmds->PredictedTrackingState(absTime); +} - // Instrument data from eye pose - p->LagStats.InstrumentEyePose(result); - } - else - memset(&result, 0, sizeof(result)); -#ifdef OVR_OS_WIN32 - // Set up display code for Windows - Win32::DisplayShim::GetInstance().Active = (result.StatusFlags & ovrStatus_HmdConnected) != 0; -#endif - return result; -} //------------------------------------------------------------------------------------- // *** General Setup // Per HMD -> calculateIdealPixelSize -OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmddesc, ovrEyeType eye, ovrFovPort fov, - float pixelsPerDisplayPixel) +OVR_PUBLIC_FUNCTION(ovrSizei) ovrHmd_GetFovTextureSize(ovrHmd hmddesc, ovrEyeType eye, + ovrFovPort fov, float pixelsPerDisplayPixel) { - ovrHmdStruct * hmd = hmddesc->Handle; - if (!hmd) return Sizei(0); - - HMDState* hmds = (HMDState*)hmd; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return Sizei(0); + return hmds->RenderState.GetFOVTextureSize(eye, fov, pixelsPerDisplayPixel); } @@ -579,73 +626,69 @@ OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmddesc, ovrEyeType eye, ovr //------------------------------------------------------------------------------------- -OVR_EXPORT -ovrBool ovrHmd_ConfigureRendering( ovrHmd hmddesc, - const ovrRenderAPIConfig* apiConfig, - unsigned int distortionCaps, - const ovrFovPort eyeFovIn[2], - ovrEyeRenderDesc eyeRenderDescOut[2] ) -{ - ovrHmdStruct * hmd = hmddesc->Handle; - if (!hmd) return 0; - return ((HMDState*)hmd)->ConfigureRendering(eyeRenderDescOut, eyeFovIn, - apiConfig, distortionCaps); -} - - - -// TBD: MA - Deprecated, need alternative -void ovrHmd_SetVsync(ovrHmd hmddesc, ovrBool vsync) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ConfigureRendering(ovrHmd hmddesc, + const ovrRenderAPIConfig* apiConfig, + unsigned int distortionCaps, + const ovrFovPort eyeFovIn[2], + ovrEyeRenderDesc eyeRenderDescOut[2]) { - ovrHmdStruct * hmd = hmddesc->Handle; - if (!hmd) return; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return ovrFalse; - return ((HMDState*)hmd)->TimeManager.SetVsync(vsync? true : false); + return hmds->ConfigureRendering(eyeRenderDescOut, eyeFovIn, + apiConfig, distortionCaps); } +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_BeginFrame(ovrHmd hmddesc, unsigned int frameIndex) +{ + // NOTE: frameIndex == 0 is handled inside ovrHmd_BeginFrameTiming() -OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrame(ovrHmd hmddesc, unsigned int frameIndex) -{ - HMDState* hmds = (HMDState*)hmddesc->Handle; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); if (!hmds) - { - ovrFrameTiming f; - memset(&f, 0, sizeof(f)); - return f; - } + return GetNullFrameTiming(); + + TraceCall(frameIndex); // Check: Proper configure and threading state for the call. hmds->checkRenderingConfigured("ovrHmd_BeginFrame"); - OVR_DEBUG_LOG_COND(hmds->BeginFrameCalled, ("ovrHmd_BeginFrame called multiple times.")); + OVR_DEBUG_LOG_COND(hmds->BeginFrameCalled, ("ovrHmd_BeginFrame called multiple times.")); ThreadChecker::Scope checkScope(&hmds->RenderAPIThreadChecker, "ovrHmd_BeginFrame"); - + hmds->BeginFrameCalled = true; hmds->BeginFrameThreadId = OVR::GetCurrentThreadId(); - return ovrHmd_BeginFrameTiming(hmddesc, frameIndex); + ovrFrameTiming timing = ovrHmd_BeginFrameTiming(hmddesc, frameIndex); + + TraceReturn(frameIndex); + + return timing; } // Renders textures to frame buffer -OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmddesc, - const ovrPosef renderPose[2], - const ovrTexture eyeTexture[2]) +OVR_PUBLIC_FUNCTION(void) ovrHmd_EndFrame(ovrHmd hmddesc, + const ovrPosef renderPose[2], + const ovrTexture eyeTexture[2]) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - if (!hmds) return; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return; - // Instrument when the EndFrame() call started - hmds->LagStats.InstrumentEndFrameStart(ovr_GetTimeInSeconds()); + const ovrTexture* eyeDepthTexture = nullptr; + ovrPositionTimewarpDesc* posTimewarpDesc = nullptr; - hmds->SubmitEyeTextures(renderPose, eyeTexture); + TraceCall(hmds->BeginFrameIndex); + + hmds->SubmitEyeTextures(renderPose, eyeTexture, eyeDepthTexture); // Debug state checks: Must be in BeginFrame, on the same thread. hmds->checkBeginFrameScope("ovrHmd_EndFrame"); ThreadChecker::Scope checkScope(&hmds->RenderAPIThreadChecker, "ovrHmd_EndFrame"); - hmds->pRenderer->SetLatencyTestColor(hmds->LatencyTestActive ? hmds->LatencyTestDrawColor : NULL); + hmds->pRenderer->SetLatencyTestColor(hmds->LatencyTestActive ? hmds->LatencyTestDrawColor : nullptr); - ovrHmd_GetLatencyTest2DrawColor(hmddesc, NULL); // We don't actually need to draw color, so send NULL + ovrHmd_GetLatencyTest2DrawColor(hmddesc, nullptr); // We don't actually need to draw color, so send nullptr if (hmds->pRenderer) { @@ -664,35 +707,32 @@ OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmddesc, } } - hmds->pRenderer->EndFrame(true); + if (posTimewarpDesc) + hmds->pRenderer->SetPositionTimewarpDesc(*posTimewarpDesc); + + hmds->pRenderer->EndFrame(hmds->BeginFrameIndex, true); hmds->pRenderer->RestoreGraphicsState(); } // Call after present ovrHmd_EndFrameTiming(hmddesc); - // Instrument latency tester - hmds->LagStats.InstrumentLatencyTimings(hmds->TimeManager); - - // Instrument when the EndFrame() call ended - hmds->LagStats.InstrumentEndFrameEnd(ovr_GetTimeInSeconds()); + TraceReturn(hmds->BeginFrameIndex); // Out of BeginFrame hmds->BeginFrameThreadId = 0; hmds->BeginFrameCalled = false; + hmds->BeginFrameIndex++; // Set frame index to the next value in case 0 is passed. } - // Not exposed as part of public API -OVR_EXPORT void ovrHmd_RegisterPostDistortionCallback(ovrHmd hmddesc, PostDistortionCallback callback) +OVR_PUBLIC_FUNCTION(void) ovrHmd_RegisterPostDistortionCallback(ovrHmd hmddesc, PostDistortionCallback callback) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - if (!hmds) return; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds || !hmds->pRenderer) + return; - if (hmds->pRenderer) - { - hmds->pRenderer->RegisterPostDistortionCallback(callback); - } + hmds->pRenderer->RegisterPostDistortionCallback(callback); } @@ -700,245 +740,262 @@ OVR_EXPORT void ovrHmd_RegisterPostDistortionCallback(ovrHmd hmddesc, PostDistor //------------------------------------------------------------------------------------- // ***** Frame Timing logic - -OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_GetFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) { - ovrHmdStruct * hmd = hmddesc->Handle; - ovrFrameTiming f; - memset(&f, 0, sizeof(f)); + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return GetNullFrameTiming(); - HMDState* hmds = (HMDState*)hmd; - if (hmds) + // If no frame index is provided, + if (frameIndex == 0) { - FrameTimeManager::Timing frameTiming = hmds->TimeManager.GetFrameTiming(frameIndex); - - f.ThisFrameSeconds = frameTiming.ThisFrameTime; - f.NextFrameSeconds = frameTiming.NextFrameTime; - f.TimewarpPointSeconds = frameTiming.TimewarpPointTime; - f.ScanoutMidpointSeconds = frameTiming.MidpointTime; - f.EyeScanoutSeconds[0] = frameTiming.EyeRenderTimes[0]; - f.EyeScanoutSeconds[1] = frameTiming.EyeRenderTimes[1]; - - // Compute DeltaSeconds. - f.DeltaSeconds = (hmds->LastGetFrameTimeSeconds == 0.0f) ? 0.0f : - (float) (f.ThisFrameSeconds - hmds->LastFrameTimeSeconds); - hmds->LastGetFrameTimeSeconds = f.ThisFrameSeconds; - if (f.DeltaSeconds > 1.0f) - f.DeltaSeconds = 1.0f; + // Use the next one in the series. + frameIndex = hmds->BeginFrameIndex; } - - return f; + + return hmds->GetFrameTiming(frameIndex); } -OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_BeginFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) { - ovrHmdStruct * hmd = hmddesc->Handle; - ovrFrameTiming f; - memset(&f, 0, sizeof(f)); - - HMDState* hmds = (HMDState*)hmd; - if (!hmds) return f; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return GetNullFrameTiming(); // Check: Proper state for the call. OVR_DEBUG_LOG_COND(hmds->BeginFrameTimingCalled, ("ovrHmd_BeginFrameTiming called multiple times.")); hmds->BeginFrameTimingCalled = true; - double thisFrameTime = hmds->TimeManager.BeginFrame(frameIndex); - - const FrameTimeManager::Timing &frameTiming = hmds->TimeManager.GetFrameTiming(); + // If a frame index is specified, + if (frameIndex != 0) + { + // Use the next one after the last BeginFrame() index. + hmds->BeginFrameIndex = (uint32_t)frameIndex; + } + else + { + frameIndex = hmds->BeginFrameIndex; + } - f.ThisFrameSeconds = thisFrameTime; - f.NextFrameSeconds = frameTiming.NextFrameTime; - f.TimewarpPointSeconds = frameTiming.TimewarpPointTime; - f.ScanoutMidpointSeconds= frameTiming.MidpointTime; - f.EyeScanoutSeconds[0] = frameTiming.EyeRenderTimes[0]; - f.EyeScanoutSeconds[1] = frameTiming.EyeRenderTimes[1]; + // Update latency tester once per frame + hmds->LatencyTestActive = hmds->ProcessLatencyTest(hmds->LatencyTestDrawColor); - // Compute DeltaSeconds. - f.DeltaSeconds = (hmds->LastFrameTimeSeconds == 0.0f) ? 0.0f : - (float) (thisFrameTime - hmds->LastFrameTimeSeconds); - hmds->LastFrameTimeSeconds = thisFrameTime; - if (f.DeltaSeconds > 1.0f) - f.DeltaSeconds = 1.0f; + if (!hmds->BeginFrameCalled) + { + hmds->TimewarpTimer.CalculateTimewarpTiming(frameIndex); + } - return f; + return hmds->GetFrameTiming(frameIndex); } - -OVR_EXPORT void ovrHmd_EndFrameTiming(ovrHmd hmddesc) +OVR_PUBLIC_FUNCTION(void) ovrHmd_EndFrameTiming(ovrHmd hmddesc) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - if (!hmds) return; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return; // Debug state checks: Must be in BeginFrameTiming, on the same thread. hmds->checkBeginFrameTimingScope("ovrHmd_EndTiming"); // MA TBD: Correct check or not? // ThreadChecker::Scope checkScope(&hmds->RenderAPIThreadChecker, "ovrHmd_EndFrame"); - hmds->TimeManager.EndFrame(); hmds->BeginFrameTimingCalled = false; - bool dk2LatencyTest = (hmds->EnabledHmdCaps & ovrHmdCap_DynamicPrediction) != 0; - if (dk2LatencyTest) - { - Util::FrameTimeRecordSet recordset; - hmds->TheLatencyTestStateReader.GetRecordSet(recordset); - hmds->TimeManager.UpdateFrameLatencyTrackingAfterEndFrame( hmds->LatencyTest2DrawColor, - recordset); - } + hmds->endFrameRenderTiming(); } - -OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) +OVR_PUBLIC_FUNCTION(void) ovrHmd_ResetFrameTiming(ovrHmd hmddesc, unsigned int frameIndex) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - if (!hmds) return; - - hmds->TimeManager.ResetFrameTiming(frameIndex, - false, - hmds->RenderingConfigured); - hmds->LastFrameTimeSeconds = 0.0; - hmds->LastGetFrameTimeSeconds = 0.0; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return; + + OVR_UNUSED(frameIndex); + + // Clear timing-related state. + hmds->BeginFrameIndex = frameIndex; + hmds->TimewarpTimer.Reset(); } -OVR_EXPORT void ovrHmd_GetEyePoses(ovrHmd hmd, unsigned int frameIndex, ovrVector3f hmdToEyeViewOffset[2], - ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState) +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyePoses(ovrHmd hmddesc, unsigned int frameIndex, const ovrVector3f hmdToEyeViewOffset[2], + ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState) { - HMDState* hmds = (HMDState*)hmd->Handle; - if (!hmds) return; + if (!hmdToEyeViewOffset || !outEyePoses) + { + OVR_ASSERT(false); + return; + } - hmds->LatencyTestActive = hmds->ProcessLatencyTest(hmds->LatencyTestDrawColor); - - ovrTrackingState hmdTrackingState = hmds->TimeManager.GetEyePredictionTracking(hmd, ovrEye_Count, frameIndex); + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + { + outEyePoses[0] = ovrPosef(); outEyePoses[0].Orientation.w = 1; + outEyePoses[1] = ovrPosef(); outEyePoses[1].Orientation.w = 1; + if (outHmdTrackingState) + *outHmdTrackingState = GetNullTrackingState(); + return; + } + + // If no frame index is provided, + if (frameIndex == 0) + { + // Use the next one in the series. + frameIndex = hmds->BeginFrameIndex; + } + + ovrTrackingState hmdTrackingState = hmds->GetMidpointPredictionTracking(frameIndex); + TraceTrackingState(hmdTrackingState); ovrPosef hmdPose = hmdTrackingState.HeadPose.ThePose; // caller passed in a valid pointer, so copy to output - if(outHmdTrackingState) + if (outHmdTrackingState) *outHmdTrackingState = hmdTrackingState; // Currently HmdToEyeViewOffset is only a 3D vector // (Negate HmdToEyeViewOffset because offset is a view matrix offset and not a camera offset) outEyePoses[0] = Posef(hmdPose.Orientation, ((Posef)hmdPose).Apply(-((Vector3f)hmdToEyeViewOffset[0]))); outEyePoses[1] = Posef(hmdPose.Orientation, ((Posef)hmdPose).Apply(-((Vector3f)hmdToEyeViewOffset[1]))); - - // Instrument data from eye pose - hmds->LagStats.InstrumentEyePose(hmdTrackingState); } -ovrPosef ovrHmd_GetHmdPosePerEye(ovrHmd hmd, ovrEyeType eye) +OVR_PUBLIC_FUNCTION(ovrPosef) ovrHmd_GetHmdPosePerEye(ovrHmd hmddesc, ovrEyeType eye) { - HMDState* hmds = (HMDState*)hmd->Handle; - if (!hmds) return ovrPosef(); - - // This isn't a great place, but since we removed ovrHmd_BeginEyeRender... - // Only process latency tester for drawing the left eye (assumes left eye is drawn first) - if (hmds->pRenderer && eye == 0) + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) { - hmds->LatencyTestActive = hmds->ProcessLatencyTest(hmds->LatencyTestDrawColor); + ovrPosef nullPose = ovrPosef(); + nullPose.Orientation.w = 1.0f; // Return a proper quaternion. + return nullPose; } hmds->checkBeginFrameTimingScope("ovrHmd_GetEyePose"); - return hmds->TimeManager.GetEyePredictionPose(hmd, eye); + + return hmds->GetEyePredictionPose(eye); } -OVR_EXPORT void ovrHmd_AddDistortionTimeMeasurement(ovrHmd hmddesc, double distortionTimeSeconds) +OVR_PUBLIC_FUNCTION(void) ovrHmd_AddDistortionTimeMeasurement(ovrHmd hmddesc, double distortionTimeSeconds) { - if (!hmddesc) + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) return; - HMDState* hmds = (HMDState*)hmddesc->Handle; hmds->checkBeginFrameTimingScope("ovrHmd_GetTimewarpEyeMatrices"); - hmds->TimeManager.AddDistortionTimeMeasurement(distortionTimeSeconds); -} - + hmds->TimewarpTimer.AddDistortionTimeMeasurement(distortionTimeSeconds); +} -OVR_EXPORT void ovrHmd_GetEyeTimewarpMatricesDebug(ovrHmd hmddesc, ovrEyeType eye, - ovrPosef renderPose, ovrMatrix4f twmOut[2],double debugTimingOffsetInSeconds) +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyeTimewarpMatricesDebug(ovrHmd hmddesc, ovrEyeType eye, ovrPosef renderPose, + ovrQuatf playerTorsoMotion, ovrMatrix4f twmOut[2], + double debugTimingOffsetInSeconds) { - if (!hmddesc) + if (!twmOut) + { + OVR_ASSERT(false); + return; + } + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) return; - HMDState* hmds = (HMDState*)hmddesc->Handle; // Debug checks: BeginFrame was called, on the same thread. hmds->checkBeginFrameTimingScope("ovrHmd_GetTimewarpEyeMatrices"); - hmds->TimeManager.GetTimewarpMatrices(hmddesc, eye, renderPose, twmOut, debugTimingOffsetInSeconds); + // TODO: Position input disabled for now + bool calcPosition = false; + ovrVector3f* hmdToEyeViewOffset = nullptr; - /* - // MA: Took this out because new latency test approach just sames - // the sample times in FrameTimeManager. - // TODO: if no timewarp, then test latency in begin eye render - if (eye == 0) - { - hmds->ProcessLatencyTest2(hmds->LatencyTest2DrawColor, -1.0f); - } - */ + // playerTorsoMotion can be fed in by the app to indicate player rotation, + // i.e. renderPose is in torso space, and playerTorsoMotion says that torso space changed. + Quatf playerTorsoMotionInv = Quatf(playerTorsoMotion).Inverted(); + Posef renderPoseTorso = (Posef)renderPose * Posef(playerTorsoMotionInv, Vector3f::Zero()); + hmds->GetTimewarpMatricesEx(eye, renderPoseTorso, calcPosition, hmdToEyeViewOffset, twmOut, + debugTimingOffsetInSeconds); } -OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmddesc, ovrEyeType eye, - ovrPosef renderPose, ovrMatrix4f twmOut[2]) +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmddesc, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]) { - return(ovrHmd_GetEyeTimewarpMatricesDebug(hmddesc, eye, renderPose, twmOut, 0.0)); -} + if (!twmOut) + { + OVR_ASSERT(false); + return; + } + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return; + // Shortcut to doing orientation-only timewarp. + + hmds->GetTimewarpMatrices(eye, renderPose, twmOut); +} -OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmddesc, - ovrEyeType eyeType, ovrFovPort fov) +OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovrHmd_GetRenderDesc(ovrHmd hmddesc, + ovrEyeType eyeType, ovrFovPort fov) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - ovrEyeRenderDesc erd; - + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); if (!hmds) - { - memset(&erd, 0, sizeof(erd)); - return erd; - } + return ovrEyeRenderDesc(); return hmds->RenderState.CalcRenderDesc(eyeType, fov); } - #define OVR_OFFSET_OF(s, field) ((size_t)&((s*)0)->field) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_CreateDistortionMeshDebug(ovrHmd hmddesc, + ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, + ovrDistortionMesh *meshData, + float debugEyeReliefOverrideInMetres) +{ + if (!meshData) + { + OVR_ASSERT(false); + return ovrFalse; + } + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return ovrFalse; -OVR_EXPORT ovrBool ovrHmd_CreateDistortionMeshDebug( ovrHmd hmddesc, - ovrEyeType eyeType, ovrFovPort fov, - unsigned int distortionCaps, - ovrDistortionMesh *meshData, - float debugEyeReliefOverrideInMetres) -{ - // The 'internal' function below can be found in CAPI_HMDState. - // Not ideal, but navigating the convolutions of what compiles - // where, meant they are in the few places which actually lets these compile. - // Please relocate (if you wish) to a more meaningful place if you can navigate the compiler gymnastics :) - return(ovrHmd_CreateDistortionMeshInternal( hmddesc->Handle, - eyeType, fov, - distortionCaps, - meshData, - debugEyeReliefOverrideInMetres)); - -} -OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmddesc, - ovrEyeType eyeType, ovrFovPort fov, - unsigned int distortionCaps, - ovrDistortionMesh *meshData) + return hmds->CreateDistortionMesh(eyeType, fov, + distortionCaps, + meshData, + debugEyeReliefOverrideInMetres) + ? ovrTrue : ovrFalse; +} + + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_CreateDistortionMesh(ovrHmd hmddesc, + ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, + ovrDistortionMesh *meshData) { - return(ovrHmd_CreateDistortionMeshDebug( hmddesc, eyeType, fov, distortionCaps,meshData, 0)); + if (!meshData) + { + OVR_ASSERT(false); + return ovrFalse; + } + + return ovrHmd_CreateDistortionMeshDebug(hmddesc, eyeType, fov, distortionCaps, meshData, 0); } // Frees distortion mesh allocated by ovrHmd_GenerateDistortionMesh. meshData elements // are set to null and 0s after the call. -OVR_EXPORT void ovrHmd_DestroyDistortionMesh(ovrDistortionMesh* meshData) +OVR_PUBLIC_FUNCTION(void) ovrHmd_DestroyDistortionMesh(ovrDistortionMesh* meshData) { + if (!meshData) + { + OVR_ASSERT(false); + return; + } + if (meshData->pVertexData) DistortionMeshDestroy((DistortionMeshVertexData*)meshData->pVertexData, meshData->pIndexData); @@ -952,10 +1009,16 @@ OVR_EXPORT void ovrHmd_DestroyDistortionMesh(ovrDistortionMesh* meshData) // Computes updated 'uvScaleOffsetOut' to be used with a distortion if render target size or // viewport changes after the fact. This can be used to adjust render size every frame, if desired. -OVR_EXPORT void ovrHmd_GetRenderScaleAndOffset( ovrFovPort fov, - ovrSizei textureSize, ovrRecti renderViewport, - ovrVector2f uvScaleOffsetOut[2] ) +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetRenderScaleAndOffset(ovrFovPort fov, + ovrSizei textureSize, ovrRecti renderViewport, + ovrVector2f uvScaleOffsetOut[2] ) { + if (!uvScaleOffsetOut) + { + OVR_ASSERT(false); + return; + } + // Find the mapping from TanAngle space to target NDC space. ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(fov); // Find the mapping from TanAngle space to textureUV space. @@ -963,73 +1026,95 @@ OVR_EXPORT void ovrHmd_GetRenderScaleAndOffset( ovrFovPort fov, eyeToSourceNDC, renderViewport, textureSize ); - uvScaleOffsetOut[0] = eyeToSourceUV.Scale; - uvScaleOffsetOut[1] = eyeToSourceUV.Offset; + if (uvScaleOffsetOut) + { + uvScaleOffsetOut[0] = eyeToSourceUV.Scale; + uvScaleOffsetOut[1] = eyeToSourceUV.Offset; + } } //------------------------------------------------------------------------------------- // ***** Latency Test interface -OVR_EXPORT ovrBool ovrHmd_GetLatencyTestDrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetLatencyTestDrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]) { - HMDState* p = (HMDState*)hmddesc->Handle; - rgbColorOut[0] = p->LatencyTestDrawColor[0]; - rgbColorOut[1] = p->LatencyTestDrawColor[1]; - rgbColorOut[2] = p->LatencyTestDrawColor[2]; - return p->LatencyTestActive; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return ovrFalse; + + if (rgbColorOut) + { + rgbColorOut[0] = hmds->LatencyTestDrawColor[0]; + rgbColorOut[1] = hmds->LatencyTestDrawColor[1]; + rgbColorOut[2] = hmds->LatencyTestDrawColor[2]; + } + + return hmds->LatencyTestActive; } -OVR_EXPORT ovrBool ovrHmd_ProcessLatencyTest(ovrHmd hmddesc, unsigned char rgbColorOut[3]) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ProcessLatencyTest(ovrHmd hmddesc, unsigned char rgbColorOut[3]) { OVR_UNUSED(hmddesc); + + if (!rgbColorOut) + { + OVR_ASSERT(false); + return ovrFalse; + } + return NetClient::GetInstance()->LatencyUtil_ProcessInputs(Timer::GetSeconds(), rgbColorOut); } -OVR_EXPORT const char* ovrHmd_GetLatencyTestResult(ovrHmd hmddesc) +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetLatencyTestResult(ovrHmd hmddesc) { OVR_UNUSED(hmddesc); + return NetClient::GetInstance()->LatencyUtil_GetResultsString(); } -OVR_EXPORT ovrBool ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - if (!hmds) return false; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return ovrFalse; // TBD: Move directly into renderer bool dk2LatencyTest = (hmds->EnabledHmdCaps & ovrHmdCap_DynamicPrediction) != 0; if (dk2LatencyTest) { - hmds->TimeManager.GetFrameLatencyTestDrawColor(hmds->LatencyTest2DrawColor); - if(rgbColorOut != NULL) + hmds->LatencyTest2DrawColor[0] = hmds->ScreenLatencyTracker.GetNextDrawColor(); + hmds->LatencyTest2DrawColor[1] = hmds->ScreenLatencyTracker.IsLatencyTimingAvailable() ? 255 : 0; + hmds->LatencyTest2DrawColor[2] = hmds->ScreenLatencyTracker.IsLatencyTimingAvailable() ? 0 : 255; + + if (rgbColorOut) { rgbColorOut[0] = hmds->LatencyTest2DrawColor[0]; rgbColorOut[1] = hmds->LatencyTest2DrawColor[1]; rgbColorOut[2] = hmds->LatencyTest2DrawColor[2]; } - if(hmds->pRenderer != NULL) + if (hmds->pRenderer) hmds->pRenderer->SetLatencyTest2Color(hmds->LatencyTest2DrawColor); } else { - if(hmds->pRenderer != NULL) - hmds->pRenderer->SetLatencyTest2Color(NULL); + if (hmds->pRenderer) + hmds->pRenderer->SetLatencyTest2Color(nullptr); } - return dk2LatencyTest; + return dk2LatencyTest ? ovrTrue : ovrFalse; } -OVR_EXPORT double ovrHmd_GetMeasuredLatencyTest2(ovrHmd hmddesc) +OVR_PUBLIC_FUNCTION(double) ovrHmd_GetMeasuredLatencyTest2(ovrHmd hmddesc) { - HMDState* p = (HMDState*)hmddesc->Handle; - - // MA Test - float latencyRender, latencyTimewarp, latencyPostPresent; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return 0.; - p->TimeManager.GetLatencyTimings(latencyRender, latencyTimewarp, latencyPostPresent); + double latencyPostPresent = 0.; + hmds->ScreenLatencyTracker.GetVsyncToScanout(latencyPostPresent); return latencyPostPresent; } @@ -1038,252 +1123,295 @@ OVR_EXPORT double ovrHmd_GetMeasuredLatencyTest2(ovrHmd hmddesc) // ***** Health and Safety Warning Display interface // -OVR_EXPORT void ovrHmd_GetHSWDisplayState(ovrHmd hmd, ovrHSWDisplayState *hswDisplayState) +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetHSWDisplayState(ovrHmd hmddesc, ovrHSWDisplayState *hswDisplayState) { - OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; - - if (pHMDState) + if (!hswDisplayState) { - OVR::CAPI::HSWDisplay* pHSWDisplay = pHMDState->pHSWDisplay; - - if(pHSWDisplay) - pHSWDisplay->TickState(hswDisplayState); // This may internally call HSWDisplay::Display. + OVR_ASSERT(false); + return; } + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return; + + OVR::CAPI::HSWDisplay* pHSWDisplay = hmds->pHSWDisplay; + + if (pHSWDisplay) + pHSWDisplay->TickState(hswDisplayState); // This may internally call HSWDisplay::Display. } -OVR_EXPORT ovrBool ovrHmd_DismissHSWDisplay(ovrHmd hmd) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_DismissHSWDisplay(ovrHmd hmddesc) { - OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) + return ovrFalse; - if (pHMDState) - { - OVR::CAPI::HSWDisplay* pHSWDisplay = pHMDState->pHSWDisplay; + OVR::CAPI::HSWDisplay* pHSWDisplay = hmds->pHSWDisplay; - if(pHSWDisplay) - return (pHSWDisplay->Dismiss() ? 1 : 0); - } + if (pHSWDisplay && pHSWDisplay->Dismiss()) + return ovrTrue; - return false; + return ovrFalse; } // ----------------------------------------------------------------------------------- // ***** Property Access -OVR_EXPORT ovrBool ovrHmd_GetBool(ovrHmd hmddesc, - const char* propertyName, - ovrBool defaultVal) + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetBool(ovrHmd hmddesc, + const char* propertyName, + ovrBool defaultVal) { - OVR_ASSERT(propertyName); - if (hmddesc) + OVR_ASSERT(propertyName != nullptr); + if (!propertyName) + return ovrFalse; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + bool success = false; + if (hmds) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - OVR_ASSERT(hmds); - if (hmds) - { - return hmds->getBoolValue(propertyName, (defaultVal != 0)); - } + success = hmds->getBoolValue(propertyName, (defaultVal != ovrFalse)); } - - return NetClient::GetInstance()->GetBoolValue(InvalidVirtualHmdId, propertyName, (defaultVal != 0)) ? 1 : 0; -} - -OVR_EXPORT ovrBool ovrHmd_SetBool(ovrHmd hmddesc, - const char* propertyName, - ovrBool value) -{ - OVR_ASSERT(propertyName); - if (hmddesc) + else { - HMDState* hmds = (HMDState*)hmddesc->Handle; - OVR_ASSERT(hmds); - if (hmds) - { - return hmds->setBoolValue(propertyName, value != 0) ? 1 : 0; - } + success = NetClient::GetInstance()->GetBoolValue(InvalidVirtualHmdId, propertyName, (defaultVal != ovrFalse)); } - - return NetClient::GetInstance()->SetBoolValue(InvalidVirtualHmdId, propertyName, (value != 0)) ? 1 : 0; + return success ? ovrTrue : ovrFalse; } -OVR_EXPORT int ovrHmd_GetInt(ovrHmd hmddesc, - const char* propertyName, - int defaultVal) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetBool(ovrHmd hmddesc, + const char* propertyName, + ovrBool value) { - OVR_ASSERT(propertyName); - if (hmddesc) + OVR_ASSERT(propertyName != nullptr); + if (!propertyName) + return ovrFalse; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + bool retval = false; + if (hmds) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - OVR_ASSERT(hmds); - if (hmds) - { - return hmds->getIntValue(propertyName, defaultVal); - } + retval = hmds->setBoolValue(propertyName, value != ovrFalse); } - - return NetClient::GetInstance()->GetIntValue(InvalidVirtualHmdId, propertyName, defaultVal); + else + { + retval = NetClient::GetInstance()->SetBoolValue(InvalidVirtualHmdId, propertyName, (value != ovrFalse)); + } + return retval ? ovrTrue : ovrFalse; } -OVR_EXPORT ovrBool ovrHmd_SetInt(ovrHmd hmddesc, - const char* propertyName, - int value) +OVR_PUBLIC_FUNCTION(int) ovrHmd_GetInt(ovrHmd hmddesc, + const char* propertyName, + int defaultVal) { - OVR_ASSERT(propertyName); - if (hmddesc) + OVR_ASSERT(propertyName != nullptr); + if (!propertyName) + return ovrFalse; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (hmds) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - OVR_ASSERT(hmds); - if (hmds) - { - return hmds->setIntValue(propertyName, value) ? 1 : 0; - } + return hmds->getIntValue(propertyName, defaultVal); + } + else + { + return NetClient::GetInstance()->GetIntValue(InvalidVirtualHmdId, propertyName, defaultVal); } - - return NetClient::GetInstance()->SetIntValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; } -OVR_EXPORT float ovrHmd_GetFloat(ovrHmd hmddesc, - const char* propertyName, - float defaultVal) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetInt(ovrHmd hmddesc, + const char* propertyName, + int value) { - OVR_ASSERT(propertyName); - if (hmddesc) + OVR_ASSERT(propertyName != nullptr); + if (!propertyName) + return ovrFalse; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + bool success = false; + if (hmds) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - OVR_ASSERT(hmds); - if (hmds) - { - return hmds->getFloatValue(propertyName, defaultVal); - } + success = hmds->setIntValue(propertyName, value); } - - return (float)NetClient::GetInstance()->GetNumberValue(InvalidVirtualHmdId, propertyName, defaultVal); + else + { + success = NetClient::GetInstance()->SetIntValue(InvalidVirtualHmdId, propertyName, value); + } + return success ? ovrTrue : ovrFalse; } -OVR_EXPORT ovrBool ovrHmd_SetFloat(ovrHmd hmddesc, - const char* propertyName, - float value) +OVR_PUBLIC_FUNCTION(float) ovrHmd_GetFloat(ovrHmd hmddesc, + const char* propertyName, + float defaultVal) { - OVR_ASSERT(propertyName); - if (hmddesc) + OVR_ASSERT(propertyName != nullptr); + if (!propertyName) + return ovrFalse; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (hmds) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - OVR_ASSERT(hmds); - if (hmds) - { - return hmds->setFloatValue(propertyName, value) ? 1 : 0; - } + return hmds->getFloatValue(propertyName, defaultVal); + } + else + { + return (float)NetClient::GetInstance()->GetNumberValue(InvalidVirtualHmdId, propertyName, defaultVal); } - - return NetClient::GetInstance()->SetNumberValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; } -OVR_EXPORT unsigned int ovrHmd_GetFloatArray(ovrHmd hmddesc, +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetFloat(ovrHmd hmddesc, const char* propertyName, - float values[], - unsigned int arraySize) + float value) { - OVR_ASSERT(propertyName); - OVR_ASSERT(hmddesc); - if (hmddesc) + OVR_ASSERT(propertyName != nullptr); + if (!propertyName) + return ovrFalse; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + bool success = false; + if (hmds) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - OVR_ASSERT(hmds); - if (hmds) - { - return hmds->getFloatArray(propertyName, values, arraySize); - } + success = hmds->setFloatValue(propertyName, value); + } + else + { + success = NetClient::GetInstance()->SetNumberValue(InvalidVirtualHmdId, propertyName, value); } + return success ? ovrTrue : ovrFalse; +} + +OVR_PUBLIC_FUNCTION(unsigned int) ovrHmd_GetFloatArray(ovrHmd hmddesc, + const char* propertyName, + float values[], + unsigned int arraySize) +{ + OVR_ASSERT(propertyName != nullptr && values != nullptr); + if (!propertyName || !values) + return 0; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) return 0; - // FIXME: Currently it takes a few lines of code to do this, so just not supported for now. - return 0; + return hmds->getFloatArray(propertyName, values, arraySize); } // Modify float[] property; false if property doesn't exist or is readonly. -OVR_EXPORT ovrBool ovrHmd_SetFloatArray(ovrHmd hmddesc, - const char* propertyName, - float values[], - unsigned int arraySize) +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetFloatArray(ovrHmd hmddesc, + const char* propertyName, + float values[], + unsigned int arraySize) { - OVR_ASSERT(propertyName); - OVR_ASSERT(hmddesc); - if (hmddesc) - { - HMDState* hmds = (HMDState*)hmddesc->Handle; - OVR_ASSERT(hmds); - if (hmds) - { - return hmds->setFloatArray(propertyName, values, arraySize) ? 1 : 0; - } - } + OVR_ASSERT(propertyName != nullptr && values != nullptr); + if (!propertyName || !values) + return ovrFalse; - // FIXME: Currently it takes a few lines of code to do this, so just not supported for now. - return 0; + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (!hmds) return ovrFalse; + + return hmds->setFloatArray(propertyName, values, arraySize) ? ovrTrue : ovrFalse; } -OVR_EXPORT const char* ovrHmd_GetString(ovrHmd hmddesc, - const char* propertyName, - const char* defaultVal) +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetString(ovrHmd hmddesc, + const char* propertyName, + const char* defaultVal) { - OVR_ASSERT(propertyName); - if (hmddesc) + OVR_ASSERT(propertyName != nullptr); + if (!propertyName) + return ""; + + // Replace null default with empty string + if (!defaultVal) + defaultVal = ""; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + if (hmds) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - if (hmds) - { - return hmds->getString(propertyName, defaultVal); - } + return hmds->getString(propertyName, defaultVal); + } + else + { + return NetClient::GetInstance()->GetStringValue(InvalidVirtualHmdId, propertyName, defaultVal); } - - return NetClient::GetInstance()->GetStringValue(InvalidVirtualHmdId, propertyName, defaultVal); } - -OVR_EXPORT ovrBool ovrHmd_SetString(ovrHmd hmddesc, - const char* propertyName, - const char* value) + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetString(ovrHmd hmddesc, + const char* propertyName, + const char* value) { - OVR_ASSERT(propertyName); - if (hmddesc) + OVR_ASSERT(propertyName != nullptr); + if (!propertyName) + return ovrFalse; + + // Replace null value with empty string + if (!value) + value = ""; + + HMDState* hmds = GetHMDStateFromOvrHmd(hmddesc); + bool success = false; + if (hmds) { - HMDState* hmds = (HMDState*)hmddesc->Handle; - if (hmds) - { - return hmds->setString(propertyName, value) ? 1 : 0; - } + success = hmds->setString(propertyName, value); } - - return NetClient::GetInstance()->SetStringValue(InvalidVirtualHmdId, propertyName, value) ? 1 : 0; + else + { + success = NetClient::GetInstance()->SetStringValue(InvalidVirtualHmdId, propertyName, value); + } + return success ? ovrTrue : ovrFalse; } + // ----------------------------------------------------------------------------------- // ***** Logging -OVR_EXPORT ovrBool ovrHmd_StartPerfLog(ovrHmd hmd, const char* fileName, const char* userData1) -{ - OVR_ASSERT(fileName && fileName[0]); +// make sure OVR_Log.h's enum matches CAPI's +static_assert( + ((ovrLogLevel_Debug == ovrLogLevel(LogLevel_Debug)) && + (ovrLogLevel_Info == ovrLogLevel(LogLevel_Info)) && + (ovrLogLevel_Error == ovrLogLevel(LogLevel_Error))), + "mismatched LogLevel enums" +); - OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; +#define OVR_TRACEMSG_MAX_LEN 1024 /* in chars */ - if (pHMDState) - { - ovrBool started = pHMDState->LagStatsCSV.Start(fileName, userData1) ? 1 : 0; - if (started) - pHMDState->LagStats.AddResultsObserver(pHMDState->LagStatsCSV.GetObserver()); - return started; - } - return 0; -} -OVR_EXPORT ovrBool ovrHmd_StopPerfLog(ovrHmd hmd) +OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message) { - OVR::CAPI::HMDState* pHMDState = (OVR::CAPI::HMDState*)hmd->Handle; + OVR_ASSERT(message != nullptr); + if (!message) + return -1; + + // Keep traced messages to some reasonable maximum length + int len = (int)strnlen(message, OVR_TRACEMSG_MAX_LEN); + if (len >= OVR_TRACEMSG_MAX_LEN) + return -1; - if (pHMDState) + switch (level) { - return pHMDState->LagStatsCSV.Stop() ? 1 : 0; + case ovrLogLevel_Debug: + TraceLogDebug(message); + break; + case ovrLogLevel_Info: + default: + TraceLogInfo(message); + break; + case ovrLogLevel_Error: + TraceLogError(message); + break; } - return false; + + return len; } +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_StartPerfLog(ovrHmd hmddesc, const char* fileName, const char* userData1) +{ + // DEPRECATED + OVR_UNUSED3(hmddesc, fileName, userData1); + return ovrFalse; +} -#ifdef __cplusplus -} // extern "C" -#endif +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_StopPerfLog(ovrHmd hmddesc) +{ + // DEPRECATED + OVR_UNUSED(hmddesc); + return ovrFalse; +} diff --git a/LibOVR/Src/OVR_CAPI.h b/LibOVR/Src/OVR_CAPI.h deleted file mode 100644 index ca41d3f..0000000 --- a/LibOVR/Src/OVR_CAPI.h +++ /dev/null @@ -1,950 +0,0 @@ -/************************************************************************************ - -Filename : OVR_CAPI.h -Content : C Interface to Oculus tracking and rendering. -Created : November 23, 2013 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -/// @file OVR_CAPI.h -/// Exposes all general Rift functionality. - -#ifndef OVR_CAPI_h -#define OVR_CAPI_h - -#include - -#include "OVR_CAPI_Keys.h" - -typedef char ovrBool; - -//----------------------------------------------------------------------------------- -// ***** OVR_EXPORT definition - -#if !defined(OVR_EXPORT) - #ifdef OVR_OS_WIN32 - #define OVR_EXPORT __declspec(dllexport) - #else - #define OVR_EXPORT - #endif -#endif - - - -//----------------------------------------------------------------------------------- -// ***** OVR_ALIGNAS definition -// -#if !defined(OVR_ALIGNAS) - // C++11 alignas - #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 408) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || (__cplusplus >= 201103L)) - #define OVR_ALIGNAS(n) alignas(n) - #elif defined(__clang__) && !defined(__APPLE__) && (((__clang_major__ * 100) + __clang_minor__) >= 300) && (__cplusplus >= 201103L) - #define OVR_ALIGNAS(n) alignas(n) - #elif defined(__clang__) && defined(__APPLE__) && (((__clang_major__ * 100) + __clang_minor__) >= 401) && (__cplusplus >= 201103L) - #define OVR_ALIGNAS(n) alignas(n) - #elif defined(_MSC_VER) && (_MSC_VER >= 1900) - #define OVR_ALIGNAS(n) alignas(n) - #elif defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408) - #define OVR_ALIGNAS(n) alignas(n) - - // Pre-C++11 alignas fallbacks - #elif defined(__GNUC__) || defined(__clang__) - #define OVR_ALIGNAS(n) __attribute__((aligned(n))) - #elif defined(_MSC_VER) || defined(__INTEL_COMPILER) - #define OVR_ALIGNAS(n) __declspec(align(n)) // For Microsoft the alignment must be a literal integer. - #elif defined(__CC_ARM) - #define OVR_ALIGNAS(n) __align(n) - #else - #error Need to define OVR_ALIGNAS - #endif -#endif - -#if defined(_MSC_VER) - #pragma warning(push) - #pragma warning(disable: 4324) // structure was padded due to __declspec(align()) -#endif - - -//#define ENABLE_LATENCY_TESTER - -//----------------------------------------------------------------------------------- -// ***** Simple Math Structures - -/// A 2D vector with integer components. -typedef struct ovrVector2i_ -{ - int x, y; -} ovrVector2i; - -/// A 2D size with integer components. -typedef struct ovrSizei_ -{ - int w, h; -} ovrSizei; -/// A 2D rectangle with a position and size. -/// All components are integers. -typedef struct ovrRecti_ -{ - ovrVector2i Pos; - ovrSizei Size; -} ovrRecti; - -/// A quaternion rotation. -typedef struct ovrQuatf_ -{ - float x, y, z, w; -} ovrQuatf; - -/// A 2D vector with float components. -typedef struct ovrVector2f_ -{ - float x, y; -} ovrVector2f; - -/// A 3D vector with float components. -typedef struct ovrVector3f_ -{ - float x, y, z; -} ovrVector3f; - -/// A 4x4 matrix with float elements. -typedef struct ovrMatrix4f_ -{ - float M[4][4]; -} ovrMatrix4f; - -/// Position and orientation together. -typedef struct ovrPosef_ -{ - ovrQuatf Orientation; - ovrVector3f Position; -} ovrPosef; - -/// A full pose (rigid body) configuration with first and second derivatives. -typedef struct ovrPoseStatef_ -{ - ovrPosef ThePose; ///< The body's position and orientation. - ovrVector3f AngularVelocity; ///< The body's angular velocity in radians per second. - ovrVector3f LinearVelocity; ///< The body's velocity in meters per second. - ovrVector3f AngularAcceleration; ///< The body's angular acceleration in radians per second per second. - ovrVector3f LinearAcceleration; ///< The body's acceleration in meters per second per second. - double TimeInSeconds; ///< Absolute time of this state sample. -} ovrPoseStatef; - -/// Field Of View (FOV) in tangent of the angle units. -/// As an example, for a standard 90 degree vertical FOV, we would -/// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }. -typedef struct ovrFovPort_ -{ - /// The tangent of the angle between the viewing vector and the top edge of the field of view. - float UpTan; - /// The tangent of the angle between the viewing vector and the bottom edge of the field of view. - float DownTan; - /// The tangent of the angle between the viewing vector and the left edge of the field of view. - float LeftTan; - /// The tangent of the angle between the viewing vector and the right edge of the field of view. - float RightTan; -} ovrFovPort; - -//----------------------------------------------------------------------------------- -// ***** HMD Types - -/// Enumerates all HMD types that we support. -typedef enum -{ - ovrHmd_None = 0, - ovrHmd_DK1 = 3, - ovrHmd_DKHD = 4, - ovrHmd_DK2 = 6, - ovrHmd_Other // Some HMD other then the one in the enumeration. -} ovrHmdType; - -/// HMD capability bits reported by device. -typedef enum -{ - // Read-only flags. - ovrHmdCap_Present = 0x0001, /// The HMD is plugged in and detected by the system. - ovrHmdCap_Available = 0x0002, /// The HMD and its sensor are available for ownership use. - /// i.e. it is not already owned by another application. - ovrHmdCap_Captured = 0x0004, /// Set to 'true' if we captured ownership of this HMD. - - // These flags are intended for use with the new driver display mode. - ovrHmdCap_ExtendDesktop = 0x0008, /// (read only) Means the display driver is in compatibility mode. - - // Modifiable flags (through ovrHmd_SetEnabledCaps). - ovrHmdCap_NoMirrorToWindow = 0x2000, /// Disables mirroring of HMD output to the window. This may improve - /// rendering performance slightly (only if 'ExtendDesktop' is off). - ovrHmdCap_DisplayOff = 0x0040, /// Turns off HMD screen and output (only if 'ExtendDesktop' is off). - - ovrHmdCap_LowPersistence = 0x0080, /// HMD supports low persistence mode. - ovrHmdCap_DynamicPrediction = 0x0200, /// Adjust prediction dynamically based on internally measured latency. - ovrHmdCap_DirectPentile = 0x0400, /// Write directly in pentile color mapping format - ovrHmdCap_NoVSync = 0x1000, /// Support rendering without VSync for debugging. - - // These bits can be modified by ovrHmd_SetEnabledCaps. - ovrHmdCap_Writable_Mask = 0x32F0, - - /// These flags are currently passed into the service. May change without notice. - ovrHmdCap_Service_Mask = 0x22F0 -} ovrHmdCaps; - - -/// Tracking capability bits reported by the device. -/// Used with ovrHmd_ConfigureTracking. -typedef enum -{ - ovrTrackingCap_Orientation = 0x0010, /// Supports orientation tracking (IMU). - ovrTrackingCap_MagYawCorrection = 0x0020, /// Supports yaw drift correction via a magnetometer or other means. - ovrTrackingCap_Position = 0x0040, /// Supports positional tracking. - /// Overrides the other flags. Indicates that the application - /// doesn't care about tracking settings. This is the internal - /// default before ovrHmd_ConfigureTracking is called. - ovrTrackingCap_Idle = 0x0100, -} ovrTrackingCaps; - -/// Distortion capability bits reported by device. -/// Used with ovrHmd_ConfigureRendering and ovrHmd_CreateDistortionMesh. -typedef enum -{ - ovrDistortionCap_Chromatic = 0x01, /// Supports chromatic aberration correction. - ovrDistortionCap_TimeWarp = 0x02, /// Supports timewarp. - // 0x04 unused - ovrDistortionCap_Vignette = 0x08, /// Supports vignetting around the edges of the view. - ovrDistortionCap_NoRestore = 0x10, /// Do not save and restore the graphics and compute state when rendering distortion. - ovrDistortionCap_FlipInput = 0x20, /// Flip the vertical texture coordinate of input images. - ovrDistortionCap_SRGB = 0x40, /// Assume input images are in sRGB gamma-corrected color space. - ovrDistortionCap_Overdrive = 0x80, /// Overdrive brightness transitions to reduce artifacts on DK2+ displays - ovrDistortionCap_HqDistortion = 0x100, /// High-quality sampling of distortion buffer for anti-aliasing - ovrDistortionCap_LinuxDevFullscreen = 0x200, /// Indicates window is fullscreen on a device when set. The SDK will automatically apply distortion mesh rotation if needed. - ovrDistortionCap_ComputeShader = 0x400, /// Using compute shader (DX11+ only) - - ovrDistortionCap_ProfileNoTimewarpSpinWaits = 0x10000, /// Use when profiling with timewarp to remove false positives -} ovrDistortionCaps; - -/// Specifies which eye is being used for rendering. -/// This type explicitly does not include a third "NoStereo" option, as such is -/// not required for an HMD-centered API. -typedef enum -{ - ovrEye_Left = 0, - ovrEye_Right = 1, - ovrEye_Count = 2 -} ovrEyeType; - -/// This is a complete descriptor of the HMD. -typedef struct ovrHmdDesc_ -{ - /// Internal handle of this HMD. - struct ovrHmdStruct* Handle; - - /// This HMD's type. - ovrHmdType Type; - - /// Name string describing the product: "Oculus Rift DK1", etc. - const char* ProductName; - const char* Manufacturer; - - /// HID Vendor and ProductId of the device. - short VendorId; - short ProductId; - /// Sensor (and display) serial number. - char SerialNumber[24]; - /// Sensor firmware version. - short FirmwareMajor; - short FirmwareMinor; - /// External tracking camera frustum dimensions (if present). - float CameraFrustumHFovInRadians; - float CameraFrustumVFovInRadians; - float CameraFrustumNearZInMeters; - float CameraFrustumFarZInMeters; - - /// Capability bits described by ovrHmdCaps. - unsigned int HmdCaps; - /// Capability bits described by ovrTrackingCaps. - unsigned int TrackingCaps; - /// Capability bits described by ovrDistortionCaps. - unsigned int DistortionCaps; - - /// These define the recommended and maximum optical FOVs for the HMD. - ovrFovPort DefaultEyeFov[ovrEye_Count]; - ovrFovPort MaxEyeFov[ovrEye_Count]; - - /// Preferred eye rendering order for best performance. - /// Can help reduce latency on sideways-scanned screens. - ovrEyeType EyeRenderOrder[ovrEye_Count]; - - /// Resolution of the full HMD screen (both eyes) in pixels. - ovrSizei Resolution; - /// Location of the application window on the desktop (or 0,0). - ovrVector2i WindowsPos; - - /// Display that the HMD should present on. - /// TBD: It may be good to remove this information relying on WindowPos instead. - /// Ultimately, we may need to come up with a more convenient alternative, - /// such as API-specific functions that return adapter, or something that will - /// work with our monitor driver. - /// Windows: (e.g. "\\\\.\\DISPLAY3", can be used in EnumDisplaySettings/CreateDC). - const char* DisplayDeviceName; - /// MacOS: - int DisplayId; - -} ovrHmdDesc; - -/// Simple type ovrHmd is used in ovrHmd_* calls. -typedef const ovrHmdDesc * ovrHmd; - -/// Bit flags describing the current status of sensor tracking. -typedef enum -{ - ovrStatus_OrientationTracked = 0x0001, /// Orientation is currently tracked (connected and in use). - ovrStatus_PositionTracked = 0x0002, /// Position is currently tracked (false if out of range). - ovrStatus_CameraPoseTracked = 0x0004, /// Camera pose is currently tracked. - ovrStatus_PositionConnected = 0x0020, /// Position tracking hardware is connected. - ovrStatus_HmdConnected = 0x0080 /// HMD Display is available and connected. -} ovrStatusBits; - -/// Specifies a reading we can query from the sensor. -typedef struct ovrSensorData_ -{ - ovrVector3f Accelerometer; /// Acceleration reading in m/s^2. - ovrVector3f Gyro; /// Rotation rate in rad/s. - ovrVector3f Magnetometer; /// Magnetic field in Gauss. - float Temperature; /// Temperature of the sensor in degrees Celsius. - float TimeInSeconds; /// Time when the reported IMU reading took place, in seconds. -} ovrSensorData; - -/// Tracking state at a given absolute time (describes predicted HMD pose etc). -/// Returned by ovrHmd_GetTrackingState. -typedef struct ovrTrackingState_ -{ - /// Predicted head pose (and derivatives) at the requested absolute time. - /// The look-ahead interval is equal to (HeadPose.TimeInSeconds - RawSensorData.TimeInSeconds). - ovrPoseStatef HeadPose; - - /// Current pose of the external camera (if present). - /// This pose includes camera tilt (roll and pitch). For a leveled coordinate - /// system use LeveledCameraPose. - ovrPosef CameraPose; - - /// Camera frame aligned with gravity. - /// This value includes position and yaw of the camera, but not roll and pitch. - /// It can be used as a reference point to render real-world objects in the correct location. - ovrPosef LeveledCameraPose; - - /// The most recent sensor data received from the HMD. - ovrSensorData RawSensorData; - - /// Tracking status described by ovrStatusBits. - unsigned int StatusFlags; - - //// 0.4.1 - - // Measures the time from receiving the camera frame until vision CPU processing completes. - double LastVisionProcessingTime; - - //// 0.4.3 - - // Measures the time from exposure until the pose is available for the frame, including processing time. - double LastVisionFrameLatency; - - /// Tag the vision processing results to a certain frame counter number. - uint32_t LastCameraFrameCounter; -} ovrTrackingState; - -/// Frame timing data reported by ovrHmd_BeginFrameTiming() or ovrHmd_BeginFrame(). -typedef struct ovrFrameTiming_ -{ - /// The amount of time that has passed since the previous frame's - /// ThisFrameSeconds value (usable for movement scaling). - /// This will be clamped to no more than 0.1 seconds to prevent - /// excessive movement after pauses due to loading or initialization. - float DeltaSeconds; - - /// It is generally expected that the following holds: - /// ThisFrameSeconds < TimewarpPointSeconds < NextFrameSeconds < - /// EyeScanoutSeconds[EyeOrder[0]] <= ScanoutMidpointSeconds <= EyeScanoutSeconds[EyeOrder[1]]. - - /// Absolute time value when rendering of this frame began or is expected to - /// begin. Generally equal to NextFrameSeconds of the previous frame. Can be used - /// for animation timing. - double ThisFrameSeconds; - /// Absolute point when IMU expects to be sampled for this frame. - double TimewarpPointSeconds; - /// Absolute time when frame Present followed by GPU Flush will finish and the next frame begins. - double NextFrameSeconds; - - /// Time when half of the screen will be scanned out. Can be passed as an absolute time - /// to ovrHmd_GetTrackingState() to get the predicted general orientation. - double ScanoutMidpointSeconds; - /// Timing points when each eye will be scanned out to display. Used when rendering each eye. - double EyeScanoutSeconds[2]; -} ovrFrameTiming; - -/// Rendering information for each eye. Computed by either ovrHmd_ConfigureRendering() -/// or ovrHmd_GetRenderDesc() based on the specified FOV. Note that the rendering viewport -/// is not included here as it can be specified separately and modified per frame through: -/// (a) ovrHmd_GetRenderScaleAndOffset in the case of client rendered distortion, -/// or (b) passing different values via ovrTexture in the case of SDK rendered distortion. -typedef struct ovrEyeRenderDesc_ -{ - ovrEyeType Eye; ///< The eye index this instance corresponds to. - ovrFovPort Fov; ///< The field of view. - ovrRecti DistortedViewport; ///< Distortion viewport. - ovrVector2f PixelsPerTanAngleAtCenter; ///< How many display pixels will fit in tan(angle) = 1. - ovrVector3f HmdToEyeViewOffset; ///< Translation to be applied to view matrix for each eye offset. -} ovrEyeRenderDesc; - -//----------------------------------------------------------------------------------- -// ***** Platform-independent Rendering Configuration - -/// These types are used to hide platform-specific details when passing -/// render device, OS, and texture data to the API. -/// -/// The benefit of having these wrappers versus platform-specific API functions is -/// that they allow game glue code to be portable. A typical example is an -/// engine that has multiple back ends, say GL and D3D. Portable code that calls -/// these back ends may also use LibOVR. To do this, back ends can be modified -/// to return portable types such as ovrTexture and ovrRenderAPIConfig. -typedef enum -{ - ovrRenderAPI_None, - ovrRenderAPI_OpenGL, - ovrRenderAPI_Android_GLES, // May include extra native window pointers, etc. - ovrRenderAPI_D3D9, - ovrRenderAPI_D3D10, - ovrRenderAPI_D3D11, - ovrRenderAPI_Count -} ovrRenderAPIType; - -/// Platform-independent part of rendering API-configuration data. -/// It is a part of ovrRenderAPIConfig, passed to ovrHmd_Configure. -typedef struct OVR_ALIGNAS(8) ovrRenderAPIConfigHeader_ -{ - ovrRenderAPIType API; - ovrSizei BackBufferSize; // Previously named RTSize. - int Multisample; -} ovrRenderAPIConfigHeader; - -/// Contains platform-specific information for rendering. -typedef struct OVR_ALIGNAS(8) ovrRenderAPIConfig_ -{ - ovrRenderAPIConfigHeader Header; - uintptr_t PlatformData[8]; -} ovrRenderAPIConfig; - -/// Platform-independent part of the eye texture descriptor. -/// It is a part of ovrTexture, passed to ovrHmd_EndFrame. -/// If RenderViewport is all zeros then the full texture will be used. -typedef struct OVR_ALIGNAS(8) ovrTextureHeader_ -{ - ovrRenderAPIType API; - ovrSizei TextureSize; - ovrRecti RenderViewport; // Pixel viewport in texture that holds eye image. - uint32_t _PAD0_; -} ovrTextureHeader; - -/// Contains platform-specific information about a texture. -typedef struct OVR_ALIGNAS(8) ovrTexture_ -{ - ovrTextureHeader Header; - uintptr_t PlatformData[8]; -} ovrTexture; - - -// ----------------------------------------------------------------------------------- -// ***** API Interfaces - -// Basic steps to use the API: -// -// Setup: -// * ovrInitialize() -// * ovrHMD hmd = ovrHmd_Create(0) -// * Use hmd members and ovrHmd_GetFovTextureSize() to determine graphics configuration. -// * Call ovrHmd_ConfigureTracking() to configure and initialize tracking. -// * Call ovrHmd_ConfigureRendering() to setup graphics for SDK rendering, -// which is the preferred approach. -// Please refer to "Client Distorton Rendering" below if you prefer to do that instead. -// * If the ovrHmdCap_ExtendDesktop flag is not set, then use ovrHmd_AttachToWindow to -// associate the relevant application window with the hmd. -// * Allocate render target textures as needed. -// -// Game Loop: -// * Call ovrHmd_BeginFrame() to get the current frame timing information. -// * Render each eye using ovrHmd_GetEyePoses or ovrHmd_GetHmdPosePerEye to get -// the predicted hmd pose and each eye pose. -// * Call ovrHmd_EndFrame() to render the distorted textures to the back buffer -// and present them on the hmd. -// -// Shutdown: -// * ovrHmd_Destroy(hmd) -// * ovr_Shutdown() -// - -#ifdef __cplusplus -extern "C" { -#endif - -// ovr_InitializeRenderingShim initializes the rendering shim appart from everything -// else in LibOVR. This may be helpful if the application prefers to avoid -// creating any OVR resources (allocations, service connections, etc) at this point. -// ovr_InitializeRenderingShim does not bring up anything within LibOVR except the -// necessary hooks to enable the Direct-to-Rift functionality. -// -// Either ovr_InitializeRenderingShim() or ovr_Initialize() must be called before any -// Direct3D or OpenGL initilization is done by applictaion (creation of devices, etc). -// ovr_Initialize() must still be called after to use the rest of LibOVR APIs. -OVR_EXPORT ovrBool ovr_InitializeRenderingShim(); - -// Library init/shutdown, must be called around all other OVR code. -// No other functions calls besides ovr_InitializeRenderingShim are allowed -// before ovr_Initialize succeeds or after ovr_Shutdown. -/// Initializes all Oculus functionality. -OVR_EXPORT ovrBool ovr_Initialize(); -/// Shuts down all Oculus functionality. -OVR_EXPORT void ovr_Shutdown(); - -/// Returns version string representing libOVR version. Static, so -/// string remains valid for app lifespan -OVR_EXPORT const char* ovr_GetVersionString(); - -/// Detects or re-detects HMDs and reports the total number detected. -/// Users can get information about each HMD by calling ovrHmd_Create with an index. -OVR_EXPORT int ovrHmd_Detect(); - -/// Creates a handle to an HMD which doubles as a description structure. -/// Index can [0 .. ovrHmd_Detect()-1]. Index mappings can cange after each ovrHmd_Detect call. -/// If not null, then the returned handle must be freed with ovrHmd_Destroy. -OVR_EXPORT ovrHmd ovrHmd_Create(int index); -OVR_EXPORT void ovrHmd_Destroy(ovrHmd hmd); - -/// Creates a 'fake' HMD used for debugging only. This is not tied to specific hardware, -/// but may be used to debug some of the related rendering. -OVR_EXPORT ovrHmd ovrHmd_CreateDebug(ovrHmdType type); - -/// Returns last error for HMD state. Returns null for no error. -/// String is valid until next call or GetLastError or HMD is destroyed. -/// Pass null hmd to get global errors (during create etc). -OVR_EXPORT const char* ovrHmd_GetLastError(ovrHmd hmd); - -/// Platform specific function to specify the application window whose output will be -/// displayed on the HMD. Only used if the ovrHmdCap_ExtendDesktop flag is false. -/// Windows: SwapChain associated with this window will be displayed on the HMD. -/// Specify 'destMirrorRect' in window coordinates to indicate an area -/// of the render target output that will be mirrored from 'sourceRenderTargetRect'. -/// Null pointers mean "full size". -/// @note Source and dest mirror rects are not yet implemented. -OVR_EXPORT ovrBool ovrHmd_AttachToWindow(ovrHmd hmd, void* window, - const ovrRecti* destMirrorRect, - const ovrRecti* sourceRenderTargetRect); - -/// Returns capability bits that are enabled at this time as described by ovrHmdCaps. -/// Note that this value is different font ovrHmdDesc::HmdCaps, which describes what -/// capabilities are available for that HMD. -OVR_EXPORT unsigned int ovrHmd_GetEnabledCaps(ovrHmd hmd); - -/// Modifies capability bits described by ovrHmdCaps that can be modified, -/// such as ovrHmdCap_LowPersistance. -OVR_EXPORT void ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int hmdCaps); - -//------------------------------------------------------------------------------------- -// ***** Tracking Interface - -/// All tracking interface functions are thread-safe, allowing tracking state to be sampled -/// from different threads. -/// ConfigureTracking starts sensor sampling, enabling specified capabilities, -/// described by ovrTrackingCaps. -/// - supportedTrackingCaps specifies support that is requested. The function will succeed -/// even if these caps are not available (i.e. sensor or camera is unplugged). Support -/// will automatically be enabled if such device is plugged in later. Software should -/// check ovrTrackingState.StatusFlags for real-time status. -/// - requiredTrackingCaps specify sensor capabilities required at the time of the call. -/// If they are not available, the function will fail. Pass 0 if only specifying -/// supportedTrackingCaps. -/// - Pass 0 for both supportedTrackingCaps and requiredTrackingCaps to disable tracking. -OVR_EXPORT ovrBool ovrHmd_ConfigureTracking(ovrHmd hmd, unsigned int supportedTrackingCaps, - unsigned int requiredTrackingCaps); - -/// Re-centers the sensor orientation. -/// Normally this will recenter the (x,y,z) translational components and the yaw -/// component of orientation. -OVR_EXPORT void ovrHmd_RecenterPose(ovrHmd hmd); - -/// Returns tracking state reading based on the specified absolute system time. -/// Pass an absTime value of 0.0 to request the most recent sensor reading. In this case -/// both PredictedPose and SamplePose will have the same value. -/// ovrHmd_GetEyePoses relies on this function internally. -/// This may also be used for more refined timing of FrontBuffer rendering logic, etc. -OVR_EXPORT ovrTrackingState ovrHmd_GetTrackingState(ovrHmd hmd, double absTime); - -//------------------------------------------------------------------------------------- -// ***** Graphics Setup - -/// Calculates the recommended texture size for rendering a given eye within the HMD -/// with a given FOV cone. Higher FOV will generally require larger textures to -/// maintain quality. -/// - pixelsPerDisplayPixel specifies the ratio of the number of render target pixels -/// to display pixels at the center of distortion. 1.0 is the default value. Lower -/// values can improve performance. -OVR_EXPORT ovrSizei ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov, - float pixelsPerDisplayPixel); - -//------------------------------------------------------------------------------------- -// ***** Rendering API Thread Safety - -// All of rendering functions including the configure and frame functions -// are *NOT thread safe*. It is ok to use ConfigureRendering on one thread and handle -// frames on another thread, but explicit synchronization must be done since -// functions that depend on configured state are not reentrant. -// -// As an extra requirement, any of the following calls must be done on -// the render thread, which is the same thread that calls ovrHmd_BeginFrame -// or ovrHmd_BeginFrameTiming. -// - ovrHmd_EndFrame -// - ovrHmd_GetEyeTimewarpMatrices - -//------------------------------------------------------------------------------------- -// ***** SDK Distortion Rendering Functions - -// These functions support rendering of distortion by the SDK through direct -// access to the underlying rendering API, such as D3D or GL. -// This is the recommended approach since it allows better support for future -// Oculus hardware, and enables a range of low-level optimizations. - -/// Configures rendering and fills in computed render parameters. -/// This function can be called multiple times to change rendering settings. -/// eyeRenderDescOut is a pointer to an array of two ovrEyeRenderDesc structs -/// that are used to return complete rendering information for each eye. -/// - apiConfig provides D3D/OpenGL specific parameters. Pass null -/// to shutdown rendering and release all resources. -/// - distortionCaps describe desired distortion settings. -OVR_EXPORT ovrBool ovrHmd_ConfigureRendering( ovrHmd hmd, - const ovrRenderAPIConfig* apiConfig, - unsigned int distortionCaps, - const ovrFovPort eyeFovIn[2], - ovrEyeRenderDesc eyeRenderDescOut[2] ); - - -/// Begins a frame, returning timing information. -/// This should be called at the beginning of the game rendering loop (on the render thread). -/// Pass 0 for the frame index if not using ovrHmd_GetFrameTiming. -OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrame(ovrHmd hmd, unsigned int frameIndex); - -/// Ends a frame, submitting the rendered textures to the frame buffer. -/// - RenderViewport within each eyeTexture can change per frame if necessary. -/// - 'renderPose' will typically be the value returned from ovrHmd_GetEyePoses, -/// ovrHmd_GetHmdPosePerEye but can be different if a different head pose was -/// used for rendering. -/// - This may perform distortion and scaling internally, assuming is it not -/// delegated to another thread. -/// - Must be called on the same thread as BeginFrame. -/// - *** This Function will call Present/SwapBuffers and potentially wait for GPU Sync ***. -OVR_EXPORT void ovrHmd_EndFrame(ovrHmd hmd, - const ovrPosef renderPose[2], - const ovrTexture eyeTexture[2]); - -/// Returns predicted head pose in outHmdTrackingState and offset eye poses in outEyePoses -/// as an atomic operation. Caller need not worry about applying HmdToEyeViewOffset to the -/// returned outEyePoses variables. -/// - Thread-safe function where caller should increment frameIndex with every frame -/// and pass the index where applicable to functions called on the rendering thread. -/// - hmdToEyeViewOffset[2] can be ovrEyeRenderDesc.HmdToEyeViewOffset returned from -/// ovrHmd_ConfigureRendering or ovrHmd_GetRenderDesc. For monoscopic rendering, -/// use a vector that is the average of the two vectors for both eyes. -/// - If frameIndex is not being used, pass in 0. -/// - Assuming outEyePoses are used for rendering, it should be passed into ovrHmd_EndFrame. -/// - If called doesn't need outHmdTrackingState, it can be NULL -OVR_EXPORT void ovrHmd_GetEyePoses(ovrHmd hmd, unsigned int frameIndex, ovrVector3f hmdToEyeViewOffset[2], - ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState); - -/// Function was previously called ovrHmd_GetEyePose -/// Returns the predicted head pose to use when rendering the specified eye. -/// - Important: Caller must apply HmdToEyeViewOffset before using ovrPosef for rendering -/// - Must be called between ovrHmd_BeginFrameTiming and ovrHmd_EndFrameTiming. -/// - If the pose is used for rendering the eye, it should be passed to ovrHmd_EndFrame. -/// - Parameter 'eye' is used for prediction timing only -OVR_EXPORT ovrPosef ovrHmd_GetHmdPosePerEye(ovrHmd hmd, ovrEyeType eye); - - -//------------------------------------------------------------------------------------- -// ***** Client Distortion Rendering Functions - -// These functions provide the distortion data and render timing support necessary to allow -// client rendering of distortion. Client-side rendering involves the following steps: -// -// 1. Setup ovrEyeDesc based on the desired texture size and FOV. -// Call ovrHmd_GetRenderDesc to get the necessary rendering parameters for each eye. -// -// 2. Use ovrHmd_CreateDistortionMesh to generate the distortion mesh. -// -// 3. Use ovrHmd_BeginFrameTiming, ovrHmd_GetEyePoses, and ovrHmd_BeginFrameTiming in -// the rendering loop to obtain timing and predicted head orientation when rendering each eye. -// - When using timewarp, use ovr_WaitTillTime after the rendering and gpu flush, followed -// by ovrHmd_GetEyeTimewarpMatrices to obtain the timewarp matrices used -// by the distortion pixel shader. This will minimize latency. -// - -/// Computes the distortion viewport, view adjust, and other rendering parameters for -/// the specified eye. This can be used instead of ovrHmd_ConfigureRendering to do -/// setup for client rendered distortion. -OVR_EXPORT ovrEyeRenderDesc ovrHmd_GetRenderDesc(ovrHmd hmd, - ovrEyeType eyeType, ovrFovPort fov); - - -/// Describes a vertex used by the distortion mesh. This is intended to be converted into -/// the engine-specific format. Some fields may be unused based on the ovrDistortionCaps -/// flags selected. TexG and TexB, for example, are not used if chromatic correction is -/// not requested. -typedef struct ovrDistortionVertex_ -{ - ovrVector2f ScreenPosNDC; ///< [-1,+1],[-1,+1] over the entire framebuffer. - float TimeWarpFactor; ///< Lerp factor between time-warp matrices. Can be encoded in Pos.z. - float VignetteFactor; ///< Vignette fade factor. Can be encoded in Pos.w. - ovrVector2f TanEyeAnglesR; ///< The tangents of the horizontal and vertical eye angles for the red channel. - ovrVector2f TanEyeAnglesG; ///< The tangents of the horizontal and vertical eye angles for the green channel. - ovrVector2f TanEyeAnglesB; ///< The tangents of the horizontal and vertical eye angles for the blue channel. -} ovrDistortionVertex; - -/// Describes a full set of distortion mesh data, filled in by ovrHmd_CreateDistortionMesh. -/// Contents of this data structure, if not null, should be freed by ovrHmd_DestroyDistortionMesh. -typedef struct ovrDistortionMesh_ -{ - ovrDistortionVertex* pVertexData; ///< The distortion vertices representing each point in the mesh. - unsigned short* pIndexData; ///< Indices for connecting the mesh vertices into polygons. - unsigned int VertexCount; ///< The number of vertices in the mesh. - unsigned int IndexCount; ///< The number of indices in the mesh. -} ovrDistortionMesh; - -/// Generate distortion mesh per eye. -/// Distortion capabilities will depend on 'distortionCaps' flags. Users should -/// render using the appropriate shaders based on their settings. -/// Distortion mesh data will be allocated and written into the ovrDistortionMesh data structure, -/// which should be explicitly freed with ovrHmd_DestroyDistortionMesh. -/// Users should call ovrHmd_GetRenderScaleAndOffset to get uvScale and Offset values for rendering. -/// The function shouldn't fail unless theres is a configuration or memory error, in which case -/// ovrDistortionMesh values will be set to null. -/// This is the only function in the SDK reliant on eye relief, currently imported from profiles, -/// or overridden here. -OVR_EXPORT ovrBool ovrHmd_CreateDistortionMesh( ovrHmd hmd, - ovrEyeType eyeType, ovrFovPort fov, - unsigned int distortionCaps, - ovrDistortionMesh *meshData); -OVR_EXPORT ovrBool ovrHmd_CreateDistortionMeshDebug( ovrHmd hmddesc, - ovrEyeType eyeType, ovrFovPort fov, - unsigned int distortionCaps, - ovrDistortionMesh *meshData, - float debugEyeReliefOverrideInMetres); - - -/// Used to free the distortion mesh allocated by ovrHmd_GenerateDistortionMesh. meshData elements -/// are set to null and zeroes after the call. -OVR_EXPORT void ovrHmd_DestroyDistortionMesh( ovrDistortionMesh* meshData ); - -/// Computes updated 'uvScaleOffsetOut' to be used with a distortion if render target size or -/// viewport changes after the fact. This can be used to adjust render size every frame if desired. -OVR_EXPORT void ovrHmd_GetRenderScaleAndOffset( ovrFovPort fov, - ovrSizei textureSize, ovrRecti renderViewport, - ovrVector2f uvScaleOffsetOut[2] ); - -/// Thread-safe timing function for the main thread. Caller should increment frameIndex -/// with every frame and pass the index where applicable to functions called on the -/// rendering thread. -OVR_EXPORT ovrFrameTiming ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIndex); - -/// Called at the beginning of the frame on the rendering thread. -/// Pass frameIndex == 0 if ovrHmd_GetFrameTiming isn't being used. Otherwise, -/// pass the same frame index as was used for GetFrameTiming on the main thread. -OVR_EXPORT ovrFrameTiming ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frameIndex); - -/// Marks the end of client distortion rendered frame, tracking the necessary timing information. -/// This function must be called immediately after Present/SwapBuffers + GPU sync. GPU sync is -/// important before this call to reduce latency and ensure proper timing. -OVR_EXPORT void ovrHmd_EndFrameTiming(ovrHmd hmd); - -/// Initializes and resets frame time tracking. This is typically not necessary, but -/// is helpful if game changes vsync state or video mode. vsync is assumed to be on if this -/// isn't called. Resets internal frame index to the specified number. -OVR_EXPORT void ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex); - -/// Computes timewarp matrices used by distortion mesh shader, these are used to adjust -/// for head orientation change since the last call to ovrHmd_GetEyePoses -/// when rendering this eye. The ovrDistortionVertex::TimeWarpFactor is used to blend between the -/// matrices, usually representing two different sides of the screen. -/// Must be called on the same thread as ovrHmd_BeginFrameTiming. -OVR_EXPORT void ovrHmd_GetEyeTimewarpMatrices (ovrHmd hmd, ovrEyeType eye, - ovrPosef renderPose, ovrMatrix4f twmOut[2]); -OVR_EXPORT void ovrHmd_GetEyeTimewarpMatricesDebug(ovrHmd hmd, ovrEyeType eye, - ovrPosef renderPose, ovrMatrix4f twmOut[2], - double debugTimingOffsetInSeconds); - - - - -//------------------------------------------------------------------------------------- -// ***** Stateless math setup functions - -/// Used to generate projection from ovrEyeDesc::Fov. -OVR_EXPORT ovrMatrix4f ovrMatrix4f_Projection( ovrFovPort fov, - float znear, float zfar, ovrBool rightHanded ); - -/// Used for 2D rendering, Y is down -/// orthoScale = 1.0f / pixelsPerTanAngleAtCenter -/// orthoDistance = distance from camera, such as 0.8m -OVR_EXPORT ovrMatrix4f ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale, - float orthoDistance, float hmdToEyeViewOffsetX); - -/// Returns global, absolute high-resolution time in seconds. This is the same -/// value as used in sensor messages. -OVR_EXPORT double ovr_GetTimeInSeconds(); - -/// Waits until the specified absolute time. -OVR_EXPORT double ovr_WaitTillTime(double absTime); - -// ----------------------------------------------------------------------------------- -// ***** Latency Test interface - -/// Does latency test processing and returns 'TRUE' if specified rgb color should -/// be used to clear the screen. -OVR_EXPORT ovrBool ovrHmd_ProcessLatencyTest(ovrHmd hmd, unsigned char rgbColorOut[3]); - -/// Returns non-null string once with latency test result, when it is available. -/// Buffer is valid until next call. -OVR_EXPORT const char* ovrHmd_GetLatencyTestResult(ovrHmd hmd); - -/// Returns the latency testing color in rgbColorOut to render when using a DK2 -/// Returns false if this feature is disabled or not-applicable (e.g. using a DK1) -OVR_EXPORT ovrBool ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmddesc, unsigned char rgbColorOut[3]); - -//------------------------------------------------------------------------------------- -// ***** Health and Safety Warning Display interface -// - -/// Used by ovrhmd_GetHSWDisplayState to report the current display state. -typedef struct ovrHSWDisplayState_ -{ - /// If true then the warning should be currently visible - /// and the following variables have meaning. Else there is no - /// warning being displayed for this application on the given HMD. - ovrBool Displayed; ///< True if the Health&Safety Warning is currently displayed. - double StartTime; ///< Absolute time when the warning was first displayed. See ovr_GetTimeInSeconds(). - double DismissibleTime; ///< Earliest absolute time when the warning can be dismissed. May be a time in the past. -} ovrHSWDisplayState; - -/// Returns the current state of the HSW display. If the application is doing the rendering of -/// the HSW display then this function serves to indicate that the warning should be -/// currently displayed. If the application is using SDK-based eye rendering then the SDK by -/// default automatically handles the drawing of the HSW display. An application that uses -/// application-based eye rendering should use this function to know when to start drawing the -/// HSW display itself and can optionally use it in conjunction with ovrhmd_DismissHSWDisplay -/// as described below. -/// -/// Example usage for application-based rendering: -/// bool HSWDisplayCurrentlyDisplayed = false; // global or class member variable -/// ovrHSWDisplayState hswDisplayState; -/// ovrhmd_GetHSWDisplayState(Hmd, &hswDisplayState); -/// -/// if (hswDisplayState.Displayed && !HSWDisplayCurrentlyDisplayed) { -/// -/// HSWDisplayCurrentlyDisplayed = true; -/// } -OVR_EXPORT void ovrHmd_GetHSWDisplayState(ovrHmd hmd, ovrHSWDisplayState *hasWarningState); - -/// Dismisses the HSW display if the warning is dismissible and the earliest dismissal time -/// has occurred. Returns true if the display is valid and could be dismissed. The application -/// should recognize that the HSW display is being displayed (via ovrhmd_GetHSWDisplayState) -/// and if so then call this function when the appropriate user input to dismiss the warning -/// occurs. -/// -/// Example usage : -/// void ProcessEvent(int key) { -/// if (key == escape) { -/// ovrHSWDisplayState hswDisplayState; -/// ovrhmd_GetHSWDisplayState(hmd, &hswDisplayState); -/// -/// if (hswDisplayState.Displayed && ovrhmd_DismissHSWDisplay(hmd)) { -/// -/// HSWDisplayCurrentlyDisplayed = false; -/// } -/// } -/// } -OVR_EXPORT ovrBool ovrHmd_DismissHSWDisplay(ovrHmd hmd); - -/// Get boolean property. Returns first element if property is a boolean array. -/// Returns defaultValue if property doesn't exist. -OVR_EXPORT ovrBool ovrHmd_GetBool(ovrHmd hmd, const char* propertyName, ovrBool defaultVal); - -/// Modify bool property; false if property doesn't exist or is readonly. -OVR_EXPORT ovrBool ovrHmd_SetBool(ovrHmd hmd, const char* propertyName, ovrBool value); - -/// Get integer property. Returns first element if property is an integer array. -/// Returns defaultValue if property doesn't exist. -OVR_EXPORT int ovrHmd_GetInt(ovrHmd hmd, const char* propertyName, int defaultVal); - -/// Modify integer property; false if property doesn't exist or is readonly. -OVR_EXPORT ovrBool ovrHmd_SetInt(ovrHmd hmd, const char* propertyName, int value); - -/// Get float property. Returns first element if property is a float array. -/// Returns defaultValue if property doesn't exist. -OVR_EXPORT float ovrHmd_GetFloat(ovrHmd hmd, const char* propertyName, float defaultVal); - -/// Modify float property; false if property doesn't exist or is readonly. -OVR_EXPORT ovrBool ovrHmd_SetFloat(ovrHmd hmd, const char* propertyName, float value); - -/// Get float[] property. Returns the number of elements filled in, 0 if property doesn't exist. -/// Maximum of arraySize elements will be written. -OVR_EXPORT unsigned int ovrHmd_GetFloatArray(ovrHmd hmd, const char* propertyName, - float values[], unsigned int arraySize); - -/// Modify float[] property; false if property doesn't exist or is readonly. -OVR_EXPORT ovrBool ovrHmd_SetFloatArray(ovrHmd hmd, const char* propertyName, - float values[], unsigned int arraySize); - -/// Get string property. Returns first element if property is a string array. -/// Returns defaultValue if property doesn't exist. -/// String memory is guaranteed to exist until next call to GetString or GetStringArray, or HMD is destroyed. -OVR_EXPORT const char* ovrHmd_GetString(ovrHmd hmd, const char* propertyName, - const char* defaultVal); - -/// Set string property -OVR_EXPORT ovrBool ovrHmd_SetString(ovrHmd hmddesc, const char* propertyName, - const char* value); - -// ----------------------------------------------------------------------------------- -// ***** Logging - -/// Start performance logging. guid is optional and if included is written with each file entry. -/// If called while logging is already active with the same filename, only the guid will be updated -/// If called while logging is already active with a different filename, ovrHmd_StopPerfLog() will be called, followed by ovrHmd_StartPerfLog() -OVR_EXPORT ovrBool ovrHmd_StartPerfLog(ovrHmd hmd, const char* fileName, const char* userData1); -/// Stop performance logging. -OVR_EXPORT ovrBool ovrHmd_StopPerfLog(ovrHmd hmd); - - -#ifdef __cplusplus -} // extern "C" -#endif - - -#if defined(_MSC_VER) - #pragma warning(pop) -#endif - - -#endif // OVR_CAPI_h diff --git a/LibOVR/Src/OVR_CAPIShim.c b/LibOVR/Src/OVR_CAPIShim.c new file mode 100755 index 0000000..351e057 --- /dev/null +++ b/LibOVR/Src/OVR_CAPIShim.c @@ -0,0 +1,1416 @@ +/************************************************************************************ + +Filename : OVR_CAPIShim.c +Content : CAPI DLL user library +Created : November 20, 2014 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + + +#include "OVR_CAPI.h" +#include "OVR_Version.h" +#include +#include +#include +#include + +#if defined(_WIN32) + #include +#else + #if defined(__APPLE__) + #include + #include + #include + #include + #include + #endif + #include + #include + #include +#endif + + +#if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable: 4996) // 'getenv': This function or variable may be unsafe. +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_ENABLE_DEVELOPER_SEARCH +// +// If defined then our shared library loading code searches for developer build +// directories. +// +#if !defined(OVR_ENABLE_DEVELOPER_SEARCH) +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_BUILD_DEBUG +// +// Defines OVR_BUILD_DEBUG when the compiler default debug preprocessor is set. +// +// If you want to control the behavior of these flags, then explicitly define +// either -DOVR_BUILD_RELEASE or -DOVR_BUILD_DEBUG in the compiler arguments. + +#if !defined(OVR_BUILD_DEBUG) && !defined(OVR_BUILD_RELEASE) + #if defined(_MSC_VER) + #if defined(_DEBUG) + #define OVR_BUILD_DEBUG + #endif + #else + #if defined(DEBUG) + #define OVR_BUILD_DEBUG + #endif + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** FilePathCharType, ModuleHandleType, ModuleFunctionType +// +#if defined(_WIN32) // We need to use wchar_t on Microsoft platforms, as that's the native file system character type. + #define FilePathCharType wchar_t // #define instead of typedef because debuggers (VC++, XCode) don't recognize typedef'd types as a string type. + typedef HMODULE ModuleHandleType; + typedef FARPROC ModuleFunctionType; +#else + #define FilePathCharType char + typedef void* ModuleHandleType; + typedef void* ModuleFunctionType; +#endif + +#define ModuleHandleTypeNull ((ModuleHandleType)NULL) +#define ModuleFunctionTypeNull ((ModuleFunctionType)NULL) + + +//----------------------------------------------------------------------------------- +// ***** OVR_MAX_PATH +// +#if !defined(OVR_MAX_PATH) + #if defined(_WIN32) + #define OVR_MAX_PATH _MAX_PATH + #elif defined(__APPLE__) + #define OVR_MAX_PATH PATH_MAX + #else + #define OVR_MAX_PATH 1024 + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_DECLARE_IMPORT +// +// Creates typedef and pointer declaration for a function of a given signature. +// The typedef is Type, and the pointer is Ptr. +// +// Example usage: +// int MultiplyValues(float x, float y); // Assume this function exists in an external shared library. We don't actually need to redeclare it. +// OVR_DECLARE_IMPORT(int, MultiplyValues, (float x, float y)) // This creates a local typedef and pointer for it. + +#define OVR_DECLARE_IMPORT(ReturnValue, FunctionName, Arguments) \ + typedef ReturnValue (OVR_CDECL *FunctionName##Type)Arguments; \ + FunctionName##Type FunctionName##Ptr = NULL; + + + +//----------------------------------------------------------------------------------- +// ***** OVR_GETFUNCTION +// +// Loads Ptr from hLibOVR if not already loaded. +// Assumes a variable named Ptr of type Type exists which is called in LibOVR. +// +// Example usage: +// OVR_GETFUNCTION(MultiplyValues) // Normally this would be done on library init and not before every usage. +// int result = MultiplyValuesPtr(3.f, 4.f); + +#if !defined(OVR_DLSYM) + #if defined(_WIN32) + #define OVR_DLSYM(dlImage, name) GetProcAddress(dlImage, name) + #else + #define OVR_DLSYM(dlImage, name) dlsym(dlImage, name) + #endif +#endif + +#define OVR_GETFUNCTION(f) \ + if(!f##Ptr) \ + { \ + union \ + { \ + f##Type p1; \ + ModuleFunctionType p2; \ + } u; \ + u.p2 = OVR_DLSYM(hLibOVR, #f); \ + f##Ptr = u.p1; \ + } + + +#if defined(__APPLE__) || defined(OVR_ENABLE_DEVELOPER_SEARCH) +static size_t OVR_strlcpy(char* dest, const char* src, size_t destsize) +{ + const char* s = src; + size_t n = destsize; + + if(n && --n) + { + do{ + if((*dest++ = *s++) == 0) + break; + } while(--n); + } + + if(!n) + { + if(destsize) + *dest = 0; + while(*s++) + { } + } + + return (size_t)((s - src) - 1); +} +#endif // __APPLE__ || OVR_ENABLE_DEVELOPER_SEARCH + + +#if defined(__APPLE__) // Currently used on Apple only. + static size_t OVR_strlcat(char* dest, const char* src, size_t destsize) + { + const size_t d = destsize ? strlen(dest) : 0; + const size_t s = strlen(src); + const size_t t = s + d; + + if(t < destsize) + memcpy(dest + d, src, (s + 1) * sizeof(*src)); + else + { + if(destsize) + { + memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src)); + dest[destsize - 1] = 0; + } + } + + return t; + } +#endif + + +#if defined(__APPLE__) + static ovrBool OVR_strend(const char* pStr, const char* pFind, size_t strLength, size_t findLength) + { + if(strLength == (size_t)-1) + strLength = strlen(pStr); + if(findLength == (size_t)-1) + findLength = strlen(pFind); + if(strLength >= findLength) + return (strcmp(pStr + strLength - findLength, pFind) == 0); + return ovrFalse; + } + + static ovrBool OVR_isBundleFolder(const char* filePath) + { + static const char* extensionArray[] = { ".app", ".bundle", ".framework", ".plugin", ".kext" }; + size_t i; + + for(i = 0; i < sizeof(extensionArray)/sizeof(extensionArray[0]); i++) + { + if(OVR_strend(filePath, extensionArray[i], (size_t)-1, (size_t)-1)) + return ovrTrue; + } + + return ovrFalse; + } +#endif + + +#if defined(OVR_ENABLE_DEVELOPER_SEARCH) + +// Returns true if the path begins with the given prefix. +// Doesn't support non-ASCII paths, else the return value may be incorrect. +static int OVR_PathStartsWith(const FilePathCharType* path, const char* prefix) +{ + while(*prefix) + { + if(tolower((unsigned char)*path++) != tolower((unsigned char)*prefix++)) + return ovrFalse; + } + + return ovrTrue; +} + +#endif + + +static ovrBool OVR_GetCurrentWorkingDirectory(FilePathCharType* directoryPath, size_t directoryPathCapacity) +{ + #if defined(_WIN32) + DWORD dwSize = GetCurrentDirectoryW((DWORD)directoryPathCapacity, directoryPath); + + if((dwSize > 0) && (directoryPathCapacity > 1)) // Test > 1 so we have room to possibly append a \ char. + { + size_t length = wcslen(directoryPath); + + if((length == 0) || ((directoryPath[length - 1] != L'\\') && (directoryPath[length - 1] != L'/'))) + { + directoryPath[length++] = L'\\'; + directoryPath[length] = L'\0'; + } + + return ovrTrue; + } + + #else + char* cwd = getcwd(directoryPath, directoryPathCapacity); + + if(cwd && directoryPath[0] && (directoryPathCapacity > 1)) // Test > 1 so we have room to possibly append a / char. + { + size_t length = strlen(directoryPath); + + if((length == 0) || (directoryPath[length - 1] != '/')) + { + directoryPath[length++] = '/'; + directoryPath[length] = '\0'; + } + + return ovrTrue; + } + #endif + + if(directoryPathCapacity > 0) + directoryPath[0] = '\0'; + + return ovrFalse; +} + + +// The appContainer argument is specific currently to only Macintosh. If true and the application is a .app bundle then it returns the +// location of the bundle and not the path to the executable within the bundle. Else return the path to the executable binary itself. +// The moduleHandle refers to the relevant dynamic (a.k.a. shared) library. The main executable is the main module, and each of the shared +// libraries is a module. This way you can specify that you want to know the directory of the given shared library, which may be different +// from the main executable. If the moduleHandle is NULL then the current application module is used. +static ovrBool OVR_GetCurrentApplicationDirectory(FilePathCharType* directoryPath, size_t directoryPathCapacity, ovrBool appContainer, ModuleHandleType moduleHandle) +{ + #if defined(_WIN32) + DWORD length = GetModuleFileNameW(moduleHandle, directoryPath, (DWORD)directoryPathCapacity); + DWORD pos; + + if((length != 0) && (length < (DWORD)directoryPathCapacity)) // If there wasn't an error and there was enough capacity... + { + for(pos = length; (pos > 0) && (directoryPath[pos] != '\\') && (directoryPath[pos] != '/'); --pos) + { + if((directoryPath[pos - 1] != '\\') && (directoryPath[pos - 1] != '/')) + directoryPath[pos - 1] = 0; + } + + return ovrTrue; + } + + (void)appContainer; // Not used on this platform. + + #elif defined(__APPLE__) + uint32_t directoryPathCapacity32 = (uint32_t)directoryPathCapacity; + int result = _NSGetExecutablePath(directoryPath, &directoryPathCapacity32); + + if(result == 0) // If success... + { + char realPath[OVR_MAX_PATH]; + + if(realpath(directoryPath, realPath)) // realpath returns the canonicalized absolute file path. + { + size_t length = 0; + + if(appContainer) // If the caller wants the path to the containing bundle... + { + char containerPath[OVR_MAX_PATH]; + ovrBool pathIsContainer; + + OVR_strlcpy(containerPath, realPath, sizeof(containerPath)); + pathIsContainer = OVR_isBundleFolder(containerPath); + + while(!pathIsContainer && strncmp(containerPath, ".", OVR_MAX_PATH) && strncmp(containerPath, "/", OVR_MAX_PATH)) // While the container we're looking for is not found and while the path doesn't start with a . or / + { + OVR_strlcpy(containerPath, dirname(containerPath), sizeof(containerPath)); + pathIsContainer = OVR_isBundleFolder(containerPath); + } + + if(pathIsContainer) + length = OVR_strlcpy(directoryPath, containerPath, directoryPathCapacity); + } + + if(length == 0) // If not set above in the appContainer block... + length = OVR_strlcpy(directoryPath, realPath, directoryPathCapacity); + + while(length-- && (directoryPath[length] != '/')) + directoryPath[length] = '\0'; // Strip the file name from the file path, leaving a trailing / char. + + return ovrTrue; + } + } + + (void)moduleHandle; // Not used on this platform. + + #else + ssize_t length = readlink("/proc/self/exe", directoryPath, directoryPathCapacity); + ssize_t pos; + + if(length > 0) + { + for(pos = length; (pos > 0) && (directoryPath[pos] != '/'); --pos) + { + if(directoryPath[pos - 1] != '/') + directoryPath[pos - 1] = '\0'; + } + + return ovrTrue; + } + + (void)appContainer; // Not used on this platform. + (void)moduleHandle; + #endif + + if(directoryPathCapacity > 0) + directoryPath[0] = '\0'; + + return ovrFalse; +} + + +#if defined(_WIN32) || defined(OVR_ENABLE_DEVELOPER_SEARCH) // Used only in these cases + +// Get the file path to the current module's (DLL or EXE) directory within the current process. +// Will be different from the process module handle if the current module is a DLL and is in a different directory than the EXE module. +// If successful then directoryPath will be valid and ovrTrue is returned, else directoryPath will be empty and ovrFalse is returned. +static ovrBool OVR_GetCurrentModuleDirectory(FilePathCharType* directoryPath, size_t directoryPathCapacity, ovrBool appContainer) +{ + #if defined(_WIN32) + HMODULE hModule; + BOOL result = GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCWSTR)(uintptr_t)OVR_GetCurrentModuleDirectory, &hModule); + if(result) + OVR_GetCurrentApplicationDirectory(directoryPath, directoryPathCapacity, ovrTrue, hModule); + else + directoryPath[0] = 0; + + (void)appContainer; + + return directoryPath[0] ? ovrTrue : ovrFalse; + #else + return OVR_GetCurrentApplicationDirectory(directoryPath, directoryPathCapacity, appContainer, NULL); + #endif +} + +#endif + + +static ModuleHandleType OVR_OpenLibrary(const FilePathCharType* libraryPath) +{ + #if defined(_WIN32) + return LoadLibraryW(libraryPath); + #else + // Don't bother trying to dlopen() a file that is not even there. + if (access(libraryPath, X_OK | R_OK ) != 0) + { + return NULL; + } + + dlerror(); // Clear any previous dlopen() errors + + // Use RTLD_NOW because we don't want unexpected stalls at runtime, and the library isn't very large. + // Use RTLD_LOCAL to avoid unilaterally exporting resolved symbols to the rest of this process. + void *lib = dlopen(libraryPath, RTLD_NOW | RTLD_LOCAL); + + if (!lib) + { + #if defined(__APPLE__) + // TODO: Output the error in whatever logging system OSX uses (jhughes) + #else // __APPLE__ + fprintf(stderr, "ERROR: Can't load '%s':\n%s\n", libraryPath, dlerror()); + #endif // __APPLE__ + } + + return lib; + #endif +} + + +/* Currently not in use, but expected to be used in the future +static void OVR_CloseLibrary(ModuleHandleType hLibrary) +{ + if (hLibrary) + { + #if defined(_WIN32) + FreeLibrary(hLibrary); + #else + dlclose(hLibrary); + #endif + } +} +*/ + + +// Returns a valid ModuleHandleType (e.g. Windows HMODULE) or returns ModuleHandleTypeNull (e.g. NULL). +// The caller is required to eventually call OVR_CloseLibrary on a valid return handle. +// +static ModuleHandleType OVR_FindLibraryPath(int requestedProductVersion, int requestedMajorVersion, + FilePathCharType* libraryPath, size_t libraryPathCapacity) +{ + ModuleHandleType moduleHandle; + int printfResult; + FilePathCharType developerDir[OVR_MAX_PATH]; + + #if defined(_MSC_VER) + #if defined(_WIN64) + const char* pBitDepth = "64"; + #else + const char* pBitDepth = "32"; + #endif + #elif defined(__APPLE__) + // For Apple platforms we are using a Universal Binary LibOVRRT dylib which has both 32 and 64 in it. + #else // Other Unix. + #if defined(__x86_64__) + const char* pBitDepth = "64"; + #else + const char* pBitDepth = "32"; + #endif + #endif + + moduleHandle = ModuleHandleTypeNull; + if(libraryPathCapacity) + libraryPath[0] = '\0'; + + // Support checking for a developer library location override via the OVR_SDK_ROOT environment variable. + developerDir[0] = '\0'; + + #if defined(OVR_ENABLE_DEVELOPER_SEARCH) + { + #if (defined(_MSC_VER) || defined(_WIN32)) && !defined(OVR_FILE_PATH_SEPARATOR) + #define OVR_FILE_PATH_SEPARATOR "\\" + #else + #define OVR_FILE_PATH_SEPARATOR "/" + #endif + + char sdkRoot[OVR_MAX_PATH]; + const char* pSDKRootEnv = getenv("OVR_SDK_ROOT"); // Example value: /dev/OculusSDK/0.4/Main/ + + if(pSDKRootEnv) + { + size_t length = OVR_strlcpy(sdkRoot, pSDKRootEnv, sizeof(sdkRoot)); + + if((length > 0) || (length < sizeof(sdkRoot))) + { + if(sdkRoot[length-1] == OVR_FILE_PATH_SEPARATOR[0]) + sdkRoot[length-1] = '\0'; + } + else + sdkRoot[0] = '\0'; + } + else + { + // __FILE__ maps to /LibOVR/Src/OVR_CAPIShim.c + char* pLibOVR; + size_t i; + + // We assume that __FILE__ returns a full path, which isn't the case for some compilers. + // Need to compile with /FC under VC++ for __FILE__ to expand to the full file path. + // clang expands __FILE__ to a full path by default. + OVR_strlcpy(sdkRoot, __FILE__, sizeof(sdkRoot)); + for(i = 0; sdkRoot[i]; ++i) + sdkRoot[i] = (char)tolower(sdkRoot[i]); // Microsoft doesn't maintain case. + pLibOVR = strstr(sdkRoot, "libovr"); + if(pLibOVR && (pLibOVR > sdkRoot)) + pLibOVR[-1] = '\0'; + else + sdkRoot[0] = '\0'; + } + + if(sdkRoot[0]) + { + // We want to use a developer version of the library only if the application is also being executed from + // a developer location. Ideally we would do this by checking that the relative path from the executable to + // the shared library is the same at runtime as it was when the executable was first built, but we don't have + // an easy way to do that from here and it would require some runtime help from the application code. + // Instead we verify that the application is simply in the same developer tree that was was when built. + // We could put in some additional logic to make it very likely to know if the EXE is in its original location. + FilePathCharType modulePath[OVR_MAX_PATH]; + const ovrBool pathMatch = OVR_GetCurrentModuleDirectory(modulePath, OVR_MAX_PATH, ovrTrue) && + (OVR_PathStartsWith(modulePath, sdkRoot) == ovrTrue); + if(pathMatch == ovrFalse) + { + sdkRoot[0] = '\0'; // The application module is not in the developer tree, so don't try to use the developer shared library. + } + } + + if(sdkRoot[0]) + { + #if defined(OVR_BUILD_DEBUG) + const char* pConfigDirName = "Debug"; + #else + const char* pConfigDirName = "Release"; + #endif + + #if defined(_MSC_VER) + #if defined(_WIN64) + const char* pArchDirName = "x64"; + #else + const char* pArchDirName = "Win32"; + #endif + #else + #if defined(__x86_64__) + const char* pArchDirName = "x86_64"; + #else + const char* pArchDirName = "i386"; + #endif + #endif + + #if defined(_MSC_VER) && (_MSC_VER == 1600) + const char* pCompilerVersion = "VS2010"; + #elif defined(_MSC_VER) && (_MSC_VER == 1700) + const char* pCompilerVersion = "VS2012"; + #elif defined(_MSC_VER) && (_MSC_VER == 1800) + const char* pCompilerVersion = "VS2013"; + #elif defined(_MSC_VER) && (_MSC_VER == 1900) + const char* pCompilerVersion = "VS2014"; + #endif + + #if defined(_WIN32) + int count = swprintf_s(developerDir, OVR_MAX_PATH, L"%hs\\LibOVR\\Lib\\Windows\\%hs\\%hs\\%hs\\", + sdkRoot, pArchDirName, pConfigDirName, pCompilerVersion); + #elif defined(__APPLE__) + // Apple/XCode doesn't let you specify an arch in build paths, which is OK if we build a universal binary. + (void)pArchDirName; + int count = snprintf(developerDir, OVR_MAX_PATH, "%s/LibOVR/Lib/Mac/%s/", + sdkRoot, pConfigDirName); + #else + int count = snprintf(developerDir, OVR_MAX_PATH, "%s/LibOVR/Lib/Linux/%s/%s/", + sdkRoot, pArchDirName, pConfigDirName); + #endif + + if((count < 0) || (count >= (int)OVR_MAX_PATH)) // If there was an error or capacity overflow... clear the string. + { + developerDir[0] = '\0'; + } + } + } + #endif // OVR_ENABLE_DEVELOPER_SEARCH + + { + FilePathCharType cwDir[OVR_MAX_PATH]; // Will be filled in below. + FilePathCharType appDir[OVR_MAX_PATH]; + size_t i; + + #if defined(_WIN32) + FilePathCharType moduleDir[OVR_MAX_PATH]; + FilePathCharType* directoryArray[5]; + directoryArray[0] = cwDir; + directoryArray[1] = moduleDir; + directoryArray[2] = appDir; + directoryArray[3] = developerDir; // Developer directory. + directoryArray[4] = L""; // No directory, which causes Windows to use the standard search strategy to find the DLL. + + OVR_GetCurrentModuleDirectory(moduleDir, sizeof(moduleDir)/sizeof(moduleDir[0]), ovrTrue); + + #elif defined(__APPLE__) + // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/dyld.1.html + + FilePathCharType homeDir[OVR_MAX_PATH]; + FilePathCharType homeFrameworkDir[OVR_MAX_PATH]; + FilePathCharType* directoryArray[5]; + size_t homeDirLength = 0; + + const char* pHome = getenv("HOME"); // Try getting the HOME environment variable. + + if (pHome) + { + homeDirLength = OVR_strlcpy(homeDir, pHome, sizeof(homeDir)); + } + else + { + // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man3/getpwuid_r.3.html + const long pwBufferSize = sysconf(_SC_GETPW_R_SIZE_MAX); + + if (pwBufferSize != -1) + { + char pwBuffer[pwBufferSize]; + struct passwd pw; + struct passwd* pwResult = NULL; + + if ((getpwuid_r(getuid(), &pw, pwBuffer, pwBufferSize, &pwResult) == 0) && pwResult) + homeDirLength = OVR_strlcpy(homeDir, pw.pw_dir, sizeof(homeDir)); + } + } + + if (homeDirLength) + { + if (homeDir[homeDirLength - 1] == '/') + homeDir[homeDirLength - 1] = '\0'; + OVR_strlcpy(homeFrameworkDir, homeDir, sizeof(homeFrameworkDir)); + OVR_strlcat(homeFrameworkDir, "/Library/Frameworks/", sizeof(homeFrameworkDir)); + } + else + { + homeFrameworkDir[0] = '\0'; + } + + directoryArray[0] = cwDir; + directoryArray[1] = appDir; + directoryArray[2] = homeFrameworkDir; // ~/Library/Frameworks/ + directoryArray[3] = "/Library/Frameworks/"; // DYLD_FALLBACK_FRAMEWORK_PATH + directoryArray[4] = developerDir; // Developer directory. + + #else + #define STR1(x) #x + #define STR(x) STR1(x) + #ifdef LIBDIR + #define TEST_LIB_DIR STR(LIBDIR) "/" + #else + #define TEST_LIB_DIR appDir + #endif + + FilePathCharType* directoryArray[5]; + directoryArray[0] = cwDir; + directoryArray[1] = TEST_LIB_DIR; // Directory specified by LIBDIR if defined. + directoryArray[2] = developerDir; // Developer directory. + directoryArray[3] = "/usr/local/lib/"; + directoryArray[4] = "/usr/lib/"; + #endif + + OVR_GetCurrentWorkingDirectory(cwDir, sizeof(cwDir) / sizeof(cwDir[0])); + OVR_GetCurrentApplicationDirectory(appDir, sizeof(appDir) / sizeof(appDir[0]), ovrTrue, NULL); + + // Versioned file expectations. + // Windows: LibOVRRT__.dll // Example: LibOVRRT64_1_1.dll -- LibOVRRT 64 bit, product 1, major version 1, minor/patch/build numbers unspecified in the name. + // Mac: LibOVRRT_.framework/Versions//LibOVRRT_ // We are not presently using the .framework bundle's Current directory to hold the version number. This may change. + // Linux: libOVRRT_.so. // The file on disk may contain a minor version number, but a symlink is used to map this major-only version to it. + + // Since we are manually loading the LibOVR dynamic library, we need to look in various locations for a file + // that matches our requirements. The functionality required is somewhat similar to the operating system's + // dynamic loader functionality. Each OS has some differences in how this is handled. + // Future versions of this may iterate over all libOVRRT.so.* files in the directory and use the one that matches our requirements. + // + // We need to look for a library that matches the product version and major version of the caller's request, + // and that library needs to support a minor version that is >= the requested minor version. Currently we + // don't test the minor version here, as the library is named based only on the product and major version. + // Currently the minor version test is handled via the initialization of the library and the initialization + // fails if minor version cannot be supported by the library. The reason this is done during initialization + // is that the library can at runtime support multiple minor versions based on the user's request. To the + // external user, all that matters it that they call ovr_Initialize with a requested version and it succeeds + // or fails. + // + // The product version is something that is at a higher level than the major version, and is not something that's + // always seen in libraries (an example is the well-known LibXml2 library, in which the 2 is essentially the product version). + + for(i = 0; i < sizeof(directoryArray)/sizeof(directoryArray[0]); ++i) + { + #if defined(_WIN32) + printfResult = swprintf(libraryPath, libraryPathCapacity, L"%lsLibOVRRT%hs_%d_%d.dll", directoryArray[i], pBitDepth, requestedProductVersion, requestedMajorVersion); + + #elif defined(__APPLE__) + // https://developer.apple.com/library/mac/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/VersionInformation.html + // Macintosh application bundles have the option of embedding dependent frameworks within the application + // bundle itself. A problem with that is that it doesn't support vendor-supplied updates to the framework. + printfResult = snprintf(libraryPath, libraryPathCapacity, "%sLibOVRRT_%d.framework/Versions/%d/LibOVRRT_%d", directoryArray[i], requestedProductVersion, requestedMajorVersion, requestedProductVersion); + + #else // Unix + // Applications that depend on the OS (e.g. ld-linux / ldd) can rely on the library being in a common location + // such as /usr/lib or can rely on the -rpath linker option to embed a path for the OS to check for the library, + // or can rely on the LD_LIBRARY_PATH environment variable being set. It's generally not recommended that applications + // depend on LD_LIBRARY_PATH be globally modified, partly due to potentialy security issues. + // Currently we check the current application directory, current working directory, and then /usr/lib and possibly others. + printfResult = snprintf(libraryPath, libraryPathCapacity, "%slibOVRRT%s_%d.so.%d", directoryArray[i], pBitDepth, requestedProductVersion, requestedMajorVersion); + #endif + + if((printfResult >= 0) && (printfResult < (int)libraryPathCapacity)) + { + moduleHandle = OVR_OpenLibrary(libraryPath); + if(moduleHandle != ModuleHandleTypeNull) + return moduleHandle; + } + } + } + + return moduleHandle; +} + + + +//----------------------------------------------------------------------------------- +// ***** hLibOVR +// +// global handle to the LivOVR shared library. +// +static ModuleHandleType hLibOVR = NULL; + +// This function is currently unsupported. +ModuleHandleType ovr_GetLibOVRRTHandle() +{ + return hLibOVR; +} + + + +//----------------------------------------------------------------------------------- +// ***** Function declarations +// +// To consider: Move OVR_DECLARE_IMPORT and the declarations below to OVR_CAPI.h +// +//OVR_DECLARE_IMPORT(ovrBool, ovr_InitializeRenderingShim, ()) +OVR_DECLARE_IMPORT(ovrBool, ovr_InitializeRenderingShimVersion, (int requestedMinorVersion)) +OVR_DECLARE_IMPORT(ovrBool, ovr_Initialize, (ovrInitParams const* params)) +OVR_DECLARE_IMPORT(ovrBool, ovr_Shutdown, ()) +OVR_DECLARE_IMPORT(const char*, ovr_GetVersionString, ()) +OVR_DECLARE_IMPORT(int, ovrHmd_Detect, ()) +OVR_DECLARE_IMPORT(ovrHmd, ovrHmd_Create, (int index)) +OVR_DECLARE_IMPORT(void, ovrHmd_Destroy, (ovrHmd hmd)) +OVR_DECLARE_IMPORT(ovrHmd, ovrHmd_CreateDebug, (ovrHmdType type)) +OVR_DECLARE_IMPORT(const char*, ovrHmd_GetLastError, (ovrHmd hmd)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_AttachToWindow, (ovrHmd hmd, void* window, const ovrRecti* destMirrorRect, const ovrRecti* sourceRenderTargetRect)) +OVR_DECLARE_IMPORT(unsigned int, ovrHmd_GetEnabledCaps, (ovrHmd hmd)) +OVR_DECLARE_IMPORT(void, ovrHmd_SetEnabledCaps, (ovrHmd hmd, unsigned int hmdCaps)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_ConfigureTracking, (ovrHmd hmd, unsigned int supportedTrackingCaps, unsigned int requiredTrackingCaps)) +OVR_DECLARE_IMPORT(void, ovrHmd_RecenterPose, (ovrHmd hmd)) +OVR_DECLARE_IMPORT(ovrTrackingState, ovrHmd_GetTrackingState, (ovrHmd hmd, double absTime)) +OVR_DECLARE_IMPORT(ovrSizei, ovrHmd_GetFovTextureSize, (ovrHmd hmd, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_ConfigureRendering, ( ovrHmd hmd, const ovrRenderAPIConfig* apiConfig, unsigned int distortionCaps, const ovrFovPort eyeFovIn[2], ovrEyeRenderDesc eyeRenderDescOut[2] )) +OVR_DECLARE_IMPORT(ovrFrameTiming, ovrHmd_BeginFrame, (ovrHmd hmd, unsigned int frameIndex)) +OVR_DECLARE_IMPORT(void, ovrHmd_EndFrame, (ovrHmd hmd, const ovrPosef renderPose[2], const ovrTexture eyeTexture[2])) +OVR_DECLARE_IMPORT(void, ovrHmd_GetEyePoses, (ovrHmd hmd, unsigned int frameIndex, const ovrVector3f hmdToEyeViewOffset[2], ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState)) +OVR_DECLARE_IMPORT(ovrPosef, ovrHmd_GetHmdPosePerEye, (ovrHmd hmd, ovrEyeType eye)) +OVR_DECLARE_IMPORT(ovrEyeRenderDesc, ovrHmd_GetRenderDesc, (ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_CreateDistortionMesh, (ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, ovrDistortionMesh *meshData)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_CreateDistortionMeshDebug, (ovrHmd hmddesc, ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, ovrDistortionMesh *meshData, float debugEyeReliefOverrideInMetres)) +OVR_DECLARE_IMPORT(void, ovrHmd_DestroyDistortionMesh, (ovrDistortionMesh* meshData )) +OVR_DECLARE_IMPORT(void, ovrHmd_GetRenderScaleAndOffset, (ovrFovPort fov, ovrSizei textureSize, ovrRecti renderViewport, ovrVector2f uvScaleOffsetOut[2] )) +OVR_DECLARE_IMPORT(ovrFrameTiming, ovrHmd_GetFrameTiming, (ovrHmd hmd, unsigned int frameIndex)) +OVR_DECLARE_IMPORT(ovrFrameTiming, ovrHmd_BeginFrameTiming, (ovrHmd hmd, unsigned int frameIndex)) +OVR_DECLARE_IMPORT(void, ovrHmd_EndFrameTiming, (ovrHmd hmd)) +OVR_DECLARE_IMPORT(void, ovrHmd_ResetFrameTiming, (ovrHmd hmd, unsigned int frameIndex)) +OVR_DECLARE_IMPORT(void, ovrHmd_GetEyeTimewarpMatrices, (ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2])) +OVR_DECLARE_IMPORT(void, ovrHmd_GetEyeTimewarpMatricesDebug, (ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrQuatf playerTorsoMotion, ovrMatrix4f twmOut[2], double debugTimingOffsetInSeconds)) +//OVR_DECLARE_IMPORT(ovrMatrix4f, ovrMatrix4f_Projection, (ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags)) +//OVR_DECLARE_IMPORT(ovrMatrix4f, ovrMatrix4f_OrthoSubProjection, (ovrMatrix4f projection, ovrVector2f orthoScale, float orthoDistance, float hmdToEyeViewOffsetX)) +OVR_DECLARE_IMPORT(double, ovr_GetTimeInSeconds, ()) +//OVR_DECLARE_IMPORT(double, ovr_WaitTillTime, (double absTime)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_ProcessLatencyTest, (ovrHmd hmd, unsigned char rgbColorOut[3])) +OVR_DECLARE_IMPORT(const char*, ovrHmd_GetLatencyTestResult, (ovrHmd hmd)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_GetLatencyTest2DrawColor, (ovrHmd hmddesc, unsigned char rgbColorOut[3])) +OVR_DECLARE_IMPORT(void, ovrHmd_GetHSWDisplayState, (ovrHmd hmd, ovrHSWDisplayState *hasWarningState)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_DismissHSWDisplay, (ovrHmd hmd)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_GetBool, (ovrHmd hmd, const char* propertyName, ovrBool defaultVal)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_SetBool, (ovrHmd hmd, const char* propertyName, ovrBool value)) +OVR_DECLARE_IMPORT(int, ovrHmd_GetInt, (ovrHmd hmd, const char* propertyName, int defaultVal)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_SetInt, (ovrHmd hmd, const char* propertyName, int value)) +OVR_DECLARE_IMPORT(float, ovrHmd_GetFloat, (ovrHmd hmd, const char* propertyName, float defaultVal)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_SetFloat, (ovrHmd hmd, const char* propertyName, float value)) +OVR_DECLARE_IMPORT(unsigned int, ovrHmd_GetFloatArray, (ovrHmd hmd, const char* propertyName, float values[], unsigned int arraySize)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_SetFloatArray, (ovrHmd hmd, const char* propertyName, float values[], unsigned int arraySize)) +OVR_DECLARE_IMPORT(const char*, ovrHmd_GetString, (ovrHmd hmd, const char* propertyName, const char* defaultVal)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_SetString, (ovrHmd hmddesc, const char* propertyName, const char* value)) +OVR_DECLARE_IMPORT(int, ovr_TraceMessage, (int level, const char* message)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_StartPerfLog, (ovrHmd hmd, const char* fileName, const char* userData1)) +OVR_DECLARE_IMPORT(ovrBool, ovrHmd_StopPerfLog, (ovrHmd hmd)) + +static ovrBool OVR_LoadSharedLibrary(int requestedMinorVersion, int requestedPatchVersion) +{ + FilePathCharType filePath[OVR_MAX_PATH]; + + if(hLibOVR) + return ovrTrue; + + hLibOVR = OVR_FindLibraryPath(requestedMinorVersion, requestedPatchVersion, + filePath, sizeof(filePath) / sizeof(filePath[0])); + if(!hLibOVR) + return ovrFalse; + + //OVR_GETFUNCTION(ovr_InitializeRenderingShim) // No longer exposed. + OVR_GETFUNCTION(ovr_InitializeRenderingShimVersion) + OVR_GETFUNCTION(ovr_Initialize) + OVR_GETFUNCTION(ovr_Shutdown) + OVR_GETFUNCTION(ovr_GetVersionString) + OVR_GETFUNCTION(ovrHmd_Detect) + OVR_GETFUNCTION(ovrHmd_Create) + OVR_GETFUNCTION(ovrHmd_Destroy) + OVR_GETFUNCTION(ovrHmd_CreateDebug) + OVR_GETFUNCTION(ovrHmd_GetLastError) + OVR_GETFUNCTION(ovrHmd_AttachToWindow) + OVR_GETFUNCTION(ovrHmd_GetEnabledCaps) + OVR_GETFUNCTION(ovrHmd_SetEnabledCaps) + OVR_GETFUNCTION(ovrHmd_ConfigureTracking) + OVR_GETFUNCTION(ovrHmd_RecenterPose) + OVR_GETFUNCTION(ovrHmd_GetTrackingState) + OVR_GETFUNCTION(ovrHmd_GetFovTextureSize) + OVR_GETFUNCTION(ovrHmd_ConfigureRendering) + OVR_GETFUNCTION(ovrHmd_BeginFrame) + OVR_GETFUNCTION(ovrHmd_EndFrame) + OVR_GETFUNCTION(ovrHmd_GetEyePoses) + OVR_GETFUNCTION(ovrHmd_GetHmdPosePerEye) + OVR_GETFUNCTION(ovrHmd_GetRenderDesc) + OVR_GETFUNCTION(ovrHmd_CreateDistortionMesh) + OVR_GETFUNCTION(ovrHmd_CreateDistortionMeshDebug) + OVR_GETFUNCTION(ovrHmd_DestroyDistortionMesh) + OVR_GETFUNCTION(ovrHmd_GetRenderScaleAndOffset) + OVR_GETFUNCTION(ovrHmd_GetFrameTiming) + OVR_GETFUNCTION(ovrHmd_BeginFrameTiming) + OVR_GETFUNCTION(ovrHmd_EndFrameTiming) + OVR_GETFUNCTION(ovrHmd_ResetFrameTiming) + OVR_GETFUNCTION(ovrHmd_GetEyeTimewarpMatrices) + OVR_GETFUNCTION(ovrHmd_GetEyeTimewarpMatricesDebug) + //OVR_GETFUNCTION(ovrMatrix4f_Projection) + //OVR_GETFUNCTION(ovrMatrix4f_OrthoSubProjection) + OVR_GETFUNCTION(ovr_GetTimeInSeconds) + //OVR_GETFUNCTION(ovr_WaitTillTime) + OVR_GETFUNCTION(ovrHmd_ProcessLatencyTest) + OVR_GETFUNCTION(ovrHmd_GetLatencyTestResult) + OVR_GETFUNCTION(ovrHmd_GetLatencyTest2DrawColor) + OVR_GETFUNCTION(ovrHmd_GetHSWDisplayState) + OVR_GETFUNCTION(ovrHmd_DismissHSWDisplay) + OVR_GETFUNCTION(ovrHmd_GetBool) + OVR_GETFUNCTION(ovrHmd_SetBool) + OVR_GETFUNCTION(ovrHmd_GetInt) + OVR_GETFUNCTION(ovrHmd_SetInt) + OVR_GETFUNCTION(ovrHmd_GetFloat) + OVR_GETFUNCTION(ovrHmd_SetFloat) + OVR_GETFUNCTION(ovrHmd_GetFloatArray) + OVR_GETFUNCTION(ovrHmd_SetFloatArray) + OVR_GETFUNCTION(ovrHmd_GetString) + OVR_GETFUNCTION(ovrHmd_SetString) + OVR_GETFUNCTION(ovr_TraceMessage) + OVR_GETFUNCTION(ovrHmd_StartPerfLog) + OVR_GETFUNCTION(ovrHmd_StopPerfLog) + + return ovrTrue; +} + +static void OVR_UnloadSharedLibrary() +{ + // TBD: Currently there are some CAPI functions and code in the render shim that does + // not work with unloading the LibOVRRT. We also have the problem that LibOVR returns + // a string pointer in the GetLastError function. + //OVR_CloseLibrary(hLibOVR); + //hLibOVR = NULL; +} + + + +OVR_PUBLIC_FUNCTION(ovrBool) ovr_InitializeRenderingShim() +{ + return ovr_InitializeRenderingShimVersion(OVR_MINOR_VERSION); +} + + +OVR_PUBLIC_FUNCTION(ovrBool) ovr_InitializeRenderingShimVersion(int requestedMinorVersion) +{ + // By design we ignore the build version in the library search. + ovrBool result = OVR_LoadSharedLibrary(OVR_PRODUCT_VERSION, OVR_MAJOR_VERSION); + + if (!result) + return ovrFalse; + + result = ovr_InitializeRenderingShimVersionPtr(requestedMinorVersion); + + if (result == ovrFalse) + OVR_UnloadSharedLibrary(); + + return result; +} + + +// These defaults are also in CAPI.cpp +static const ovrInitParams DefaultParams = { + ovrInit_RequestVersion, // Flags + OVR_MINOR_VERSION, // RequestedMinorVersion + 0, // LogCallback + 0 // ConnectionTimeoutSeconds +}; + +OVR_PUBLIC_FUNCTION(ovrBool) ovr_Initialize(ovrInitParams const* inputParams) +{ + ovrBool result; + ovrInitParams params; + + if (!inputParams) + { + params = DefaultParams; + } + else + { + params = *inputParams; + + // If not requesting a particular minor version, + if (!(params.Flags & ovrInit_RequestVersion)) + { + // Enable requesting the default minor version. + params.Flags |= ovrInit_RequestVersion; + params.RequestedMinorVersion = OVR_MINOR_VERSION; + } + } + +#if defined(OVR_BUILD_DEBUG) + // If no debug setting is provided, + if (!(params.Flags & (ovrInit_Debug | ovrInit_ForceNoDebug))) + { + // Set the debug flag in debug mode. + params.Flags |= ovrInit_Debug; + } +#endif + + // By design we ignore the build version in the library search. + result = OVR_LoadSharedLibrary(OVR_PRODUCT_VERSION, OVR_MAJOR_VERSION); + if (!result) + return ovrFalse; + + result = ovr_InitializePtr(¶ms); + if (result == ovrFalse) + OVR_UnloadSharedLibrary(); + + return result; +} + +OVR_PUBLIC_FUNCTION(void) ovr_Shutdown() +{ + if (!ovr_ShutdownPtr) + return; + ovr_ShutdownPtr(); + OVR_UnloadSharedLibrary(); +} + +OVR_PUBLIC_FUNCTION(const char*) ovr_GetVersionString() +{ + if (!ovr_GetVersionStringPtr) + return "(Unable to load LibOVR)"; + return ovr_GetVersionStringPtr(); +} + +OVR_PUBLIC_FUNCTION(int) ovrHmd_Detect() +{ + if (!ovrHmd_DetectPtr) + return -1; + return ovrHmd_DetectPtr(); +} + +OVR_PUBLIC_FUNCTION(ovrHmd) ovrHmd_Create(int index) +{ + if (!ovrHmd_CreatePtr) + return 0; + return ovrHmd_CreatePtr(index); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_Destroy(ovrHmd hmd) +{ + if (!ovrHmd_DestroyPtr) + return; + ovrHmd_DestroyPtr(hmd); +} + +OVR_PUBLIC_FUNCTION(ovrHmd) ovrHmd_CreateDebug(ovrHmdType type) +{ + if (!ovrHmd_CreateDebugPtr) + return 0; + return ovrHmd_CreateDebugPtr(type); +} + +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetLastError(ovrHmd hmd) +{ + if (!ovrHmd_GetLastErrorPtr) + return "(Unable to load LibOVR)"; + return ovrHmd_GetLastErrorPtr(hmd); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_AttachToWindow(ovrHmd hmd, void* window, + const ovrRecti* destMirrorRect, const ovrRecti* sourceRenderTargetRect) +{ + if (!ovrHmd_AttachToWindowPtr) + return ovrFalse; + return ovrHmd_AttachToWindowPtr(hmd, window, destMirrorRect, sourceRenderTargetRect); +} + +OVR_PUBLIC_FUNCTION(unsigned int) ovrHmd_GetEnabledCaps(ovrHmd hmd) +{ + if (!ovrHmd_GetEnabledCapsPtr) + return 0; + return ovrHmd_GetEnabledCapsPtr(hmd); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_SetEnabledCaps(ovrHmd hmd, unsigned int hmdCaps) +{ + if (!ovrHmd_SetEnabledCapsPtr) + return; + ovrHmd_SetEnabledCapsPtr(hmd, hmdCaps); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ConfigureTracking(ovrHmd hmd, unsigned int supportedTrackingCaps, + unsigned int requiredTrackingCaps) +{ + if (!ovrHmd_ConfigureTrackingPtr) + return ovrFalse; + return ovrHmd_ConfigureTrackingPtr(hmd, supportedTrackingCaps, requiredTrackingCaps); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_RecenterPose(ovrHmd hmd) +{ + if (!ovrHmd_RecenterPosePtr) + return; + ovrHmd_RecenterPosePtr(hmd); +} + +OVR_PUBLIC_FUNCTION(ovrTrackingState) ovrHmd_GetTrackingState(ovrHmd hmd, double absTime) +{ + if (!ovrHmd_GetTrackingStatePtr) + { + static ovrTrackingState nullTrackingState; + memset(&nullTrackingState, 0, sizeof(nullTrackingState)); + return nullTrackingState; + } + + return ovrHmd_GetTrackingStatePtr(hmd, absTime); +} + + + +OVR_PUBLIC_FUNCTION(ovrSizei) ovrHmd_GetFovTextureSize(ovrHmd hmd, ovrEyeType eye, ovrFovPort fov, + float pixelsPerDisplayPixel) +{ + if (!ovrHmd_GetFovTextureSizePtr) + { + static ovrSizei nullSize; + memset(&nullSize, 0, sizeof(nullSize)); + return nullSize; + } + + return ovrHmd_GetFovTextureSizePtr(hmd, eye, fov, pixelsPerDisplayPixel); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ConfigureRendering(ovrHmd hmd, const ovrRenderAPIConfig* apiConfig, unsigned int distortionCaps, + const ovrFovPort eyeFovIn[2], ovrEyeRenderDesc eyeRenderDescOut[2]) +{ + if (!ovrHmd_ConfigureRenderingPtr) + return ovrFalse; + return ovrHmd_ConfigureRenderingPtr(hmd, apiConfig, distortionCaps, eyeFovIn, eyeRenderDescOut); +} + +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_BeginFrame(ovrHmd hmd, unsigned int frameIndex) +{ + if (!ovrHmd_BeginFramePtr) + { + static ovrFrameTiming nullFrameTiming; + memset(&nullFrameTiming, 0, sizeof(nullFrameTiming)); + return nullFrameTiming; + } + return ovrHmd_BeginFramePtr(hmd, frameIndex); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_EndFrame(ovrHmd hmd, const ovrPosef renderPose[2], const ovrTexture eyeTexture[2]) +{ + if (!ovrHmd_EndFramePtr) + return; + ovrHmd_EndFramePtr(hmd, renderPose, eyeTexture); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyePoses(ovrHmd hmd, unsigned int frameIndex, const ovrVector3f hmdToEyeViewOffset[2], + ovrPosef outEyePoses[2], ovrTrackingState* outHmdTrackingState) +{ + if (!ovrHmd_GetEyePosesPtr) + return; + ovrHmd_GetEyePosesPtr(hmd, frameIndex, hmdToEyeViewOffset, outEyePoses, outHmdTrackingState); +} + +OVR_PUBLIC_FUNCTION(ovrPosef) ovrHmd_GetHmdPosePerEye(ovrHmd hmd, ovrEyeType eye) +{ + if (!ovrHmd_GetHmdPosePerEyePtr) + { + static ovrPosef nullPose; + memset(&nullPose, 0, sizeof(nullPose)); + nullPose.Orientation.w = 1.0f; // Return a proper quaternion. + return nullPose; + } + return ovrHmd_GetHmdPosePerEyePtr(hmd, eye); +} + +OVR_PUBLIC_FUNCTION(ovrEyeRenderDesc) ovrHmd_GetRenderDesc(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov) +{ + if (!ovrHmd_GetRenderDescPtr) + { + static ovrEyeRenderDesc nullEyeRenderDesc; + memset(&nullEyeRenderDesc, 0, sizeof(nullEyeRenderDesc)); + return nullEyeRenderDesc; + } + return ovrHmd_GetRenderDescPtr(hmd, eyeType, fov); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_CreateDistortionMesh(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov, + unsigned int distortionCaps, ovrDistortionMesh *meshData) +{ + if (!ovrHmd_CreateDistortionMeshPtr) + return ovrFalse; + return ovrHmd_CreateDistortionMeshPtr(hmd, eyeType, fov, distortionCaps, meshData); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_CreateDistortionMeshDebug(ovrHmd hmd, ovrEyeType eyeType, ovrFovPort fov, unsigned int distortionCaps, + ovrDistortionMesh *meshData, float debugEyeReliefOverrideInMetres) +{ + if (!ovrHmd_CreateDistortionMeshDebugPtr) + return ovrFalse; + return ovrHmd_CreateDistortionMeshDebugPtr(hmd, eyeType, fov, distortionCaps, meshData, debugEyeReliefOverrideInMetres); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_DestroyDistortionMesh(ovrDistortionMesh* meshData) +{ + if (!ovrHmd_DestroyDistortionMeshPtr) + return; + ovrHmd_DestroyDistortionMeshPtr(meshData); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetRenderScaleAndOffset(ovrFovPort fov, ovrSizei textureSize, ovrRecti renderViewport, + ovrVector2f uvScaleOffsetOut[2]) +{ + if (!ovrHmd_GetRenderScaleAndOffsetPtr) + return; + ovrHmd_GetRenderScaleAndOffsetPtr(fov, textureSize, renderViewport, uvScaleOffsetOut); +} + +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_GetFrameTiming(ovrHmd hmd, unsigned int frameIndex) +{ + if (!ovrHmd_GetFrameTimingPtr) + { + static ovrFrameTiming nullFrameTiming; + memset(&nullFrameTiming, 0, sizeof(nullFrameTiming)); + return nullFrameTiming; + } + return ovrHmd_GetFrameTimingPtr(hmd, frameIndex); +} + +OVR_PUBLIC_FUNCTION(ovrFrameTiming) ovrHmd_BeginFrameTiming(ovrHmd hmd, unsigned int frameIndex) +{ + if (!ovrHmd_BeginFrameTimingPtr) +{ + static ovrFrameTiming nullFrameTiming; + memset(&nullFrameTiming, 0, sizeof(nullFrameTiming)); + return nullFrameTiming; + } + return ovrHmd_BeginFrameTimingPtr(hmd, frameIndex); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_EndFrameTiming(ovrHmd hmd) +{ + if (!ovrHmd_EndFrameTimingPtr) + return; + ovrHmd_EndFrameTimingPtr(hmd); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_ResetFrameTiming(ovrHmd hmd, unsigned int frameIndex) +{ + if (!ovrHmd_ResetFrameTimingPtr) + return; + ovrHmd_ResetFrameTimingPtr(hmd, frameIndex); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyeTimewarpMatrices(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, ovrMatrix4f twmOut[2]) +{ + if (!ovrHmd_GetEyeTimewarpMatricesPtr) + return; + ovrHmd_GetEyeTimewarpMatricesPtr(hmd, eye, renderPose, twmOut); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetEyeTimewarpMatricesDebug(ovrHmd hmd, ovrEyeType eye, ovrPosef renderPose, + ovrQuatf playerTorsoMotion, ovrMatrix4f twmOut[2], double debugTimingOffsetInSeconds) +{ + if (!ovrHmd_GetEyeTimewarpMatricesDebugPtr) + return; + ovrHmd_GetEyeTimewarpMatricesDebugPtr(hmd, eye, renderPose, playerTorsoMotion, twmOut, debugTimingOffsetInSeconds); +} + +/* +OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags) +{ + if (!ovrMatrix4f_ProjectionPtr) + { + static ovrMatrix4f nullMatrix; + memset(&nullMatrix, 0, sizeof(nullMatrix)); + return nullMatrix; + } + return ovrMatrix4f_ProjectionPtr(fov, znear, zfar, projectionModFlags); +} +*/ + +/* +OVR_PUBLIC_FUNCTION(ovrMatrix4f) ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale, + float orthoDistance, float hmdToEyeViewOffsetX) +{ + if (!ovrMatrix4f_OrthoSubProjectionPtr) + { + static ovrMatrix4f nullMatrix; + memset(&nullMatrix, 0, sizeof(nullMatrix)); + return nullMatrix; + } + return ovrMatrix4f_OrthoSubProjectionPtr(projection, orthoScale, orthoDistance, hmdToEyeViewOffsetX); +} +*/ + +OVR_PUBLIC_FUNCTION(double) ovr_GetTimeInSeconds() +{ + if (!ovr_GetTimeInSecondsPtr) + return 0.; + return ovr_GetTimeInSecondsPtr(); +} + +/* +OVR_PUBLIC_FUNCTION(double) ovr_WaitTillTime(double absTime) +{ + if (!ovr_WaitTillTimePtr) + return 0.; + return ovr_WaitTillTimePtr(absTime); +} +*/ + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_ProcessLatencyTest(ovrHmd hmd, unsigned char rgbColorOut[3]) +{ + if (!ovrHmd_ProcessLatencyTestPtr) + return ovrFalse; + return ovrHmd_ProcessLatencyTestPtr(hmd, rgbColorOut); +} + +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetLatencyTestResult(ovrHmd hmd) +{ + if (!ovrHmd_GetLatencyTestResultPtr) + return "(Unable to load LibOVR)"; + return ovrHmd_GetLatencyTestResultPtr(hmd); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetLatencyTest2DrawColor(ovrHmd hmd, unsigned char rgbColorOut[3]) +{ + if (!ovrHmd_GetLatencyTest2DrawColorPtr) + return ovrFalse; + return ovrHmd_GetLatencyTest2DrawColorPtr(hmd, rgbColorOut); +} + +OVR_PUBLIC_FUNCTION(void) ovrHmd_GetHSWDisplayState(ovrHmd hmd, ovrHSWDisplayState *hasWarningState) +{ + if (!ovrHmd_GetHSWDisplayStatePtr) + return; + ovrHmd_GetHSWDisplayStatePtr(hmd, hasWarningState); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_DismissHSWDisplay(ovrHmd hmd) +{ + if (!ovrHmd_DismissHSWDisplayPtr) + return ovrFalse; + return ovrHmd_DismissHSWDisplayPtr(hmd); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_GetBool(ovrHmd hmd, const char* propertyName, ovrBool defaultVal) +{ + if (!ovrHmd_GetBoolPtr) + return ovrFalse; + return ovrHmd_GetBoolPtr(hmd, propertyName, defaultVal); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetBool(ovrHmd hmd, const char* propertyName, ovrBool value) +{ + if (!ovrHmd_SetBoolPtr) + return ovrFalse; + return ovrHmd_SetBoolPtr(hmd, propertyName, value); +} + +OVR_PUBLIC_FUNCTION(int) ovrHmd_GetInt(ovrHmd hmd, const char* propertyName, int defaultVal) +{ + if (!ovrHmd_GetIntPtr) + return 0; + return ovrHmd_GetIntPtr(hmd, propertyName, defaultVal); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetInt(ovrHmd hmd, const char* propertyName, int value) +{ + if (!ovrHmd_SetIntPtr) + return ovrFalse; + return ovrHmd_SetIntPtr(hmd, propertyName, value); +} + +OVR_PUBLIC_FUNCTION(float) ovrHmd_GetFloat(ovrHmd hmd, const char* propertyName, float defaultVal) +{ + if (!ovrHmd_GetFloatPtr) + return 0.f; + return ovrHmd_GetFloatPtr(hmd, propertyName, defaultVal); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetFloat(ovrHmd hmd, const char* propertyName, float value) +{ + if (!ovrHmd_SetFloatPtr) + return ovrFalse; + return ovrHmd_SetFloatPtr(hmd, propertyName, value); +} + +OVR_PUBLIC_FUNCTION(unsigned int) ovrHmd_GetFloatArray(ovrHmd hmd, const char* propertyName, + float values[], unsigned int arraySize) +{ + if (!ovrHmd_GetFloatArrayPtr) + return 0; + return ovrHmd_GetFloatArrayPtr(hmd, propertyName, values, arraySize); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetFloatArray(ovrHmd hmd, const char* propertyName, + float values[], unsigned int arraySize) +{ + if (!ovrHmd_SetFloatArrayPtr) + return ovrFalse; + return ovrHmd_SetFloatArrayPtr(hmd, propertyName, values, arraySize); +} + +OVR_PUBLIC_FUNCTION(const char*) ovrHmd_GetString(ovrHmd hmd, const char* propertyName, + const char* defaultVal) +{ + if (!ovrHmd_GetStringPtr) + return "(Unable to load LibOVR)"; + return ovrHmd_GetStringPtr(hmd, propertyName, defaultVal); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_SetString(ovrHmd hmd, const char* propertyName, + const char* value) +{ + if (!ovrHmd_SetStringPtr) + return ovrFalse; + return ovrHmd_SetStringPtr(hmd, propertyName, value); +} + +OVR_PUBLIC_FUNCTION(int) ovr_TraceMessage(int level, const char* message) +{ + if (!ovr_TraceMessagePtr) + return -1; + + return ovr_TraceMessagePtr(level, message); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_StartPerfLog(ovrHmd hmd, const char* fileName, const char* userData1) +{ + if (!ovrHmd_StartPerfLogPtr) + return ovrFalse; + return ovrHmd_StartPerfLogPtr(hmd, fileName, userData1); +} + +OVR_PUBLIC_FUNCTION(ovrBool) ovrHmd_StopPerfLog(ovrHmd hmd) +{ + if (!ovrHmd_StopPerfLogPtr) + return ovrFalse; + return ovrHmd_StopPerfLogPtr(hmd); +} + + + +#if defined(_MSC_VER) + #pragma warning(pop) +#endif + diff --git a/LibOVR/Src/OVR_CAPI_D3D.h b/LibOVR/Src/OVR_CAPI_D3D.h deleted file mode 100644 index 25a6b2e..0000000 --- a/LibOVR/Src/OVR_CAPI_D3D.h +++ /dev/null @@ -1,176 +0,0 @@ -/************************************************************************************ - -Filename : OVR_CAPI_D3D.h -Content : D3D specific structures used by the CAPI interface. -Created : November 7, 2013 -Authors : Michael Antonov - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ -#ifndef OVR_CAPI_D3D_h -#define OVR_CAPI_D3D_h - -/// @file OVR_CAPI_D3D.h -/// D3D rendering support. - -#include "OVR_CAPI.h" - -#ifndef OVR_D3D_VERSION -#error Please define OVR_D3D_VERSION to 9 or 10 or 11 before including OVR_CAPI_D3D.h -#endif - - -#if defined(OVR_D3D_VERSION) && (OVR_D3D_VERSION == 11) - -//----------------------------------------------------------------------------------- -// ***** D3D11 Specific - -#if defined(OVR_OS_WIN32) // Desktop Windows only. -#include -#endif - -/// Used to configure slave D3D rendering (i.e. for devices created externally). -struct OVR_ALIGNAS(8) ovrD3D11ConfigData -{ - /// General device settings. - ovrRenderAPIConfigHeader Header; - /// The D3D device to use for rendering. - ID3D11Device* pDevice; - /// The D3D device context to use for rendering. - ID3D11DeviceContext* pDeviceContext; - /// A render target view for the backbuffer. - ID3D11RenderTargetView* pBackBufferRT; - /// A UAV for the backbuffer (if using compute shaders) - ID3D11UnorderedAccessView* pBackBufferUAV; - /// The swapchain that will present rendered frames. - IDXGISwapChain* pSwapChain; -}; - -/// Contains D3D11-specific rendering information. -union ovrD3D11Config -{ - /// General device settings. - ovrRenderAPIConfig Config; - /// D3D11-specific settings. - ovrD3D11ConfigData D3D11; -}; - -/// Used to pass D3D11 eye texture data to ovrHmd_EndFrame. -struct OVR_ALIGNAS(8) ovrD3D11TextureData -{ - /// General device settings. - ovrTextureHeader Header; - /// The D3D11 texture containing the undistorted eye image. - ID3D11Texture2D* pTexture; - /// The D3D11 shader resource view for this texture. - ID3D11ShaderResourceView* pSRView; -}; - -/// Contains OpenGL-specific texture information. -union ovrD3D11Texture -{ - /// General device settings. - ovrTexture Texture; - /// D3D11-specific settings. - ovrD3D11TextureData D3D11; -}; - - - -#elif defined(OVR_D3D_VERSION) && (OVR_D3D_VERSION == 10) - -#include -#include - -//----------------------------------------------------------------------------------- -// ***** D3D10 Specific - -/// Used to configure slave D3D rendering (i.e. for devices created externally). -struct OVR_ALIGNAS(8) ovrD3D10ConfigData -{ - /// General device settings. - ovrRenderAPIConfigHeader Header; - ID3D10Device* pDevice; - void* Unused1; // pDeviceContext in DX11 - ID3D10RenderTargetView* pBackBufferRT; - void* Unused2; // pBackBufferUAV in DX11 - IDXGISwapChain* pSwapChain; -}; - -union ovrD3D10Config -{ - ovrRenderAPIConfig Config; - ovrD3D10ConfigData D3D10; -}; - -/// Used to pass D3D10 eye texture data to ovrHmd_EndFrame. -struct OVR_ALIGNAS(8) ovrD3D10TextureData -{ - /// General device settings. - ovrTextureHeader Header; - ID3D10Texture2D* pTexture; - ID3D10ShaderResourceView* pSRView; -}; - -union ovrD3D10Texture -{ - ovrTexture Texture; - ovrD3D10TextureData D3D10; -}; - -#elif defined(OVR_D3D_VERSION) && (OVR_D3D_VERSION == 9) - -#include - -//----------------------------------------------------------------------------------- -// ***** D3D9 Specific - -// Used to configure D3D9 rendering -struct OVR_ALIGNAS(8) ovrD3D9ConfigData -{ - // General device settings. - ovrRenderAPIConfigHeader Header; - - IDirect3DDevice9* pDevice; - IDirect3DSwapChain9* pSwapChain; -}; - -union ovrD3D9Config -{ - ovrRenderAPIConfig Config; - ovrD3D9ConfigData D3D9; -}; - -// Used to pass D3D9 eye texture data to ovrHmd_EndFrame. -struct OVR_ALIGNAS(8) ovrD3D9TextureData -{ - // General device settings. - ovrTextureHeader Header; - IDirect3DTexture9* pTexture; -}; - -union ovrD3D9Texture -{ - ovrTexture Texture; - ovrD3D9TextureData D3D9; -}; - -#endif - -#endif // OVR_CAPI_h diff --git a/LibOVR/Src/OVR_CAPI_GL.h b/LibOVR/Src/OVR_CAPI_GL.h deleted file mode 100644 index 2aa846f..0000000 --- a/LibOVR/Src/OVR_CAPI_GL.h +++ /dev/null @@ -1,76 +0,0 @@ -/************************************************************************************ - -Filename : OVR_CAPI_GL.h -Content : GL specific structures used by the CAPI interface. -Created : November 7, 2013 -Authors : Lee Cooper - -Copyright : Copyright 2013 Oculus VR, LLC. All Rights reserved. - -Use of this software is subject to the terms of the Oculus Inc license -agreement provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -************************************************************************************/ -#ifndef OVR_CAPI_GL_h -#define OVR_CAPI_GL_h - -/// @file OVR_CAPI_GL.h -/// OpenGL rendering support. - -#include "OVR_CAPI.h" -#if defined(__APPLE__) - #include -#else - #include -#endif - - -/// Used to configure slave GL rendering (i.e. for devices created externally). -typedef struct OVR_ALIGNAS(8) ovrGLConfigData_s -{ - /// General device settings. - ovrRenderAPIConfigHeader Header; - -#if defined(OVR_OS_WIN32) - /// The optional window handle. If unset, rendering will use the current window. - HWND Window; - /// The optional device context. If unset, rendering will use a new context. - HDC DC; -#elif defined (OVR_OS_LINUX) - /// Optional display. If unset, will issue glXGetCurrentDisplay when context - /// is current. - struct _XDisplay* Disp; -#endif -} ovrGLConfigData; - -/// Contains OpenGL-specific rendering information. -union ovrGLConfig -{ - /// General device settings. - ovrRenderAPIConfig Config; - /// OpenGL-specific settings. - ovrGLConfigData OGL; -}; - -/// Used to pass GL eye texture data to ovrHmd_EndFrame. -typedef struct OVR_ALIGNAS(8) ovrGLTextureData_s -{ - /// General device settings. - ovrTextureHeader Header; - /// The OpenGL name for this texture. - GLuint TexId; -} ovrGLTextureData; - -static_assert(offsetof(ovrGLTextureData, TexId) == offsetof(ovrTexture, PlatformData), "Mismatch of structs that are presumed binary equivalents."); - -/// Contains OpenGL-specific texture information. -typedef union ovrGLTexture_s -{ - /// General device settings. - ovrTexture Texture; - /// OpenGL-specific settings. - ovrGLTextureData OGL; -} ovrGLTexture; - -#endif // OVR_CAPI_GL_h diff --git a/LibOVR/Src/OVR_CAPI_Keys.h b/LibOVR/Src/OVR_CAPI_Keys.h deleted file mode 100644 index 13451e5..0000000 --- a/LibOVR/Src/OVR_CAPI_Keys.h +++ /dev/null @@ -1,56 +0,0 @@ -/************************************************************************************ - -Filename : OVR_CAPI.h -Content : Keys for CAPI calls -Created : September 25, 2014 -Authors : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - - - -#define OVR_KEY_USER "User" // string -#define OVR_KEY_NAME "Name" // string -#define OVR_KEY_GENDER "Gender" // string -#define OVR_KEY_PLAYER_HEIGHT "PlayerHeight" // float -#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float -#define OVR_KEY_IPD "IPD" // float -#define OVR_KEY_NECK_TO_EYE_DISTANCE "NeckEyeDistance" // float[2] -#define OVR_KEY_EYE_RELIEF_DIAL "EyeReliefDial" // int -#define OVR_KEY_EYE_TO_NOSE_DISTANCE "EyeToNoseDist" // float[2] -#define OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE "MaxEyeToPlateDist" // float[2] -#define OVR_KEY_EYE_CUP "EyeCup" // char[16] -#define OVR_KEY_CUSTOM_EYE_RENDER "CustomEyeRender" // bool -#define OVR_KEY_CAMERA_POSITION "CenteredFromWorld" // double[7] - -// Default measurements empirically determined at Oculus to make us happy -// The neck model numbers were derived as an average of the male and female averages from ANSUR-88 -// NECK_TO_EYE_HORIZONTAL = H22 - H43 = INFRAORBITALE_BACK_OF_HEAD - TRAGION_BACK_OF_HEAD -// NECK_TO_EYE_VERTICAL = H21 - H15 = GONION_TOP_OF_HEAD - ECTOORBITALE_TOP_OF_HEAD -// These were determined to be the best in a small user study, clearly beating out the previous default values -#define OVR_DEFAULT_GENDER "Unknown" -#define OVR_DEFAULT_PLAYER_HEIGHT 1.778f -#define OVR_DEFAULT_EYE_HEIGHT 1.675f -#define OVR_DEFAULT_IPD 0.064f -#define OVR_DEFAULT_NECK_TO_EYE_HORIZONTAL 0.0805f -#define OVR_DEFAULT_NECK_TO_EYE_VERTICAL 0.075f -#define OVR_DEFAULT_EYE_RELIEF_DIAL 3 -#define OVR_DEFAULT_CAMERA_POSITION {0,0,0,1,0,0,0} - diff --git a/LibOVR/Src/OVR_CAPI_Util.cpp b/LibOVR/Src/OVR_CAPI_Util.cpp new file mode 100644 index 0000000..61ea56a --- /dev/null +++ b/LibOVR/Src/OVR_CAPI_Util.cpp @@ -0,0 +1,125 @@ +/************************************************************************************ + +PublicHeader: OVR_CAPI_Util.c +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + + +#include +#include "OVR_StereoProjection.h" + +#if defined(_MSC_VER) + #include + #pragma intrinsic(_mm_pause) +#endif + + + +// Used to generate projection from ovrEyeDesc::Fov +ovrMatrix4f ovrMatrix4f_Projection(ovrFovPort fov, float znear, float zfar, unsigned int projectionModFlags) +{ + bool rightHanded = (projectionModFlags & ovrProjection_RightHanded) > 0; + bool flipZ = (projectionModFlags & ovrProjection_FarLessThanNear) > 0; + bool farAtInfinity = (projectionModFlags & ovrProjection_FarClipAtInfinity) > 0; + bool isOpenGL = (projectionModFlags & ovrProjection_ClipRangeOpenGL) > 0; + + // TODO: Pass in correct eye to CreateProjection if we want to support canted displays from CAPI + return OVR::CreateProjection(rightHanded , isOpenGL, fov, OVR::StereoEye_Center, znear, zfar, flipZ, farAtInfinity); +} + + +ovrMatrix4f ovrMatrix4f_OrthoSubProjection(ovrMatrix4f projection, ovrVector2f orthoScale, + float orthoDistance, float hmdToEyeViewOffsetX) +{ + ovrMatrix4f ortho; + float orthoHorizontalOffset = hmdToEyeViewOffsetX / orthoDistance; + + /* + // Current projection maps real-world vector (x,y,1) to the RT. + // We want to find the projection that maps the range [-FovPixels/2,FovPixels/2] to + // the physical [-orthoHalfFov,orthoHalfFov] + // Note moving the offset from M[0][2]+M[1][2] to M[0][3]+M[1][3] - this means + // we don't have to feed in Z=1 all the time. + // The horizontal offset math is a little hinky because the destination is + // actually [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset] + // So we need to first map [-FovPixels/2,FovPixels/2] to + // [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]: + // x1 = x0 * orthoHalfFov/(FovPixels/2) + orthoHorizontalOffset; + // = x0 * 2*orthoHalfFov/FovPixels + orthoHorizontalOffset; + // But then we need the same mapping as the existing projection matrix, i.e. + // x2 = x1 * Projection.M[0][0] + Projection.M[0][2]; + // = x0 * (2*orthoHalfFov/FovPixels + orthoHorizontalOffset) * Projection.M[0][0] + Projection.M[0][2]; + // = x0 * Projection.M[0][0]*2*orthoHalfFov/FovPixels + + // orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]; + // So in the new projection matrix we need to scale by Projection.M[0][0]*2*orthoHalfFov/FovPixels and + // offset by orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]. + */ + + ortho.M[0][0] = projection.M[0][0] * orthoScale.x; + ortho.M[0][1] = 0.0f; + ortho.M[0][2] = 0.0f; + ortho.M[0][3] = -projection.M[0][2] + ( orthoHorizontalOffset * projection.M[0][0] ); + + ortho.M[1][0] = 0.0f; + ortho.M[1][1] = -projection.M[1][1] * orthoScale.y; /* Note sign flip (text rendering uses Y=down). */ + ortho.M[1][2] = 0.0f; + ortho.M[1][3] = -projection.M[1][2]; + + ortho.M[2][0] = 0.0f; + ortho.M[2][1] = 0.0f; + ortho.M[2][2] = 0.0f; + ortho.M[2][3] = 0.0f; + + /* No perspective correction for ortho. */ + ortho.M[3][0] = 0.0f; + ortho.M[3][1] = 0.0f; + ortho.M[3][2] = 0.0f; + ortho.M[3][3] = 1.0f; + + return ortho; +} + + +double ovr_WaitTillTime(double absTime) +{ + double initialTime = ovr_GetTimeInSeconds(); + double newTime = initialTime; + + while(newTime < absTime) + { + for (int j = 0; j < 5; j++) + { + #if defined(__x86_64__) || defined(_M_AMD64) || defined(__i386__) || defined(_M_IX86) // Intel architecture... + #if defined(__GNUC__) || defined(__clang__) + asm volatile("pause" ::: "memory"); + #elif defined(_MSC_VER) + _mm_pause(); + #endif + #endif + } + + newTime = ovr_GetTimeInSeconds(); + } + + return (newTime - initialTime); +} + + + + diff --git a/LibOVR/Src/OVR_Error.h b/LibOVR/Src/OVR_Error.h new file mode 100644 index 0000000..b019834 --- /dev/null +++ b/LibOVR/Src/OVR_Error.h @@ -0,0 +1,236 @@ +/************************************************************************************ + +Filename : OVR_Error.h +Content : Structs and functions for handling OVRErrors +Created : February 15, 2015 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Error_h +#define OVR_Error_h + + +#include "OVR_ErrorCode.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Array.h" +#include +#include + + +/// ----------------------------------------------------------------------------- +/// ***** OVR_FILE / OVR_LINE +/// +#if !defined(OVR_FILE) + #if defined(OVR_BUILD_DEBUG) + #define OVR_FILE __FILE__ + #define OVR_LINE __LINE__ + #else + #define OVR_FILE nullptr + #define OVR_LINE 0 + #endif +#endif + + +namespace OVR +{ + /// ----------------------------------------------------------------------------- + /// ***** OVR_MAKE_ERROR, OVR_MAKE_SYS_ERROR + /// + /// Declaration: + /// OVRError OVR_MAKE_ERROR(ovrResult code, const char* pDescription); + /// OVRError OVR_MAKE_SYS_ERROR(ovrResult code, ovrSysErrorCode sysCode, const char* pDescription); + /// + /// Example usage: + /// OVRError InitGraphics() + /// { + /// if(!GraphicsCardPresent()) + /// { + /// return OVR_MAKE_ERROR(ovrError_GraphicsInit, "Failed to init graphics; graphics support absent."); + /// } + /// + /// HRESULT hr = pDevice->CreateTexture2D(&dsDesc, nullptr, &Texture); + /// if(FAILED(hr)) + /// { + /// return OVR_MAKE_SYS_ERROR_F(ovrError_GraphicsInit, hr, "Failed to create texture of size %u x %u", dsDesc.Width, dsDesc.Height); + /// } + /// + /// return ovrSuccess; // Converts to an OVRError instance that has no error. + /// } + /// + #define OVR_MAKE_ERROR(errorCode, pDescription) \ + OVR::MakeError((errorCode), OVR::ovrSysErrorCodeSuccess, OVR_FILE, OVR_LINE, nullptr, "%s", (pDescription)) + + #define OVR_MAKE_ERROR_F(errorCode, pDescriptionFormat, ...) \ + OVR::MakeError((errorCode), OVR::ovrSysErrorCodeSuccess, OVR_FILE, OVR_LINE, nullptr, (pDescriptionFormat), __VA_ARGS__) + + + #define OVR_MAKE_SYS_ERROR(errorCode, sysErrorCode, pDescription) \ + OVR::MakeError((errorCode), (sysErrorCode), OVR_FILE, OVR_LINE, nullptr, "%s", (pDescriptionFormat)) + + #define OVR_MAKE_SYS_ERROR_F(errorCode, sysErrorCode, pDescriptionFormat, ...) \ + OVR::MakeError((errorCode), (sysErrorCode), OVR_FILE, OVR_LINE, nullptr, (pDescriptionFormat), __VA_ARGS__) + + + + + /// ----------------------------------------------------------------------------- + /// ***** ovrSysErrorCode + /// + /// Identifies a platform-specific error identifier. + /// For Windows this means an HRESULT or DWORD system error code from GetLastError. + /// For Unix this means errno. + /// + typedef uint32_t ovrSysErrorCode; + + + /// ----------------------------------------------------------------------------- + /// ***** ovrSysErrorCodeSuccess + /// + /// Identifies a ovrSysErrorCode that's success. + /// + const ovrSysErrorCode ovrSysErrorCodeSuccess = 0; + + + + // SysClockTime is a C++11 equivalent to C time_t. + typedef std::chrono::time_point SysClockTime; + + + + /// ----------------------------------------------------------------------------- + /// ***** OVRError + /// + /// Represents an error and relevant information about it. + /// While you can create error instances directly via this class, it's better if + /// you create them via the OVR_MAKE_ERROR family of macros, or at least via the + /// MakeError function. + /// + /// Relevant design analogues: + /// https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/ + /// https://msdn.microsoft.com/en-us/library/windows/desktop/ms723041%28v=vs.85%29.aspx + /// + class OVRError + { + public: + OVRError(); + OVRError(ovrResult code); // Intentionally not explicit. + + OVRError(const OVRError& OVRError); + OVRError(OVRError&& OVRError); + + virtual ~OVRError(); + + OVRError& operator=(const OVRError& OVRError); + OVRError& operator=(OVRError&& OVRError); + + operator bool() const; + + // Sets the OVRTime, ClockTime, Backtrace to current values. + void SetCurrentValues(); // To do: Come up with a more appropiate name. + + // Clears all members to a newly default-constructed state. + void Reset(); + + // Get the full error string for this error. May include newlines. + String GetErrorString() const; + + // Property accessors + void SetCode(ovrResult code); + ovrResult GetCode() const; + + void SetSysCode(ovrSysErrorCode sysCode); + ovrSysErrorCode GetSysCode() const; + + void SetDescription(const char* pDescription); + String GetDescription() const; + + void SetContext(const char* pContext); + String GetContext() const; + + void SetOVRTime(double ovrTime); + double GetOVRTime() const; + + void SetSysClockTime(const SysClockTime& clockTime); + SysClockTime GetSysClockTime() const; + + static const int64_t kLogLineUnset = -1; + void SetLogLine(int64_t logLine); + int64_t GetLogLine() const; + + void SetSource(const char* pSourceFilePath, int sourceFileLine); + std::pair GetSource() const; + + typedef OVR::Array AddressArray; + AddressArray GetBacktrace() const; + + protected: + ovrResult Code; /// The main ovrResult, which is a high level error id. + ovrSysErrorCode SysCode; /// May be ovrSysErrorCodeSuccess to indicate there isn't a relevant system error code. + String Description; /// Unlocalized error description string. + String Context; /// Context string. For example, for a file open failure this is the file path. + double OVRTime; /// Time when the error was generated. Same format as OVR time. + SysClockTime ClockTime; /// Wall clock time. + int64_t LogLine; /// Log line of the error. -1 if not set (not logged). + String SourceFilePath; /// The __FILE__ where the error was first encountered. + int SourceFileLine; /// The __LINE__ where the error was first encountered. + AddressArray Backtrace; /// Backtrace at point of error. May be empty in publicly released builds. + }; + + + + /// ----------------------------------------------------------------------------- + /// ***** MakeError + /// + /// Utility function for making an error and logging it. + /// It's preferred to instead use the OVR_MAKE_ERROR macro functions, as they + /// handle file/line functionality cleanly between debug and release. + /// + OVRError MakeError(ovrResult errorCode, ovrSysErrorCode sysCode, const char* pSourceFile, + int sourceLine, const char* pContext, const char* pDescriptionFormat, ...); + + + /// ----------------------------------------------------------------------------- + /// ***** GetErrorCodeString + /// + /// Converts an ovrResult error code to a readable string version. + /// + bool GetErrorCodeString(ovrResult errorCode, bool prefixErrorCode, OVR::String& sResult); + + + /// ----------------------------------------------------------------------------- + /// ***** GetSysErrorCodeString + /// + /// Converts a system error to a string. Similar to the Windows FormatMessage function. + /// If prefixErrorCode is true then the string is prefixed with ": " + /// Returns true if the sysErrorCode was a known valid code and a string was produced from it. + /// Else the returned string will be empty. The returned string may have tabs or newlines. + /// Users of OVR_MAKE_SYS_ERROR and MakeError don't need to call this function, as it's done + /// automatically internally. + /// + bool GetSysErrorCodeString(ovrSysErrorCode sysErrorCode, bool prefixErrorCode, OVR::String& sResult); + + +} // namespace OVR + + + +#endif // Header include guard + + + diff --git a/LibOVR/Src/OVR_JSON.cpp b/LibOVR/Src/OVR_JSON.cpp deleted file mode 100644 index 7b40fb1..0000000 --- a/LibOVR/Src/OVR_JSON.cpp +++ /dev/null @@ -1,1287 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_JSON.h -Content : JSON format reader and writer -Created : April 9, 2013 -Author : Brant Lewis -Notes : - The code is a derivative of the cJSON library written by Dave Gamble and subject - to the following permissive copyright. - - Copyright (c) 2009 Dave Gamble - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include "OVR_JSON.h" -#include "Kernel/OVR_SysFile.h" -#include "Kernel/OVR_Log.h" - -#ifdef OVR_OS_LINUX -#include -#endif - -namespace OVR { - - -//----------------------------------------------------------------------------- -// Create a new copy of a string -static char* JSON_strdup(const char* str) -{ - size_t len = OVR_strlen(str) + 1; - char* copy = (char*)OVR_ALLOC(len); - if (!copy) - return 0; - memcpy(copy, str, len); - return copy; -} - - -//----------------------------------------------------------------------------- -// Render the number from the given item into a string. -static char* PrintInt(int valueint) -{ - char *str; - str = (char*)OVR_ALLOC(21); // 2^64+1 can be represented in 21 chars. - if (str) - { - OVR_sprintf(str, 21, "%d", valueint); - } - return str; -} - - -//----------------------------------------------------------------------------- -// Render the number from the given item into a string. -static char* PrintNumber(double d) -{ - char *str; - int valueint = (int)d; - if (fabs(((double)valueint)-d)<=DBL_EPSILON && d<=INT_MAX && d>=INT_MIN) - { - return PrintInt(valueint); - } - else - { - str=(char*)OVR_ALLOC(64); // This is a nice tradeoff. - if (str) - { - if (fabs(floor(d)-d)<=DBL_EPSILON && fabs(d)<1.0e60) - OVR_sprintf(str, 64, "%.0f", d); - else if (fabs(d)<1.0e-6 || fabs(d)>1.0e9) - OVR_sprintf(str, 64, "%e", d); - else - OVR_sprintf(str, 64, "%f", d); - } - } - return str; -} - - -// Parse the input text into an un-escaped cstring, and populate item. -static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -// Helper to assign error sting and return 0. -const char* AssignError(const char** perror, const char *errorMessage) -{ - if (perror) - *perror = errorMessage; - return 0; -} - -//----------------------------------------------------------------------------- -// ***** JSON Node class - -JSON::JSON(JSONItemType itemType) : - Type(itemType), dValue(0.) -{ -} - -JSON::~JSON() -{ - JSON* child = Children.GetFirst(); - while (!Children.IsNull(child)) - { - child->RemoveNode(); - child->Release(); - child = Children.GetFirst(); - } -} - -//----------------------------------------------------------------------------- -// Parse the input text to generate a number, and populate the result into item -// Returns the text position after the parsed number -const char* JSON::parseNumber(const char *num) -{ - const char* num_start = num; - double n=0, scale=0; - int subscale = 0, - signsubscale = 1; - bool positiveSign = true; - char localeSeparator = '.'; - -#ifdef OVR_OS_LINUX - // We should switch to a locale aware parsing function, such as atof. We - // will probably want to go farther and enforce the 'C' locale on all JSON - // output/input. - struct lconv* localeConv = localeconv(); - localeSeparator = localeConv->decimal_point[0]; -#endif - - // Could use sscanf for this? - if (*num == '-') - { - positiveSign = false; - num++; // Has sign? - } - if (*num == '0') - { - num++; // is zero - } - - if (*num>='1' && *num<='9') - { - do - { - n = (n*10.0) + (*num++ - '0'); - } - while (*num>='0' && *num<='9'); // Number? - } - - if ((*num=='.' || *num==localeSeparator) && num[1]>='0' && num[1]<='9') - { - num++; - do - { - n=(n*10.0)+(*num++ -'0'); - scale--; - } - while (*num>='0' && *num<='9'); // Fractional part? - } - - if (*num=='e' || *num=='E') // Exponent? - { - num++; - if (*num == '+') - { - num++; - } - else if (*num=='-') - { - signsubscale=-1; - num++; // With sign? - } - - while (*num >= '0' && *num <= '9') - { - subscale = (subscale * 10) + (*num++ - '0'); // Number? - } - } - - // Number = +/- number.fraction * 10^+/- exponent - n *= pow(10.0, (scale + subscale*signsubscale)); - - if (!positiveSign) - { - n = -n; - } - - // Assign parsed value. - Type = JSON_Number; - dValue = n; - Value.AssignString(num_start, num - num_start); - - return num; -} - -// Parses a hex string up to the specified number of digits. -// Returns the first character after the string. -const char* ParseHex(unsigned* val, unsigned digits, const char* str) -{ - *val = 0; - - for(unsigned digitCount = 0; digitCount < digits; digitCount++, str++) - { - unsigned v = *str; - - if ((v >= '0') && (v <= '9')) - v -= '0'; - else if ((v >= 'a') && (v <= 'f')) - v = 10 + v - 'a'; - else if ((v >= 'A') && (v <= 'F')) - v = 10 + v - 'A'; - else - break; - - *val = *val * 16 + v; - } - - return str; -} - -//----------------------------------------------------------------------------- -// Parses the input text into a string item and returns the text position after -// the parsed string -const char* JSON::parseString(const char* str, const char** perror) -{ - const char* ptr = str+1; - const char* p; - char* ptr2; - char* out; - int len=0; - unsigned uc, uc2; - - if (*str!='\"') - { - return AssignError(perror, "Syntax Error: Missing quote"); - } - - while (*ptr!='\"' && *ptr && ++len) - { - if (*ptr++ == '\\') ptr++; // Skip escaped quotes. - } - - // This is how long we need for the string, roughly. - out=(char*)OVR_ALLOC(len+1); - if (!out) - return 0; - - ptr = str+1; - ptr2= out; - - while (*ptr!='\"' && *ptr) - { - if (*ptr!='\\') - { - *ptr2++ = *ptr++; - } - else - { - ptr++; - switch (*ptr) - { - case 'b': *ptr2++ = '\b'; break; - case 'f': *ptr2++ = '\f'; break; - case 'n': *ptr2++ = '\n'; break; - case 'r': *ptr2++ = '\r'; break; - case 't': *ptr2++ = '\t'; break; - - // Transcode utf16 to utf8. - case 'u': - - // Get the unicode char. - p = ParseHex(&uc, 4, ptr + 1); - if (ptr != p) - ptr = p - 1; - - if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) - break; // Check for invalid. - - // UTF16 surrogate pairs. - if (uc>=0xD800 && uc<=0xDBFF) - { - if (ptr[1]!='\\' || ptr[2]!='u') - break; // Missing second-half of surrogate. - - p= ParseHex(&uc2, 4, ptr + 3); - if (ptr != p) - ptr = p - 1; - - if (uc2<0xDC00 || uc2>0xDFFF) - break; // Invalid second-half of surrogate. - - uc = 0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); - } - - len=4; - - if (uc<0x80) - len=1; - else if (uc<0x800) - len=2; - else if (uc<0x10000) - len=3; - - ptr2+=len; - - switch (len) - { - case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - //no break, fall through - case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - //no break - case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; - //no break - case 1: *--ptr2 = (char)(uc | firstByteMark[len]); - //no break - } - ptr2+=len; - break; - - default: - *ptr2++ = *ptr; - break; - } - ptr++; - } - } - - *ptr2 = 0; - if (*ptr=='\"') - ptr++; - - // Make a copy of the string - Value=out; - OVR_FREE(out); - Type=JSON_String; - - return ptr; -} - -//----------------------------------------------------------------------------- -// Render the string provided to an escaped version that can be printed. -char* PrintString(const char* str) -{ - const char *ptr; - char *ptr2,*out; - int len=0; - unsigned char token; - - if (!str) - return JSON_strdup(""); - ptr=str; - - token=*ptr; - while (token && ++len)\ - { - if (strchr("\"\\\b\f\n\r\t",token)) - len++; - else if (token<32) - len+=5; - ptr++; - token=*ptr; - } - - int buff_size = len+3; - out=(char*)OVR_ALLOC(buff_size); - if (!out) - return 0; - - ptr2 = out; - ptr = str; - *ptr2++ = '\"'; - - while (*ptr) - { - if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') - *ptr2++=*ptr++; - else - { - *ptr2++='\\'; - switch (token=*ptr++) - { - case '\\': *ptr2++='\\'; break; - case '\"': *ptr2++='\"'; break; - case '\b': *ptr2++='b'; break; - case '\f': *ptr2++='f'; break; - case '\n': *ptr2++='n'; break; - case '\r': *ptr2++='r'; break; - case '\t': *ptr2++='t'; break; - default: - OVR_sprintf(ptr2, buff_size - (ptr2-out), "u%04x",token); - ptr2+=5; - break; // Escape and print. - } - } - } - *ptr2++='\"'; - *ptr2++=0; - return out; -} - -//----------------------------------------------------------------------------- -// Utility to jump whitespace and cr/lf -static const char* skip(const char* in) -{ - while (in && *in && (unsigned char)*in<=' ') - in++; - return in; -} - -//----------------------------------------------------------------------------- -// Parses the supplied buffer of JSON text and returns a JSON object tree -// The returned object must be Released after use -JSON* JSON::Parse(const char* buff, const char** perror) -{ - const char* end = 0; - JSON* json = new JSON(); - - if (!json) - { - AssignError(perror, "Error: Failed to allocate memory"); - return 0; - } - - end = json->parseValue(skip(buff), perror); - if (!end) - { - json->Release(); - return NULL; - } // parse failure. ep is set. - - return json; -} - -//----------------------------------------------------------------------------- -// This version works for buffers that are not null terminated strings. -JSON* JSON::ParseBuffer(const char *buff, int len, const char** perror) -{ - // Our JSON parser does not support length-based parsing, - // so ensure it is null-terminated. - char *termStr = new char[len + 1]; - memcpy(termStr, buff, len); - termStr[len] = '\0'; - - JSON *objJson = Parse(termStr, perror); - - delete[]termStr; - - return objJson; -} - -//----------------------------------------------------------------------------- -// Parser core - when encountering text, process appropriately. -const char* JSON::parseValue(const char* buff, const char** perror) -{ - if (perror) - *perror = 0; - - if (!buff) - return NULL; // Fail on null. - - if (!strncmp(buff,"null",4)) - { - Type = JSON_Null; - return buff+4; - } - if (!strncmp(buff,"false",5)) - { - Type = JSON_Bool; - Value = "false"; - dValue = 0.; - return buff+5; - } - if (!strncmp(buff,"true",4)) - { - Type = JSON_Bool; - Value = "true"; - dValue = 1.; - return buff + 4; - } - if (*buff=='\"') - { - return parseString(buff, perror); - } - if (*buff=='-' || (*buff>='0' && *buff<='9')) - { - return parseNumber(buff); - } - if (*buff=='[') - { - return parseArray(buff, perror); - } - if (*buff=='{') - { - return parseObject(buff, perror); - } - - return AssignError(perror, "Syntax Error: Invalid syntax"); -} - - -//----------------------------------------------------------------------------- -// Render a value to text. -char* JSON::PrintValue(int depth, bool fmt) -{ - char *out=0; - - switch (Type) - { - case JSON_Null: out = JSON_strdup("null"); break; - case JSON_Bool: - if ((int)dValue == 0) - out = JSON_strdup("false"); - else - out = JSON_strdup("true"); - break; - case JSON_Number: out = PrintNumber(dValue); break; - case JSON_String: out = PrintString(Value); break; - case JSON_Array: out = PrintArray(depth, fmt); break; - case JSON_Object: out = PrintObject(depth, fmt); break; - case JSON_None: OVR_ASSERT_LOG(false, ("Bad JSON type.")); break; - } - return out; -} - -//----------------------------------------------------------------------------- -// Build an array object from input text and returns the text position after -// the parsed array -const char* JSON::parseArray(const char* buff, const char** perror) -{ - JSON *child; - if (*buff!='[') - { - return AssignError(perror, "Syntax Error: Missing opening bracket"); - } - - Type=JSON_Array; - buff=skip(buff+1); - - if (*buff==']') - return buff+1; // empty array. - - child = new JSON(); - if (!child) - return 0; // memory fail - Children.PushBack(child); - - buff=skip(child->parseValue(skip(buff), perror)); // skip any spacing, get the buff. - if (!buff) - return 0; - - while (*buff==',') - { - JSON *new_item = new JSON(); - if (!new_item) - return AssignError(perror, "Error: Failed to allocate memory"); - - Children.PushBack(new_item); - - buff=skip(new_item->parseValue(skip(buff+1), perror)); - if (!buff) - return AssignError(perror, "Error: Failed to allocate memory"); - } - - if (*buff==']') - return buff+1; // end of array - - return AssignError(perror, "Syntax Error: Missing ending bracket"); -} - -//----------------------------------------------------------------------------- -// Render an array to text. The returned text must be freed -char* JSON::PrintArray(int depth, bool fmt) -{ - char ** entries; - char * out = 0, *ptr,*ret; - intptr_t len = 5; - - bool fail = false; - - // How many entries in the array? - int numentries = GetItemCount(); - if (!numentries) - { - out=(char*)OVR_ALLOC(3); - if (out) - OVR_strcpy(out, 3, "[]"); - return out; - } - // Allocate an array to hold the values for each - entries=(char**)OVR_ALLOC(numentries*sizeof(char*)); - if (!entries) - return 0; - memset(entries,0,numentries*sizeof(char*)); - - //// Retrieve all the results: - JSON* child = Children.GetFirst(); - for (int i=0; iPrintValue(depth+1, fmt); - entries[i]=ret; - if (ret) - len+=OVR_strlen(ret)+2+(fmt?1:0); - else - { - fail = true; - break; - } - child = Children.GetNext(child); - } - - // If we didn't fail, try to malloc the output string - if (!fail) - out=(char*)OVR_ALLOC(len); - // If that fails, we fail. - if (!out) - fail = true; - - // Handle failure. - if (fail) - { - for (int i=0; iparseString(skip(buff), perror)); - if (!buff) - return 0; - child->Name = child->Value; - child->Value.Clear(); - - if (*buff!=':') - { - return AssignError(perror, "Syntax Error: Missing colon"); - } - - buff=skip(child->parseValue(skip(buff+1), perror)); // skip any spacing, get the value. - if (!buff) - return 0; - - while (*buff==',') - { - child = new JSON(); - if (!child) - return 0; // memory fail - - Children.PushBack(child); - - buff=skip(child->parseString(skip(buff+1), perror)); - if (!buff) - return 0; - - child->Name=child->Value; - child->Value.Clear(); - - if (*buff!=':') - { - return AssignError(perror, "Syntax Error: Missing colon"); - } // fail! - - // Skip any spacing, get the value. - buff=skip(child->parseValue(skip(buff+1), perror)); - if (!buff) - return 0; - } - - if (*buff=='}') - return buff+1; // end of array - - return AssignError(perror, "Syntax Error: Missing closing brace"); -} - -//----------------------------------------------------------------------------- -// Render an object to text. The returned string must be freed -char* JSON::PrintObject(int depth, bool fmt) -{ - char** entries = 0, **names = 0; - char* out = 0; - char* ptr, *ret, *str; - intptr_t len = 7, i = 0, j; - bool fail = false; - - // Count the number of entries. - int numentries = GetItemCount(); - - // Explicitly handle empty object case - if (numentries == 0) - { - out=(char*)OVR_ALLOC(fmt?depth+4:4); - if (!out) - return 0; - ptr=out; - *ptr++='{'; - - if (fmt) - { - *ptr++='\n'; - for (i=0;iName); - entries[i++] = ret = child->PrintValue(depth, fmt); - - if (str && ret) - { - len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?3+depth:0); - } - else - { - fail = true; - break; - } - - child = Children.GetNext(child); - } - - // Try to allocate the output string - if (!fail) - out=(char*)OVR_ALLOC(len); - if (!out) - fail=true; - - // Handle failure - if (fail) - { - for (i=0;ipNext) - { - count++; - } - return count; -} - -JSON* JSON::GetItemByIndex(unsigned index) -{ - unsigned i = 0; - JSON* child = 0; - - if (!Children.IsEmpty()) - { - child = Children.GetFirst(); - - while (i < index) - { - if (Children.IsNull(child->pNext)) - { - child = 0; - break; - } - child = child->pNext; - i++; - } - } - - return child; -} - -// Returns the child item with the given name or NULL if not found -JSON* JSON::GetItemByName(const char* name) -{ - JSON* child = 0; - - if (!Children.IsEmpty()) - { - child = Children.GetFirst(); - - while (OVR_strcmp(child->Name, name) != 0) - { - if (Children.IsNull(child->pNext)) - { - child = 0; - break; - } - child = child->pNext; - } - } - - return child; -} - -//----------------------------------------------------------------------------- -// Adds a new item to the end of the child list -void JSON::AddItem(const char *string, JSON *item) -{ - if (item) - { - item->Name = string; - Children.PushBack(item); - } -} - -/* - -// Removes and frees the items at the given index -void JSON::DeleteItem(unsigned int index) -{ - unsigned int num_items = 0; - JSON* child = Children.GetFirst(); - while (!Children.IsNull(child) && num_items < index) - { - num_items++; - child = Children.GetNext(child); - } - - if (!Children.IsNull(child)) - - child->RemoveNode(); - child->Release(); - } -} - -// Replaces and frees the item at the give index with the new item -void JSON::ReplaceItem(unsigned int index, JSON* new_item) -{ - unsigned int num_items = 0; - JSON* child = Children.GetFirst(); - while (!Children.IsNull(child) && num_items < index) - { - num_items++; - child = Children.GetNext(child); - } - - if (!Children.IsNull(child)) - { - child->ReplaceNodeWith(new_item); - child->Release(); - } -} -*/ - -// Removes and frees the last child item -void JSON::RemoveLast() -{ - JSON* child = Children.GetLast(); - if (!Children.IsNull(child)) - { - child->RemoveNode(); - child->Release(); - } -} - -JSON* JSON::CreateBool(bool b) -{ - JSON *item = new JSON(JSON_Bool); - if (item) - { - item->dValue = b ? 1. : 0.; - item->Value = b ? "true" : "false"; - } - return item; -} - -JSON* JSON::CreateNumber(double num) -{ - JSON *item = new JSON(JSON_Number); - if (item) - { - item->dValue = num; - } - return item; -} - -JSON* JSON::CreateInt(int num) -{ - JSON *item = new JSON(JSON_Number); - if (item) - { - item->dValue = num; - } - return item; -} - -JSON* JSON::CreateString(const char *s) -{ - JSON *item = new JSON(JSON_String); - if (item && s) - { - item->Value = s; - } - return item; -} - - -//----------------------------------------------------------------------------- -// Get elements by name -double JSON::GetNumberByName(const char *name, double defValue) -{ - JSON* item = GetItemByName(name); - if (!item || item->Type != JSON_Number) - { - return defValue; - } - else - { - return item->dValue; - } -} - -int JSON::GetIntByName(const char *name, int defValue) -{ - JSON* item = GetItemByName(name); - if (!item || item->Type != JSON_Number) - { - return defValue; - } - else - { - return (int)item->dValue; - } -} - -bool JSON::GetBoolByName(const char *name, bool defValue) -{ - JSON* item = GetItemByName(name); - if (!item || item->Type != JSON_Bool) - { - return defValue; - } - else - { - return (int)item->dValue != 0; - } -} - -String JSON::GetStringByName(const char *name, const String &defValue) -{ - JSON* item = GetItemByName(name); - if (!item || item->Type != JSON_String) - { - return defValue; - } - else - { - return item->Value; - } -} - -//----------------------------------------------------------------------------- -// Adds an element to an array object type -void JSON::AddArrayElement(JSON *item) -{ - if (item) - { - Children.PushBack(item); - } -} - -// Inserts an element into a valid array position -void JSON::InsertArrayElement(int index, JSON *item) -{ - if (!item) - { - return; - } - - if (index == 0) - { - Children.PushFront(item); - return; - } - - JSON* iter = Children.GetFirst(); - int i=0; - while (iter && iInsertNodeBefore(item); - else - Children.PushBack(item); -} - -// Returns the size of an array -int JSON::GetArraySize() -{ - if (Type == JSON_Array) - { - return GetItemCount(); - } - - return 0; -} - -// Returns the number value an the give array index -double JSON::GetArrayNumber(int index) -{ - if (Type == JSON_Array) - { - JSON* number = GetItemByIndex(index); - return number ? number->dValue : 0.0; - } - - return 0; -} - -// Returns the string value at the given array index -const char* JSON::GetArrayString(int index) -{ - if (Type == JSON_Array) - { - JSON* number = GetItemByIndex(index); - return number ? number->Value : 0; - } - - return 0; -} - -JSON* JSON::Copy() -{ - JSON* copy = new JSON(Type); - copy->Name = Name; - copy->Value = Value; - copy->dValue = dValue; - - JSON* child = Children.GetFirst(); - while (!Children.IsNull(child)) - { - copy->Children.PushBack(child->Copy()); - child = Children.GetNext(child); - } - - return copy; -} - -//----------------------------------------------------------------------------- -// Loads and parses the given JSON file pathname and returns a JSON object tree. -// The returned object must be Released after use. -JSON* JSON::Load(const char* path, const char** perror) -{ - SysFile f; - if (!f.Open(path, File::Open_Read, File::Mode_Read)) - { - AssignError(perror, "Failed to open file"); - return NULL; - } - - int len = f.GetLength(); - uint8_t* buff = (uint8_t*)OVR_ALLOC(len + 1); - int bytes = f.Read(buff, len); - f.Close(); - - if (bytes == 0 || bytes != len) - { - OVR_FREE(buff); - return NULL; - } - - // Ensure the result is null-terminated since Parse() expects null-terminated input. - buff[len] = '\0'; - - JSON* json = JSON::Parse((char*)buff, perror); - OVR_FREE(buff); - return json; -} - -//----------------------------------------------------------------------------- -// Serializes the JSON object and writes to the give file path -bool JSON::Save(const char* path) -{ - SysFile f; - if (!f.Open(path, File::Open_Write | File::Open_Create | File::Open_Truncate, File::Mode_Write)) - return false; - - char* text = PrintValue(0, true); - if (text) - { - intptr_t len = OVR_strlen(text); - OVR_ASSERT(len <= (intptr_t)(int)len); - - int bytes = f.Write((uint8_t*)text, (int)len); - f.Close(); - OVR_FREE(text); - return (bytes == len); - } - else - { - return false; - } -} - - -} // namespace OVR diff --git a/LibOVR/Src/OVR_JSON.h b/LibOVR/Src/OVR_JSON.h deleted file mode 100644 index 488cb1d..0000000 --- a/LibOVR/Src/OVR_JSON.h +++ /dev/null @@ -1,165 +0,0 @@ -/************************************************************************************ - -PublicHeader: None -Filename : OVR_JSON.h -Content : JSON format reader and writer -Created : April 9, 2013 -Author : Brant Lewis -Notes : - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#ifndef OVR_JSON_H -#define OVR_JSON_H - -#include "Kernel/OVR_RefCount.h" -#include "Kernel/OVR_String.h" -#include "Kernel/OVR_List.h" - -namespace OVR { - -// JSONItemType describes the type of JSON item, specifying the type of -// data that can be obtained from it. -enum JSONItemType -{ - JSON_None = 0, - JSON_Null = 1, - JSON_Bool = 2, - JSON_Number = 3, - JSON_String = 4, - JSON_Array = 5, - JSON_Object = 6 -}; - -//----------------------------------------------------------------------------- -// ***** JSON - -// JSON object represents a JSON node that can be either a root of the JSON tree -// or a child item. Every node has a type that describes what is is. -// New JSON trees are typically loaded JSON::Load or created with JSON::Parse. - -class JSON : public RefCountBase, public ListNode -{ -protected: - List Children; - -public: - JSONItemType Type; // Type of this JSON node. - String Name; // Name part of the {Name, Value} pair in a parent object. - String Value; - double dValue; - -public: - ~JSON(); - - // *** Creation of NEW JSON objects - - static JSON* CreateObject() { return new JSON(JSON_Object);} - static JSON* CreateNull() { return new JSON(JSON_Null); } - static JSON* CreateArray() { return new JSON(JSON_Array); } - static JSON* CreateBool(bool b); - static JSON* CreateNumber(double num); - static JSON* CreateInt(int num); - static JSON* CreateString(const char *s); - - // Creates a new JSON object from parsing string. - // Returns null pointer and fills in *perror in case of parse error. - static JSON* Parse(const char* buff, const char** perror = 0); - - // This version works for buffers that are not null terminated strings. - static JSON* ParseBuffer(const char *buff, int len, const char** perror = 0); - - // Loads and parses a JSON object from a file. - // Returns 0 and assigns perror with error message on fail. - static JSON* Load(const char* path, const char** perror = 0); - - // Saves a JSON object to a file. - bool Save(const char* path); - - // *** Object Member Access - - // These provide access to child items of the list. - bool HasItems() const { return Children.IsEmpty(); } - // Returns first/last child item, or null if child list is empty - JSON* GetFirstItem() { return (!Children.IsEmpty()) ? Children.GetFirst() : 0; } - JSON* GetLastItem() { return (!Children.IsEmpty()) ? Children.GetLast() : 0; } - - // Counts the number of items in the object; these methods are inefficient. - unsigned GetItemCount() const; - JSON* GetItemByIndex(unsigned i); - JSON* GetItemByName(const char* name); - - // Accessors by name - double GetNumberByName(const char *name, double defValue = 0.0); - int GetIntByName(const char *name, int defValue = 0); - bool GetBoolByName(const char *name, bool defValue = false); - String GetStringByName(const char *name, const String &defValue = ""); - - // Returns next item in a list of children; 0 if no more items exist. - JSON* GetNextItem(JSON* item) { return Children.IsNull(item->pNext) ? 0 : item->pNext; } - JSON* GetPrevItem(JSON* item) { return Children.IsNull(item->pPrev) ? 0 : item->pPrev; } - - - // Child item access functions - void AddItem(const char *string, JSON* item); - void AddNullItem(const char* name) { AddItem(name, CreateNull()); } - void AddBoolItem(const char* name, bool b) { AddItem(name, CreateBool(b)); } - void AddIntItem(const char* name, int n) { AddItem(name, CreateInt(n)); } - void AddNumberItem(const char* name, double n) { AddItem(name, CreateNumber(n)); } - void AddStringItem(const char* name, const char* s) { AddItem(name, CreateString(s)); } -// void ReplaceItem(unsigned index, JSON* new_item); -// void DeleteItem(unsigned index); - void RemoveLast(); - - // *** Array Element Access - - // Add new elements to the end of array. - void AddArrayElement(JSON *item); - void InsertArrayElement(int index, JSON* item); - void AddArrayNumber(double n) { AddArrayElement(CreateNumber(n)); } - void AddArrayInt(int n) { AddArrayElement(CreateInt(n)); } - void AddArrayString(const char* s) { AddArrayElement(CreateString(s)); } - - // Accessed array elements; currently inefficient. - int GetArraySize(); - double GetArrayNumber(int index); - const char* GetArrayString(int index); - - JSON* Copy(); // Create a copy of this object - -protected: - JSON(JSONItemType itemType = JSON_Object); - - // JSON Parsing helper functions. - const char* parseValue(const char *buff, const char** perror); - const char* parseNumber(const char *num); - const char* parseArray(const char* value, const char** perror); - const char* parseObject(const char* value, const char** perror); - const char* parseString(const char* str, const char** perror); - - char* PrintValue(int depth, bool fmt); - char* PrintObject(int depth, bool fmt); - char* PrintArray(int depth, bool fmt); -}; - - -} - -#endif diff --git a/LibOVR/Src/OVR_Linux_UDEV.cpp b/LibOVR/Src/OVR_Linux_UDEV.cpp new file mode 100644 index 0000000..fafd940 --- /dev/null +++ b/LibOVR/Src/OVR_Linux_UDEV.cpp @@ -0,0 +1,112 @@ +/************************************************************************************ + +Filename : OVR_Linux_UDEV.cpp +Content : This is the interface for libudev1 or libudev0 in Linux. + +Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "OVR_Linux_UDEV.h" + +namespace OVR +{ +namespace Linux +{ + +static void *udev_library = nullptr; + +#define LOAD_UDEV_SYMBOL(symbol) \ + dlerror(); \ + ((void*&)(symbol)) = dlsym(udev_library, #symbol); \ + if (dlerror()) return false; + +bool LoadUDEVSymbols() +{ + if (udev_library) + { + return true; + } + + udev_library = nullptr; + udev_library = dlopen("libudev.so.1", RTLD_LAZY | RTLD_GLOBAL); + if (!udev_library) + { + udev_library = dlopen("libudev.so.0", RTLD_LAZY | RTLD_GLOBAL); + } + assert(udev_library); + + LOAD_UDEV_SYMBOL(udev_new); + LOAD_UDEV_SYMBOL(udev_unref); + + LOAD_UDEV_SYMBOL(udev_device_new_from_syspath); + LOAD_UDEV_SYMBOL(udev_device_get_action); + LOAD_UDEV_SYMBOL(udev_device_get_devnode); + LOAD_UDEV_SYMBOL(udev_device_get_parent_with_subsystem_devtype); + LOAD_UDEV_SYMBOL(udev_device_get_sysattr_value); + LOAD_UDEV_SYMBOL(udev_device_unref); + + LOAD_UDEV_SYMBOL(udev_enumerate_new); + LOAD_UDEV_SYMBOL(udev_enumerate_add_match_subsystem); + LOAD_UDEV_SYMBOL(udev_enumerate_get_list_entry); + LOAD_UDEV_SYMBOL(udev_enumerate_scan_devices); + LOAD_UDEV_SYMBOL(udev_enumerate_unref); + + LOAD_UDEV_SYMBOL(udev_list_entry_get_name); + LOAD_UDEV_SYMBOL(udev_list_entry_get_next); + + LOAD_UDEV_SYMBOL(udev_monitor_new_from_netlink); + LOAD_UDEV_SYMBOL(udev_monitor_enable_receiving); + LOAD_UDEV_SYMBOL(udev_monitor_filter_add_match_subsystem_devtype); + LOAD_UDEV_SYMBOL(udev_monitor_get_fd); + LOAD_UDEV_SYMBOL(udev_monitor_receive_device); + LOAD_UDEV_SYMBOL(udev_monitor_unref); + + return true; +} + +#undef LOAD_UDEV_SYMBOL + +// Function pointers returned from dlsym (global, NOT in OVR::). +struct udev* (*udev_new)(void); +void (*udev_unref)(struct udev*); + +struct udev_device* (*udev_device_new_from_syspath)(struct udev*, const char*); +const char* (*udev_device_get_action)(struct udev_device*); +const char* (*udev_device_get_devnode)(struct udev_device*); +struct udev_device* (*udev_device_get_parent_with_subsystem_devtype)(struct udev_device*, const char*, const char*); +const char* (*udev_device_get_sysattr_value)(struct udev_device*, const char*); +void (*udev_device_unref)(struct udev_device*); + +struct udev_enumerate* (*udev_enumerate_new)(struct udev*); +int (*udev_enumerate_add_match_subsystem)(struct udev_enumerate*, const char*); +struct udev_list_entry* (*udev_enumerate_get_list_entry)(struct udev_enumerate*); +int (*udev_enumerate_scan_devices)(struct udev_enumerate*); +void (*udev_enumerate_unref)(struct udev_enumerate*); + +const char* (*udev_list_entry_get_name)(struct udev_list_entry*); +struct udev_list_entry* (*udev_list_entry_get_next)(struct udev_list_entry *); + +struct udev_monitor* (*udev_monitor_new_from_netlink)(struct udev*, const char*); +int (*udev_monitor_enable_receiving)(struct udev_monitor*); +int (*udev_monitor_filter_add_match_subsystem_devtype)(struct udev_monitor*, const char*, const char*); +int (*udev_monitor_get_fd)(struct udev_monitor*); +struct udev_device* (*udev_monitor_receive_device)(struct udev_monitor*); +void (*udev_monitor_unref)(struct udev_monitor*); + +}} // namespace OVR::Linux diff --git a/LibOVR/Src/OVR_Linux_UDEV.h b/LibOVR/Src/OVR_Linux_UDEV.h new file mode 100644 index 0000000..295f04c --- /dev/null +++ b/LibOVR/Src/OVR_Linux_UDEV.h @@ -0,0 +1,72 @@ +/************************************************************************************ + +Filename : OVR_Linux_UDEV.h +Content : This is the interface for libudev1 or libudev0 in Linux. + +Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Linux_UDEV_h +#define OVR_Linux_UDEV_h + +#include +#include + +namespace OVR +{ +namespace Linux +{ + +bool LoadUDEVSymbols(); + +// Function pointers returned from dlsym (global, NOT in OVR::). +extern struct udev* (*udev_new)(void); +extern void (*udev_unref)(struct udev*); + +extern struct udev_device* (*udev_device_new_from_syspath)(struct udev*, const char*); +extern const char* (*udev_device_get_action)(struct udev_device*); +extern const char* (*udev_device_get_devnode)(struct udev_device*); +extern struct udev_device* (*udev_device_get_parent_with_subsystem_devtype)(struct udev_device*, const char*, const char*); +extern const char* (*udev_device_get_sysattr_value)(struct udev_device*, const char*); +extern void (*udev_device_unref)(struct udev_device*); + +extern struct udev_enumerate* (*udev_enumerate_new)(struct udev*); +extern int (*udev_enumerate_add_match_subsystem)(struct udev_enumerate*, const char*); +extern struct udev_list_entry* (*udev_enumerate_get_list_entry)(struct udev_enumerate*); +extern int (*udev_enumerate_scan_devices)(struct udev_enumerate*); +extern void (*udev_enumerate_unref)(struct udev_enumerate*); + +extern const char* (*udev_list_entry_get_name)(struct udev_list_entry*); +extern struct udev_list_entry* (*udev_list_entry_get_next)(struct udev_list_entry *); + +extern struct udev_monitor* (*udev_monitor_new_from_netlink)(struct udev*, const char*); +extern int (*udev_monitor_enable_receiving)(struct udev_monitor*); +extern int (*udev_monitor_filter_add_match_subsystem_devtype)(struct udev_monitor*, const char*, const char*); +extern int (*udev_monitor_get_fd)(struct udev_monitor*); +extern struct udev_device* (*udev_monitor_receive_device)(struct udev_monitor*); +extern void (*udev_monitor_unref)(struct udev_monitor*); + +#define udev_list_entry_foreach(list_entry, first_entry) \ + for (list_entry = first_entry; \ + list_entry != NULL; \ + list_entry = udev_list_entry_get_next(list_entry)) + +}} // namespace OVR::Linux + +#endif // OVR_Linux_UDEV_h diff --git a/LibOVR/Src/OVR_Profile.cpp b/LibOVR/Src/OVR_Profile.cpp old mode 100644 new mode 100755 index dcbc95d..273d551 --- a/LibOVR/Src/OVR_Profile.cpp +++ b/LibOVR/Src/OVR_Profile.cpp @@ -32,14 +32,13 @@ limitations under the License. ************************************************************************************/ #include "OVR_Profile.h" -#include "OVR_JSON.h" +#include "Kernel/OVR_JSON.h" #include "Kernel/OVR_SysFile.h" #include "Kernel/OVR_Allocator.h" #include "OVR_Stereo.h" #ifdef OVR_OS_WIN32 -#define WIN32_LEAN_AND_MEAN -#include +#include "Kernel/OVR_Win32_IncludeWindows.h" #include #elif defined(OVR_OS_MS) // Other Microsoft OSs // Nothing, thanks. @@ -54,6 +53,7 @@ limitations under the License. #endif + #define PROFILE_VERSION 2.0 #define MAX_PROFILE_MAJOR_VERSION 2 #define MAX_DEVICE_PROFILE_MAJOR_VERSION 1 @@ -805,25 +805,41 @@ const char* ProfileManager::GetDefaultUser(const char* product, const char* seri const char* tag_names[2] = {"Product", "Serial"}; const char* tags[2]; + Ptr p; if (product && serial) { tags[0] = product; tags[1] = serial; // Look for a default user on this specific device - Ptr p = *GetTaggedProfile(tag_names, tags, 2); - if (p == NULL) + Profile* tmp_ptr = GetTaggedProfile(tag_names, tags, 2); + if (tmp_ptr == nullptr) { // Look for a default user on this product - p = *GetTaggedProfile(tag_names, tags, 1); + tmp_ptr = GetTaggedProfile(tag_names, tags, 1); + } + if (tmp_ptr != nullptr) + { + p = *tmp_ptr; } - if (p) - { - const char* user = p->GetValue("DefaultUser"); - if (user != NULL && user[0] != 0) - { - TempBuff = user; - return TempBuff.ToCStr(); - } + } + else if (product) + { + tags[0] = product; + // Look for a default user on this specific device + Profile* tmp_ptr = GetTaggedProfile(tag_names, tags, 1); + if (tmp_ptr != nullptr) + { + p = *tmp_ptr; + } + } + + if (p) + { + const char* user = p->GetValue("DefaultUser"); + if (user != nullptr && user[0] != 0) + { + TempBuff = user; + return TempBuff.ToCStr(); } } @@ -1137,9 +1153,10 @@ bool Profile::LoadDeviceFile(unsigned int productId, const char* printedSerialNu String path = BasePath + "/Devices.json"; // Load the device profiles - Ptr root = *JSON::Load(path); - if (root == NULL) + JSON *tmp_ptr = JSON::Load(path); + if (tmp_ptr == NULL) return false; + Ptr root = *tmp_ptr; // Quick sanity check of the file type and format before we parse it JSON* version = root->GetFirstItem(); diff --git a/LibOVR/Src/OVR_SerialFormat.cpp b/LibOVR/Src/OVR_SerialFormat.cpp old mode 100644 new mode 100755 index 0b9a95b..80def57 --- a/LibOVR/Src/OVR_SerialFormat.cpp +++ b/LibOVR/Src/OVR_SerialFormat.cpp @@ -29,8 +29,13 @@ limitations under the License. #ifdef SERIAL_FORMAT_UNIT_TEST #include "Kernel/OVR_Log.h" +#include "Kernel/OVR_Rand.h" #endif + +#include +#include + namespace OVR { @@ -191,18 +196,18 @@ bool DK2BinarySerialFormat::operator==(const DK2BinarySerialFormat& rhs) // v, w, x, y, z => 27, 28, 29, 30, 31 static const char Base32FromChar[256] = { // Null - Unit Separator - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 0 - 15 + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 16 - 31 // (sp)!"#$%&'()*+,-./ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // 32 - 47 // 0123456789:;<=>? - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, - // @ - _ (upper case) - -1, 10, 11, 12, 13, 14, 15, 16, 17, 1, 18, 19, 1, 20, 21, 0, - 22, 23, 24, 25, 26, -1, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, - // ` - DEL (lower case) - -1, 10, 11, 12, 13, 14, 15, 16, 17, 1, 18, 19, 1, 20, 21, 0, - 22, 23, 24, 25, 26, -1, 27, 28, 29, 30, 31, -1, 1, -1, -1, -1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // 48 - 63 + // @A-Z[\]^_ + -1, 10, 11, 12, 13, 14, 15, 16, 17, 1, 18, 19, 1, 20, 21, 0, // 64 - 79 + 22, 23, 24, 25, 26, -1, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, // 80 - 95 + // `a-z{|}~DEL + -1, 10, 11, 12, 13, 14, 15, 16, 17, 1, 18, 19, 1, 20, 21, 0, // 96 - 111 + 22, 23, 24, 25, 26, -1, 27, 28, 29, 30, 31, -1, 1, -1, -1, -1, // 112 - 127 // Extended ASCII: -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -357,95 +362,6 @@ void DK2PrintedSerialFormat::FromBinary(const DK2BinarySerialFormat& bin) } -//// Unit Tests - -#ifdef SERIAL_FORMAT_UNIT_TEST - -int DecodeBase32(char ch) -{ - if (ch >= '2' && ch <= '9') - return 2 + ch - '2'; - if (ch >= 'a' && ch <= 'h') - return 10 + ch - 'a'; - if (ch >= 'A' && ch <= 'H') - return 10 + ch - 'A'; - if (ch >= 'j' && ch <= 'k') - return 18 + ch - 'j'; - if (ch >= 'J' && ch <= 'K') - return 18 + ch - 'J'; - if (ch >= 'm' && ch <= 'n') - return 20 + ch - 'm'; - if (ch >= 'M' && ch <= 'N') - return 20 + ch - 'M'; - if (ch >= 'p' && ch <= 't') - return 22 + ch - 'p'; - if (ch >= 'P' && ch <= 'T') - return 22 + ch - 'P'; - if (ch >= 'v' && ch <= 'z') - return 27 + ch - 'v'; - if (ch >= 'V' && ch <= 'Z') - return 27 + ch - 'V'; - - switch (ch) - { - case '0': - case 'o': - case 'O': - return 0; - case '1': - case 'i': - case '|': - case 'I': - case 'L': - case 'l': - return 1; - } - - return -1; -} - -void TestSerialFormatStuff() -{ - for (int ii = 0; ii < 256; ++ii) - { - OVR_ASSERT(Base32FromChar[ii] == (char)DecodeBase32((char)ii)); - } - - DK2BinarySerialFormat sa; - sa.ProductId = DK2ProductId_DK2; - sa.PartId = DK2PartId_HMD; - sa.MinutesSinceEpoch = 65000; - sa.UnitNumber = 2; - sa.MacHash[0] = 0xa1; - sa.MacHash[1] = 0xb2; - sa.MacHash[2] = 0xc3; - sa.MacHash[3] = 0xd4; - sa.MacHash[4] = 0xe5; - - uint8_t buffer[12]; - sa.ToBuffer(buffer); - - DK2BinarySerialFormat sb; - bool success = sb.FromBuffer(buffer); - OVR_ASSERT(success); - OVR_UNUSED(success); - - OVR_ASSERT(sa == sb); - - DK2PrintedSerialFormat psn; - psn.FromBinary(sb); - - OVR_ASSERT(psn == sa); - - String s = psn.ToBase32(); - - DK2PrintedSerialFormat psn2; - psn2.FromBase32(s.ToCStr()); - - OVR_ASSERT(psn == psn2); -} - -#endif // SERIAL_FORMAT_UNIT_TEST } // OVR diff --git a/LibOVR/Src/OVR_SerialFormat.h b/LibOVR/Src/OVR_SerialFormat.h old mode 100644 new mode 100755 index 9d9fbb7..f9ccb13 --- a/LibOVR/Src/OVR_SerialFormat.h +++ b/LibOVR/Src/OVR_SerialFormat.h @@ -30,6 +30,9 @@ limitations under the License. #include "Kernel/OVR_Types.h" #include "Kernel/OVR_String.h" +#include "OVR_Version.h" + + namespace OVR { @@ -117,10 +120,6 @@ public: }; -//#define SERIAL_FORMAT_UNIT_TEST -#ifdef SERIAL_FORMAT_UNIT_TEST -void TestSerialFormatStuff(); -#endif } // OVR diff --git a/LibOVR/Src/OVR_Stereo.cpp b/LibOVR/Src/OVR_Stereo.cpp index 1b0723f..1c66a2f 100644 --- a/LibOVR/Src/OVR_Stereo.cpp +++ b/LibOVR/Src/OVR_Stereo.cpp @@ -29,9 +29,12 @@ limitations under the License. #include "Kernel/OVR_Log.h" #include "Kernel/OVR_Alg.h" +#include "Util/Util_Render_Stereo.h" // DistortionMeshCreate + + //To allow custom distortion to be introduced to CatMulSpline. -float (*CustomDistortion)(float) = NULL; -float (*CustomDistortionInv)(float) = NULL; +float (*CustomDistortion)(float) = nullptr; +float (*CustomDistortionInv)(float) = nullptr; namespace OVR { @@ -144,7 +147,7 @@ float EvalCatmullRom10Spline ( float const *K, float scaledVal ) case NumSegments-2: // Last tangent is just the slope of the last two points. p0 = K[NumSegments-2]; - m0 = 0.5f * ( K[NumSegments-1] - K[NumSegments-2] ); + m0 = 0.5f * ( K[NumSegments-1] - K[NumSegments-3] ); p1 = K[NumSegments-1]; m1 = K[NumSegments-1] - K[NumSegments-2]; break; @@ -609,6 +612,86 @@ void TestSaveLoadLensConfig ( LensConfig const &config ) #endif +//----------------------------------------------------------------------------- +// ProfileRenderInfo + +ProfileRenderInfo::ProfileRenderInfo() : + EyeCupType(), + EyeReliefDial(0) +{ + Eye2Nose[0] = OVR_DEFAULT_IPD * 0.5f; + Eye2Nose[1] = OVR_DEFAULT_IPD * 0.5f; + Eye2Plate[0] = 0.; + Eye2Plate[1] = 0.; +} + +ProfileRenderInfo GenerateProfileRenderInfoFromProfile( HMDInfo const& hmdInfo, + Profile const* profile ) +{ + ProfileRenderInfo profileRenderInfo; + + if (!profile) + { + LogError("[Stereo] Error: No user profile provided."); + OVR_ASSERT(false); + return profileRenderInfo; + } + + // Eye cup type + char eyecup[16]; + if (profile->GetValue(OVR_KEY_EYE_CUP, eyecup, 16)) + { + profileRenderInfo.EyeCupType = eyecup; + } + + Ptr def = *ProfileManager::GetInstance()->GetDefaultProfile(hmdInfo.HmdType); + + // Set the eye position + // Use the user profile value unless they have elected to use the defaults + if (!profile->GetBoolValue(OVR_KEY_CUSTOM_EYE_RENDER, true)) + { + profile = def; // use the default + } + + if (!def) + { + LogError("[Stereo] Error: No user profile provided."); + OVR_ASSERT(false); + return profileRenderInfo; + } + + // Username + char user[32] = {}; + profile->GetValue(OVR_KEY_USER, user, 32); // for debugging purposes + + // TBD: Maybe we should separate custom camera positioning from custom distortion rendering ?? + float ipd = OVR_DEFAULT_IPD; + if (profile->GetFloatValues(OVR_KEY_EYE_TO_NOSE_DISTANCE, profileRenderInfo.Eye2Nose, 2) != 2) + { + // Legacy profiles may not include half-ipd, so use the regular IPD value instead + ipd = profile->GetFloatValue(OVR_KEY_IPD, OVR_DEFAULT_IPD); + } + + const float ipd_div2 = ipd * 0.5f; + profileRenderInfo.Eye2Nose[0] = ipd_div2; + profileRenderInfo.Eye2Nose[1] = ipd_div2; + + if ((profile->GetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, profileRenderInfo.Eye2Plate, 2) != 2) && + (def->GetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, profileRenderInfo.Eye2Plate, 2) != 2)) + { + // We shouldn't be here. The user or default profile should have the eye relief + OVR_ASSERT(false); + } + + profileRenderInfo.EyeReliefDial = profile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, OVR_DEFAULT_EYE_RELIEF_DIAL); + + + + OVR_DEBUG_LOG(("[Stereo] Read profile render info for user '%s'", user)); + + return profileRenderInfo; +} + //----------------------------------------------------------------------------------- @@ -620,9 +703,12 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) { HMDInfo info; - if ((hmdType != HmdType_DK1) && - (hmdType != HmdType_CrystalCoveProto) && - (hmdType != HmdType_DK2)) + info.DebugDevice = true; + + if ((hmdType != HmdType_DK1) + && (hmdType != HmdType_CrystalCoveProto) + && (hmdType != HmdType_DK2) + ) { LogText("Debug HMDInfo - HmdType not supported. Defaulting to DK1.\n"); hmdType = HmdType_DK1; @@ -687,6 +773,7 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) info.Shutter.PixelPersistence = 0.18f * info.Shutter.VsyncToNextVsync; break; + default: break; } @@ -696,16 +783,12 @@ HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType) HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, - Profile const *profile, + ProfileRenderInfo const& profileRenderInfo, DistortionEqnType distortionType /*= Distortion_CatmullRom10*/, EyeCupType eyeCupOverride /*= EyeCup_LAST*/ ) { HmdRenderInfo renderInfo; - OVR_ASSERT(profile); // profiles are required - if(!profile) - return renderInfo; - renderInfo.HmdType = hmdInfo.HmdType; renderInfo.ResolutionInPixels = hmdInfo.ResolutionInPixels; renderInfo.ScreenSizeInMeters = hmdInfo.ScreenSizeInMeters; @@ -727,6 +810,20 @@ HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, renderInfo.LensSurfaceToMidplateInMeters = 0.025f; renderInfo.EyeCups = EyeCup_DK1A; +#if defined(OVR_OS_LINUX) + // If the Rift is a monitor, + if (hmdInfo.InCompatibilityMode) + { + renderInfo.Rotation = hmdInfo.ShimInfo.Rotation; + } + else // Direct mode handles rotation internally + { +#endif + renderInfo.Rotation = 0; +#if defined(OVR_OS_LINUX) + } +#endif + #if 0 // Device settings are out of date - don't use them. if (Contents & Contents_Distortion) { @@ -760,13 +857,9 @@ HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, renderInfo.EyeRight = renderInfo.EyeLeft; - // Obtain data from profile. - char eyecup[16]; - if (profile->GetValue(OVR_KEY_EYE_CUP, eyecup, 16)) - { - SetEyeCup(&renderInfo, eyecup); - } - + // Set eye cup type + SetEyeCup(&renderInfo, profileRenderInfo.EyeCupType.ToCStr()); + switch ( hmdInfo.HmdType ) { case HmdType_None: @@ -831,59 +924,18 @@ HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, default: OVR_ASSERT ( false ); break; } - Profile* def = ProfileManager::GetInstance()->GetDefaultProfile(hmdInfo.HmdType); + renderInfo.EyeLeft.NoseToPupilInMeters = profileRenderInfo.Eye2Nose[0]; + renderInfo.EyeRight.NoseToPupilInMeters = profileRenderInfo.Eye2Nose[1]; - // Set the eye position - // Use the user profile value unless they have elected to use the defaults - if (!profile->GetBoolValue(OVR_KEY_CUSTOM_EYE_RENDER, true)) - profile = def; // use the default + // Subtract the eye-cup height from the plate distance to get the eye-to-lens distance + // This measurement should be the the distance at maximum dial setting + // We still need to adjust with the dial offset + renderInfo.EyeLeft.ReliefInMeters = profileRenderInfo.Eye2Plate[0] - renderInfo.LensSurfaceToMidplateInMeters; + renderInfo.EyeRight.ReliefInMeters = profileRenderInfo.Eye2Plate[1] - renderInfo.LensSurfaceToMidplateInMeters; - char user[32]; - profile->GetValue(OVR_KEY_USER, user, 32); // for debugging purposes - - // TBD: Maybe we should separate custom camera positioning from custom distortion rendering ?? - float eye2nose[2] = { OVR_DEFAULT_IPD / 2, OVR_DEFAULT_IPD / 2 }; - if (profile->GetFloatValues(OVR_KEY_EYE_TO_NOSE_DISTANCE, eye2nose, 2) == 2) - { - renderInfo.EyeLeft.NoseToPupilInMeters = eye2nose[0]; - renderInfo.EyeRight.NoseToPupilInMeters = eye2nose[1]; - } - else - { // Legacy profiles may not include half-ipd, so use the regular IPD value instead - float ipd = profile->GetFloatValue(OVR_KEY_IPD, OVR_DEFAULT_IPD); - renderInfo.EyeLeft.NoseToPupilInMeters = 0.5f * ipd; - renderInfo.EyeRight.NoseToPupilInMeters = 0.5f * ipd; - } - - float eye2plate[2]; - if ((profile->GetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, eye2plate, 2) == 2) || - (def->GetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, eye2plate, 2) == 2)) - { // Subtract the eye-cup height from the plate distance to get the eye-to-lens distance - // This measurement should be the the distance at maximum dial setting - // We still need to adjust with the dial offset - renderInfo.EyeLeft.ReliefInMeters = eye2plate[0] - renderInfo.LensSurfaceToMidplateInMeters; - renderInfo.EyeRight.ReliefInMeters = eye2plate[1] - renderInfo.LensSurfaceToMidplateInMeters; - - // Adjust the eye relief with the dial setting (from the assumed max eye relief) - int dial = profile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, OVR_DEFAULT_EYE_RELIEF_DIAL); - renderInfo.EyeLeft.ReliefInMeters -= ((10 - dial) * 0.001f); - renderInfo.EyeRight.ReliefInMeters -= ((10 - dial) * 0.001f); - } - else - { - // We shouldn't be here. The user or default profile should have the eye relief - OVR_ASSERT(false); - - // Set the eye relief with the user configured dial setting - //int dial = profile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, OVR_DEFAULT_EYE_RELIEF_DIAL); - - // Assume a default of 7 to 17 mm eye relief based on the dial. This corresponds - // to the sampled and tuned distortion range on the DK1. - //renderInfo.EyeLeft.ReliefInMeters = 0.007f + (dial * 0.001f); - //renderInfo.EyeRight.ReliefInMeters = 0.007f + (dial * 0.001f); - } - - def->Release(); + // Adjust the eye relief with the dial setting (from the assumed max eye relief) + renderInfo.EyeLeft.ReliefInMeters -= ((10 - profileRenderInfo.EyeReliefDial) * 0.001f); + renderInfo.EyeRight.ReliefInMeters -= ((10 - profileRenderInfo.EyeReliefDial) * 0.001f); // Now we know where the eyes are relative to the lenses, we can compute a distortion for each. @@ -897,6 +949,7 @@ HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, float eye_relief = pHmdEyeConfig->ReliefInMeters; LensConfig distortionConfig = GenerateLensConfigFromEyeRelief ( eye_relief, renderInfo, distortionType ); pHmdEyeConfig->Distortion = distortionConfig; + } return renderInfo; @@ -937,7 +990,31 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI { numDistortions = 0; + /* + distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10; + distortions[numDistortions].EyeRelief = 0.010f; + distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.0425f; + distortions[numDistortions].Config.K[0] = 1.0000f; + distortions[numDistortions].Config.K[1] = 1.0f; + distortions[numDistortions].Config.K[2] = 1.0f; + distortions[numDistortions].Config.K[3] = 1.0f; + distortions[numDistortions].Config.K[4] = 1.0f; + distortions[numDistortions].Config.K[5] = 1.0f; + distortions[numDistortions].Config.K[6] = 1.0f; + distortions[numDistortions].Config.K[7] = 1.0f; + distortions[numDistortions].Config.K[8] = 1.0f; + distortions[numDistortions].Config.K[9] = 1.0f; + distortions[numDistortions].Config.K[10] = 1.0f; + distortions[numDistortions].MaxRadius = 1.0f; + defaultDistortion = numDistortions; // this is the default + numDistortions++; + distortions[0].Config.ChromaticAberration[0] = 0.0f; + distortions[0].Config.ChromaticAberration[1] = 0.0f; + distortions[0].Config.ChromaticAberration[2] = 0.0f; + distortions[0].Config.ChromaticAberration[3] = 0.0f; + */ + // Tuned at minimum dial setting - extended to r^2 == 1.8 distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10; distortions[numDistortions].EyeRelief = 0.012760465f - 0.005f; @@ -1003,6 +1080,7 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI distortions[i].Config.ChromaticAberration[2] = 0.014f; distortions[i].Config.ChromaticAberration[3] = 0.0f; } + } else if ( hmd.EyeCups == EyeCup_DKHD2A ) { @@ -1099,26 +1177,6 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI defaultDistortion = numDistortions; // this is the default numDistortions++; - - /* - // Orange Lens on DK2 - distortions[numDistortions].EyeRelief = 0.010f; - distortions[numDistortions].Config.MetersPerTanAngleAtCenter = 0.031f; - - distortions[numDistortions].Config.Eqn = Distortion_CatmullRom10; - distortions[numDistortions].Config.K[0] = 1.00f; - distortions[numDistortions].Config.K[1] = 1.0169f; - distortions[numDistortions].Config.K[2] = 1.0378f; - distortions[numDistortions].Config.K[3] = 1.0648f; - distortions[numDistortions].Config.K[4] = 1.0990f; - distortions[numDistortions].Config.K[5] = 1.141f; - distortions[numDistortions].Config.K[6] = 1.192f; - distortions[numDistortions].Config.K[7] = 1.255f; - distortions[numDistortions].Config.K[8] = 1.335f; - distortions[numDistortions].Config.K[9] = 1.435f; - distortions[numDistortions].Config.K[10] = 1.56f; - distortions[numDistortions].MaxRadius = 1.0f; - */ } else { @@ -1152,8 +1210,8 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI OVR_ASSERT(numDistortions < MaxDistortions); - DistortionDescriptor *pUpper = NULL; - DistortionDescriptor *pLower = NULL; + DistortionDescriptor *pUpper = nullptr; + DistortionDescriptor *pLower = nullptr; float lerpVal = 0.0f; if (eyeReliefInMeters == 0) { // Use a constant default distortion if an invalid eye-relief is supplied @@ -1176,7 +1234,7 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI } } - if ( pUpper == NULL ) + if ( pUpper == nullptr ) { #if 0 // Outside the range, so extrapolate rather than interpolate. @@ -1315,7 +1373,7 @@ LensConfig GenerateLensConfigFromEyeRelief ( float eyeReliefInMeters, HmdRenderI DistortionRenderDesc CalculateDistortionRenderDesc ( StereoEye eyeType, HmdRenderInfo const &hmd, - const LensConfig *pLensOverride /*= NULL */ ) + const LensConfig *pLensOverride /*= nullptr */ ) { // From eye relief, IPD and device characteristics, we get the distortion mapping. // This distortion does the following things: @@ -1342,7 +1400,7 @@ DistortionRenderDesc CalculateDistortionRenderDesc ( StereoEye eyeType, HmdRende DistortionRenderDesc localDistortion; localDistortion.Lens = hmdEyeConfig.Distortion; - if ( pLensOverride != NULL ) + if ( pLensOverride != nullptr ) { localDistortion.Lens = *pLensOverride; } @@ -1454,6 +1512,7 @@ FovPort CalculateFovFromHmdInfo ( StereoEye eyeType, // unnecessarily large render targets) eyeReliefInMeters = Alg::Max(eyeReliefInMeters, 0.006f); + // Central view. fovPort = CalculateFovFromEyePosition ( eyeReliefInMeters, offsetToRightInMeters, @@ -1566,24 +1625,6 @@ Recti GetFramebufferViewport ( StereoEye eyeType, HmdRenderInfo const &hmd ) } -ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort tanHalfFov ) -{ - float projXScale = 2.0f / ( tanHalfFov.LeftTan + tanHalfFov.RightTan ); - float projXOffset = ( tanHalfFov.LeftTan - tanHalfFov.RightTan ) * projXScale * 0.5f; - float projYScale = 2.0f / ( tanHalfFov.UpTan + tanHalfFov.DownTan ); - float projYOffset = ( tanHalfFov.UpTan - tanHalfFov.DownTan ) * projYScale * 0.5f; - - ScaleAndOffset2D result; - result.Scale = Vector2f(projXScale, projYScale); - result.Offset = Vector2f(projXOffset, projYOffset); - // Hey - why is that Y.Offset negated? - // It's because a projection matrix transforms from world coords with Y=up, - // whereas this is from NDC which is Y=down. - - return result; -} - - ScaleAndOffset2D CreateUVScaleAndOffsetfromNDCScaleandOffset ( ScaleAndOffset2D scaleAndOffsetNDC, Recti renderedViewport, Sizei renderTargetSize ) @@ -1608,132 +1649,6 @@ ScaleAndOffset2D CreateUVScaleAndOffsetfromNDCScaleandOffset ( ScaleAndOffset2D } - -Matrix4f CreateProjection( bool rightHanded, FovPort tanHalfFov, - float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/ ) -{ - // A projection matrix is very like a scaling from NDC, so we can start with that. - ScaleAndOffset2D scaleAndOffset = CreateNDCScaleAndOffsetFromFov ( tanHalfFov ); - - float handednessScale = 1.0f; - if ( rightHanded ) - { - handednessScale = -1.0f; - } - - Matrix4f projection; - // Produces X result, mapping clip edges to [-w,+w] - projection.M[0][0] = scaleAndOffset.Scale.x; - projection.M[0][1] = 0.0f; - projection.M[0][2] = handednessScale * scaleAndOffset.Offset.x; - projection.M[0][3] = 0.0f; - - // Produces Y result, mapping clip edges to [-w,+w] - // Hey - why is that YOffset negated? - // It's because a projection matrix transforms from world coords with Y=up, - // whereas this is derived from an NDC scaling, which is Y=down. - projection.M[1][0] = 0.0f; - projection.M[1][1] = scaleAndOffset.Scale.y; - projection.M[1][2] = handednessScale * -scaleAndOffset.Offset.y; - projection.M[1][3] = 0.0f; - - // Produces Z-buffer result - app needs to fill this in with whatever Z range it wants. - // We'll just use some defaults for now. - projection.M[2][0] = 0.0f; - projection.M[2][1] = 0.0f; - projection.M[2][2] = -handednessScale * zFar / (zNear - zFar); - projection.M[2][3] = (zFar * zNear) / (zNear - zFar); - - // Produces W result (= Z in) - projection.M[3][0] = 0.0f; - projection.M[3][1] = 0.0f; - projection.M[3][2] = handednessScale; - projection.M[3][3] = 0.0f; - - return projection; -} - - -Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType, - float tanHalfFovX, float tanHalfFovY, - float unitsX, float unitsY, - float distanceFromCamera, float interpupillaryDistance, - Matrix4f const &projection, - float zNear /*= 0.0f*/, float zFar /*= 0.0f*/ ) -{ - OVR_UNUSED1 ( rightHanded ); - - float orthoHorizontalOffset = interpupillaryDistance * 0.5f / distanceFromCamera; - switch ( eyeType ) - { - case StereoEye_Center: - orthoHorizontalOffset = 0.0f; - break; - case StereoEye_Left: - break; - case StereoEye_Right: - orthoHorizontalOffset = -orthoHorizontalOffset; - break; - default: OVR_ASSERT ( false ); break; - } - - // Current projection maps real-world vector (x,y,1) to the RT. - // We want to find the projection that maps the range [-FovPixels/2,FovPixels/2] to - // the physical [-orthoHalfFov,orthoHalfFov] - // Note moving the offset from M[0][2]+M[1][2] to M[0][3]+M[1][3] - this means - // we don't have to feed in Z=1 all the time. - // The horizontal offset math is a little hinky because the destination is - // actually [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset] - // So we need to first map [-FovPixels/2,FovPixels/2] to - // [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]: - // x1 = x0 * orthoHalfFov/(FovPixels/2) + orthoHorizontalOffset; - // = x0 * 2*orthoHalfFov/FovPixels + orthoHorizontalOffset; - // But then we need the sam mapping as the existing projection matrix, i.e. - // x2 = x1 * Projection.M[0][0] + Projection.M[0][2]; - // = x0 * (2*orthoHalfFov/FovPixels + orthoHorizontalOffset) * Projection.M[0][0] + Projection.M[0][2]; - // = x0 * Projection.M[0][0]*2*orthoHalfFov/FovPixels + - // orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]; - // So in the new projection matrix we need to scale by Projection.M[0][0]*2*orthoHalfFov/FovPixels and - // offset by orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]. - - float orthoScaleX = 2.0f * tanHalfFovX / unitsX; - float orthoScaleY = 2.0f * tanHalfFovY / unitsY; - Matrix4f ortho; - ortho.M[0][0] = projection.M[0][0] * orthoScaleX; - ortho.M[0][1] = 0.0f; - ortho.M[0][2] = 0.0f; - ortho.M[0][3] = -projection.M[0][2] + ( orthoHorizontalOffset * projection.M[0][0] ); - - ortho.M[1][0] = 0.0f; - ortho.M[1][1] = -projection.M[1][1] * orthoScaleY; // Note sign flip (text rendering uses Y=down). - ortho.M[1][2] = 0.0f; - ortho.M[1][3] = -projection.M[1][2]; - - if ( fabsf ( zNear - zFar ) < 0.001f ) - { - ortho.M[2][0] = 0.0f; - ortho.M[2][1] = 0.0f; - ortho.M[2][2] = 0.0f; - ortho.M[2][3] = zFar; - } - else - { - ortho.M[2][0] = 0.0f; - ortho.M[2][1] = 0.0f; - ortho.M[2][2] = zFar / (zNear - zFar); - ortho.M[2][3] = (zFar * zNear) / (zNear - zFar); - } - - // No perspective correction for ortho. - ortho.M[3][0] = 0.0f; - ortho.M[3][1] = 0.0f; - ortho.M[3][2] = 0.0f; - ortho.M[3][3] = 1.0f; - - return ortho; -} - - //----------------------------------------------------------------------------------- // A set of "forward-mapping" functions, mapping from framebuffer space to real-world and/or texture space. @@ -1863,6 +1778,312 @@ Vector2f TransformRendertargetNDCToTanFovSpace( const ScaleAndOffset2D &eyeToSou +//----------------------------------------------------------------------------- +// Timewarp Matrix +// +// These functions provide helper functions to compute the timewarp shader input +// matrices needed during the distortion/timewarp/chroma draw call. + +//----------------------------------------------------------------------------- +// CalculateOrientationTimewarpMatrix +// +// For Orientation-only Timewarp, the inputs are quaternions and the output is +// a transform matrix. The matrix may need to be transposed depending on which +// renderer is used. This function produces one compatible with D3D11. +// +// eye: Input quaternion of EyeRenderPose.Orientation inverted. +// pred: Input quaternion of predicted eye pose at scanout. +// M: Output D3D11-compatible transform matrix for the Timewarp shader. +void CalculateOrientationTimewarpMatrix(Quatf const & eyeInv, Quatf const & pred, Matrix4f& M) +{ + Posef renderFromEyeInverted = Posef ( eyeInv, Vector3f::Zero() ); + Posef hmdPose = Posef ( pred, Vector3f::Zero() ); + + CalculatePositionalTimewarpMatrix ( renderFromEyeInverted, hmdPose, Vector3f::Zero(), M ); +} + +//----------------------------------------------------------------------------- +// CalculatePositionalTimewarpMatrix +// +// The matrix may need to be transposed depending on which +// renderer is used. This function produces one compatible with D3D11. +// +// renderFromEyeInverted: Input render transform from eye inverted. +// hmdPose: Input predicted head pose from HMD tracking code. +// extraQuat: Input extra quaternion rotation applied to calculations. +// extraEyeOffset: Input extra eye position offset applied to calculations. +// M: Output D3D11-compatible transform matrix for the Timewarp shader. +void CalculatePositionalTimewarpMatrix(Posef const & renderFromEyeInverted, Posef const & hmdPose, + Vector3f const & extraEyeOffset, + Matrix4f& M) +{ + + Posef eyePose = Posef(hmdPose.Rotation, hmdPose.Translation + extraEyeOffset); + Matrix4f Mres = Matrix4f(renderFromEyeInverted * eyePose); + + // The real-world orientations have: X=right, Y=up, Z=backwards. + // The vectors inside the mesh are in NDC to keep the shader simple: X=right, Y=down, Z=forwards. + // So we need to perform a similarity transform on this delta matrix. + // The verbose code would look like this: + /* + Matrix4f matBasisChange; + matBasisChange.SetIdentity(); + matBasisChange.M[0][0] = 1.0f; + matBasisChange.M[1][1] = -1.0f; + matBasisChange.M[2][2] = -1.0f; + Matrix4f matBasisChangeInv = matBasisChange.Inverted(); + matRenderFromNow = matBasisChangeInv * matRenderFromNow * matBasisChange; + */ + // ...but of course all the above is a constant transform and much more easily done. + // We flip the signs of the Y&Z row, then flip the signs of the Y&Z column, + // and of course most of the flips cancel: + // +++ +-- +-- + // +++ -> flip Y&Z columns -> +-- -> flip Y&Z rows -> -++ + // +++ +-- -++ + Mres.M[0][1] = -Mres.M[0][1]; + Mres.M[0][2] = -Mres.M[0][2]; + Mres.M[1][0] = -Mres.M[1][0]; + Mres.M[2][0] = -Mres.M[2][0]; + Mres.M[1][3] = -Mres.M[1][3]; + Mres.M[2][3] = -Mres.M[2][3]; + + M = Mres; +} + + +//----------------------------------------------------------------------------- +// CalculateTimewarpFromSensors +// +// Read current pose from sensors and construct timewarp matrices for start/end +// predicted poses. +// +// hmdPose: RenderPose eye quaternion, *not* inverted. +// reader: the tracking state +// poseInFaceSpace: true if the pose supplied is stuck-to-your-face rather than fixed-in-space +// calcPosition: true if the position part of the result is actually used (false = orientation only) +// hmdToEyeViewOffset: offset from the HMD "middle eye" to actual eye. +// startEndTimes: start and end times of the screen - typically fed direct from Timing->GetTimewarpTiming()->EyeStartEndTimes[eyeNum] +// +// Results: +// startEndMatrices: Timewarp matrices for the start and end times respectively. +// timewarpIMUTime: On success it contains the raw IMU sample time for the pose. +// Returns false on failure to read state. +bool CalculateTimewarpFromSensors(Posef const & hmdPose, + Vision::TrackingStateReader* reader, + bool poseInFaceSpace, + bool calcPosition, + ovrVector3f const &hmdToEyeViewOffset, + const double startEndTimes[2], + Matrix4f startEndMatrices[2], + double& timewarpIMUTime) +{ + Vision::TrackingState startState, endState; + if (!reader->GetTrackingStateAtTime(startEndTimes[0], startState) || + !reader->GetTrackingStateAtTime(startEndTimes[1], endState)) + { + // No data is available so do not do timewarp. + startEndMatrices[0] = Matrix4f::Identity(); + startEndMatrices[1] = Matrix4f::Identity(); + timewarpIMUTime = 0.; + return false; + } + + ovrPosef startHmdPose; + ovrPosef endHmdPose; + if ( poseInFaceSpace ) + { + startHmdPose.Position = Vector3f::Zero(); + startHmdPose.Orientation = Quatf::Identity(); + endHmdPose = startHmdPose; + } + else + { + startHmdPose = startState.HeadPose.ThePose; + endHmdPose = endState.HeadPose.ThePose; + } + + Posef renderPose = hmdPose; + Vector3f eyeOffset = Vector3f(0.0f, 0.0f, 0.0f); + if(calcPosition) + { + if(hmdToEyeViewOffset.x >= MATH_FLOAT_MAXVALUE) + { + OVR_ASSERT(false); + LogError("{ERR-103} [FrameTime] Invalid hmdToEyeViewOffset provided by client."); + + renderPose.Translation = Vector3f::Zero(); // disable position to avoid positional issues + } + else + { + // Currently HmdToEyeViewOffset is only a 3D vector + // (Negate HmdToEyeViewOffset because offset is a view matrix offset and not a camera offset) + eyeOffset = ((Posef)startHmdPose).Apply(-((Vector3f)hmdToEyeViewOffset)); + } + } + else + { + // Orientation only. + renderPose.Translation = Vector3f::Zero(); + } + + + if(calcPosition) + { + Posef hmdPoseInv = hmdPose.Inverted(); + CalculatePositionalTimewarpMatrix ( hmdPoseInv, startHmdPose, + eyeOffset, startEndMatrices[0] ); + CalculatePositionalTimewarpMatrix ( hmdPoseInv, endHmdPose, + eyeOffset, startEndMatrices[1] ); + } + else + { + // Orientation-only. + Quatf quatFromEye = hmdPose.Rotation.Inverted(); + CalculateOrientationTimewarpMatrix(quatFromEye, startHmdPose.Orientation, startEndMatrices[0]); + CalculateOrientationTimewarpMatrix(quatFromEye, endHmdPose.Orientation, startEndMatrices[1]); + } + + // Store off the IMU sample time. + timewarpIMUTime = startState.RawSensorData.AbsoluteTimeSeconds; + + return true; +} + +// Only handles orientation, not translation. +bool CalculateOrientationTimewarpFromSensors(Quatf const & eyeQuat, + Vision::TrackingStateReader* reader, + const double startEndTimes[2], + Matrix4f startEndMatrices[2], + double& timewarpIMUTime) +{ + Posef hmdPose = Posef ( eyeQuat, Vector3f::Zero() ); + return CalculateTimewarpFromSensors ( hmdPose, reader, false, false, Vector3f::Zero(), startEndTimes, startEndMatrices, timewarpIMUTime ); +} + + +//----------------------------------------------------------------------------- +// CalculateEyeTimewarpTimes +// +// Given the scanout start time, duration of scanout, and shutter type, this +// function returns the timewarp left/right eye start and end prediction times. +void CalculateEyeTimewarpTimes(double scanoutStartTime, double scanoutDuration, + HmdShutterTypeEnum shutterType, + double leftEyeStartEndTime[2], double rightEyeStartEndTime[2]) +{ + // Calculate absolute points in time when eye rendering or corresponding time-warp + // screen edges will become visible. + // This only matters with VSync. + switch (shutterType) + { + case HmdShutter_RollingTopToBottom: + case HmdShutter_RollingLeftToRight: + case HmdShutter_RollingRightToLeft: + // This is *Correct* with Tom's distortion mesh organization. + leftEyeStartEndTime[0] = scanoutStartTime; + leftEyeStartEndTime[1] = scanoutStartTime + scanoutDuration; + rightEyeStartEndTime[0] = scanoutStartTime; + rightEyeStartEndTime[1] = scanoutStartTime + scanoutDuration; + break; + case HmdShutter_Global: + // TBD + { + double midpoint = scanoutStartTime + scanoutDuration * 0.5; + leftEyeStartEndTime[0] = midpoint; + leftEyeStartEndTime[1] = midpoint; + rightEyeStartEndTime[0] = midpoint; + rightEyeStartEndTime[1] = midpoint; + } + break; + default: + OVR_ASSERT(false); + break; + } +} + +//----------------------------------------------------------------------------- +// CalculateEyeRenderTimes +// +// Given the scanout start time, duration of scanout, and shutter type, this +// function returns the left/right eye render times. +void CalculateEyeRenderTimes(double scanoutStartTime, double scanoutDuration, + HmdShutterTypeEnum shutterType, + double& leftEyeRenderTime, double& rightEyeRenderTime) +{ + switch(shutterType) + { + case HmdShutter_RollingTopToBottom: + case HmdShutter_Global: + leftEyeRenderTime = scanoutStartTime + scanoutDuration * 0.5; + rightEyeRenderTime = scanoutStartTime + scanoutDuration * 0.5; + break; + case HmdShutter_RollingLeftToRight: + leftEyeRenderTime = scanoutStartTime + scanoutDuration * 0.25; + rightEyeRenderTime = scanoutStartTime + scanoutDuration * 0.75; + break; + case HmdShutter_RollingRightToLeft: + leftEyeRenderTime = scanoutStartTime + scanoutDuration * 0.75; + rightEyeRenderTime = scanoutStartTime + scanoutDuration * 0.25; + break; + default: + OVR_ASSERT(false); + break; + } +} + + +//----------------------------------------------------------------------------- +// CalculateDistortionMeshFromFOV +// +// This function fills in the target meshData object given the provided +// parameters, for a single specified eye. +// +// Returns false on failure. +bool CalculateDistortionMeshFromFOV(HmdRenderInfo const & renderInfo, + DistortionRenderDesc const & distortionDesc, + StereoEye stereoEye, FovPort fov, + unsigned distortionCaps, + ovrDistortionMesh *meshData) +{ + if (!meshData) + { + return false; + } + + // Not used now, but Chromatic flag or others could possibly be checked for in the future. + OVR_UNUSED1(distortionCaps); + + // *** Calculate a part of "StereoParams" needed for mesh generation + + // Note that mesh distortion generation is invariant of RenderTarget UVs, allowing + // render target size and location to be changed after the fact dynamically. + // eyeToSourceUV is computed here for convenience, so that users don't need + // to call ovrHmd_GetRenderScaleAndOffset unless changing RT dynamically. + + // Find the mapping from TanAngle space to target NDC space. + ScaleAndOffset2D eyeToSourceNDC = CreateNDCScaleAndOffsetFromFov(fov); + + int triangleCount = 0; + int vertexCount = 0; + + OVR::Util::Render::DistortionMeshCreate( + (OVR::Util::Render::DistortionMeshVertexData**)&meshData->pVertexData, + (uint16_t**)&meshData->pIndexData, + &vertexCount, &triangleCount, + (stereoEye == StereoEye_Right), + renderInfo, distortionDesc, eyeToSourceNDC); + + if (meshData->pVertexData) + { + // Convert to index + meshData->IndexCount = triangleCount * 3; + meshData->VertexCount = vertexCount; + return true; + } + + return false; +} + + } //namespace OVR //Just want to make a copy disentangled from all these namespaces! @@ -1870,5 +2091,3 @@ float ExtEvalCatmullRom10Spline ( float const *K, float scaledVal ) { return(OVR::EvalCatmullRom10Spline ( K, scaledVal )); } - - diff --git a/LibOVR/Src/OVR_Stereo.h b/LibOVR/Src/OVR_Stereo.h old mode 100644 new mode 100755 index f002d14..cea2261 --- a/LibOVR/Src/OVR_Stereo.h +++ b/LibOVR/Src/OVR_Stereo.h @@ -29,7 +29,11 @@ limitations under the License. #include "Sensors/OVR_DeviceConstants.h" #include "Displays/OVR_Display.h" +#include "Vision/SensorFusion/Vision_SensorStateReader.h" #include "OVR_Profile.h" +#include "OVR_CAPI.h" // ovrDistortionMesh +#include "OVR_StereoProjection.h" + // CAPI Forward declaration. typedef struct ovrFovPort_ ovrFovPort; @@ -40,117 +44,6 @@ namespace OVR { class SensorDevice; // Opaque forward declaration -//----------------------------------------------------------------------------------- -// ***** Stereo Enumerations - -// StereoEye specifies which eye we are rendering for; it is used to -// retrieve StereoEyeParams. -enum StereoEye -{ - StereoEye_Center, - StereoEye_Left, - StereoEye_Right -}; - - -//----------------------------------------------------------------------------------- -// ***** FovPort - -// FovPort describes Field Of View (FOV) of a viewport. -// This class has values for up, down, left and right, stored in -// tangent of the angle units to simplify calculations. -// -// As an example, for a standard 90 degree vertical FOV, we would -// have: { UpTan = tan(90 degrees / 2), DownTan = tan(90 degrees / 2) }. -// -// CreateFromRadians/Degrees helper functions can be used to -// access FOV in different units. - -struct FovPort -{ - float UpTan; - float DownTan; - float LeftTan; - float RightTan; - - FovPort ( float sideTan = 0.0f ) : - UpTan(sideTan), DownTan(sideTan), LeftTan(sideTan), RightTan(sideTan) { } - FovPort ( float u, float d, float l, float r ) : - UpTan(u), DownTan(d), LeftTan(l), RightTan(r) { } - - // C-interop support: FovPort <-> ovrFovPort (implementation in OVR_CAPI.cpp). - FovPort(const ovrFovPort& src); - operator ovrFovPort () const; - - static FovPort CreateFromRadians(float horizontalFov, float verticalFov) - { - FovPort result; - result.UpTan = tanf ( verticalFov * 0.5f ); - result.DownTan = tanf ( verticalFov * 0.5f ); - result.LeftTan = tanf ( horizontalFov * 0.5f ); - result.RightTan = tanf ( horizontalFov * 0.5f ); - return result; - } - - static FovPort CreateFromDegrees(float horizontalFovDegrees, - float verticalFovDegrees) - { - return CreateFromRadians(DegreeToRad(horizontalFovDegrees), - DegreeToRad(verticalFovDegrees)); - } - - // Get Horizontal/Vertical components of Fov in radians. - float GetVerticalFovRadians() const { return atanf(UpTan) + atanf(DownTan); } - float GetHorizontalFovRadians() const { return atanf(LeftTan) + atanf(RightTan); } - // Get Horizontal/Vertical components of Fov in degrees. - float GetVerticalFovDegrees() const { return RadToDegree(GetVerticalFovRadians()); } - float GetHorizontalFovDegrees() const { return RadToDegree(GetHorizontalFovRadians()); } - - // Compute maximum tangent value among all four sides. - float GetMaxSideTan() const - { - return Alg::Max(Alg::Max(UpTan, DownTan), Alg::Max(LeftTan, RightTan)); - } - - // Converts Fov Tan angle units to [-1,1] render target NDC space - Vector2f TanAngleToRendertargetNDC(Vector2f const &tanEyeAngle); - - - // Compute per-channel minimum and maximum of Fov. - static FovPort Min(const FovPort& a, const FovPort& b) - { - FovPort fov( Alg::Min( a.UpTan , b.UpTan ), - Alg::Min( a.DownTan , b.DownTan ), - Alg::Min( a.LeftTan , b.LeftTan ), - Alg::Min( a.RightTan, b.RightTan ) ); - return fov; - } - - static FovPort Max(const FovPort& a, const FovPort& b) - { - FovPort fov( Alg::Max( a.UpTan , b.UpTan ), - Alg::Max( a.DownTan , b.DownTan ), - Alg::Max( a.LeftTan , b.LeftTan ), - Alg::Max( a.RightTan, b.RightTan ) ); - return fov; - } -}; - - -//----------------------------------------------------------------------------------- -// ***** ScaleAndOffset - -struct ScaleAndOffset2D -{ - Vector2f Scale; - Vector2f Offset; - - ScaleAndOffset2D(float sx = 0.0f, float sy = 0.0f, float ox = 0.0f, float oy = 0.0f) - : Scale(sx, sy), Offset(ox, oy) - { } -}; - - //----------------------------------------------------------------------------------- // ***** Misc. utility functions. @@ -285,8 +178,8 @@ struct DistortionRenderDesc // Set update mode: Stereo (both sides together), mono (same in both eyes), // Alternating, Alternating scan-lines. -// Win32 Oculus VR Display Driver Shim Information -struct Win32ShimInfo +// Oculus VR Display Driver Shim Information +struct ExtraMonitorInfo { int DeviceNumber; int NativeWidth; @@ -294,11 +187,11 @@ struct Win32ShimInfo int Rotation; int UseMirroring; - Win32ShimInfo() : - DeviceNumber(-1), - NativeWidth(-1), - NativeHeight(-1), - Rotation(-1), + ExtraMonitorInfo() : + DeviceNumber(0), + NativeWidth(1920), + NativeHeight(1080), + Rotation(0), UseMirroring(1) { } @@ -315,6 +208,7 @@ public: // Characteristics of the HMD screen and enclosure HmdTypeEnum HmdType; + bool DebugDevice; // Indicates if the HMD is a virtual debug device, such as when there is no HMD present. Size ResolutionInPixels; Size ScreenSizeInMeters; float ScreenGapSizeInMeters; @@ -323,7 +217,6 @@ public: Vector2f PelOffsetR; // Offsets from the green pel in pixels (i.e. usual values are 0.5 or 0.333) Vector2f PelOffsetB; - // Timing & shutter data. All values in seconds. struct ShutterInfo { @@ -342,7 +235,7 @@ public: // Windows: // "\\\\.\\DISPLAY3", etc. Can be used in EnumDisplaySettings/CreateDC. String DisplayDeviceName; - Win32ShimInfo ShimInfo; + ExtraMonitorInfo ShimInfo; // MacOS: int DisplayId; @@ -370,6 +263,7 @@ public: Manufacturer(), Version(0), HmdType(HmdType_None), + DebugDevice(false), ResolutionInPixels(0), ScreenSizeInMeters(0.0f), ScreenGapSizeInMeters(0.0f), @@ -409,6 +303,7 @@ public: Manufacturer = src.Manufacturer; Version = src.Version; HmdType = src.HmdType; + DebugDevice = src.DebugDevice; ResolutionInPixels = src.ResolutionInPixels; ScreenSizeInMeters = src.ScreenSizeInMeters; ScreenGapSizeInMeters = src.ScreenGapSizeInMeters; @@ -475,6 +370,13 @@ struct HmdRenderInfo Vector2f PelOffsetR; // Offsets from the green pel in pixels (i.e. usual values are 0.5 or 0.333) Vector2f PelOffsetB; + // Display is rotated 0/90/180/270 degrees counter-clockwise? + int Rotation; + + // Some displays scan out in different directions, so this flag can be used to change + // where we render the latency test pixel. + bool OffsetLatencyTester; + // Characteristics of the lenses. float CenterFromTopInMeters; float LensSeparationInMeters; @@ -491,7 +393,7 @@ struct HmdRenderInfo float FirstScanlineToLastScanline; // for global shutter, will be zero. float PixelSettleTime; // estimated. float PixelPersistence; // Full persistence = 1/framerate. - } Shutter; + } Shutter; // These are all set from the user's profile. @@ -520,6 +422,8 @@ struct HmdRenderInfo LensSurfaceToMidplateInMeters = 0.0f; PelOffsetR = Vector2f ( 0.0f, 0.0f ); PelOffsetB = Vector2f ( 0.0f, 0.0f ); + Rotation = 0; + OffsetLatencyTester = false; Shutter.Type = HmdShutter_LAST; Shutter.VsyncToNextVsync = 0.0f; Shutter.VsyncToFirstScanline = 0.0f; @@ -547,6 +451,30 @@ struct HmdRenderInfo }; +//----------------------------------------------------------------------------- +// ProfileRenderInfo +// +// Render-related information from the user profile. +struct ProfileRenderInfo +{ + // Type of eye cup on the headset + // ie. "A", "Orange A" + String EyeCupType; + + // IPD/2 offset for each eye + float Eye2Nose[2]; + + // Eye to plate distance for each eye + float Eye2Plate[2]; + + // Eye relief dial + int EyeReliefDial; + + + ProfileRenderInfo(); +}; + + //----------------------------------------------------------------------------------- // Stateless computation functions, in somewhat recommended execution order. @@ -558,12 +486,16 @@ const float OVR_DEFAULT_EXTRA_EYE_ROTATION = 30.0f * MATH_FLOAT_DEGREETORADFACTO // Useful for development without an actual HMD attached. HMDInfo CreateDebugHMDInfo(HmdTypeEnum hmdType); +// Fills in a render info object from a user Profile object. +// It may need to fill in some defaults, so it also takes in the HMD type. +ProfileRenderInfo GenerateProfileRenderInfoFromProfile( HMDInfo const& hmdInfo, + Profile const* profile ); // profile may be NULL, in which case it uses the hard-coded defaults. // distortionType should be left at the default unless you require something specific for your distortion shaders. // eyeCupOverride can be EyeCup_LAST, in which case it uses the one in the profile. HmdRenderInfo GenerateHmdRenderInfoFromHmdInfo ( HMDInfo const &hmdInfo, - Profile const *profile = NULL, + ProfileRenderInfo const& profileRenderInfo, DistortionEqnType distortionType = Distortion_CatmullRom10, EyeCupType eyeCupOverride = EyeCup_LAST ); @@ -594,17 +526,6 @@ Sizei CalculateIdealPixelSize ( StereoEye eyeType, DistortionRende Recti GetFramebufferViewport ( StereoEye eyeType, HmdRenderInfo const &hmd ); -Matrix4f CreateProjection ( bool rightHanded, FovPort fov, - float zNear = 0.01f, float zFar = 10000.0f ); - -Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType, - float tanHalfFovX, float tanHalfFovY, - float unitsX, float unitsY, float distanceFromCamera, - float interpupillaryDistance, Matrix4f const &projection, - float zNear = 0.0f, float zFar = 0.0f ); - -ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort fov ); - ScaleAndOffset2D CreateUVScaleAndOffsetfromNDCScaleandOffset ( ScaleAndOffset2D scaleAndOffsetNDC, Recti renderedViewport, Sizei renderTargetSize ); @@ -676,6 +597,97 @@ inline Vector2f TransformTanFovSpaceToRendertargetNDC ( StereoEyeParams const &e return TransformTanFovSpaceToRendertargetNDC ( eyeParams.EyeToSourceNDC, tanEyeAngle ); } + +//----------------------------------------------------------------------------- +// CalculateOrientationTimewarpMatrix +// +// For Orientation-only Timewarp, the inputs are quaternions and the output is +// a transform matrix. The matrix may need to be transposed depending on which +// renderer is used. This function produces one compatible with D3D11. +// +// eye: Input quaternion of EyeRenderPose.Orientation inverted. +// pred: Input quaternion of predicted eye pose at scanout. +// M: Output D3D11-compatible transform matrix for the Timewarp shader. +void CalculateOrientationTimewarpMatrix(Quatf const & eye, Quatf const & pred, Matrix4f& M); + +//----------------------------------------------------------------------------- +// CalculatePositionalTimewarpMatrix +// +// The matrix may need to be transposed depending on which +// renderer is used. This function produces one compatible with D3D11. +// +// renderFromEyeInverted: Input render transform from eye inverted. +// hmdPose: Input predicted head pose from HMD tracking code. +// extraEyeOffset: Input extra eye position offset applied to calculations. +// M: Output D3D11-compatible transform matrix for the Timewarp shader. +void CalculatePositionalTimewarpMatrix(Posef const & renderFromEyeInverted, Posef const & hmdPose, + Vector3f const & extraEyeOffset, Matrix4f& M); + +//----------------------------------------------------------------------------- +// CalculateTimewarpFromSensors +// +// Read current pose from sensors and construct timewarp matrices for start/end +// predicted poses. +// +// hmdPose: RenderPose eye quaternion, *not* inverted. +// reader: the tracking state +// poseInFaceSpace: true if the pose supplied is stuck-to-your-face rather than fixed-in-place +// calcPosition: true if the position part of the result is actually used (false = orientation only) +// hmdToEyeViewOffset: offset from the HMD "middle eye" to actual eye. +// startEndTimes: start and end times of the screen - typically fed direct from Timing->GetTimewarpTiming()->EyeStartEndTimes[eyeNum] +// +// Results: +// startEndMatrices: Timewarp matrices for the start and end times respectively. +// timewarpIMUTime: On success it contains the raw IMU sample time for the pose. +// Returns false on failure to read state. +bool CalculateTimewarpFromSensors(Posef const & hmdPose, + Vision::TrackingStateReader* reader, + bool poseInFaceSpace, + bool calcPosition, + ovrVector3f const &hmdToEyeViewOffset, + const double startEndTimes[2], + Matrix4f startEndMatrices[2], + double& timewarpIMUTime); + +// Orientation-only version. +bool CalculateOrientationTimewarpFromSensors(Quatf const & eyeQuat, + Vision::TrackingStateReader* reader, + const double startEndTimes[2], Matrix4f startEndMatrices[2], + double& timewarpIMUTime); + +//----------------------------------------------------------------------------- +// CalculateEyeTimewarpTimes +// +// Given the scanout start time, duration of scanout, and shutter type, this +// function returns the timewarp left/right eye start and end prediction times. +void CalculateEyeTimewarpTimes(double scanoutStartTime, double scanoutDuration, + HmdShutterTypeEnum shutterType, + double leftEyeStartEndTime[2], double rightEyeStartEndTime[2]); + +//----------------------------------------------------------------------------- +// CalculateEyeRenderTimes +// +// Given the scanout start time, duration of scanout, and shutter type, this +// function returns the left/right eye render times. +void CalculateEyeRenderTimes(double scanoutStartTime, double scanoutDuration, + HmdShutterTypeEnum shutterType, + double& leftEyeRenderTime, double& rightEyeRenderTime); + + +//----------------------------------------------------------------------------- +// CalculateDistortionMeshFromFOV +// +// This function fills in the target meshData object given the provided +// parameters, for a single specified eye. +// +// Returns false on failure. +bool CalculateDistortionMeshFromFOV(HmdRenderInfo const & renderInfo, + DistortionRenderDesc const & distortionDesc, + StereoEye stereoEye, FovPort fov, + unsigned distortionCaps, + ovrDistortionMesh *meshData); + + } //namespace OVR #endif // OVR_Stereo_h diff --git a/LibOVR/Src/OVR_StereoProjection.cpp b/LibOVR/Src/OVR_StereoProjection.cpp new file mode 100644 index 0000000..f0ae034 --- /dev/null +++ b/LibOVR/Src/OVR_StereoProjection.cpp @@ -0,0 +1,216 @@ +/************************************************************************************ + +Filename : OVR_StereoProjection.cpp +Content : Stereo rendering functions +Created : November 30, 2013 +Authors : Tom Fosyth + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "OVR_StereoProjection.h" + + +namespace OVR { + + +ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort tanHalfFov ) +{ + float projXScale = 2.0f / ( tanHalfFov.LeftTan + tanHalfFov.RightTan ); + float projXOffset = ( tanHalfFov.LeftTan - tanHalfFov.RightTan ) * projXScale * 0.5f; + float projYScale = 2.0f / ( tanHalfFov.UpTan + tanHalfFov.DownTan ); + float projYOffset = ( tanHalfFov.UpTan - tanHalfFov.DownTan ) * projYScale * 0.5f; + + ScaleAndOffset2D result; + result.Scale = Vector2f(projXScale, projYScale); + result.Offset = Vector2f(projXOffset, projYOffset); + // Hey - why is that Y.Offset negated? + // It's because a projection matrix transforms from world coords with Y=up, + // whereas this is from NDC which is Y=down. + + return result; +} + + + +Matrix4f CreateProjection( bool rightHanded, bool isOpenGL, FovPort tanHalfFov, StereoEye /*eye*/, + float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/, + bool flipZ /*= false*/, bool farAtInfinity /*= false*/) +{ + if(!flipZ && farAtInfinity) + { + //OVR_ASSERT_M(false, "Cannot push Far Clip to Infinity when Z-order is not flipped"); Assertion disabled because this code no longer has access to LibOVRKernel assertion functionality. + farAtInfinity = false; + } + + // A projection matrix is very like a scaling from NDC, so we can start with that. + ScaleAndOffset2D scaleAndOffset = CreateNDCScaleAndOffsetFromFov ( tanHalfFov ); + + float handednessScale = rightHanded ? -1.0f : 1.0f; + + Matrix4f projection; + // Produces X result, mapping clip edges to [-w,+w] + projection.M[0][0] = scaleAndOffset.Scale.x; + projection.M[0][1] = 0.0f; + projection.M[0][2] = handednessScale * scaleAndOffset.Offset.x; + projection.M[0][3] = 0.0f; + + // Produces Y result, mapping clip edges to [-w,+w] + // Hey - why is that YOffset negated? + // It's because a projection matrix transforms from world coords with Y=up, + // whereas this is derived from an NDC scaling, which is Y=down. + projection.M[1][0] = 0.0f; + projection.M[1][1] = scaleAndOffset.Scale.y; + projection.M[1][2] = handednessScale * -scaleAndOffset.Offset.y; + projection.M[1][3] = 0.0f; + + // Produces Z-buffer result - app needs to fill this in with whatever Z range it wants. + // We'll just use some defaults for now. + projection.M[2][0] = 0.0f; + projection.M[2][1] = 0.0f; + + if (farAtInfinity) + { + projection.M[2][2] = 0.0f; + projection.M[2][3] = zNear; + } + else + { + if (isOpenGL) + { + projection.M[2][2] = -handednessScale * (flipZ ? 1.0f : -1.0f) * (zNear + zFar) / (zFar - zNear); + projection.M[2][3] = -2.0f * ((flipZ ? -zFar : zFar) * zNear) / (zFar - zNear); + } + else + { + projection.M[2][2] = -handednessScale * (flipZ ? -zNear : zFar) / (zNear - zFar); + projection.M[2][3] = ((flipZ ? -zFar : zFar) * zNear) / (zNear - zFar); + } + } + + // Produces W result (= Z in) + projection.M[3][0] = 0.0f; + projection.M[3][1] = 0.0f; + projection.M[3][2] = handednessScale; + projection.M[3][3] = 0.0f; + + return projection; +} + + +Matrix4f CreateOrthoSubProjection ( bool /*rightHanded*/, StereoEye eyeType, + float tanHalfFovX, float tanHalfFovY, + float unitsX, float unitsY, + float distanceFromCamera, float interpupillaryDistance, + Matrix4f const &projection, + float zNear /*= 0.0f*/, float zFar /*= 0.0f*/, + bool flipZ /*= false*/, bool farAtInfinity /*= false*/) +{ + if(!flipZ && farAtInfinity) + { + //OVR_ASSERT_M(false, "Cannot push Far Clip to Infinity when Z-order is not flipped"); Assertion disabled because this code no longer has access to LibOVRKernel assertion functionality. + farAtInfinity = false; + } + + float orthoHorizontalOffset = interpupillaryDistance * 0.5f / distanceFromCamera; + switch ( eyeType ) + { + case StereoEye_Center: + orthoHorizontalOffset = 0.0f; + break; + case StereoEye_Left: + break; + case StereoEye_Right: + orthoHorizontalOffset = -orthoHorizontalOffset; + break; + default: + break; + } + + // Current projection maps real-world vector (x,y,1) to the RT. + // We want to find the projection that maps the range [-FovPixels/2,FovPixels/2] to + // the physical [-orthoHalfFov,orthoHalfFov] + // Note moving the offset from M[0][2]+M[1][2] to M[0][3]+M[1][3] - this means + // we don't have to feed in Z=1 all the time. + // The horizontal offset math is a little hinky because the destination is + // actually [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset] + // So we need to first map [-FovPixels/2,FovPixels/2] to + // [-orthoHalfFov+orthoHorizontalOffset,orthoHalfFov+orthoHorizontalOffset]: + // x1 = x0 * orthoHalfFov/(FovPixels/2) + orthoHorizontalOffset; + // = x0 * 2*orthoHalfFov/FovPixels + orthoHorizontalOffset; + // But then we need the sam mapping as the existing projection matrix, i.e. + // x2 = x1 * Projection.M[0][0] + Projection.M[0][2]; + // = x0 * (2*orthoHalfFov/FovPixels + orthoHorizontalOffset) * Projection.M[0][0] + Projection.M[0][2]; + // = x0 * Projection.M[0][0]*2*orthoHalfFov/FovPixels + + // orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]; + // So in the new projection matrix we need to scale by Projection.M[0][0]*2*orthoHalfFov/FovPixels and + // offset by orthoHorizontalOffset*Projection.M[0][0] + Projection.M[0][2]. + + float orthoScaleX = 2.0f * tanHalfFovX / unitsX; + float orthoScaleY = 2.0f * tanHalfFovY / unitsY; + Matrix4f ortho; + ortho.M[0][0] = projection.M[0][0] * orthoScaleX; + ortho.M[0][1] = 0.0f; + ortho.M[0][2] = 0.0f; + ortho.M[0][3] = -projection.M[0][2] + ( orthoHorizontalOffset * projection.M[0][0] ); + + ortho.M[1][0] = 0.0f; + ortho.M[1][1] = -projection.M[1][1] * orthoScaleY; // Note sign flip (text rendering uses Y=down). + ortho.M[1][2] = 0.0f; + ortho.M[1][3] = -projection.M[1][2]; + + const float zDiff = zNear - zFar; + if (fabsf(zDiff) < 0.001f) + { + ortho.M[2][0] = 0.0f; + ortho.M[2][1] = 0.0f; + ortho.M[2][2] = 0.0f; + ortho.M[2][3] = flipZ ? zNear : zFar; + } + else + { + ortho.M[2][0] = 0.0f; + ortho.M[2][1] = 0.0f; + + if(farAtInfinity) + { + ortho.M[2][2] = 0.0f; + ortho.M[2][3] = zNear; + } + else if (zDiff != 0.0f) + { + ortho.M[2][2] = (flipZ ? zNear : zFar) / zDiff; + ortho.M[2][3] = ((flipZ ? -zFar : zFar) * zNear) / zDiff; + } + } + + // No perspective correction for ortho. + ortho.M[3][0] = 0.0f; + ortho.M[3][1] = 0.0f; + ortho.M[3][2] = 0.0f; + ortho.M[3][3] = 1.0f; + + return ortho; +} + + + +} //namespace OVR + + diff --git a/LibOVR/Src/OVR_StereoProjection.h b/LibOVR/Src/OVR_StereoProjection.h new file mode 100644 index 0000000..1ec4566 --- /dev/null +++ b/LibOVR/Src/OVR_StereoProjection.h @@ -0,0 +1,70 @@ +/************************************************************************************ + +Filename : OVR_StereoProjection.h +Content : Stereo projection functions +Created : November 30, 2013 +Authors : Tom Fosyth + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_StereoProjection_h +#define OVR_StereoProjection_h + + +#include "Extras/OVR_Math.h" + + +namespace OVR { + + +//----------------------------------------------------------------------------------- +// ***** Stereo Enumerations + +// StereoEye specifies which eye we are rendering for; it is used to +// retrieve StereoEyeParams. +enum StereoEye +{ + StereoEye_Center, + StereoEye_Left, + StereoEye_Right +}; + + + +//----------------------------------------------------------------------------------- +// ***** Propjection functions + +Matrix4f CreateProjection ( bool rightHanded, bool isOpenGL, FovPort fov, StereoEye eye, + float zNear = 0.01f, float zFar = 10000.0f, + bool flipZ = false, bool farAtInfinity = false); + +Matrix4f CreateOrthoSubProjection ( bool rightHanded, StereoEye eyeType, + float tanHalfFovX, float tanHalfFovY, + float unitsX, float unitsY, float distanceFromCamera, + float interpupillaryDistance, Matrix4f const &projection, + float zNear = 0.0f, float zFar = 0.0f, + bool flipZ = false, bool farAtInfinity = false); + +ScaleAndOffset2D CreateNDCScaleAndOffsetFromFov ( FovPort fov ); + + +} //namespace OVR + +#endif // OVR_StereoProjection_h diff --git a/LibOVR/Src/Resources/Windows/resource.h b/LibOVR/Src/Resources/Windows/resource.h new file mode 100644 index 0000000..e69de29 diff --git a/LibOVR/Src/Sensors/OVR_DeviceConstants.h b/LibOVR/Src/Sensors/OVR_DeviceConstants.h old mode 100644 new mode 100755 index 445ae74..f974e92 --- a/LibOVR/Src/Sensors/OVR_DeviceConstants.h +++ b/LibOVR/Src/Sensors/OVR_DeviceConstants.h @@ -27,7 +27,9 @@ limitations under the License. #ifndef OVR_DeviceConstants_h #define OVR_DeviceConstants_h -#include "../Kernel/OVR_Math.h" +#include "Kernel/OVR_Types.h" +#include "Extras/OVR_Math.h" + // CAPI forward declarations. struct ovrSensorData_; @@ -70,6 +72,7 @@ enum DistortionEqnType //------------------------------------------------------------------------------------- // HMD types. +// We use ordinal comparison on the enums often, so the list should be in chronological/capabilities order // enum HmdTypeEnum { @@ -82,6 +85,8 @@ enum HmdTypeEnum HmdType_DKHDProto566Mi, // DKHD, 5.66-inch panel, never sold. HmdType_CrystalCoveProto, // Crystal Cove, 5.66-inch panel, shown at shows but never sold. HmdType_DK2, + HmdType_BlackStar, // Prototype for E3 2014 + HmdType_CB, // EVT Prototypes for Oculus Connect // Reminder - this header file is public - codenames only! @@ -100,11 +105,6 @@ enum HmdShutterTypeEnum HmdShutter_RollingTopToBottom, HmdShutter_RollingLeftToRight, HmdShutter_RollingRightToLeft, - // TODO: - // color-sequential e.g. LCOS? - // alternate eyes? - // alternate columns? - // outside-in? HmdShutter_LAST }; @@ -134,6 +134,8 @@ enum EyeCupType EyeCup_Delilah2A, EyeCup_JamesA, EyeCup_SunMandalaA, + EyeCup_BlackStar, + EyeCup_EVTProto, EyeCup_LAST }; @@ -147,7 +149,6 @@ enum EyeCupType class SensorDataType { public: - SensorDataType() : Temperature(0.0f), AbsoluteTimeSeconds(0.0) { } // C-interop support @@ -176,6 +177,9 @@ public: static_assert((sizeof(SensorDataType) == 3*sizeof(Vector3f) + sizeof(float) + sizeof(double)), "sizeof(SensorDataType) failure"); + + + #pragma pack(pop) diff --git a/LibOVR/Src/Service/Service_NetClient.cpp b/LibOVR/Src/Service/Service_NetClient.cpp index c6af2cd..22fea89 100644 --- a/LibOVR/Src/Service/Service_NetClient.cpp +++ b/LibOVR/Src/Service/Service_NetClient.cpp @@ -25,11 +25,12 @@ limitations under the License. ************************************************************************************/ #include "Service_NetClient.h" -#include "../Net/OVR_MessageIDTypes.h" +#include "Net/OVR_MessageIDTypes.h" #if defined (OVR_OS_MAC) || defined(OVR_OS_LINUX) #define GetCurrentProcessId getpid #endif + OVR_DEFINE_SINGLETON(OVR::Service::NetClient); namespace OVR { namespace Service { @@ -37,13 +38,17 @@ namespace OVR { namespace Service { using namespace OVR::Net; +// Default connection timeout in milliseconds. +static const int kDefaultConnectionTimeoutMS = 5000; // Timeout in Milliseconds + + //// NetClient NetClient::NetClient() : - LatencyTesterAvailable(false), - HMDCount(0), - EdgeTriggeredHMDCount(false) + LatencyTesterAvailable(false), HMDCount(-1), EdgeTriggeredHMDCount(false) { + SetDefaultParameters(); + GetSession()->AddSessionListener(this); // Register RPC functions @@ -51,7 +56,7 @@ NetClient::NetClient() : Start(); - // Must be at end of function + // Must be at end of function PushDestroyCallbacks(); } @@ -69,19 +74,40 @@ void NetClient::OnThreadDestroy() onThreadDestroy(); } +void NetClient::SetDefaultParameters() +{ + ServerOptional = false; + ExtraDebugging = false; + ConnectionTimeoutMS = kDefaultConnectionTimeoutMS; +} + +void NetClient::ApplyParameters(ovrInitParams const* params) +{ + SetDefaultParameters(); + + // If connection timeout is specified, + if (params->ConnectionTimeoutMS > 0) + { + ConnectionTimeoutMS = params->ConnectionTimeoutMS; + } + + ServerOptional = (params->Flags & ovrInit_ServerOptional) != 0; + ExtraDebugging = (params->Flags & ovrInit_Debug) != 0; +} + int NetClient::Run() { SetThreadName("NetClient"); - while (!Terminated) + while (!Terminated.load(std::memory_order_relaxed)) { - // Note: There is no watchdog here because the watchdog is part of the private code + // There is no watchdog here because the watchdog is part of the private code. GetSession()->Poll(false); if (GetSession()->GetActiveSocketsCount() == 0) { - Thread::MSleep(10); + Thread::MSleep(100); } } @@ -107,8 +133,22 @@ void NetClient::OnConnected(Connection* conn) { OVR_UNUSED(conn); - OVR_DEBUG_LOG(("[NetClient] Connected to a server running version %d.%d.%d (my version=%d.%d.%d)", + OVR_DEBUG_LOG(("[NetClient] Connected to the server running SDK version " \ + "(prod=%d).%d.%d(req=%d).%d(build=%d), RPC version %d.%d.%d. " \ + "Client SDK version (prod=%d).%d.%d(req=%d).%d.(build=%d), RPC version=%d.%d.%d", + conn->RemoteCodeVersion.ProductVersion, + conn->RemoteCodeVersion.MajorVersion, + conn->RemoteCodeVersion.MinorVersion, + conn->RemoteCodeVersion.RequestedMinorVersion, + conn->RemoteCodeVersion.PatchVersion, + conn->RemoteCodeVersion.BuildNumber, conn->RemoteMajorVersion, conn->RemoteMinorVersion, conn->RemotePatchVersion, + OVR_PRODUCT_VERSION, + OVR_MAJOR_VERSION, + OVR_MINOR_VERSION, + RuntimeSDKVersion.RequestedMinorVersion, + OVR_PATCH_VERSION, + OVR_BUILD_NUMBER, RPCVersion_Major, RPCVersion_Minor, RPCVersion_Patch)); EdgeTriggeredHMDCount = false; @@ -116,12 +156,18 @@ void NetClient::OnConnected(Connection* conn) bool NetClient::Connect(bool blocking) { + // If server is optional, + if (ServerOptional && !Session::IsSingleProcess()) + { + blocking = false; // Poll: Do not block + } + // Set up bind parameters - OVR::Net::BerkleyBindParameters bbp; - bbp.Address = "::1"; // Bind to localhost only! - bbp.blockingTimeout = 5000; - OVR::Net::SockAddr sa; - sa.Set("::1", VRServicePort, SOCK_STREAM); + OVR::Net::BerkleyBindParameters bbp; + bbp.Address = "::1"; // Bind to localhost only! + bbp.blockingTimeout = ConnectionTimeoutMS; + OVR::Net::SockAddr sa; + sa.Set("::1", VRServicePort, SOCK_STREAM); // Attempt to connect OVR::Net::SessionResult result = GetSession()->ConnectPTCP(&bbp, &sa, blocking); @@ -140,7 +186,7 @@ void NetClient::Disconnect() bool NetClient::IsConnected(bool attemptReconnect, bool blockOnReconnect) { // If it was able to connect, - if (GetSession()->GetConnectionCount() > 0) + if (GetSession()->ConnectionSuccessful()) { return true; } @@ -150,7 +196,7 @@ bool NetClient::IsConnected(bool attemptReconnect, bool blockOnReconnect) Connect(blockOnReconnect); // If it connected, - if (GetSession()->GetConnectionCount() > 0) + if (GetSession()->ConnectionSuccessful()) { return true; } @@ -182,21 +228,39 @@ bool NetClient::GetRemoteProtocolVersion(int& major, int& minor, int& patch) return false; } +void NetClient::GetLocalSDKVersion(SDKVersion& requestedSDKVersion) +{ + requestedSDKVersion = RuntimeSDKVersion; +} + +bool NetClient::GetRemoteSDKVersion(SDKVersion& remoteSDKVersion) +{ + Ptr conn = GetSession()->GetConnectionAtIndex(0); + + if (conn) + { + remoteSDKVersion = conn->RemoteCodeVersion; + return true; + } + + return false; +} + //// NetClient API const char* NetClient::GetStringValue(VirtualHmdId hmd, const char* key, const char* default_val) { - if (!IsConnected(true, true)) + // If a null value is provided, + if (!default_val) { - return ""; + default_val = ""; } - // If a null value is provided, - if (!default_val) - { - default_val = ""; - } + if (!IsConnected(true, true)) + { + return default_val; + } ProfileGetValue1_Str = default_val; @@ -206,11 +270,11 @@ const char* NetClient::GetStringValue(VirtualHmdId hmd, const char* key, const c bsOut.Write(default_val); if (!GetRPC1()->CallBlocking("GetStringValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) { - return ""; + return default_val; } if (!returnData.Read(ProfileGetValue1_Str)) { - OVR_ASSERT(false); + OVR_ASSERT(false); //This assert will hit if you tamper or restart the service mid-call. } return ProfileGetValue1_Str.ToCStr(); } @@ -227,12 +291,12 @@ bool NetClient::GetBoolValue(VirtualHmdId hmd, const char* key, bool default_val bsOut.Write(default_val); if (!GetRPC1()->CallBlocking("GetBoolValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) { - return default_val; + return default_val; } uint8_t out = 0; if (!returnData.Read(out)) { - OVR_ASSERT(false); + OVR_ASSERT(false); //This assert will hit if you tamper or restart the service mid-call. } return out != 0; } @@ -249,12 +313,12 @@ int NetClient::GetIntValue(VirtualHmdId hmd, const char* key, int default_val) bsOut.Write(default_val); if (!GetRPC1()->CallBlocking("GetIntValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) { - return default_val; + return default_val; } int32_t out = (int32_t)default_val; if (!returnData.Read(out)) { - OVR_ASSERT(false); + OVR_ASSERT(false); //This assert will hit if you tamper or restart the service mid-call. } return out; } @@ -271,10 +335,13 @@ double NetClient::GetNumberValue(VirtualHmdId hmd, const char* key, double defau bsOut.Write(default_val); if (!GetRPC1()->CallBlocking("GetNumberValue_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) { - return default_val; + return default_val; } double out = 0.; - returnData.Read(out); + if (!returnData.Read(out)) + { + OVR_ASSERT(false); //This assert will hit if you tamper or restart the service mid-call. + } return out; } int NetClient::GetNumberValues(VirtualHmdId hmd, const char* key, double* values, int num_vals) @@ -293,7 +360,7 @@ int NetClient::GetNumberValues(VirtualHmdId hmd, const char* key, double* values if (!GetRPC1()->CallBlocking("GetNumberValues_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) { - return 0; + return 0; } int32_t out = 0; @@ -439,7 +506,7 @@ int NetClient::Hmd_Detect() { if (!IsConnected(true, false)) { - return 0; + return -1; } // If using edge-triggered HMD counting, @@ -451,21 +518,21 @@ int NetClient::Hmd_Detect() // Otherwise: We need to ask the first time - OVR::Net::BitStream bsOut, returnData; + OVR::Net::BitStream bsOut, returnData; - if (!GetRPC1()->CallBlocking("Hmd_Detect_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) - { - return 0; - } + if (!GetRPC1()->CallBlocking("Hmd_Detect_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return -1; + } int32_t out = 0; if (!returnData.Read(out)) { - OVR_ASSERT(false); + OVR_ASSERT(false); //This assert will hit if you tamper or restart the service mid-call. } HMDCount = out; EdgeTriggeredHMDCount = true; - return out; + return out; } bool NetClient::Hmd_Create(int index, HMDNetworkInfo* netInfo) @@ -475,21 +542,21 @@ bool NetClient::Hmd_Create(int index, HMDNetworkInfo* netInfo) return false; } - OVR::Net::BitStream bsOut, returnData; + OVR::Net::BitStream bsOut, returnData; int32_t w = (int32_t)index; - bsOut.Write(w); + bsOut.Write(w); // Need the Pid for driver mode pid_t pid = GetCurrentProcessId(); bsOut.Write(pid); - if (!GetRPC1()->CallBlocking("Hmd_Create_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) - { - return false; - } + if (!GetRPC1()->CallBlocking("Hmd_Create_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return false; + } - return netInfo->Deserialize(&returnData); + return netInfo->Serialize(&returnData, false); } bool NetClient::GetDriverMode(bool& driverInstalled, bool& compatMode, bool& hideDK1Mode) @@ -566,15 +633,19 @@ bool NetClient::Hmd_AttachToWindow(VirtualHmdId hmd, void* hWindow) OVR::Net::BitStream bsOut; bsOut.Write(hmd); + uint64_t hWinWord = 0; #ifdef OVR_OS_LINUX - if (hWindow == NULL) - { - return false; - } - unsigned long hWinWord = *(unsigned long *)hWindow; + if (hWindow == NULL) + { + return false; + } + hWinWord = *(uint64_t *)&hWindow; + #elif defined(OVR_OS_WIN32) + hWinWord = (UPInt)hWindow; #else - UInt64 hWinWord = (UPInt)hWindow; + OVR_UNUSED(hWindow); #endif + bsOut.Write(hWinWord); if (!GetRPC1()->CallBlocking("Hmd_AttachToWindow_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) @@ -592,9 +663,9 @@ void NetClient::Hmd_Release(VirtualHmdId hmd) return; } - OVR::Net::BitStream bsOut; - bsOut.Write(hmd); - bool result = GetRPC1()->CallBlocking("Hmd_Release_1", &bsOut, GetSession()->GetConnectionAtIndex(0)); + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + bool result = GetRPC1()->CallBlocking("Hmd_Release_1", &bsOut, GetSession()->GetConnectionAtIndex(0)); OVR_ASSERT_AND_UNUSED(result, result); } @@ -612,16 +683,16 @@ const char* NetClient::Hmd_GetLastError(VirtualHmdId hmd) } OVR::Net::BitStream bsOut, returnData; - bsOut.Write(hmd); + bsOut.Write(hmd); if (!GetRPC1()->CallBlocking("Hmd_GetLastError_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) - { - return Hmd_GetLastError_Str.ToCStr(); - } + { + return Hmd_GetLastError_Str.ToCStr(); + } if (!returnData.Read(Hmd_GetLastError_Str)) { OVR_ASSERT(false); } - return Hmd_GetLastError_Str.ToCStr(); + return Hmd_GetLastError_Str.ToCStr(); } @@ -634,14 +705,14 @@ bool NetClient::Hmd_GetHmdInfo(VirtualHmdId hmd, HMDInfo* hmdInfo) return false; } - OVR::Net::BitStream bsOut, returnData; - bsOut.Write(hmd); - if (!GetRPC1()->CallBlocking("Hmd_GetHmdInfo_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) - { - return false; - } + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + if (!GetRPC1()->CallBlocking("Hmd_GetHmdInfo_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return false; + } - return NetSessionCommon::DeserializeHMDInfo(&returnData, hmdInfo); + return NetSessionCommon::SerializeHMDInfo(&returnData, hmdInfo, false); } @@ -653,19 +724,19 @@ unsigned int NetClient::Hmd_GetEnabledCaps(VirtualHmdId hmd) return 0; } - OVR::Net::BitStream bsOut, returnData; - bsOut.Write(hmd); - if (!GetRPC1()->CallBlocking("Hmd_GetEnabledCaps_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) - { - return 0; - } + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); + if (!GetRPC1()->CallBlocking("Hmd_GetEnabledCaps_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return 0; + } uint32_t c = 0; if (!returnData.Read(c)) { - OVR_ASSERT(false); + OVR_ASSERT(false); //This assert will hit if you tamper or restart the service mid-call. } - return c; + return c; } // Returns new caps after modification @@ -676,21 +747,21 @@ unsigned int NetClient::Hmd_SetEnabledCaps(VirtualHmdId hmd, unsigned int hmdCap return 0; } - OVR::Net::BitStream bsOut, returnData; - bsOut.Write(hmd); + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); uint32_t c = (uint32_t)hmdCaps; - bsOut.Write(c); + bsOut.Write(c); - if (!GetRPC1()->CallBlocking("Hmd_SetEnabledCaps_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) - { - return 0; - } + if (!GetRPC1()->CallBlocking("Hmd_SetEnabledCaps_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return 0; + } c = 0; if (!returnData.Read(c)) { - OVR_ASSERT(false); + OVR_ASSERT(false); //This assert will hit if you tamper or restart the service mid-call. } return c; } @@ -706,18 +777,18 @@ bool NetClient::Hmd_ConfigureTracking(VirtualHmdId hmd, unsigned supportedCaps, return false; } - OVR::Net::BitStream bsOut, returnData; - bsOut.Write(hmd); + OVR::Net::BitStream bsOut, returnData; + bsOut.Write(hmd); uint32_t w_sc = supportedCaps; bsOut.Write(w_sc); uint32_t w_rc = requiredCaps; bsOut.Write(w_rc); - if (!GetRPC1()->CallBlocking("Hmd_ConfigureTracking_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) - { - return false; - } + if (!GetRPC1()->CallBlocking("Hmd_ConfigureTracking_1", &bsOut, GetSession()->GetConnectionAtIndex(0), &returnData)) + { + return false; + } uint8_t b; if (!returnData.Read(b)) @@ -725,23 +796,28 @@ bool NetClient::Hmd_ConfigureTracking(VirtualHmdId hmd, unsigned supportedCaps, OVR_ASSERT(false); } - return b != 0; + return b != 0; } -void NetClient::Hmd_ResetTracking(VirtualHmdId hmd) +void NetClient::Hmd_ResetTracking(VirtualHmdId hmd, bool visionReset) { if (!IsConnected(false, false)) { return; } - OVR::Net::BitStream bsOut; - bsOut.Write(hmd); - if (!GetRPC1()->CallBlocking("Hmd_ResetTracking_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) - { - return; - } + OVR::Net::BitStream bsOut; + bsOut.Write(hmd); + + int32_t w_visionReset; + w_visionReset = visionReset ? 1 : 0; + bsOut.Write(w_visionReset); + + if (!GetRPC1()->CallBlocking("Hmd_ResetTracking_1", &bsOut, GetSession()->GetConnectionAtIndex(0))) + { + return; + } } bool NetClient::LatencyUtil_ProcessInputs(double startTestSeconds, unsigned char rgbColorOut[3]) @@ -817,7 +893,8 @@ bool NetClient::ShutdownServer() void NetClient::registerRPC() { #define RPC_REGISTER_SLOT(observerScope, functionName) \ - observerScope.SetHandler(OVR::Net::Plugins::RPCSlot::FromMember(this)); pRPC->RegisterSlot(OVR_STRINGIZE(functionName), observerScope); + observerScope.SetHandler(OVR::Net::Plugins::RPCSlot::FromMember(this)); \ + pRPC->RegisterSlot(OVR_STRINGIZE(functionName), &observerScope); // Register RPC functions: RPC_REGISTER_SLOT(InitialServerStateScope, InitialServerState_1); diff --git a/LibOVR/Src/Service/Service_NetClient.h b/LibOVR/Src/Service/Service_NetClient.h index ab7906e..508c485 100644 --- a/LibOVR/Src/Service/Service_NetClient.h +++ b/LibOVR/Src/Service/Service_NetClient.h @@ -27,11 +27,11 @@ limitations under the License. #ifndef OVR_Service_NetClient_h #define OVR_Service_NetClient_h -#include "../Net/OVR_NetworkTypes.h" +#include "Net/OVR_NetworkTypes.h" #include "Service_NetSessionCommon.h" -#include "../Kernel/OVR_System.h" -#include "../OVR_CAPI.h" -#include "../Util/Util_Render_Stereo.h" +#include "Kernel/OVR_System.h" +#include "OVR_CAPI.h" +#include "Util/Util_Render_Stereo.h" namespace OVR { namespace Service { @@ -48,28 +48,22 @@ class NetClient : public NetSessionCommon, OVR_DECLARE_SINGLETON(NetClient); virtual void OnThreadDestroy(); - // Status - bool LatencyTesterAvailable; - int HMDCount; - bool EdgeTriggeredHMDCount; - - virtual void OnReceive(Net::ReceivePayload* pPayload, Net::ListenerReceiveResult* lrrOut); - virtual void OnDisconnected(Net::Connection* conn); - virtual void OnConnected(Net::Connection* conn); - - virtual int Run(); - public: bool Connect(bool blocking); bool IsConnected(bool attemptReconnect, bool blockOnReconnect); void Disconnect(); void GetLocalProtocolVersion(int& major, int& minor, int& patch); - // This function may fail if it is not connected + void GetLocalSDKVersion(SDKVersion& requestedSDKVersion); + + // These functions may fail if it is not connected bool GetRemoteProtocolVersion(int& major, int& minor, int& patch); + bool GetRemoteSDKVersion(SDKVersion& remoteSDKVersion); void SetLastError(String str); + void ApplyParameters(ovrInitParams const* params); + public: // Persistent key-value storage const char* GetStringValue(VirtualHmdId hmd, const char* key, const char* default_val); @@ -112,7 +106,7 @@ public: // *** Tracking Setup bool Hmd_ConfigureTracking(VirtualHmdId hmd, unsigned supportedCaps, unsigned requiredCaps); - void Hmd_ResetTracking(VirtualHmdId hmd); + void Hmd_ResetTracking(VirtualHmdId hmd, bool visionReset); // TBD: Camera frames bool LatencyUtil_ProcessInputs(double startTestSeconds, unsigned char rgbColorOut[3]); @@ -121,25 +115,43 @@ public: bool ShutdownServer(); protected: + // Status + bool LatencyTesterAvailable; + int HMDCount; + bool EdgeTriggeredHMDCount; + String Hmd_GetLastError_Str; String LatencyUtil_GetResultsString_Str; String ProfileGetValue1_Str, ProfileGetValue3_Str; + // Parameters passed to ovr_Initialize() + bool ServerOptional; // Server connection is optional? + bool ExtraDebugging; // Extra debugging enabled? + int ConnectionTimeoutMS; // Connection timeout in milliseconds + + void SetDefaultParameters(); + protected: + virtual void OnReceive(Net::ReceivePayload* pPayload, Net::ListenerReceiveResult* lrrOut); + virtual void OnDisconnected(Net::Connection* conn); + virtual void OnConnected(Net::Connection* conn); + + virtual int Run(); + //// Push Notifications: void registerRPC(); - ObserverScope InitialServerStateScope; + CallbackListener InitialServerStateScope; void InitialServerState_1(BitStream* userData, ReceivePayload* pPayload); - ObserverScope LatencyTesterAvailableScope; + CallbackListener LatencyTesterAvailableScope; void LatencyTesterAvailable_1(BitStream* userData, ReceivePayload* pPayload); - ObserverScope DefaultLogOutputScope; + CallbackListener DefaultLogOutputScope; void DefaultLogOutput_1(BitStream* userData, ReceivePayload* pPayload); - ObserverScope HMDCountUpdateScope; + CallbackListener HMDCountUpdateScope; void HMDCountUpdate_1(BitStream* userData, ReceivePayload* pPayload); }; diff --git a/LibOVR/Src/Service/Service_NetSessionCommon.cpp b/LibOVR/Src/Service/Service_NetSessionCommon.cpp index ba2c773..4a9fda6 100644 --- a/LibOVR/Src/Service/Service_NetSessionCommon.cpp +++ b/LibOVR/Src/Service/Service_NetSessionCommon.cpp @@ -30,7 +30,8 @@ limitations under the License. namespace OVR { namespace Service { -//// NetSessionCommon +//----------------------------------------------------------------------------- +// NetSessionCommon NetSessionCommon::NetSessionCommon() : Terminated(false) @@ -57,14 +58,14 @@ NetSessionCommon::~NetSessionCommon() pRPC = NULL; } - Terminated = true; + Terminated.store(true, std::memory_order_relaxed); OVR_ASSERT(IsFinished()); } void NetSessionCommon::onSystemDestroy() { - Terminated = true; + Terminated.store(true, std::memory_order_relaxed); Join(); @@ -73,93 +74,106 @@ void NetSessionCommon::onSystemDestroy() void NetSessionCommon::onThreadDestroy() { - Terminated = true; + Terminated.store(true, std::memory_order_relaxed); if (pSession) { pSession->Shutdown(); } } -void NetSessionCommon::SerializeHMDInfo(Net::BitStream *bitStream, HMDInfo* hmdInfo) +template +static bool SerializeUInt32(bool write, Net::BitStream* bitStream, T& data) { - bitStream->Write(hmdInfo->ProductName); - bitStream->Write(hmdInfo->Manufacturer); - - int32_t w = hmdInfo->Version; - bitStream->Write(w); - - w = hmdInfo->HmdType; - bitStream->Write(w); - - w = hmdInfo->ResolutionInPixels.w; - bitStream->Write(w); - - w = hmdInfo->ResolutionInPixels.h; - bitStream->Write(w); + int32_t w = 0; + bool result = false; - w = hmdInfo->ShimInfo.DeviceNumber; - bitStream->Write(w); + if (write) + { + w = (int32_t)data; + result = bitStream->Serialize(write, w); + } + else + { + result = bitStream->Serialize(write, w); + data = (T)w; + } - w = hmdInfo->ShimInfo.NativeWidth; - bitStream->Write(w); + return result; +} - w = hmdInfo->ShimInfo.NativeHeight; - bitStream->Write(w); +static bool SerializeBool(bool write, Net::BitStream* bitStream, bool& data) +{ + uint8_t x = 0; + bool result = false; - w = hmdInfo->ShimInfo.Rotation; - bitStream->Write(w); + if (write) + { + x = data ? 1 : 0; + result = bitStream->Serialize(write, x); + } + else + { + result = bitStream->Serialize(write, x); + data = (x != 0); + } - bitStream->Write(hmdInfo->ScreenSizeInMeters.w); - bitStream->Write(hmdInfo->ScreenSizeInMeters.h); - bitStream->Write(hmdInfo->ScreenGapSizeInMeters); - bitStream->Write(hmdInfo->CenterFromTopInMeters); - bitStream->Write(hmdInfo->LensSeparationInMeters); + return result; +} - w = hmdInfo->DesktopX; - bitStream->Write(w); +bool NetSessionCommon::SerializeHMDInfo(Net::BitStream *bitStream, HMDInfo* hmdInfo, bool write) +{ + bool result = false; - w = hmdInfo->DesktopY; - bitStream->Write(w); + bitStream->Serialize(write, hmdInfo->ProductName); + bitStream->Serialize(write, hmdInfo->Manufacturer); - w = hmdInfo->Shutter.Type; - bitStream->Write(w); + SerializeUInt32(write, bitStream, hmdInfo->Version); + SerializeUInt32(write, bitStream, hmdInfo->HmdType); + SerializeUInt32(write, bitStream, hmdInfo->ResolutionInPixels.w); + SerializeUInt32(write, bitStream, hmdInfo->ResolutionInPixels.h); + SerializeUInt32(write, bitStream, hmdInfo->ShimInfo.DeviceNumber); + SerializeUInt32(write, bitStream, hmdInfo->ShimInfo.NativeWidth); + SerializeUInt32(write, bitStream, hmdInfo->ShimInfo.NativeHeight); + SerializeUInt32(write, bitStream, hmdInfo->ShimInfo.Rotation); - bitStream->Write(hmdInfo->Shutter.VsyncToNextVsync); - bitStream->Write(hmdInfo->Shutter.VsyncToFirstScanline); - bitStream->Write(hmdInfo->Shutter.FirstScanlineToLastScanline); - bitStream->Write(hmdInfo->Shutter.PixelSettleTime); - bitStream->Write(hmdInfo->Shutter.PixelPersistence); - bitStream->Write(hmdInfo->DisplayDeviceName); + bitStream->Serialize(write, hmdInfo->ScreenSizeInMeters.w); + bitStream->Serialize(write, hmdInfo->ScreenSizeInMeters.h); + bitStream->Serialize(write, hmdInfo->ScreenGapSizeInMeters); + bitStream->Serialize(write, hmdInfo->CenterFromTopInMeters); + bitStream->Serialize(write, hmdInfo->LensSeparationInMeters); - w = hmdInfo->DisplayId; - bitStream->Write(w); + SerializeUInt32(write, bitStream, hmdInfo->DesktopX); + SerializeUInt32(write, bitStream, hmdInfo->DesktopY); + SerializeUInt32(write, bitStream, hmdInfo->Shutter.Type); - bitStream->Write(hmdInfo->PrintedSerial); + bitStream->Serialize(write, hmdInfo->Shutter.VsyncToNextVsync); + bitStream->Serialize(write, hmdInfo->Shutter.VsyncToFirstScanline); + bitStream->Serialize(write, hmdInfo->Shutter.FirstScanlineToLastScanline); + bitStream->Serialize(write, hmdInfo->Shutter.PixelSettleTime); + bitStream->Serialize(write, hmdInfo->Shutter.PixelPersistence); + bitStream->Serialize(write, hmdInfo->DisplayDeviceName); - uint8_t b = hmdInfo->InCompatibilityMode ? 1 : 0; - bitStream->Write(b); + SerializeUInt32(write, bitStream, hmdInfo->DisplayId); - w = hmdInfo->VendorId; - bitStream->Write(w); + bitStream->Serialize(write, hmdInfo->PrintedSerial); - w = hmdInfo->ProductId; - bitStream->Write(w); + SerializeBool(write, bitStream, hmdInfo->InCompatibilityMode); - bitStream->Write(hmdInfo->CameraFrustumFarZInMeters); - bitStream->Write(hmdInfo->CameraFrustumHFovInRadians); - bitStream->Write(hmdInfo->CameraFrustumNearZInMeters); - bitStream->Write(hmdInfo->CameraFrustumVFovInRadians); + SerializeUInt32(write, bitStream, hmdInfo->VendorId); + SerializeUInt32(write, bitStream, hmdInfo->ProductId); - w = hmdInfo->FirmwareMajor; - bitStream->Write(w); + bitStream->Serialize(write, hmdInfo->CameraFrustumFarZInMeters); + bitStream->Serialize(write, hmdInfo->CameraFrustumHFovInRadians); + bitStream->Serialize(write, hmdInfo->CameraFrustumNearZInMeters); + bitStream->Serialize(write, hmdInfo->CameraFrustumVFovInRadians); - w = hmdInfo->FirmwareMinor; - bitStream->Write(w); + SerializeUInt32(write, bitStream, hmdInfo->FirmwareMajor); + SerializeUInt32(write, bitStream, hmdInfo->FirmwareMinor); - bitStream->Write(hmdInfo->PelOffsetR.x); - bitStream->Write(hmdInfo->PelOffsetR.y); - bitStream->Write(hmdInfo->PelOffsetB.x); - bitStream->Write(hmdInfo->PelOffsetB.y); + bitStream->Serialize(write, hmdInfo->PelOffsetR.x); + bitStream->Serialize(write, hmdInfo->PelOffsetR.y); + bitStream->Serialize(write, hmdInfo->PelOffsetB.x); + result = bitStream->Serialize(write, hmdInfo->PelOffsetB.y); // Important please read before modifying! // ---------------------------------------------------- @@ -167,138 +181,30 @@ void NetSessionCommon::SerializeHMDInfo(Net::BitStream *bitStream, HMDInfo* hmdI // Otherwise we will break backwards compatibility // and e.g. 0.4.4 runtime will not work with 0.4.3 SDK. - // Please also update the DeserializeHMDInfo() function - // below also and make sure that the members you added - // are initialized properly in the HMDInfo constructor. - // Note that whenever new fields are added here you // should also update the minor version of the RPC // protocol in OVR_Session.h so that clients fail at // a version check instead of when this data is // found to be truncated from the server. -} - -bool NetSessionCommon::DeserializeHMDInfo(Net::BitStream *bitStream, HMDInfo* hmdInfo) -{ - bitStream->Read(hmdInfo->ProductName); - bitStream->Read(hmdInfo->Manufacturer); - - int32_t w = 0; - if (!bitStream->Read(w)) - { - // This indicates that no HMD could be found - return false; - } - hmdInfo->Version = w; - - bitStream->Read(w); - hmdInfo->HmdType = (HmdTypeEnum)w; - - bitStream->Read(w); - hmdInfo->ResolutionInPixels.w = w; - - bitStream->Read(w); - hmdInfo->ResolutionInPixels.h = w; - - bitStream->Read(w); - hmdInfo->ShimInfo.DeviceNumber = w; - - bitStream->Read(w); - hmdInfo->ShimInfo.NativeWidth = w; - - bitStream->Read(w); - hmdInfo->ShimInfo.NativeHeight = w; - - bitStream->Read(w); - hmdInfo->ShimInfo.Rotation = w; - - bitStream->Read(hmdInfo->ScreenSizeInMeters.w); - bitStream->Read(hmdInfo->ScreenSizeInMeters.h); - bitStream->Read(hmdInfo->ScreenGapSizeInMeters); - bitStream->Read(hmdInfo->CenterFromTopInMeters); - bitStream->Read(hmdInfo->LensSeparationInMeters); - - bitStream->Read(w); - hmdInfo->DesktopX = w; - - bitStream->Read(w); - hmdInfo->DesktopY = w; - - bitStream->Read(w); - hmdInfo->Shutter.Type = (HmdShutterTypeEnum)w; - - bitStream->Read(hmdInfo->Shutter.VsyncToNextVsync); - bitStream->Read(hmdInfo->Shutter.VsyncToFirstScanline); - bitStream->Read(hmdInfo->Shutter.FirstScanlineToLastScanline); - bitStream->Read(hmdInfo->Shutter.PixelSettleTime); - bitStream->Read(hmdInfo->Shutter.PixelPersistence); - bitStream->Read(hmdInfo->DisplayDeviceName); - - bitStream->Read(w); - hmdInfo->DisplayId = w; - - bitStream->Read(hmdInfo->PrintedSerial); - - uint8_t b = 0; - bitStream->Read(b); - hmdInfo->InCompatibilityMode = (b != 0); - - bitStream->Read(w); - hmdInfo->VendorId = w; - - bitStream->Read(w); - hmdInfo->ProductId = w; - - bitStream->Read(hmdInfo->CameraFrustumFarZInMeters); - bitStream->Read(hmdInfo->CameraFrustumHFovInRadians); - bitStream->Read(hmdInfo->CameraFrustumNearZInMeters); - bitStream->Read(hmdInfo->CameraFrustumVFovInRadians); - - bitStream->Read(w); - hmdInfo->FirmwareMajor = w; - - if (!bitStream->Read(w)) - { - OVR_ASSERT(false); - return false; - } - hmdInfo->FirmwareMinor = w; - - bitStream->Read(hmdInfo->PelOffsetR.x); - bitStream->Read(hmdInfo->PelOffsetR.y); - bitStream->Read(hmdInfo->PelOffsetB.x); - if (!bitStream->Read(hmdInfo->PelOffsetB.y)) - { - OVR_ASSERT(false); - return false; - } - - // Important please read before modifying! - // ---------------------------------------------------- - // Please add new serialized data to the end, here. - // Otherwise we will break backwards compatibility - // and e.g. 0.4.4 runtime will not work with 0.4.3 SDK. - - // Be sure to check that the very last one read properly - // since HMD Info truncation should be caught here. - return true; + // The result of the final serialize should be returned to the caller. + return result; } // Prefix key names with this to pass through to server static const char* BypassPrefix = "server:"; static const char* KeyNames[][NetSessionCommon::ENumTypes] = { - /* EGetStringValue */ { "CameraSerial", "CameraUUID", 0 }, - /* EGetBoolValue */ { "ReleaseDK2Sensors", "ReleaseLegacySensors", 0 }, - /* EGetIntValue */ { 0 }, - /* EGetNumberValue */{ "CenterPupilDepth", "LoggingMask", 0 }, - /* EGetNumberValues */{ "NeckModelVector3f", 0 }, - /* ESetStringValue */ { 0 }, - /* ESetBoolValue */ { "ReleaseDK2Sensors", "ReleaseLegacySensors", 0 }, - /* ESetIntValue */ { 0 }, - /* ESetNumberValue */{ "CenterPupilDepth", "LoggingMask", 0 }, - /* ESetNumberValues */{ "NeckModelVector3f", 0 }, + /* EGetStringValue */ { "CameraSerial", "CameraUUID", 0 }, + /* EGetBoolValue */ { "ReleaseDK2Sensors", "ReleaseLegacySensors", 0 }, + /* EGetIntValue */ { 0 }, + /* EGetNumberValue */ { "CenterPupilDepth", "LoggingMask", 0 }, + /* EGetNumberValues */ { "NeckModelVector3f", 0 }, + /* ESetStringValue */ { 0 }, + /* ESetBoolValue */ { "ReleaseDK2Sensors", "ReleaseLegacySensors", 0 }, + /* ESetIntValue */ { 0 }, + /* ESetNumberValue */ { "CenterPupilDepth", "LoggingMask", 0 }, + /* ESetNumberValues */ { "NeckModelVector3f", 0 }, }; bool IsInStringArray(const char* a[], const char* key) diff --git a/LibOVR/Src/Service/Service_NetSessionCommon.h b/LibOVR/Src/Service/Service_NetSessionCommon.h old mode 100644 new mode 100755 index 79c0cfb..eefc292 --- a/LibOVR/Src/Service/Service_NetSessionCommon.h +++ b/LibOVR/Src/Service/Service_NetSessionCommon.h @@ -27,11 +27,14 @@ limitations under the License. #ifndef OVR_Service_NetSessionCommon_h #define OVR_Service_NetSessionCommon_h -#include "../OVR_CAPI.h" -#include "../Net/OVR_RPC1.h" -#include "../Kernel/OVR_Threads.h" -#include "../Net/OVR_BitStream.h" -#include "../Kernel/OVR_System.h" +#include + +#include "OVR_CAPI.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_System.h" +#include "Net/OVR_RPC1.h" +#include "Net/OVR_BitStream.h" + namespace OVR { @@ -52,6 +55,13 @@ static const int32_t InvalidVirtualHmdId = -1; // Localhost-bound TCP port that the service listens on for VR apps static const int VRServicePort = 30322; // 0x7672 = "vr" little-endian +// Stores the names of shared memory regions +struct SharedMemoryNames +{ + String Hmd; + String Camera; +}; + // HMDInfo section related to networking struct HMDNetworkInfo { @@ -63,19 +73,25 @@ struct HMDNetworkInfo // Network identifier for HMD VirtualHmdId NetId; - // Name of the shared memory object - String SharedMemoryName; + // Names of the shared memory objects + SharedMemoryNames SharedMemoryName; - void Serialize(Net::BitStream* bs) + bool Serialize(Net::BitStream* bs, bool write = true) { - bs->Write(NetId); - bs->Write(SharedMemoryName); - } - bool Deserialize(Net::BitStream* bs) - { - bs->Read(NetId); - return bs->Read(SharedMemoryName); + bs->Serialize(write, NetId); + bs->Serialize(write, SharedMemoryName.Hmd); + if (!bs->Serialize(write, SharedMemoryName.Camera)) + return false; + return true; } + + // Assignment operator + HMDNetworkInfo& operator=(HMDNetworkInfo const & rhs) + { + NetId = rhs.NetId; + SharedMemoryName = rhs.SharedMemoryName; + return *this; + } }; @@ -103,8 +119,7 @@ public: return pSession; } - static void SerializeHMDInfo(Net::BitStream* bitStream, HMDInfo* hmdInfo); - static bool DeserializeHMDInfo(Net::BitStream* bitStream, HMDInfo* hmdInfo); + static bool SerializeHMDInfo(Net::BitStream* bitStream, HMDInfo* hmdInfo, bool write = true); public: // Getter/setter tools @@ -131,9 +146,9 @@ public: static bool IsServiceProperty(EGetterSetters e, const char* key); protected: - bool Terminated; // Thread termination flag + std::atomic Terminated; // Thread termination flag Net::Session* pSession; // Networking session - Net::Plugins::RPC1* pRPC; // Remote procedure calls object + Net::Plugins::RPC1* pRPC; // Remote procedure calls object }; diff --git a/LibOVR/Src/Service/Service_Win32_FastIPC_Client.cpp b/LibOVR/Src/Service/Service_Win32_FastIPC_Client.cpp new file mode 100644 index 0000000..22a0b4a --- /dev/null +++ b/LibOVR/Src/Service/Service_Win32_FastIPC_Client.cpp @@ -0,0 +1,228 @@ +/************************************************************************************ + +Filename : Service_Win32_FastIPC_Client.cpp +Content : Client side of connectionless fast IPC +Created : Sept 16, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Service_Win32_FastIPC_Client.h" + +namespace OVR { namespace Service { namespace Win32 { + +using namespace OVR::Net; + + +//// FastIPCClient + +FastIPCClient::FastIPCClient() +{ +} + +bool FastIPCClient::ReadInitialData(const char* buffer) +{ + uint32_t magic = *(uint32_t*)(buffer); + uint32_t verMajor = *(uint32_t*)(buffer + 4); + uint32_t verMinor = *(uint32_t*)(buffer + 8); + + if (magic != Magic) + { + LogError("Magic does not match"); + return false; + } + + if (verMajor != MajorVersion) + { + LogError("Major version mismatch"); + return false; + } + + if (verMinor < MinorVersion) + { + LogError("Remote minor version too old for our feature level"); + return false; + } + + HANDLE remoteDataEvent = (HANDLE)*(uint64_t*)(buffer + 12); + HANDLE remoteReturnEvent = (HANDLE)*(uint64_t*)(buffer + 20); + pid_t serverProcessId = (pid_t) *(uint64_t*)(buffer + 28); + OVR_UNUSED(serverProcessId); + + if (!remoteDataEvent || !remoteReturnEvent) + { + LogError("Handshake was malformed. It seems like a version mismatch."); + return false; + } + + DataEvent.Attach(remoteDataEvent); + ReturnEvent.Attach(remoteReturnEvent); + + return true; +} + +bool FastIPCClient::Initialize(const char* sharedMemoryName) +{ + SharedMemory::OpenParameters params; + params.accessMode = SharedMemory::AccessMode_ReadWrite; + params.globalName = sharedMemoryName; + params.minSizeBytes = RegionSize; + params.openMode = SharedMemory::OpenMode_OpenOnly; + params.remoteMode = SharedMemory::RemoteMode_ReadWrite; + Scratch = SharedMemoryFactory::GetInstance()->Open(params); + IPCMessageIndex = 1; + + if (!Scratch || Scratch->GetSizeI() < RegionSize) + { + OVR_ASSERT(false); + LogError("Unable to open shared memory region"); + return false; + } + + char* data = (char*)Scratch->GetData(); + + // If unable to read handshake, + if (!ReadInitialData(data)) + { + return false; + } + + return true; +} + +FastIPCClient::~FastIPCClient() +{ +} + +bool FastIPCClient::Call(Net::BitStream* parameters, Net::BitStream* returnData, int timeoutMs) +{ + // If not initialized, + if (!ReturnEvent.IsValid()) + { + OVR_ASSERT(false); + return false; + } + + volatile unsigned char* scratch = (unsigned char*)Scratch->GetData(); + + uint32_t bytesUsed = ((uint32_t)parameters->GetNumberOfBitsUsed() + 7) / 8; + + // If data is too long, + if (bytesUsed > RegionSize - 4) + { + OVR_ASSERT(false); + return false; + } + + // First 4 bytes will be the size of the parameters + // Note that this is for IPC so endian-ness is not important + *(uint32_t*)(scratch + 4) = bytesUsed; + + // Copy data into place + memcpy((char*)scratch + 8, parameters->GetData(), bytesUsed); + + // Don't allow read/write operations to move around this point + MemoryBarrier(); + + // Write message index + *(volatile uint32_t*)scratch = IPCMessageIndex; + + // Wake the remote thread to service our request + if (!::SetEvent(DataEvent.Get())) + { + OVR_ASSERT(false); + return false; + } + + // Wait for result of call: + + ++IPCMessageIndex; + + // Use the GetTickCount() API for low-resolution timing + DWORD t0 = ::GetTickCount(); + int remaining = timeoutMs; + + // Forever, + for (;;) + { + // Wait on the return event + DWORD result = ::WaitForSingleObject(ReturnEvent.Get(), timeoutMs < 0 ? INFINITE : remaining); + + if (result == WAIT_FAILED) + { + int err = GetLastError(); + LogError("[FastIPC] Wait failed with error %d", err); + } + + // If wait succeeded, + if (result == WAIT_OBJECT_0) + { + if (*(volatile uint32_t*)scratch != IPCMessageIndex) + { + double callTimeoutStart = Timer::GetSeconds(); + + while (*(volatile uint32_t*)scratch != IPCMessageIndex) + { + if (Timer::GetSeconds() - callTimeoutStart > 1.) + { + LogError("[FastIPC] Timed out waiting for remote IPC message to be written."); + OVR_ASSERT(false); + return false; + } + + Thread::YieldCurrentThread(); + } + } + + _ReadBarrier(); + + // Wrap the scratch buffer + uint32_t len = *(uint32_t*)(scratch + 4); + returnData->WrapBuffer((unsigned char*)scratch + 8, len); + + ++IPCMessageIndex; + + // Return true for success + return true; + } + + // If not waiting forever, + if (timeoutMs > 0) + { + // If wait time has elapsed, + int elapsed = ::GetTickCount() - t0; + if (elapsed >= timeoutMs) + { + // Break out of loop returning false + break; + } + + // Calculate remaining wait time + remaining = timeoutMs - elapsed; + } + + // Continue waiting + } + + return false; +} + + +}}} // namespace OVR::Service::Win32 diff --git a/LibOVR/Src/Service/Service_Win32_FastIPC_Client.h b/LibOVR/Src/Service/Service_Win32_FastIPC_Client.h new file mode 100644 index 0000000..984da06 --- /dev/null +++ b/LibOVR/Src/Service/Service_Win32_FastIPC_Client.h @@ -0,0 +1,84 @@ +/************************************************************************************ + +Filename : OVR_Service_Win32_FastIPC_Client.h +Content : Client side of connectionless fast IPC +Created : Sept 16, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Service_Win32_FastIPC_Client_h +#define OVR_Service_Win32_FastIPC_Client_h + +#include "Kernel/OVR_SharedMemory.h" +#include "Net/OVR_RPC1.h" +#include "Kernel/OVR_Win32_IncludeWindows.h" + +namespace OVR { namespace Service { namespace Win32 { + + +//----------------------------------------------------------------------------- +// FastIPCClient +// +// This class implements the client side for connectionless IPC messaging. +// +// The client reads the shared memory name provided and retrieves the data +// and return event handles. It can push data to the server synchronously +// by signaling the data handle and waiting on the return handle. + +class FastIPCClient +{ + String SharedMemoryName; + Ptr Scratch; + ScopedEventHANDLE DataEvent, ReturnEvent; + uint32_t IPCMessageIndex; + +protected: + bool ReadInitialData(const char* buffer); + +public: + static const int RegionSize = 4096; + static const uint32_t Magic = 0xfe67bead; + + // Semantic versioning + static const uint32_t MajorVersion = 1; + static const uint32_t MinorVersion = 0; + +public: + FastIPCClient(); + ~FastIPCClient(); + + String GetSharedMemoryName() const + { + return SharedMemoryName; + } + + // Call this to initialize the shared memory section + bool Initialize(const char* sharedMemoryName); + + // Make a blocking call to the server + // Pass -1 for the timeout to wait forever + bool Call(Net::BitStream* bread, Net::BitStream* toast, int timeoutMs = -1); +}; + + +}}} // namespace OVR::Service::Win32 + +#endif // OVR_Service_Win32_FastIPC_Client_h diff --git a/LibOVR/Src/Tracking/Tracking_PoseState.h b/LibOVR/Src/Tracking/Tracking_PoseState.h deleted file mode 100644 index 19e2ee2..0000000 --- a/LibOVR/Src/Tracking/Tracking_PoseState.h +++ /dev/null @@ -1,133 +0,0 @@ -/************************************************************************************ - -Filename : Tracking_PoseState.h -Content : Describes the complete pose at a point in time, including derivatives -Created : May 13, 2014 -Authors : Dov Katz - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef Tracking_PoseState_h -#define Tracking_PoseState_h - -#include "../Kernel/OVR_Math.h" - -namespace OVR { - -// PoseState describes the complete pose, or a rigid body configuration, at a -// point in time, including first and second derivatives. It is used to specify -// instantaneous location and movement of the headset. -// SensorState is returned as a part of the sensor state. - -template -class PoseState -{ -public: - typedef typename CompatibleTypes >::Type CompatibleType; - - PoseState() : TimeInSeconds(0.0) { } - PoseState(Pose pose, double time) : ThePose(pose), TimeInSeconds(time) { } - - // float <-> double conversion constructor. - explicit PoseState(const PoseState::OtherFloatType> &src) - : ThePose(src.ThePose), - AngularVelocity(src.AngularVelocity), LinearVelocity(src.LinearVelocity), - AngularAcceleration(src.AngularAcceleration), LinearAcceleration(src.LinearAcceleration), - TimeInSeconds(src.TimeInSeconds) - { } - - // C-interop support: PoseStatef <-> ovrPoseStatef - PoseState(const typename CompatibleTypes >::Type& src) - : ThePose(src.ThePose), - AngularVelocity(src.AngularVelocity), LinearVelocity(src.LinearVelocity), - AngularAcceleration(src.AngularAcceleration), LinearAcceleration(src.LinearAcceleration), - TimeInSeconds(src.TimeInSeconds) - { } - - operator typename CompatibleTypes >::Type() const - { - typename CompatibleTypes >::Type result; - result.ThePose = ThePose; - result.AngularVelocity = AngularVelocity; - result.LinearVelocity = LinearVelocity; - result.AngularAcceleration = AngularAcceleration; - result.LinearAcceleration = LinearAcceleration; - result.TimeInSeconds = TimeInSeconds; - return result; - } - - Pose ThePose; - Vector3 AngularVelocity; - Vector3 LinearVelocity; - Vector3 AngularAcceleration; - Vector3 LinearAcceleration; - // Absolute time of this state sample; always a double measured in seconds. - double TimeInSeconds; - - // ***** Helpers for Pose integration - - // Stores and integrates gyro angular velocity reading for a given time step. - void StoreAndIntegrateGyro(Vector3d angVel, double dt); - // Stores and integrates position/velocity from accelerometer reading for a given time step. - void StoreAndIntegrateAccelerometer(Vector3d linearAccel, double dt); - - // Performs integration of state by adding next state delta to it - // to produce a combined state change - void AdvanceByDelta(const PoseState& delta); -}; - - -template -PoseState operator*(const OVR::Pose& trans, const PoseState& poseState) -{ - PoseState result; - result.ThePose = trans * poseState.ThePose; - result.LinearVelocity = trans.Rotate(poseState.LinearVelocity); - result.LinearAcceleration = trans.Rotate(poseState.LinearAcceleration); - result.AngularVelocity = trans.Rotate(poseState.AngularVelocity); - result.AngularAcceleration = trans.Rotate(poseState.AngularAcceleration); - return result; -} - - -// External API returns pose as float, but uses doubles internally for quaternion precision. -typedef PoseState PoseStatef; -typedef PoseState PoseStated; - - -} // namespace OVR::Vision - - -namespace OVR { - - template<> struct CompatibleTypes > { typedef ovrPoseStatef Type; }; - template<> struct CompatibleTypes > { typedef ovrPoseStated Type; }; - - static_assert((sizeof(PoseState) == sizeof(Pose) + 4*sizeof(Vector3) + sizeof(double)), "sizeof(PoseState) failure"); -#ifdef OVR_CPU_X86_64 - static_assert((sizeof(PoseState) == sizeof(Pose) + 4*sizeof(Vector3) + sizeof(uint32_t) + sizeof(double)), "sizeof(PoseState) failure"); //TODO: Manually pad template. -#elif defined(OVR_OS_WIN32) // The Windows 32 bit ABI aligns 64 bit values on 64 bit boundaries - static_assert((sizeof(PoseState) == sizeof(Pose) + 4*sizeof(Vector3) + sizeof(uint32_t) + sizeof(double)), "sizeof(PoseState) failure"); -#else // Else Unix/Apple 32 bit ABI, which aligns 64 bit values on 32 bit boundaries. - static_assert((sizeof(PoseState) == sizeof(Pose) + 4*sizeof(Vector3) + sizeof(double)), "sizeof(PoseState) failure"); -#endif -} - -#endif // Tracking_PoseState_h diff --git a/LibOVR/Src/Tracking/Tracking_SensorState.h b/LibOVR/Src/Tracking/Tracking_SensorState.h deleted file mode 100644 index e13c3ef..0000000 --- a/LibOVR/Src/Tracking/Tracking_SensorState.h +++ /dev/null @@ -1,212 +0,0 @@ -/************************************************************************************ - -Filename : Tracking_SensorState.h -Content : Sensor state information shared by tracking system with games -Created : May 13, 2014 -Authors : Dov Katz, Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef Tracking_SensorState_h -#define Tracking_SensorState_h - -#include "Tracking_PoseState.h" -#include "../Kernel/OVR_SharedMemory.h" -#include "../Kernel/OVR_Lockless.h" -#include "../Kernel/OVR_String.h" -#include "../Util/Util_LatencyTest2State.h" -#include "../Sensors/OVR_DeviceConstants.h" - -// CAPI forward declarations. -struct ovrTrackingState_; -typedef struct ovrTrackingState_ ovrTrackingState; -struct ovrPoseStatef_; -typedef struct ovrPoseStatef_ ovrPoseStatef; - -namespace OVR { namespace Tracking { - - -//------------------------------------------------------------------------------------- -// ***** Sensor State -// These values are reported as compatible with C API. - -// Bit flags describing the current status of sensor tracking. -enum StatusBits -{ - // Tracked bits: Toggled by SensorFusion - Status_OrientationTracked = 0x0001, // Orientation is currently tracked (connected and in use) - Status_PositionTracked = 0x0002, // Position is currently tracked (false if out of range) - Status_CameraPoseTracked = 0x0004, // Camera pose is currently tracked - - // Connected bits: Toggled by TrackingManager - Status_PositionConnected = 0x0020, // Position tracking HW is connected - Status_HMDConnected = 0x0080, // HMD is available & connected - - // Masks - Status_AllMask = 0xffff, - Status_TrackingMask = Status_PositionTracked | Status_OrientationTracked | Status_CameraPoseTracked, - Status_ConnectedMask = Status_PositionConnected | Status_HMDConnected, -}; - - -// Full state of of the sensor reported by GetSensorState() at a given absolute time. -class TrackingState -{ -public: - TrackingState() : HeadPose(), CameraPose(), LeveledCameraPose(), RawSensorData(), StatusFlags(0), LastVisionProcessingTime(0.0) { } - - // C-interop support - TrackingState(const ovrTrackingState& s); - operator ovrTrackingState () const; - - // HMD pose information for the requested time. - PoseStatef HeadPose; - - // Orientation and position of the external camera, if present. - Posef CameraPose; - // Orientation and position of the camera after alignment with gravity - Posef LeveledCameraPose; - - // Most recent sensor data received from the HMD - SensorDataType RawSensorData; - - // Sensor status described by ovrStatusBits. - uint32_t StatusFlags; - - //// 0.4.1 - - // Measures the time from receiving the camera frame until vision CPU processing completes. - double LastVisionProcessingTime; - - //// 0.4.3 - - // Measures the time from exposure until the pose is available for the frame, including processing time. - double LastVisionFrameLatency; - - // Tag the vision processing results to a certain frame counter number. - uint32_t LastCameraFrameCounter; -}; - - -// ----------------------------------------------- - -#pragma pack(push, 8) - -struct LocklessSensorStatePadding; - -// State version stored in lockless updater "queue" and used for -// prediction by GetPoseAtTime/GetSensorStateAtTime -struct LocklessSensorState -{ - PoseState WorldFromImu; - SensorDataType RawSensorData; - Pose WorldFromCamera; - uint32_t StatusFlags; - uint32_t _PAD_0_; - - // ImuFromCpf for HMD pose tracking - Posed ImuFromCpf; - - // Performance logging - double LastVisionProcessingTime; - double LastVisionFrameLatency; - uint32_t LastCameraFrameCounter; - uint32_t _PAD_1_; - - // Initialized to invalid state - LocklessSensorState() : - WorldFromImu() - , RawSensorData() - , WorldFromCamera() - , StatusFlags(0) - , _PAD_0_(0) // This assignment should be irrelevant, but it quells static/runtime analysis complaints. - , ImuFromCpf() - , LastVisionProcessingTime(0.0) - , LastVisionFrameLatency(0.0) - , LastCameraFrameCounter(0) - , _PAD_1_(0) // " - { - } - - LocklessSensorState& operator = (const LocklessSensorStatePadding& rhs); -}; - -static_assert((sizeof(LocklessSensorState) == sizeof(PoseState) + sizeof(SensorDataType) + sizeof(Pose) + 2*sizeof(uint32_t) + sizeof(Posed) + sizeof(double)*2 + sizeof(uint32_t)*2), "sizeof(LocklessSensorState) failure"); - -// Padded out version stored in the updater slots -// Designed to be a larger fixed size to allow the data to grow in the future -// without breaking older compiled code. -struct LocklessSensorStatePadding -{ - uint64_t words[64]; - - static const int DataWords = (sizeof(LocklessSensorState) + sizeof(uint64_t) - 1) / sizeof(uint64_t); - - // Just copy the low data words - inline LocklessSensorStatePadding& operator=(const LocklessSensorState& rhs) - { - const uint64_t* src = (const uint64_t*)&rhs; - - // if this fires off, then increase words' array size - OVR_ASSERT(sizeof(words) > sizeof(LocklessSensorState)); - - for (int i = 0; i < DataWords; ++i) - { - words[i] = src[i]; - } - - return *this; - } -}; - -// Just copy the low data words -inline LocklessSensorState& LocklessSensorState::operator = (const LocklessSensorStatePadding& rhs) -{ - uint64_t* dest = (uint64_t*)this; - - for (int i = 0; i < LocklessSensorStatePadding::DataWords; ++i) - { - dest[i] = rhs.words[i]; - } - - return *this; -} - -#pragma pack(pop) - -// A lockless updater for sensor state -typedef LocklessUpdater SensorStateUpdater; - - -//// Combined state - -struct CombinedSharedStateUpdater -{ - SensorStateUpdater SharedSensorState; - Util::LockessRecordUpdater SharedLatencyTestState; -}; - -typedef SharedObjectWriter< CombinedSharedStateUpdater > CombinedSharedStateWriter; -typedef SharedObjectReader< CombinedSharedStateUpdater > CombinedSharedStateReader; - - -}} // namespace OVR::Tracking - -#endif diff --git a/LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp b/LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp deleted file mode 100644 index a506b26..0000000 --- a/LibOVR/Src/Tracking/Tracking_SensorStateReader.cpp +++ /dev/null @@ -1,207 +0,0 @@ -/************************************************************************************ - -Filename : Tracking_SensorStateReader.cpp -Content : Separate reader component that is able to recover sensor pose -Created : June 4, 2014 -Authors : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "Tracking_SensorStateReader.h" -#include "Tracking_PoseState.h" - -namespace OVR { namespace Tracking { - - -//------------------------------------------------------------------------------------- - -// This is a "perceptually tuned predictive filter", which means that it is optimized -// for improvements in the VR experience, rather than pure error. In particular, -// jitter is more perceptible at lower speeds whereas latency is more perceptible -// after a high-speed motion. Therefore, the prediction interval is dynamically -// adjusted based on speed. Significant more research is needed to further improve -// this family of filters. -static Pose calcPredictedPose(const PoseState& poseState, double predictionDt) -{ - Pose pose = poseState.ThePose; - const double linearCoef = 1.0; - Vector3d angularVelocity = poseState.AngularVelocity; - double angularSpeed = angularVelocity.Length(); - - // This could be tuned so that linear and angular are combined with different coefficients - double speed = angularSpeed + linearCoef * poseState.LinearVelocity.Length(); - - const double slope = 0.2; // The rate at which the dynamic prediction interval varies - double candidateDt = slope * speed; // TODO: Replace with smoothstep function - - double dynamicDt = predictionDt; - - // Choose the candidate if it is shorter, to improve stability - if (candidateDt < predictionDt) - { - dynamicDt = candidateDt; - } - - if (angularSpeed > 0.001) - { - pose.Rotation = pose.Rotation * Quatd(angularVelocity, angularSpeed * dynamicDt); - } - - pose.Translation += poseState.LinearVelocity * dynamicDt; - - return pose; -} - - -//// SensorStateReader - -SensorStateReader::SensorStateReader() : - Updater(NULL), - LastLatWarnTime(0.) -{ -} - -void SensorStateReader::SetUpdater(const CombinedSharedStateUpdater* updater) -{ - Updater = updater; -} - -void SensorStateReader::RecenterPose() -{ - if (!Updater) - { - return; - } - - /* - This resets position to center in x, y, z, and resets yaw to center. - Other rotation components are not affected. - */ - - const LocklessSensorState lstate = Updater->SharedSensorState.GetState(); - - Posed worldFromCpf = lstate.WorldFromImu.ThePose * lstate.ImuFromCpf; - double hmdYaw, hmdPitch, hmdRoll; - worldFromCpf.Rotation.GetEulerAngles(&hmdYaw, &hmdPitch, &hmdRoll); - - Posed worldFromCentered(Quatd(Axis_Y, hmdYaw), worldFromCpf.Translation); - - CenteredFromWorld = worldFromCentered.Inverted(); -} - -bool SensorStateReader::GetSensorStateAtTime(double absoluteTime, TrackingState& ss) const -{ - if (!Updater) - { - ss.StatusFlags = 0; - return false; - } - - const LocklessSensorState lstate = Updater->SharedSensorState.GetState(); - - // Update time - ss.HeadPose.TimeInSeconds = absoluteTime; - - // Update the status flags - ss.StatusFlags = lstate.StatusFlags; - // If no hardware is connected, override the tracking flags - if (0 == (ss.StatusFlags & Status_HMDConnected)) - { - ss.StatusFlags &= ~Status_TrackingMask; - } - if (0 == (ss.StatusFlags & Status_PositionConnected)) - { - ss.StatusFlags &= ~(Status_PositionTracked | Status_CameraPoseTracked); - } - - // If tracking info is invalid, - if (0 == (ss.StatusFlags & Status_TrackingMask)) - { - return false; - } - - // Delta time from the last available data - double pdt = absoluteTime - lstate.WorldFromImu.TimeInSeconds; - static const double maxPdt = 0.1; - - // If delta went negative due to synchronization problems between processes or just a lag spike, - if (pdt < 0.) - { - pdt = 0.; - } - else if (pdt > maxPdt) - { - if (LastLatWarnTime != lstate.WorldFromImu.TimeInSeconds) - { - LastLatWarnTime = lstate.WorldFromImu.TimeInSeconds; - LogText("[SensorStateReader] Prediction interval too high: %f s, clamping at %f s\n", pdt, maxPdt); - } - pdt = maxPdt; - } - - ss.HeadPose = PoseStatef(lstate.WorldFromImu); - // Do prediction logic and ImuFromCpf transformation - ss.HeadPose.ThePose = Posef(CenteredFromWorld * calcPredictedPose(lstate.WorldFromImu, pdt) * lstate.ImuFromCpf); - - ss.CameraPose = Posef(CenteredFromWorld * lstate.WorldFromCamera); - - Posed worldFromLeveledCamera = Posed(Quatd(), lstate.WorldFromCamera.Translation); - ss.LeveledCameraPose = Posef(CenteredFromWorld * worldFromLeveledCamera); - - ss.RawSensorData = lstate.RawSensorData; - ss.LastVisionProcessingTime = lstate.LastVisionProcessingTime; - ss.LastVisionFrameLatency = lstate.LastVisionFrameLatency; - - return true; -} - -bool SensorStateReader::GetPoseAtTime(double absoluteTime, Posef& transform) const -{ - TrackingState ss; - if (!GetSensorStateAtTime(absoluteTime, ss)) - { - return false; - } - - transform = ss.HeadPose.ThePose; - - return true; -} - -uint32_t SensorStateReader::GetStatus() const -{ - if (!Updater) - { - return 0; - } - - const LocklessSensorState lstate = Updater->SharedSensorState.GetState(); - - // If invalid, - if (0 == (lstate.StatusFlags & Status_TrackingMask)) - { - // Return 0 indicating no orientation nor position tracking - return 0; - } - - return lstate.StatusFlags; -} - -}} // namespace OVR::Tracking diff --git a/LibOVR/Src/Tracking/Tracking_SensorStateReader.h b/LibOVR/Src/Tracking/Tracking_SensorStateReader.h deleted file mode 100644 index c2922c8..0000000 --- a/LibOVR/Src/Tracking/Tracking_SensorStateReader.h +++ /dev/null @@ -1,87 +0,0 @@ -/************************************************************************************ - -Filename : Tracking_SensorStateReader.h -Content : Separate reader component that is able to recover sensor pose -Created : June 4, 2014 -Authors : Chris Taylor - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef Tracking_SensorStateReader_h -#define Tracking_SensorStateReader_h - -#include "../Kernel/OVR_Lockless.h" -#include "Tracking_SensorState.h" - -#include "../OVR_Profile.h" - -namespace OVR { namespace Tracking { - - -//----------------------------------------------------------------------------- -// SensorStateReader - -// User interface to retrieve pose from the sensor fusion subsystem -class SensorStateReader : public NewOverrideBase -{ -protected: - const CombinedSharedStateUpdater *Updater; - - - // Last latency warning time - mutable double LastLatWarnTime; - - // Transform from real-world coordinates to centered coordinates - Posed CenteredFromWorld; - -public: - SensorStateReader(); - - // Initialize the updater - void SetUpdater(const CombinedSharedStateUpdater *updater); - - // Re-centers on the current yaw (optionally pitch) and translation - void RecenterPose(); - - // Get the full dynamical system state of the CPF, which includes velocities and accelerations, - // predicted at a specified absolute point in time. - bool GetSensorStateAtTime(double absoluteTime, Tracking::TrackingState& state) const; - - // Get the predicted pose (orientation, position) of the center pupil frame (CPF) at a specific point in time. - bool GetPoseAtTime(double absoluteTime, Posef& transform) const; - - // Get the sensor status (same as GetSensorStateAtTime(...).Status) - uint32_t GetStatus() const; - - const Posed getCenteredFromWorld() - { - return CenteredFromWorld; - } - - void setCenteredFromWorld(const Posed _CenteredFromWorld) - { - CenteredFromWorld = _CenteredFromWorld; - } -}; - - -}} // namespace OVR::Tracking - -#endif // Tracking_SensorStateReader_h diff --git a/LibOVR/Src/Util/GUIConsole.h b/LibOVR/Src/Util/GUIConsole.h deleted file mode 100644 index a1b35ed..0000000 --- a/LibOVR/Src/Util/GUIConsole.h +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************ - -Filename : GUIConsole.h -Content : A stdout console window that runs alongside Windows GUI applications -Created : Feb 4, 2013 -Authors : Brant Lewis - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef GUICONSOLE_H -#define GUICONSOLE_H - -#include "../../Include/OVR_Kernel.h" - -#ifdef OVR_INTERNAL_USE - -#include -#include -#define WIN32_LEAN_AND_MEAN -#include - -class GUIConsole -{ -public: - // constructors - GUIConsole(); - ~GUIConsole(); - - // member variables - HANDLE hStdIn, hStdOut, hStdError; -}; -#endif // #ifdef OVR_INTERNAL_USE - -#endif diff --git a/LibOVR/Src/Util/Util_DataLogger.h b/LibOVR/Src/Util/Util_DataLogger.h new file mode 100644 index 0000000..e21c9f2 --- /dev/null +++ b/LibOVR/Src/Util/Util_DataLogger.h @@ -0,0 +1,168 @@ +/************************************************************************************ + +Filename : Util_DataLogger.h +Content : General purpose data logging to Matlab +Created : Oct 3, 2014 +Authors : Neil Konzen + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_DataLogger_h +#define OVR_Util_DataLogger_h + +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_String.h" +#include "Util_MatFile.h" + +#ifndef OVR_ENABLE_DATALOGGER +#define OVR_ENABLE_DATALOGGER 1 +#endif + +namespace OVR { + +template class Vector3; +template class Quat; +template class Pose; + +namespace Util { + +#if OVR_ENABLE_DATALOGGER + +class DataLogger; + + +// DataLogger Channel +class DataLoggerChannel +{ +public: + void Log(const void* data, int sampleSize); + + bool IsLogging() const; + bool IsFull() const; + + // Logging functions for some common types + template + void Log(const Quat& q); + + template + void Log(const Vector3& v); + + template + void Log(const Pose& p); + +private: + friend class DataLogger; + + DataLoggerChannel(DataLogger* logger, const char* name, int sampleSize, int sampleRate, bool doubleMatrix); + ~DataLoggerChannel(); + + bool Write(MatFile& matfile); + +private: + DataLogger* Logger; + String Name; + int SampleSize; + int SampleRate; + int SampleCount; + int MaxSampleCount; + bool DoubleMatrix; + uint8_t* SampleData; +}; + +// DataLogger class +class DataLogger +{ +public: + DataLogger(); + ~DataLogger(); + + // Parses C command line parameters "-log " + static bool ParseCommandLine(int* pargc, const char** pargv[], int& logIndex, String& logFile, double& logTime); + + void SetLogFile(const char* filename, double logTime); + bool SaveLogFile(); + + bool IsLogging() const { return LogTime > 0; } + + DataLoggerChannel* GetChannel(const char* name); + DataLoggerChannel* CreateChannel(const char* name, int sampleSize, int sampleRate, bool doubleMatrix = true); + + void Log(const char* name, const void* data, int sampleSize, int sampleRate, bool doubleMatrix = true) + { + DataLoggerChannel *channel = CreateChannel(name, sampleSize, sampleRate, doubleMatrix); + if (channel) channel->Log(data, sampleSize); + } + +private: + friend class DataLoggerChannel; + + DataLoggerChannel* GetChannelNoLock(const char* name); + + Lock TheLock; + double LogTime; + String Filename; + ArrayPOD Channels; +}; + +#else // OVR_ENABLE_DATALOGGER + +// Disabled, no-op implementation +class DataLoggerChannel +{ +public: + OVR_FORCE_INLINE void Log(const void* data, int sampleSize) { OVR_UNUSED2(data, sampleSize); } + + OVR_FORCE_INLINE bool IsLogging() const { return false; } + OVR_FORCE_INLINE bool IsFull() const { return false; } + + template + OVR_FORCE_INLINE void Log(const Quat& q) { OVR_UNUSED(q); } + + template + OVR_FORCE_INLINE void Log(const Vector3& v) { OVR_UNUSED(v); } + + template + OVR_FORCE_INLINE void Log(const Pose& p) { OVR_UNUSED(p); } +}; + +class DataLogger +{ +public: + static bool ParseCommandLine(int* pargc, const char** pargv[], int& logIndex, String& logFile, double& logTime) { OVR_UNUSED5(pargc, pargv, logIndex, logFile, logTime); return false; } + + OVR_FORCE_INLINE void SetLogFile(const char* filename, double logTime) { OVR_UNUSED2(filename, logTime); } + OVR_FORCE_INLINE bool SaveLogFile() { return true; } + + OVR_FORCE_INLINE bool IsLogging() const { return false; } + + OVR_FORCE_INLINE DataLoggerChannel* GetChannel(const char* name) { OVR_UNUSED(name); return &NullChannel; } + OVR_FORCE_INLINE DataLoggerChannel* CreateChannel(const char* name, int sampleSize, int sampleRate) { OVR_UNUSED3(name, sampleSize, sampleRate); return &NullChannel; } + +private: + friend class DataLoggerChannel; + static DataLoggerChannel NullChannel; +}; + +#endif // OVR_ENABLE_DATALOGGER + + +}} // namespace OVR::Util + +#endif // OVR_Util_DataLogger_h diff --git a/LibOVR/Src/Util/Util_ImageWindow.cpp b/LibOVR/Src/Util/Util_ImageWindow.cpp deleted file mode 100644 index 4c120f9..0000000 --- a/LibOVR/Src/Util/Util_ImageWindow.cpp +++ /dev/null @@ -1,574 +0,0 @@ -/************************************************************************************ - -Filename : Util_ImageWindow.cpp -Content : An output object for windows that can display raw images for testing -Created : March 13, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ -#include "../../Include/OVR_Kernel.h" - -#include "Util_ImageWindow.h" - -#if defined(OVR_OS_WIN32) - -#define WIN32_LEAN_AND_MEAN -#include - -#include "DWrite.h" - -typedef HRESULT (WINAPI *D2D1CreateFactoryFn)( - _In_ D2D1_FACTORY_TYPE, - _In_ REFIID, - _In_opt_ const D2D1_FACTORY_OPTIONS*, - _Out_ ID2D1Factory ** - ); - -typedef HRESULT (WINAPI *DWriteCreateFactoryFn)( - _In_ DWRITE_FACTORY_TYPE factoryType, - _In_ REFIID iid, - _Out_ IUnknown **factory - ); - - -namespace OVR { namespace Util { - -ID2D1Factory* ImageWindow::pD2DFactory = NULL; -IDWriteFactory* ImageWindow::pDWriteFactory = NULL; -HINSTANCE ImageWindow::hInstD2d1 = NULL; -HINSTANCE ImageWindow::hInstDwrite = NULL; - - -// TODO(review): This appears to be (at present) necessary, the global list is accessed by the -// render loop in Samples. In the current version, windows will just be lost when windowCount -// exceeds MaxWindows; I've left that in place, since this is unfamiliar code. I'm not sure what -// thread-safety guarantees this portion of the code needs to satisfy, so I don't want to -// change it to a list or whatever. Asserts added to catch the error. -ImageWindow* ImageWindow::globalWindow[ImageWindow::MaxWindows]; -int ImageWindow::windowCount = 0; - -LRESULT CALLBACK MainWndProc( - HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - switch (uMsg) - { - case WM_CREATE: - return 0; - - case WM_PAINT: - { - LONG_PTR ptr = GetWindowLongPtr( hwnd, GWLP_USERDATA ); - if( ptr ) - { - ImageWindow* iw = (ImageWindow*)ptr; - iw->OnPaint(); - } - } - - return 0; - - case WM_SIZE: - // Set the size and position of the window. - return 0; - - case WM_DESTROY: - // Clean up window-specific data objects. - return 0; - - // - // Process other messages. - // - - default: - return DefWindowProc(hwnd, uMsg, wParam, lParam); - } - //return 0; -} - - -ImageWindow::ImageWindow( uint32_t width, uint32_t height ) : - hWindow(NULL), - pRT(NULL), - //resolution(), - frontBufferMutex( new Mutex() ), - frames(), - greyBitmap(NULL), - colorBitmap(NULL) -{ - D2D1CreateFactoryFn createFactory = NULL; - DWriteCreateFactoryFn writeFactory = NULL; - - if (!hInstD2d1) - { - hInstD2d1 = LoadLibraryW( L"d2d1.dll" ); - } - - if (!hInstD2d1) - { - hInstD2d1 = LoadLibraryW( L"Dwrite.dll" ); - } - - if( hInstD2d1 ) - { - createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInstD2d1, "D2D1CreateFactory" ); - } - - if( hInstDwrite ) - { - writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstDwrite, "DWriteCreateFactory" ); - } - - // TODO: see note where globalWindow is declared. - globalWindow[windowCount++ % MaxWindows] = this; - OVR_ASSERT(windowCount < MaxWindows); - - if( pD2DFactory == NULL && createFactory && writeFactory ) - { - // Create a Direct2D factory. - HRESULT hResult = createFactory( - D2D1_FACTORY_TYPE_MULTI_THREADED, - __uuidof(ID2D1Factory), - NULL, - &pD2DFactory // This will be AddRef'd for us. - ); - OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); - - // Create a DirectWrite factory. - hResult = writeFactory( - DWRITE_FACTORY_TYPE_SHARED, - __uuidof(pDWriteFactory), // This probably should instead be __uuidof(IDWriteFactory) - reinterpret_cast(&pDWriteFactory) // This will be AddRef'd for us. - ); - OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); - } - - resolution = D2D1::SizeU( width, height ); - - if (hWindow) - { - SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this ); - } -} - -ImageWindow::~ImageWindow() -{ - for( int i = 0; i < MaxWindows; ++i ) - { - if( globalWindow[i] == this ) - { - globalWindow[i] = NULL; - break; - } - } - - if( greyBitmap ) - greyBitmap->Release(); - - if( colorBitmap ) - colorBitmap->Release(); - - if( pRT ) - pRT->Release(); - - { - Mutex::Locker locker( frontBufferMutex ); - - while( frames.GetSize() ) - { - Ptr aFrame = frames.PopBack(); - } - } - - delete frontBufferMutex; - - if (hWindow) - { - ShowWindow( hWindow, SW_HIDE ); - DestroyWindow( hWindow ); - } - - if (pD2DFactory) - { - pD2DFactory->Release(); - pD2DFactory = NULL; - } - - if (pDWriteFactory) - { - pDWriteFactory->Release(); - pDWriteFactory = NULL; - } - - if( hInstD2d1 ) - { - FreeLibrary(hInstD2d1); - hInstD2d1 = NULL; - } - - if( hInstDwrite ) - { - FreeLibrary(hInstDwrite); - hInstDwrite = NULL; - } -} - -void ImageWindow::AssociateSurface( void* surface ) -{ - if (pD2DFactory) - { - // Assume an IUnknown - IUnknown* unknown = (IUnknown*)surface; - - IDXGISurface *pDxgiSurface = NULL; - HRESULT hr = unknown->QueryInterface(&pDxgiSurface); - if( hr == S_OK ) - { - D2D1_RENDER_TARGET_PROPERTIES props = - D2D1::RenderTargetProperties( - D2D1_RENDER_TARGET_TYPE_DEFAULT, - D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), - 96, - 96 - ); - - pRT = NULL; - ID2D1RenderTarget* tmpTarget; - - hr = pD2DFactory->CreateDxgiSurfaceRenderTarget( pDxgiSurface, &props, &tmpTarget ); - - if( hr == S_OK ) - { - DXGI_SURFACE_DESC desc = {0}; - pDxgiSurface->GetDesc( &desc ); - int width = desc.Width; - int height = desc.Height; - - D2D1_SIZE_U size = D2D1::SizeU( width, height ); - - D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat( - DXGI_FORMAT_A8_UNORM, - D2D1_ALPHA_MODE_PREMULTIPLIED - ); - - D2D1_PIXEL_FORMAT colorPixelFormat = D2D1::PixelFormat( - DXGI_FORMAT_B8G8R8A8_UNORM, - D2D1_ALPHA_MODE_PREMULTIPLIED - ); - - D2D1_BITMAP_PROPERTIES bitmapProps; - bitmapProps.dpiX = 96; - bitmapProps.dpiY = 96; - bitmapProps.pixelFormat = pixelFormat; - - D2D1_BITMAP_PROPERTIES colorBitmapProps; - colorBitmapProps.dpiX = 96; - colorBitmapProps.dpiY = 96; - colorBitmapProps.pixelFormat = colorPixelFormat; - - HRESULT result = tmpTarget->CreateBitmap( size, bitmapProps, &greyBitmap ); - if( result != S_OK ) - { - tmpTarget->Release(); - tmpTarget = NULL; - } - - if (tmpTarget) - { - result = tmpTarget->CreateBitmap(size, colorBitmapProps, &colorBitmap); - if (result != S_OK) - { - tmpTarget->Release(); - tmpTarget = NULL; - } - } - pRT = tmpTarget; - } - } - } -} - -void ImageWindow::Process() -{ - if( pRT && greyBitmap ) - { - OnPaint(); - - pRT->Flush(); - } -} - -void ImageWindow::Complete() -{ - Mutex::Locker locker( frontBufferMutex ); - - if( frames.IsEmpty() ) - return; - - if( frames.PeekBack(0)->ready ) - return; - - Ptr frame = frames.PeekBack(0); - - frame->ready = true; -} - -void ImageWindow::OnPaint() -{ - Mutex::Locker locker( frontBufferMutex ); - - // Nothing to do - if( frames.IsEmpty() ) - return; - - if( !frames.PeekFront(0)->ready ) - return; - - Ptr currentFrame = frames.PopFront(); - - Ptr nextFrame = NULL; - - if( !frames.IsEmpty() ) - nextFrame = frames.PeekFront(0); - - while( nextFrame && nextFrame->ready ) - { - // Free up the current frame since it's been removed from the deque - currentFrame = frames.PopFront(); - - if( frames.IsEmpty() ) - break; - - nextFrame = frames.PeekFront(0); - } - - if( currentFrame->imageData ) - greyBitmap->CopyFromMemory( NULL, currentFrame->imageData, currentFrame->width ); - - if( currentFrame->colorImageData ) - colorBitmap->CopyFromMemory( NULL, currentFrame->colorImageData, currentFrame->colorPitch ); - - pRT->BeginDraw(); - - pRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); - - pRT->Clear( D2D1::ColorF(D2D1::ColorF::Black) ); - - // This will mirror our image - D2D1_MATRIX_3X2_F m; - m._11 = -1; m._12 = 0; - m._21 = 0; m._22 = 1; - m._31 = 0; m._32 = 0; - pRT->SetTransform( m ); - - ID2D1SolidColorBrush* whiteBrush; - - pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush ); - - if( currentFrame->imageData ) - { - pRT->FillOpacityMask( greyBitmap, whiteBrush, - D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL, - D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), - //D2D1::RectF( 0.0f, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), - D2D1::RectF( 0.0f, 0.0f, (FLOAT)resolution.width, (FLOAT)resolution.height ) ); - } - else if( currentFrame->colorImageData ) - { - pRT->DrawBitmap( colorBitmap, - D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) ); - - } - - pRT->SetTransform(D2D1::Matrix3x2F::Identity()); - - whiteBrush->Release(); - - Array::Iterator it; - - for( it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it ) - { - ID2D1SolidColorBrush* aBrush; - - pRT->CreateSolidColorBrush( D2D1::ColorF( it->r, it->g, it->b), &aBrush ); - - D2D1_ELLIPSE ellipse; - ellipse.point.x = it->x; - ellipse.point.y = it->y; - ellipse.radiusX = it->radius; - ellipse.radiusY = it->radius; - - if( it->fill ) - pRT->FillEllipse( &ellipse, aBrush ); - else - pRT->DrawEllipse( &ellipse, aBrush ); - - aBrush->Release(); - } - - static const WCHAR msc_fontName[] = L"Verdana"; - static const FLOAT msc_fontSize = 20; - - IDWriteTextFormat* textFormat = NULL; - - // Create a DirectWrite text format object. - pDWriteFactory->CreateTextFormat( - msc_fontName, - NULL, - DWRITE_FONT_WEIGHT_NORMAL, - DWRITE_FONT_STYLE_NORMAL, - DWRITE_FONT_STRETCH_NORMAL, - msc_fontSize, - L"", //locale - &textFormat - ); - - D2D1_SIZE_F renderTargetSize = pRT->GetSize(); - - Array::Iterator textIt; - for( textIt = currentFrame->textLines.Begin(); textIt != currentFrame->textLines.End(); ++textIt ) - { - ID2D1SolidColorBrush* aBrush; - - pRT->CreateSolidColorBrush( D2D1::ColorF( textIt->r, textIt->g, textIt->b), &aBrush ); - - WCHAR* tmpString = (WCHAR*)calloc( textIt->text.GetLength(), sizeof( WCHAR ) ); - for( unsigned i = 0; i < textIt->text.GetLength(); ++i ) - { - tmpString[i] = (WCHAR)textIt->text.GetCharAt( i ); - } - - pRT->DrawTextW( tmpString, (UINT32)textIt->text.GetLength(), textFormat, - D2D1::RectF(textIt->x, textIt->y, renderTargetSize.width, renderTargetSize.height), aBrush ); - - free( tmpString ); - - aBrush->Release(); - } - - if( textFormat ) - textFormat->Release(); - - pRT->EndDraw(); - - pRT->Flush(); -} - -Ptr ImageWindow::lastUnreadyFrame() -{ - static int framenumber = 0; - - if( frames.GetSize() && !frames.PeekBack( 0 )->ready ) - return frames.PeekBack( 0 ); - - // Create a new frame if an unready one doesn't already exist - Ptr tmpFrame = *new Frame( framenumber ); - frames.PushBack( tmpFrame ); - - ++framenumber; - - return tmpFrame; -} - -void ImageWindow::UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) -{ - if( pRT && greyBitmap ) - { - Mutex::Locker locker( frontBufferMutex ); - - Ptr frame = lastUnreadyFrame(); - frame->imageData = malloc( width * height ); - frame->width = width; - frame->height = height; - memcpy( frame->imageData, imageData, width * height ); - } -} - -void ImageWindow::UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) -{ - if( pRT && colorBitmap ) - { - Mutex::Locker locker( frontBufferMutex ); - - Ptr frame = lastUnreadyFrame(); - frame->colorImageData = malloc( pitch * height ); - frame->width = width; - frame->height = height; - frame->colorPitch = pitch; - memcpy( frame->colorImageData, imageData, pitch * height ); - } -} - -void ImageWindow::addCircle( float x, float y, float radius, float r, float g, float b, bool fill ) -{ - if( pRT ) - { - CirclePlot cp; - - cp.x = x; - cp.y = y; - cp.radius = radius; - cp.r = r; - cp.g = g; - cp.b = b; - cp.fill = fill; - - Mutex::Locker locker( frontBufferMutex ); - - Ptr frame = lastUnreadyFrame(); - frame->plots.PushBack( cp ); - } - -} - -void ImageWindow::addText( float x, float y, float r, float g, float b, OVR::String text ) -{ - if( pRT ) - { - TextPlot tp; - - tp.x = x; - tp.y = y; - tp.r = r; - tp.g = g; - tp.b = b; - tp.text = text; - - Mutex::Locker locker( frontBufferMutex ); - Ptr frame = lastUnreadyFrame(); - frame->textLines.PushBack( tp ); - } -} - -}} - -#else //defined(OVR_OS_WIN32) - -namespace OVR { namespace Util { - -ImageWindow* ImageWindow::globalWindow[4]; -int ImageWindow::windowCount = 0; - -}} - -#endif //#else //defined(OVR_OS_WIN32) - diff --git a/LibOVR/Src/Util/Util_ImageWindow.h b/LibOVR/Src/Util/Util_ImageWindow.h deleted file mode 100644 index 979dd93..0000000 --- a/LibOVR/Src/Util/Util_ImageWindow.h +++ /dev/null @@ -1,204 +0,0 @@ -/************************************************************************************ - -Filename : Util_ImageWindow.h -Content : An output object for windows that can display raw images for testing -Created : March 13, 2014 -Authors : Dean Beeler - -Copyright : Copyright 2014 Oculus, Inc. All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef UTIL_IMAGEWINDOW_H -#define UTIL_IMAGEWINDOW_H - -#if defined(OVR_OS_WIN32) -#include -#include -#define WIN32_LEAN_AND_MEAN -#include -#include -#include -#endif - -#include "../Kernel/OVR_Hash.h" -#include "../Kernel/OVR_Array.h" -#include "../Kernel/OVR_Threads.h" -#include "../Kernel/OVR_Deque.h" - -#include - -namespace OVR { namespace Util { - - typedef struct - { - float x; - float y; - float radius; - float r; - float g; - float b; - bool fill; - } CirclePlot; - - typedef struct - { - float x; - float y; - float r; - float g; - float b; - OVR::String text; - } TextPlot; - -class Frame : virtual public RefCountBaseV - { -public: - - Frame( int frame ) : - frameNumber( frame ), - imageData( NULL ), - colorImageData( NULL ), - plots(), - textLines(), - width( 0 ), - height( 0 ), - colorPitch( 0 ), - ready( false ) - { - - } - - ~Frame() - { - if( imageData ) - free( imageData ); - if( colorImageData ) - free( colorImageData ); - - plots.ClearAndRelease(); - textLines.ClearAndRelease(); - } - - int frameNumber; - - Array plots; - Array textLines; - void* imageData; - void* colorImageData; - int width; - int height; - int colorPitch; - bool ready; -}; - -#if defined(OVR_OS_WIN32) -class ImageWindow -{ - HWND hWindow; - ID2D1RenderTarget* pRT; - D2D1_SIZE_U resolution; - - Mutex* frontBufferMutex; - - InPlaceMutableDeque< Ptr > frames; - - ID2D1Bitmap* greyBitmap; - ID2D1Bitmap* colorBitmap; - -public: - // constructors - ImageWindow(); - ImageWindow( uint32_t width, uint32_t height ); - virtual ~ImageWindow(); - - void GetResolution( size_t& width, size_t& height ) { width = resolution.width; height = resolution.height; } - - void OnPaint(); // Called by Windows when it receives a WM_PAINT message - - void UpdateImage( const uint8_t* imageData, uint32_t width, uint32_t height ) { UpdateImageBW( imageData, width, height ); } - void UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ); - void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ); - void Complete(); // Called by drawing thread to submit a frame - - void Process(); // Called by rendering thread to do window processing - - void AssociateSurface( void* surface ); - - void addCircle( float x , float y, float radius, float r, float g, float b, bool fill ); - void addText( float x, float y, float r, float g, float b, OVR::String text ); - - static ImageWindow* GlobalWindow( int window ) { return globalWindow[window]; } - static int WindowCount() { return windowCount; } - -private: - - Ptr lastUnreadyFrame(); - - static const int MaxWindows = 4; - static ImageWindow* globalWindow[MaxWindows]; - static int windowCount; - static ID2D1Factory* pD2DFactory; - static IDWriteFactory* pDWriteFactory; - static HINSTANCE hInstD2d1; - static HINSTANCE hInstDwrite; - -}; - -#else - -class ImageWindow -{ -public: - // constructors - ImageWindow() {} - ImageWindow( uint32_t width, uint32_t height ) { OVR_UNUSED( width ); OVR_UNUSED( height ); } - virtual ~ImageWindow() { } - - void GetResolution( size_t& width, size_t& height ) { width = 0; height = 0; } - - void OnPaint() { } - - void UpdateImage( const uint8_t* imageData, uint32_t width, uint32_t height ) { UpdateImageBW( imageData, width, height ); } - void UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) { OVR_UNUSED( imageData ); OVR_UNUSED( width ); OVR_UNUSED( height ); } - void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) { OVR_UNUSED( imageData ); OVR_UNUSED( width ); OVR_UNUSED( height ); OVR_UNUSED( pitch ); } - void Complete() { } - - void Process() { } - - void AssociateSurface( void* surface ) { OVR_UNUSED(surface); } - - void addCircle( float x , float y, float radius, float r, float g, float b, bool fill ) { OVR_UNUSED( x ); OVR_UNUSED( y ); OVR_UNUSED( radius ); OVR_UNUSED( r ); OVR_UNUSED( g ); OVR_UNUSED( b ); OVR_UNUSED( fill ); } - void addText( float x, float y, float r, float g, float b, OVR::String text ) { OVR_UNUSED( x ); OVR_UNUSED( y ); OVR_UNUSED( r ); OVR_UNUSED( g ); OVR_UNUSED( b ); OVR_UNUSED( text ); } - - static ImageWindow* GlobalWindow( int window ) { return globalWindow[window]; } - static int WindowCount() { return windowCount; } - -private: - - static const int MaxWindows = 4; - static ImageWindow* globalWindow[4]; - static int windowCount; -}; - -#endif - -}} // namespace OVR::Util - - -#endif diff --git a/LibOVR/Src/Util/Util_Interface.h b/LibOVR/Src/Util/Util_Interface.h index ab08715..eb2257f 100644 --- a/LibOVR/Src/Util/Util_Interface.h +++ b/LibOVR/Src/Util/Util_Interface.h @@ -29,7 +29,7 @@ limitations under the License. #ifndef OVR_Util_Interface_h #define OVR_Util_Interface_h -#include "../OVR_CAPI.h" +#include "OVR_CAPI.h" //Files left in to ease its possible return...... diff --git a/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp b/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp index e34bf19..6131c30 100644 --- a/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp +++ b/LibOVR/Src/Util/Util_LatencyTest2Reader.cpp @@ -63,7 +63,7 @@ FrameTimeRecordSet::FrameTimeRecordSet() void FrameTimeRecordSet::AddValue(int readValue, double timeSeconds) { Records[NextWriteIndex].ReadbackIndex = readValue; - Records[NextWriteIndex].TimeSeconds = timeSeconds; + Records[NextWriteIndex].TimeSeconds = timeSeconds; NextWriteIndex++; if (NextWriteIndex == RecordCount) NextWriteIndex = 0; @@ -110,7 +110,7 @@ void RecordStateReader::GetRecordSet(FrameTimeRecordSet& recordset) return; } - recordset = Updater->SharedLatencyTestState.GetState(); + recordset = Updater->LatencyTest.GetState(); return; } diff --git a/LibOVR/Src/Util/Util_LatencyTest2Reader.h b/LibOVR/Src/Util/Util_LatencyTest2Reader.h index 1863e62..fb7e5cb 100644 --- a/LibOVR/Src/Util/Util_LatencyTest2Reader.h +++ b/LibOVR/Src/Util/Util_LatencyTest2Reader.h @@ -27,7 +27,7 @@ limitations under the License. #ifndef OVR_Util_LatencyTest2Reader_h #define OVR_Util_LatencyTest2Reader_h -#include "../Tracking/Tracking_SensorState.h" +#include "Vision/SensorFusion/Vision_SensorState.h" #include "Util_LatencyTest2State.h" namespace OVR { namespace Util { @@ -40,7 +40,7 @@ namespace OVR { namespace Util { class RecordStateReader : public NewOverrideBase { protected: - const Tracking::CombinedSharedStateUpdater* Updater; + const Vision::CombinedHmdUpdater* Updater; public: RecordStateReader() @@ -49,7 +49,7 @@ public: } // Initialize the updater - void SetUpdater(const Tracking::CombinedSharedStateUpdater *updater) + void SetUpdater(const Vision::CombinedHmdUpdater *updater) { Updater = updater; } diff --git a/LibOVR/Src/Util/Util_LatencyTest2State.h b/LibOVR/Src/Util/Util_LatencyTest2State.h index 0b4ffd6..ced3d70 100644 --- a/LibOVR/Src/Util/Util_LatencyTest2State.h +++ b/LibOVR/Src/Util/Util_LatencyTest2State.h @@ -27,7 +27,7 @@ limitations under the License. #ifndef OVR_Util_LatencyTest2_State_h #define OVR_Util_LatencyTest2_State_h -#include "../Kernel/OVR_Lockless.h" +#include "Kernel/OVR_Lockless.h" namespace OVR { namespace Util { @@ -45,10 +45,11 @@ enum LatencyTester2Constants // FrameTimeRecord // Describes frame scan-out time used for latency testing. -struct FrameTimeRecord +struct OVR_ALIGNAS(8) FrameTimeRecord { - int ReadbackIndex; - double TimeSeconds; + int32_t ReadbackIndex; + int32_t Pad; + double TimeSeconds; // Utility functions to convert color to readBack indices and back. // The purpose of ReadbackIndex is to allow direct comparison by value. @@ -63,14 +64,15 @@ struct FrameTimeRecord // FrameTimeRecordSet is a container holding multiple consecutive frame timing records // returned from the lock-less state. Used by FrameTimeManager. -struct FrameTimeRecordSet +struct OVR_ALIGNAS(8) FrameTimeRecordSet { enum { RecordCount = 4, RecordMask = RecordCount - 1 }; FrameTimeRecord Records[RecordCount]; - int NextWriteIndex; + int32_t NextWriteIndex; + int32_t Pad4; FrameTimeRecordSet(); @@ -88,9 +90,6 @@ struct FrameTimeRecordSet bool IsAllZeroes() const; }; -typedef LocklessUpdater LockessRecordUpdater; - - }} // namespace OVR::Util #endif // OVR_Util_LatencyTest2_State_h diff --git a/LibOVR/Src/Util/Util_MatFile.cpp b/LibOVR/Src/Util/Util_MatFile.cpp new file mode 100644 index 0000000..f17e269 --- /dev/null +++ b/LibOVR/Src/Util/Util_MatFile.cpp @@ -0,0 +1,496 @@ +/************************************************************************************ + +Filename : Util_MatFile.cpp +Content : Matlab .MAT file access functions +Created : June 1, 2014 +Authors : Neil Konzen + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Util_MatFile.h" + +#include "Kernel/OVR_Types.h" +#include "Kernel/OVR_Alg.h" +#include "Kernel/OVR_Std.h" + +OVR_DISABLE_MSVC_WARNING(4996) // 'fopen': This function or variable may be unsafe. Consider using fopen_s inst + + +namespace OVR { namespace Util { + +using namespace OVR::Alg; + + +// Data structures relating to MATLAB .MAT binary files +#define FX_FORM_IEEE_LE 0000u +#define FX_FORM_IEEE_BE 1000u +#define FX_FORM_VAX_D_FLOAT 2000u +#define FX_FORM_VAX_G_FLOAT 3000u +#define FX_FORM_CRAY 4000u +#define FX_FORM(type) ((((type) / 1000u) % 10u) * 1000u) + +#define FX_PREC_UINT8 50u +#define FX_PREC_INTU 40u +#define FX_PREC_INTS 30u +#define FX_PREC_LONG 20u +#define FX_PREC_SINGLE 10u +#define FX_PREC_DOUBLE 00u +#define FX_PREC(type) ((((type) / 10u) % 10u) * 10u) + +// Note that the elements of a text matrix are stored as floating-point numbers +// between 0 and 255 representing ASCII-encoded characters. +#define FX_MAT_NUMERIC 0u +#define FX_MAT_TEXT 1u +#define FX_MAT_SPARSE 2u +#define FX_MAT(type) ((type) % 10u) + +struct Fmatrix +{ + uint32_t type; // Type - see #defines + uint32_t mrows; // Row dimension - NOTE: Column dimension for C Arrays! + uint32_t ncols; // Column dimension - NOTE: Row dimension for C Arrays! + uint32_t imagf; // 1=complex, 0=real + uint32_t namelen; // length including zero terminator +}; + + +uint32_t MatFile::GetMatlabType(ValueType type, size_t& valueSize) +{ + switch (type) + { + case ByteValue: valueSize = sizeof(uint8_t); return FX_PREC_UINT8; + case UInt16Value: valueSize = sizeof(uint16_t); return FX_PREC_INTU; + case Int16Value: valueSize = sizeof(int16_t); return FX_PREC_INTS; + case UInt32Value: valueSize = sizeof(uint32_t); return FX_PREC_LONG; // Not directly supported by matlab! + case Int32Value: valueSize = sizeof(int32_t); return FX_PREC_LONG; + case FloatValue: valueSize = sizeof(float); return FX_PREC_SINGLE; + case DoubleValue: valueSize = sizeof(double); return FX_PREC_DOUBLE; + case StringValue: valueSize = sizeof(char); return FX_MAT_TEXT; // special case for string arrays + default: + OVR_ASSERT(false); + valueSize = 0; + return 0; + } +} + +MatFile::ValueType MatFile::GetValueType(uint32_t matlabType, size_t& valueSize) +{ + switch (matlabType) + { + case FX_PREC_UINT8: valueSize = sizeof(uint8_t); return ByteValue; + case FX_PREC_INTU: valueSize = sizeof(uint16_t); return UInt16Value; + case FX_PREC_INTS: valueSize = sizeof(int16_t); return Int16Value; + case FX_PREC_LONG: valueSize = sizeof(int32_t); return Int32Value; + case FX_PREC_SINGLE: valueSize = sizeof(float); return FloatValue; + case FX_PREC_DOUBLE: valueSize = sizeof(double); return DoubleValue; + case FX_MAT_TEXT: valueSize = sizeof(char); return StringValue; + default: + OVR_ASSERT(false); + valueSize = 0; + return UnknownValue; + } +} + +MatFile::MatFile(void) +{ + m_f = NULL; +} + +MatFile::~MatFile(void) +{ + if (m_f) + fclose(m_f); + m_f = NULL; +} + +// Matlab arrays are stored column-major, while C/C++ arrays are stored row-major. +// This means that a C array appears to Matlab transposed, and vice versa. +// To deal with this we swap the row and column values stored in the Matlab matrix header. + +bool MatFile::Open(const char* pszFile, bool write) +{ + OVR_ASSERT(!m_f); + m_f = fopen(pszFile, write ? "wb" : "rb"); + return (m_f != nullptr); +} + +void MatFile::Close() +{ + if (m_f) + { + fclose(m_f); + m_f = NULL; + } +} + +int MatFile::ReadString(const char* name, char* text, size_t maxTextSize) +{ + int rows, cols; + ValueType valueType; + + maxTextSize = Alg::Min(maxTextSize, INT_MAX/sizeof(double)/2); + + if (!GetMatrixInfo(name, valueType, rows, cols)) + return 0; + + if (valueType != StringValue) + return 0; + + int count = rows * cols; // character count, not including zero terminator + + double* doubles = new double[count]; + ReadMatrixValues(doubles, StringValue, count, 1); + + if (maxTextSize > 0 && count > 0) + { + count = (int)Alg::Min(count, (int)(maxTextSize-1)); + for (int i = 0; i < count; i++) + text[i] = (char)doubles[i]; + text[count] = 0; // Always zero terminate + } + + delete[] doubles; + + return count; +} + +bool MatFile::WriteString(const char* name, const char* string) +{ + int length = (int)Alg::Min(strlen(string), INT_MAX/sizeof(double)/2); + + double* doubles = new double[length]; + for (int i = 0; i < length; i++) + doubles[i] = (double)((unsigned char)string[i]); + + bool ok = WriteMatrix(name, doubles, StringValue, (int)length, 1); + + delete[] doubles; + + return ok; +} + +void* MatFile::ReadMatrix(const char* name, ValueType valueType, int& rows, int& cols) +{ + ValueType fileValueType; + if (!GetMatrixInfo(name, fileValueType, rows, cols)) + return NULL; + + int valueCount = rows * cols; + + void* values = NULL; + switch (fileValueType) + { + case StringValue: // Text matrices are stored as doubles + case DoubleValue: + values = new double[valueCount]; + break; + case FloatValue: + values = new float[valueCount]; + break; + case ByteValue: + values = new uint8_t[valueCount]; + break; + case Int16Value: + values = new int16_t[valueCount]; + break; + case UInt16Value: + values = new uint16_t[valueCount]; + break; + case Int32Value: + /*case UInt32Value: -- not directly supported by matlab -v4 files */ + values = new int32_t[valueCount]; + break; + default: + OVR_ASSERT(false); + return NULL; + } + + bool ok = ReadMatrixValues(values, fileValueType, rows, cols); + + if (ok) + values = ConvertVector(values, valueCount, fileValueType, valueType); + + if (!ok) + { + delete[] (char*)values; + values = NULL; + } + + OVR_ASSERT(values); + return values; +} + +void* MatFile::ConvertVector(void* fromValues, int valueCount, ValueType fromType, ValueType toType) +{ + // Special case: Always convert characters stored as doubles to a char array + if (fromType == StringValue) + fromType = DoubleValue; + + if (fromType == toType) + return fromValues; + + // UInt32 values are stored as Int32 values by Matlab + if (fromType == Int32Value && toType == UInt32Value) + return fromValues; + + // When a .mat file is saved by Matlab, many datatypes are converted to double. + // We support conversion of doubles to some other types: float, long, byte, char + // and strings and floats to doubles. + // convert singles to doubles + bool ok = true; + if (fromType == DoubleValue) + { + const double* fromDoubles = (const double*)fromValues; + if (toType == FloatValue) + { + float* newValues = new float[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (float)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == Int32Value) + { + int32_t* newValues = new int32_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (int32_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == UInt32Value) + { + uint32_t* newValues = new uint32_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (uint32_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == Int16Value) + { + int16_t* newValues = new int16_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (int16_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == UInt16Value) + { + uint16_t* newValues = new uint16_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (uint16_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == ByteValue) + { + uint8_t* newValues = new uint8_t[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (uint8_t)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else if (toType == StringValue) + { + char* newValues = new char[valueCount]; + for (int i = 0; i < valueCount; i++) + newValues[i] = (char)fromDoubles[i]; + delete[] (char*)fromValues; + fromValues = newValues; + } + else + { + // unsupported type conversion + ok = false; + } + } + else + { + ok = false; // only conversions from doubles supported + } + + if (!ok) + { + OVR_ASSERT(false); + delete[] (char*)fromValues; + fromValues = NULL; + } + + return fromValues; +} + +bool MatFile::GetMatrixInfo(const char* name, ValueType& valueType, int& rows, int& cols) +{ + OVR_ASSERT(m_f); + fseek(m_f, 0, SEEK_SET); // rewind to start of file + + static const int maxVarNameLen = 255; + char varName[maxVarNameLen+1]; + + while (ReadMatrixInfo(varName, maxVarNameLen, valueType, rows, cols)) + { + if (OVR_stricmp(name, varName) == 0) + return true; + // skip over data to next one + ReadMatrixValues(NULL, valueType, rows, cols); + } + + return false; +} + +bool MatFile::ReadMatrixInfo(char name[], size_t maxNameSize, ValueType& valueType, int& rows, int& cols) +{ + if (name && maxNameSize > 0) + name[0] = 0; + + valueType = UnknownValue; + rows = 0; + cols = 0; + + OVR_ASSERT(m_f); + if (!m_f) + return false; + + Fmatrix header; + if (fread(&header, sizeof(header), 1, m_f) != 1) + return false; + + // Read transpose of row and column values stored in the file + cols = header.mrows; + rows = header.ncols; + + if (FX_FORM(header.type) != FX_FORM_IEEE_LE) + { + OVR_ASSERT(false); + return false; + } + + // Imaginary not supported + if (header.imagf != 0) + { + OVR_ASSERT(false); + return false; + } + + // sparse matrices not supported + if (FX_MAT(header.type) == FX_MAT_SPARSE) + { + OVR_ASSERT(false); + return false; + } + + // Special case for strings as text matrixes: they are stored as doubles(!) + if (FX_MAT(header.type) == FX_MAT_TEXT) + { + valueType = StringValue; + } + else + { + // only numeric types supported + if (FX_MAT(header.type) != FX_MAT_NUMERIC) + { + OVR_ASSERT(false); + return false; + } + size_t valueSize; + valueType = GetValueType(FX_PREC(header.type), valueSize); + } + + // Read in name + OVR_ASSERT(maxNameSize >= header.namelen); + if (maxNameSize < header.namelen) + return false; + + if (fread(name, sizeof(char), header.namelen, m_f) != header.namelen) + return false; + + return true; +} + +bool MatFile::ReadMatrixValues(void* values, ValueType valueType, int rows, int cols) +{ + OVR_ASSERT(m_f); + if (!m_f) + return false; + + OVR_ASSERT(rows*cols > 0); + + size_t valueCount = (size_t)(rows * cols); + size_t valueSize = 0; + GetMatlabType(valueType, valueSize); + if (valueSize == 0) + return false; + + // If no values pointer specified, skip over data without reading + if (!values) + { + if (fseek(m_f, (long)(valueSize * valueCount), SEEK_CUR) != 0) + return false; + } + else + { + if (fread(values, valueSize, valueCount, m_f) != valueCount) + return false; + } + + return true; +} + +bool MatFile::WriteMatrix(const char* name, const void* values, ValueType valueType, int rows, int cols) +{ + if (!m_f) + return false; + + OVR_ASSERT(rows*cols > 0); + + size_t valueCount = (size_t)(rows * cols); + size_t valueSize = 0; + uint32_t matlabType = GetMatlabType(valueType, valueSize); + if (valueSize == 0) + return false; + + Fmatrix header; + if (valueType == StringValue) + { + header.type = (FX_FORM_IEEE_LE + FX_MAT_TEXT); + } + else + { + header.type = (FX_FORM_IEEE_LE + FX_MAT_NUMERIC) + matlabType; + } + + // NOTE: We store transposed dimensions! + header.mrows = cols; + header.ncols = rows; + header.imagf = 0; + header.namelen = (uint32_t)(strlen(name) + 1); + OVR_ASSERT(header.namelen > 1); + + if (fwrite(&header, sizeof(header), 1, m_f) != 1) + return false; + if (fwrite(name, sizeof(char), header.namelen, m_f) != header.namelen) + return false; + if (fwrite(values, valueSize, valueCount, m_f) != valueCount) + return false; + + return true; +} + + +}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_MatFile.h b/LibOVR/Src/Util/Util_MatFile.h new file mode 100644 index 0000000..8b763a2 --- /dev/null +++ b/LibOVR/Src/Util/Util_MatFile.h @@ -0,0 +1,116 @@ +/************************************************************************************ + +Filename : Util_MatFile.h +Content : Matlab .MAT file access functions +Created : June 1, 2014 +Authors : Neil Konzen + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_MatFile_h +#define OVR_Util_MatFile_h + +#include "Kernel/OVR_Types.h" + +#include +#include + +// Read and write MatLab .MAT data files, in MatLab Version 4 format +namespace OVR { namespace Util { + + +class MatFile +{ +public: + MatFile(); + ~MatFile(void); + + bool Open(const char* pszFile, bool write); + void Close(); + + // Matrix element value types + enum ValueType { + UnknownValue = 0, + ByteValue = 1, + UInt16Value = 2, + Int16Value = 3, + UInt32Value = 4, // NOTE: Matlab -v4 don't support UInt32 directly: values stored as Int32. + Int32Value = 5, + FloatValue = 6, + DoubleValue = 7, + StringValue = 8 + }; + + // NOTE: A stored matrix is TRANSPOSED when read into MatLab + // MatLab uses Fortran column-major matrix storage conventions + + // Write a matrix, organized as rows x columns + // Vectors should be written with 1 column: they will appear in Matlab as a 1-row matrix. + // NOTE: this function reads StringValue matrices as an array of doubles (!) + bool WriteMatrix(const char* name, const void* values, ValueType valueType, int rows, int cols); + + bool WriteMatrix(const char* name, const uint8_t* values, int rows, int cols = 1) { return WriteMatrix(name, values, ByteValue, rows, cols); } + bool WriteMatrix(const char* name, const uint16_t* values, int rows, int cols = 1){ return WriteMatrix(name, values, UInt16Value, rows, cols); } + bool WriteMatrix(const char* name, const int16_t* values, int rows, int cols = 1) { return WriteMatrix(name, values, Int16Value, rows, cols); } + bool WriteMatrix(const char* name, const int32_t* values, int rows, int cols = 1) { return WriteMatrix(name, values, Int32Value, rows, cols); } + bool WriteMatrix(const char* name, const float* values, int rows, int cols = 1) { return WriteMatrix(name, values, FloatValue, rows, cols); } + bool WriteMatrix(const char* name, const double* values, int rows, int cols = 1) { return WriteMatrix(name, values, DoubleValue, rows, cols); } + bool WriteString(const char* name, const char* value); + + // NOTE: Matlab doesn't directly support uint32_t type: these values are saved and loaded as Int32Values + bool WriteMatrix(const char* name, const uint32_t* values, int rows, int cols = 1){ return WriteMatrix(name, values, Int32Value, rows, cols); } + + bool GetMatrixInfo(const char* name, ValueType& valueType, int& rows, int& cols); + + uint8_t* ReadByteMatrix(const char* name, int& rows, int& cols) { return (uint8_t*)ReadMatrix(name, ByteValue, rows, cols); } + uint16_t* ReadUInt16Matrix(const char* name, int& rows, int& cols) { return (uint16_t*)ReadMatrix(name, UInt16Value, rows, cols); } + int16_t* ReadInt16Matrix(const char* name, int& rows, int& cols) { return (int16_t*)ReadMatrix(name, Int16Value, rows, cols); } + int32_t* ReadInt32Matrix(const char* name, int& rows, int& cols) { return (int32_t*)ReadMatrix(name, Int32Value, rows, cols); } + float* ReadFloatMatrix(const char* name, int& rows, int& cols) { return (float*)ReadMatrix(name, FloatValue, rows, cols); } + double* ReadDoubleMatrix(const char* name, int& rows, int& cols) { return (double*)ReadMatrix(name, DoubleValue, rows, cols); } + + // NOTE: Matlab doesn't directly support uint32_t type: these values are saved and loaded as Int32Values + uint32_t* ReadUInt32Matrix(const char* name, int& rows, int& cols) { return (uint32_t*)ReadMatrix(name, Int32Value, rows, cols); } + + int ReadString(const char* name, char* string, size_t maxStringSize); + + // Read matrix values. This function performs (some) data type conversions to specified valueType in cases where data is stored in .mat file as doubles. + bool ReadMatrixValues(void* values, ValueType valueType, int rows, int cols); + +private: + static uint32_t GetMatlabType(ValueType valueType, size_t& valueSize); // returns Matlab FX_* type and size in bytes of data type element + static ValueType GetValueType(uint32_t matlabType, size_t& valueSize); + + // Read a matrix, organized as column-major rows x columns. Caller must delete returned vectors + void* ReadMatrix(const char* name, ValueType valueType, int& rows, int& cols); + + // Read next matrix name, value type, and dimensions + bool ReadMatrixInfo(char name[/*maxNameSize*/], size_t maxNameSize, ValueType& valueType, int& rows, int& cols); + + void* ConvertVector(void* fromValues, int valueCount, ValueType fromType, ValueType toType); + +private: + FILE* m_f; +}; + + +}} // namespace OVR::Util + +#endif // OVR_Util_MatFile_h diff --git a/LibOVR/Src/Util/Util_Render_Stereo.cpp b/LibOVR/Src/Util/Util_Render_Stereo.cpp index aa82b35..e60f5bd 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.cpp +++ b/LibOVR/Src/Util/Util_Render_Stereo.cpp @@ -28,9 +28,13 @@ limitations under the License. namespace OVR { namespace Util { namespace Render { -using namespace OVR::Tracking; +using namespace OVR::Vision; +#if defined (OVR_CC_MSVC) +static_assert(sizeof(DistortionMeshVertexData) == sizeof(ovrDistortionVertex), "DistortionMeshVertexData size mismatch"); +#endif + //----------------------------------------------------------------------------------- // **** Useful debug functions. @@ -51,8 +55,10 @@ char const* GetDebugNameEyeCupType ( EyeCupType eyeCupType ) case EyeCup_JamesA: return "James A"; case EyeCup_SunMandalaA: return "Sun Mandala A"; case EyeCup_DK2A: return "DK2 A"; + case EyeCup_BlackStar: return "BlackStar"; + case EyeCup_EVTProto: return "EVT A"; case EyeCup_LAST: return "LAST"; - default: OVR_ASSERT ( false ); return "Error"; + default: OVR_ASSERT ( false ); return "Error"; break; } } @@ -68,9 +74,11 @@ char const* GetDebugNameHmdType ( HmdTypeEnum hmdType ) case HmdType_DKHD2Proto: return "DK HD prototype 585"; case HmdType_CrystalCoveProto: return "Crystal Cove"; case HmdType_DK2: return "DK2"; + case HmdType_BlackStar: return "BlackStar"; + case HmdType_CB: return "Crescent Bay"; case HmdType_Unknown: return "Unknown"; case HmdType_LAST: return "LAST"; - default: OVR_ASSERT ( false ); return "Error"; + default: OVR_ASSERT ( false ); return "Error"; } } @@ -180,7 +188,8 @@ static StereoEyeParams CalculateStereoEyeParamsInternal ( StereoEye eyeType, Hmd FovPort const &fov, Sizei const &actualRendertargetSurfaceSize, Recti const &renderedViewport, - bool bRightHanded = true, float zNear = 0.01f, float zFar = 10000.0f, + bool bRightHanded = true, bool isOpenGL = false, + float zNear = 0.01f, float zFar = 10000.0f, bool bMonoRenderingMode = false, float zoomFactor = 1.0f ) { @@ -192,7 +201,7 @@ static StereoEyeParams CalculateStereoEyeParamsInternal ( StereoEye eyeType, Hmd zoomedFov.RightTan *= fovScale; zoomedFov.UpTan *= fovScale; zoomedFov.DownTan *= fovScale; - Matrix4f projection = CreateProjection ( bRightHanded, zoomedFov, zNear, zFar ); + Matrix4f projection = CreateProjection ( bRightHanded, isOpenGL, zoomedFov, eyeType, zNear, zFar ); // Find the mapping from TanAngle space to target NDC space. // Note this does NOT take the zoom factor into account because @@ -280,6 +289,7 @@ StereoEyeParams CalculateStereoEyeParams ( HmdRenderInfo const &hmd, Sizei const &actualRendertargetSurfaceSize, bool bRendertargetSharedByBothEyes, bool bRightHanded /*= true*/, + bool bOpenGL /*= false*/, float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/, Sizei const *pOverrideRenderedPixelSize /* = NULL*/, FovPort const *pOverrideFovport /*= NULL*/, @@ -309,7 +319,7 @@ StereoEyeParams CalculateStereoEyeParams ( HmdRenderInfo const &hmd, distortionAndFov.Distortion, distortionAndFov.Fov, actualRendertargetSurfaceSize, viewport, - bRightHanded, zNear, zFar, false, zoomFactor ); + bRightHanded, bOpenGL, zNear, zFar, false, zoomFactor ); } @@ -416,6 +426,7 @@ StereoConfig::StereoConfig(StereoMode mode) ExtraEyeRotationInRadians = OVR_DEFAULT_EXTRA_EYE_ROTATION; IsRendertargetSharedByBothEyes = true; RightHandedProjection = true; + UsingOpenGL = false; // This should cause an assert if the app does not call SetRendertargetSize() RendertargetSize = Sizei ( 0, 0 ); @@ -507,12 +518,14 @@ void StereoConfig::SetZeroVirtualIpdOverride ( bool enableOverride ) } -void StereoConfig::SetZClipPlanesAndHandedness ( float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/, bool rightHandedProjection /*= true*/ ) +void StereoConfig::SetZClipPlanesAndHandedness ( float zNear /*= 0.01f*/, float zFar /*= 10000.0f*/, + bool rightHandedProjection /*= true*/, bool isOpenGL /*= false*/ ) { DirtyFlag = true; ZNear = zNear; ZFar = zFar; RightHandedProjection = rightHandedProjection; + UsingOpenGL = isOpenGL; } void StereoConfig::SetExtraEyeRotation ( float extraEyeRotationInRadians ) @@ -620,7 +633,7 @@ void StereoConfig::UpdateComputedState() EyeRenderParams[eyeNum].StereoEye = CalculateStereoEyeParamsInternal ( eyeType, Hmd, localDistortion, fov, RendertargetSize, tempViewport, - RightHandedProjection, ZNear, ZFar, + RightHandedProjection, UsingOpenGL, ZNear, ZFar, OverrideZeroIpd ); // We want to create a virtual 2D surface we can draw debug text messages to. @@ -771,7 +784,7 @@ Matrix4f StereoConfig::GetProjectionWithZoom ( StereoEye eye, float fovZoom ) co fovPort.RightTan *= fovScale; fovPort.UpTan *= fovScale; fovPort.DownTan *= fovScale; - return CreateProjection ( RightHandedProjection, fovPort, ZNear, ZFar ); + return CreateProjection ( RightHandedProjection, UsingOpenGL, fovPort, eye, ZNear, ZFar ); } @@ -799,12 +812,6 @@ DistortionMeshVertexData DistortionMeshMakeVertex ( Vector2f screenNDC, { DistortionMeshVertexData result; - float xOffset = 0.0f; - if (rightEye) - { - xOffset = 1.0f; - } - Vector2f tanEyeAnglesR, tanEyeAnglesG, tanEyeAnglesB; TransformScreenNDCToTanFovSpaceChroma ( &tanEyeAnglesR, &tanEyeAnglesG, &tanEyeAnglesB, distortion, screenNDC ); @@ -878,8 +885,32 @@ DistortionMeshVertexData DistortionMeshMakeVertex ( Vector2f screenNDC, // Note - this is NOT clamped negatively. // For rendering methods that interpolate over a coarse grid, we need the values to go negative for correct intersection with zero. result.Shade = Alg::Min ( edgeFadeIn, 1.0f ); - result.ScreenPosNDC.x = 0.5f * screenNDC.x - 0.5f + xOffset; - result.ScreenPosNDC.y = -screenNDC.y; + + float eyeOffset = rightEye ? 1.0f : 0.0f; + float xOffset = 0.5f * screenNDC.x - 0.5f + eyeOffset; + float yOffset = -screenNDC.y; + + // Rotate the mesh to match screen orientation. + if (hmdRenderInfo.Rotation == 270) + { + result.ScreenPosNDC.x = -yOffset; + result.ScreenPosNDC.y = xOffset; + } + else if (hmdRenderInfo.Rotation == 0) + { + result.ScreenPosNDC.x = xOffset; + result.ScreenPosNDC.y = yOffset; + } + else if (hmdRenderInfo.Rotation == 180) + { + result.ScreenPosNDC.x = -xOffset; + result.ScreenPosNDC.y = -yOffset; + } + else if (hmdRenderInfo.Rotation == 90) + { + result.ScreenPosNDC.x = yOffset; + result.ScreenPosNDC.y = -xOffset; + } return result; } @@ -1345,6 +1376,10 @@ Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorl return matRenderXform.Inverted(); } + +#if defined(OVR_ENABLE_TIMEWARP_MACHINE) +// This is deprecated by DistortionTiming code. -cat + TimewarpMachine::TimewarpMachine() : VsyncEnabled(false), RenderInfo(), @@ -1409,7 +1444,7 @@ double TimewarpMachine::GetViewRenderPredictionTime() return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToRenderedScene; } -bool TimewarpMachine::GetViewRenderPredictionPose(SensorStateReader* reader, Posef& pose) +bool TimewarpMachine::GetViewRenderPredictionPose(TrackingStateReader* reader, Posef& pose) { return reader->GetPoseAtTime(GetViewRenderPredictionTime(), pose); } @@ -1424,15 +1459,15 @@ double TimewarpMachine::GetVisiblePixelTimeEnd() // Note that PredictionGetDeviceValues() did all the vsync-dependent thinking for us. return NextFramePresentFlushTime + CurrentPredictionValues.PresentFlushToTimewarpEnd; } -bool TimewarpMachine::GetPredictedVisiblePixelPoseStart(SensorStateReader* reader, Posef& pose) +bool TimewarpMachine::GetPredictedVisiblePixelPoseStart(TrackingStateReader* reader, Posef& pose) { return reader->GetPoseAtTime(GetVisiblePixelTimeStart(), pose); } -bool TimewarpMachine::GetPredictedVisiblePixelPoseEnd(SensorStateReader* reader, Posef& pose) +bool TimewarpMachine::GetPredictedVisiblePixelPoseEnd(TrackingStateReader* reader, Posef& pose) { return reader->GetPoseAtTime(GetVisiblePixelTimeEnd(), pose); } -bool TimewarpMachine::GetTimewarpDeltaStart(SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform) +bool TimewarpMachine::GetTimewarpDeltaStart(TrackingStateReader* reader, Posef const &renderedPose, Matrix4f& transform) { Posef visiblePose; if (!GetPredictedVisiblePixelPoseStart(reader, visiblePose)) @@ -1447,7 +1482,7 @@ bool TimewarpMachine::GetTimewarpDeltaStart(SensorStateReader* reader, Posef con return true; } -bool TimewarpMachine::GetTimewarpDeltaEnd(SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform) +bool TimewarpMachine::GetTimewarpDeltaEnd(TrackingStateReader* reader, Posef const &renderedPose, Matrix4f& transform) { Posef visiblePose; if (!GetPredictedVisiblePixelPoseEnd(reader, visiblePose)) @@ -1549,6 +1584,8 @@ void TimewarpMachine::JustInTime_AfterDistortionTimeMeasurement(double timeNo } } +#endif // OVR_ENABLE_TIMEWARP_MACHINE + }}} // OVR::Util::Render diff --git a/LibOVR/Src/Util/Util_Render_Stereo.h b/LibOVR/Src/Util/Util_Render_Stereo.h index 2ac863c..7eb016c 100644 --- a/LibOVR/Src/Util/Util_Render_Stereo.h +++ b/LibOVR/Src/Util/Util_Render_Stereo.h @@ -27,8 +27,9 @@ limitations under the License. #ifndef OVR_Util_Render_Stereo_h #define OVR_Util_Render_Stereo_h -#include "../OVR_Stereo.h" -#include "../Tracking/Tracking_SensorStateReader.h" +#include "OVR_Stereo.h" +#include "Extras/OVR_Math.h" +#include "Vision/SensorFusion/Vision_SensorStateReader.h" namespace OVR { namespace Util { namespace Render { @@ -218,7 +219,7 @@ public: // Allows the app to specify near and far clip planes and the right/left-handedness of the projection matrix. void SetZClipPlanesAndHandedness ( float zNear = 0.01f, float zFar = 10000.0f, - bool rightHandedProjection = true ); + bool rightHandedProjection = true, bool isOpenGL = false ); // Allows the app to specify how much extra eye rotation to allow when determining the visible FOV. void SetExtraEyeRotation ( float extraEyeRotationInRadians = 0.0f ); @@ -291,6 +292,7 @@ private: float ExtraEyeRotationInRadians; bool IsRendertargetSharedByBothEyes; bool RightHandedProjection; + bool UsingOpenGL; // for projection clip depth calculation bool DirtyFlag; // Set when any if the modifiable state changed. Does NOT get set by SetRender*() @@ -415,6 +417,8 @@ Matrix4f TimewarpComputePoseDelta ( Matrix4f const &renderedViewFromWorld, Matri Matrix4f TimewarpComputePoseDeltaPosition ( Matrix4f const &renderedViewFromWorld, Matrix4f const &predictedViewFromWorld, Matrix4f const&hmdToEyeViewOffset ); +#if defined(OVR_ENABLE_TIMEWARP_MACHINE) +// This is deprecated by DistortionTiming code. -cat // TimewarpMachine helps keep track of rendered frame timing and // handles predictions for time-warp rendering. @@ -438,7 +442,7 @@ public: // and the predicted pose of the HMD at that time. // You usually only need to call one of these functions. double GetViewRenderPredictionTime(); - bool GetViewRenderPredictionPose(Tracking::SensorStateReader* reader, Posef& transform); + bool GetViewRenderPredictionPose(Vision::TrackingStateReader* reader, Posef& transform); // Timewarp prediction functions. You usually only need to call one of these three sets of functions. @@ -447,13 +451,13 @@ public: double GetVisiblePixelTimeStart(); double GetVisiblePixelTimeEnd(); // Predicted poses of the HMD at those first and last pixels. - bool GetPredictedVisiblePixelPoseStart(Tracking::SensorStateReader* reader, Posef& transform); - bool GetPredictedVisiblePixelPoseEnd(Tracking::SensorStateReader* reader, Posef& transform); + bool GetPredictedVisiblePixelPoseStart(Vision::TrackingStateReader* reader, Posef& transform); + bool GetPredictedVisiblePixelPoseEnd(Vision::TrackingStateReader* reader, Posef& transform); // The delta matrices to feed to the timewarp distortion code, // given the pose that was used for rendering. // (usually the one returned by GetViewRenderPredictionPose() earlier) - bool GetTimewarpDeltaStart(Tracking::SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform); - bool GetTimewarpDeltaEnd(Tracking::SensorStateReader* reader, Posef const &renderedPose, Matrix4f& transform); + bool GetTimewarpDeltaStart(Vision::TrackingStateReader* reader, Posef const &renderedPose, Matrix4f& transform); + bool GetTimewarpDeltaEnd(Vision::TrackingStateReader* reader, Posef const &renderedPose, Matrix4f& transform); // Just-In-Time distortion aims to delay the second sensor reading & distortion // until the very last moment to improve prediction. However, it is a little scary, @@ -493,6 +497,8 @@ private: }; +#endif // OVR_ENABLE_TIMEWARP_MACHINE + }}} // OVR::Util::Render diff --git a/LibOVR/Src/Util/Util_Stopwatch.h b/LibOVR/Src/Util/Util_Stopwatch.h new file mode 100644 index 0000000..912de6c --- /dev/null +++ b/LibOVR/Src/Util/Util_Stopwatch.h @@ -0,0 +1,139 @@ +/************************************************************************************ + +Filename : Util_Stopwatch.h +Content : Handy classes for making timing measurements +Created : June 1, 2014 +Authors : Neil Konzen + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Kernel/OVR_Timer.h" + +// NOTE: This file is designed to be included in multiple .cpp files +// with different settings of OVR_DISABLE_STOPWATCH, +// so there is no include guard or #pragma once. + +namespace OVR { namespace Util { + +// Declare a StopwatchTimer as a static, global, or member variable. +// Then use Stopwatch() to accumulate timings within a scope. +/* + +static StopwatchTimer FooTimer("Foo", 37, .003); // Compute average of 37 timing samples, print timing if average time is greater than .003 seconds +static StopwatchTimer BarTimer("Bar"); // Print time of each measurement + +void SomeFunction() +{ + CodeNotToIncludeInTiming(); + + { + Stopwatch sw(FooTimer); // sw times everything in its scope + Foo(); + } // Every 37 times through the loop, if average time of Foo() is > .003 seconds, the average time is printed with LogText() + + { + Stopwatch sw(BarTimer); + Bar(); + } // Elapsed time of Bar() is printed every time + + MoreCodeNotToIncludeInTiming(); +} +*/ + +#ifndef OVR_DISABLE_STOPWATCH + +class StopwatchTimer +{ +public: + StopwatchTimer(const char* label, int printCount = 1, double printThreshold = 0.0) : + StartTime(0), + ElapsedTime(0), + Label(label), + SampleCount(0), + PrintCount(printCount), + PrintThreshold(printThreshold) + { + } + + inline void Start() + { + StartTime = Timer::GetSeconds(); + } + + inline void Stop() + { + ElapsedTime += Timer::GetSeconds() - StartTime; + if (++SampleCount >= PrintCount) + PrintAndReset(); + } + +private: + + void PrintAndReset() + { + double dt = ElapsedTime / SampleCount; + if (dt > PrintThreshold) + LogText("%s: %.5f msec\n", Label, dt * 1000); + + // reset for next time + ElapsedTime = 0; + SampleCount = 0; + } + + double StartTime; + double ElapsedTime; + const char* Label; + int SampleCount; + int PrintCount; + double PrintThreshold; +}; + + +class Stopwatch +{ +public: + inline Stopwatch(StopwatchTimer& timer) : Timer(&timer) { Timer->Start(); } + inline ~Stopwatch() { Timer->Stop(); } +private: + StopwatchTimer* Timer; +}; + +#else // !OVR_DISABLE_STOPWATCH + +// Non-invasive, zero-code stopwatch implementation + +class StopwatchTimer +{ +public: + inline StopwatchTimer(const char* label, int printCount = 1, double printThreshold = 0.0) {} + inline void Start() {} + inline void Stop() {} +}; + +class Stopwatch +{ +public: + inline Stopwatch(StopwatchTimer& timer) {} + inline ~Stopwatch() {} +}; + +#endif // OVR_DISABLE_STOPWATCH + +}} // namespace OVR::Util diff --git a/LibOVR/Src/Util/Util_SystemGUI.cpp b/LibOVR/Src/Util/Util_SystemGUI.cpp deleted file mode 100644 index 76eb890..0000000 --- a/LibOVR/Src/Util/Util_SystemGUI.cpp +++ /dev/null @@ -1,190 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemGUI.cpp -Content : OS GUI access, usually for diagnostics. -Created : October 20, 2014 -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#include "Util_SystemGUI.h" -#include "../Kernel/OVR_UTF8Util.h" -#include - -#if defined(OVR_OS_MS) - #include -#endif - - -namespace OVR { namespace Util { - - -#if defined(OVR_OS_MS) - - // On Windows we implement a manual dialog message box. The reason for this is that there's no way to - // have a message box like this without either using MFC or WinForms or relying on Windows Vista+. - - bool DisplayMessageBox(const char* pTitle, const char* pText) - { - #define ID_EDIT 100 - - struct Dialog - { - static size_t LineCount(const char* pText) - { - size_t count = 0; - while(*pText) - { - if(*pText++ == '\n') - count++; - } - return count; - } - - static WORD* WordUp(WORD* pIn){ return (WORD*)((((uintptr_t)pIn + 3) >> 2) << 2); } - - static BOOL CALLBACK Proc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) - { - switch (iMsg) - { - case WM_INITDIALOG: - { - HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT); - - const char* pText = (const char*)lParam; - SetWindowTextA(hWndEdit, pText); - - HFONT hFont = CreateFontW(-11, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, L"Courier New"); - if(hFont) - SendMessage(hWndEdit, WM_SETFONT, WPARAM(hFont), TRUE); - - SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0); - - return TRUE; - } - - case WM_COMMAND: - switch (LOWORD(wParam)) - { - case ID_EDIT: - { - // Handle messages from the edit control here. - HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT); - SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0); - return TRUE; - } - - case IDOK: - EndDialog(hDlg, 0); - return TRUE; - } - break; - } - - return FALSE; - } - }; - - - char dialogTemplateMemory[1024]; - memset(dialogTemplateMemory, 0, sizeof(dialogTemplateMemory)); - DLGTEMPLATE* pDlg = (LPDLGTEMPLATE)dialogTemplateMemory; - - const size_t textLineCount = Dialog::LineCount(pText); - - // Sizes are in Windows dialog units, which are relative to a character size. Depends on the font and environment settings. Often the pixel size will be ~3x the dialog unit x size. Often the pixel size will be ~3x the dialog unit y size. - const int kGutterSize = 6; // Empty border space around controls within the dialog - const int kButtonWidth = 24; - const int kButtonHeight = 10; - const int kDialogWidth = 600; // To do: Clip this against screen bounds. - const int kDialogHeight = ((textLineCount > 100) ? 400 : ((textLineCount > 25) ? 300 : 200)); - - // Define a dialog box. - pDlg->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION; - pDlg->cdit = 2; // Control count - pDlg->x = 10; // X position To do: Center the dialog. - pDlg->y = 10; - pDlg->cx = (short)kDialogWidth; - pDlg->cy = (short)kDialogHeight; - WORD* pWord = (WORD*)(pDlg + 1); - *pWord++ = 0; // No menu - *pWord++ = 0; // Default dialog box class - - WCHAR* pWchar = (WCHAR*)pWord; - const size_t titleLength = strlen(pTitle); - size_t wcharCount = OVR::UTF8Util::DecodeString(pWchar, pTitle, (titleLength > 128) ? 128 : titleLength); - pWord += wcharCount + 1; - - // Define an OK button. - pWord = Dialog::WordUp(pWord); - - DLGITEMTEMPLATE* pDlgItem = (DLGITEMTEMPLATE*)pWord; - pDlgItem->x = pDlg->cx - (kGutterSize + kButtonWidth); - pDlgItem->y = pDlg->cy - (kGutterSize + kButtonHeight); - pDlgItem->cx = kButtonWidth; - pDlgItem->cy = kButtonHeight; - pDlgItem->id = IDOK; - pDlgItem->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; - - pWord = (WORD*)(pDlgItem + 1); - *pWord++ = 0xFFFF; - *pWord++ = 0x0080; // button class - - pWchar = (WCHAR*)pWord; - pWchar[0] = 'O'; pWchar[1] = 'K'; pWchar[2] = '\0'; // Not currently localized. - pWord += 3; // OK\0 - *pWord++ = 0; // no creation data - - // Define an EDIT contol. - pWord = Dialog::WordUp(pWord); - - pDlgItem = (DLGITEMTEMPLATE*)pWord; - pDlgItem->x = kGutterSize; - pDlgItem->y = kGutterSize; - pDlgItem->cx = pDlg->cx - (kGutterSize + kGutterSize); - pDlgItem->cy = pDlg->cy - (kGutterSize + kButtonHeight + kGutterSize + (kGutterSize / 2)); - pDlgItem->id = ID_EDIT; - pDlgItem->style = ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | ES_READONLY | WS_VSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE; - - pWord = (WORD*)(pDlgItem + 1); - *pWord++ = 0xFFFF; - *pWord++ = 0x0081; // edit class atom - *pWord++ = 0; // no creation data - - LRESULT ret = DialogBoxIndirectParam(NULL, (LPDLGTEMPLATE)pDlg, NULL, (DLGPROC)Dialog::Proc, (LPARAM)pText); - - return (ret != 0); - } -#elif defined(OVR_OS_MAC) - // For Apple we use the Objective C implementation in Util_GUI.mm -#else - // To do. - bool DisplayMessageBox(const char* pTitle, const char* pText) - { - printf("\n\nMessageBox\n%s\n", pTitle); - printf("%s\n\n", pText); - return false; - } -#endif - - -} } // namespace OVR::Util - - - - diff --git a/LibOVR/Src/Util/Util_SystemGUI.h b/LibOVR/Src/Util/Util_SystemGUI.h deleted file mode 100644 index c6b8d6f..0000000 --- a/LibOVR/Src/Util/Util_SystemGUI.h +++ /dev/null @@ -1,39 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemGUI.h -Content : OS GUI access, usually for diagnostics. -Created : October 20, 2014 -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - -#ifndef OVR_Util_GUI_h -#define OVR_Util_GUI_h - - -namespace OVR { namespace Util { - - // Displays a modal message box on the default GUI display (not on a VR device). - // The message box interface (e.g. OK button) is not localized. - bool DisplayMessageBox(const char* pTitle, const char* pText); - - -} } // namespace OVR::Util - - -#endif diff --git a/LibOVR/Src/Util/Util_SystemGUI_OSX.mm b/LibOVR/Src/Util/Util_SystemGUI_OSX.mm deleted file mode 100644 index cbfd057..0000000 --- a/LibOVR/Src/Util/Util_SystemGUI_OSX.mm +++ /dev/null @@ -1,69 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemGUI.mm -Content : OS GUI access, usually for diagnostics. -Created : October 20, 2014 -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -*************************************************************************************/ - - - -#include "Util_SystemGUI.h" - -#include -#include - - -namespace OVR { namespace Util { - - -bool DisplayMessageBox(const char* pTitle, const char* pText) -{ - // To consider: Replace usage of CFUserNotificationDisplayAlert with something a little smarter. - - size_t titleLength = strlen(pTitle); - size_t textLength = strlen(pText); - if(textLength > 1500) // CFUserNotificationDisplayAlert isn't smart enough to handle large text sizes and screws up its size if so. - textLength = 1500; // Problem: this can theoretically split a UTF8 multibyte sequence. Need to find a divisible boundary. - CFAllocatorRef allocator = NULL; // To do: support alternative allocator. - CFStringRef titleRef = CFStringCreateWithBytes(allocator, (const UInt8*)pTitle, (CFIndex)titleLength, kCFStringEncodingUTF8, false); - CFStringRef textRef = CFStringCreateWithBytes(allocator, (const UInt8*)pText, (CFIndex)textLength, kCFStringEncodingUTF8, false); - CFOptionFlags result; - - CFUserNotificationDisplayAlert(0, // No timeout - kCFUserNotificationNoteAlertLevel, - NULL, // Icon URL, use default. - NULL, // Unused - NULL, // Localization of strings - titleRef, // Title text - textRef, // Body text - CFSTR("OK"), // Default "OK" text in button - CFSTR("Cancel"), // Other button title - NULL, // Yet another button title, NULL means no other button. - &result); // response flags - CFRelease(titleRef); - CFRelease(textRef); - - return (result == kCFUserNotificationDefaultResponse); -} - - -} } // namespace OVR { namespace Util { - - diff --git a/LibOVR/Src/Util/Util_SystemInfo.cpp b/LibOVR/Src/Util/Util_SystemInfo.cpp deleted file mode 100644 index 0fca243..0000000 --- a/LibOVR/Src/Util/Util_SystemInfo.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemInfo.cpp -Content : Various operations to get information about the system -Created : September 26, 2014 -Author : Kevin Jenkins - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - -#include "Util_SystemInfo.h" -#include "../Kernel/OVR_Timer.h" -#include "../Kernel/OVR_Threads.h" -#include "../Kernel/OVR_Log.h" -#include "../Kernel/OVR_Array.h" - -/* -// Disabled, can't link RiftConfigUtil -#ifdef OVR_OS_WIN32 -#define _WIN32_DCOM -#include -#include - -# pragma comment(lib, "wbemuuid.lib") -#endif -*/ - - -namespace OVR { namespace Util { - -// From http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx -#if defined (OVR_OS_WIN64) || defined (OVR_OS_WIN32) - -#pragma comment(lib, "version.lib") - -typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); -BOOL Is64BitWindows() -{ -#if defined(_WIN64) - return TRUE; // 64-bit programs run only on Win64 -#elif defined(_WIN32) - // 32-bit programs run on both 32-bit and 64-bit Windows - // so must sniff - BOOL f64 = FALSE; - LPFN_ISWOW64PROCESS fnIsWow64Process; - - fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(L"kernel32"), "IsWow64Process"); - if (NULL != fnIsWow64Process) - { - return fnIsWow64Process(GetCurrentProcess(), &f64) && f64; - } - return FALSE; -#else - return FALSE; // Win64 does not support Win16 -#endif -} -#endif - -const char * OSAsString() -{ -#if defined (OVR_OS_IPHONE) - return "IPhone"; -#elif defined (OVR_OS_DARWIN) - return "Darwin"; -#elif defined (OVR_OS_MAC) - return "Mac"; -#elif defined (OVR_OS_BSD) - return "BSD"; -#elif defined (OVR_OS_WIN64) || defined (OVR_OS_WIN32) - if (Is64BitWindows()) - return "Win64"; - else - return "Win32"; -#elif defined (OVR_OS_ANDROID) - return "Android"; -#elif defined (OVR_OS_LINUX) - return "Linux"; -#elif defined (OVR_OS_BSD) - return "BSD"; -#else - return "Other"; -#endif -} - -uint64_t GetGuidInt() -{ - uint64_t g = Timer::GetTicksNanos(); - - uint64_t lastTime, thisTime; - int j; - // Sleep a small random time, then use the last 4 bits as a source of randomness - for (j = 0; j < 8; j++) - { - lastTime = Timer::GetTicksNanos(); - Thread::MSleep(1); - Thread::MSleep(0); - thisTime = Timer::GetTicksNanos(); - uint64_t diff = thisTime - lastTime; - unsigned int diff4Bits = (unsigned int)(diff & 15); - diff4Bits <<= 32 - 4; - diff4Bits >>= j * 4; - ((char*)&g)[j] ^= diff4Bits; - } - - return g; -} -String GetGuidString() -{ - uint64_t guid = GetGuidInt(); - - char buff[64]; -#if defined(OVR_CC_MSVC) - OVR_sprintf(buff, sizeof(buff), "%I64u", guid); -#else - OVR_sprintf(buff, sizeof(buff), "%llu", (unsigned long long) guid); -#endif - return String(buff); -} - -const char * GetProcessInfo() -{ - #if defined (OVR_CPU_X86_64 ) - return "64 bit"; -#elif defined (OVR_CPU_X86) - return "32 bit"; -#else - return "TODO"; -#endif -} -#ifdef OVR_OS_WIN32 - - -String OSVersionAsString() -{ - return GetSystemFileVersionString("\\kernel32.dll"); -} -String GetSystemFileVersionString(String filePath) -{ - char strFilePath[MAX_PATH]; // Local variable - UINT sysDirLen = GetSystemDirectoryA(strFilePath, ARRAYSIZE(strFilePath)); - if (sysDirLen != 0) - { - OVR_strcat(strFilePath, MAX_PATH, filePath.ToCStr()); - return GetFileVersionString(strFilePath); - } - else - { - return "GetSystemDirectoryA failed"; - } -} -// See http://stackoverflow.com/questions/940707/how-do-i-programatically-get-the-version-of-a-dll-or-exe-file -String GetFileVersionString(String filePath) -{ - String result; - - DWORD dwSize = GetFileVersionInfoSizeA(filePath.ToCStr(), NULL); - if (dwSize == 0) - { - OVR_DEBUG_LOG(("Error in GetFileVersionInfoSizeA: %d (for %s)", GetLastError(), filePath.ToCStr())); - result = filePath + " not found"; - } - else - { - BYTE* pVersionInfo = new BYTE[dwSize]; - if (!pVersionInfo) - { - OVR_DEBUG_LOG(("Out of memory allocating %d bytes (for %s)", dwSize, filePath.ToCStr())); - result = "Out of memory"; - } - else - { - if (!GetFileVersionInfoA(filePath.ToCStr(), 0, dwSize, pVersionInfo)) - { - OVR_DEBUG_LOG(("Error in GetFileVersionInfo: %d (for %s)", GetLastError(), filePath.ToCStr())); - result = "Cannot get version info"; - } - else - { - VS_FIXEDFILEINFO* pFileInfo = NULL; - UINT pLenFileInfo = 0; - if (!VerQueryValue(pVersionInfo, TEXT("\\"), (LPVOID*)&pFileInfo, &pLenFileInfo)) - { - OVR_DEBUG_LOG(("Error in VerQueryValue: %d (for %s)", GetLastError(), filePath.ToCStr())); - result = "File has no version info"; - } - else - { - int major = (pFileInfo->dwFileVersionMS >> 16) & 0xffff; - int minor = (pFileInfo->dwFileVersionMS) & 0xffff; - int hotfix = (pFileInfo->dwFileVersionLS >> 16) & 0xffff; - int other = (pFileInfo->dwFileVersionLS) & 0xffff; - - char str[128]; - OVR::OVR_sprintf(str, 128, "%d.%d.%d.%d", major, minor, hotfix, other); - - result = str; - } - } - - delete[] pVersionInfo; - } - } - - return result; -} - - -String GetDisplayDriverVersion() -{ - return GetSystemFileVersionString("\\OVRDisplay32.dll"); -} -String GetCameraDriverVersion() -{ - return GetSystemFileVersionString("\\drivers\\OCUSBVID.sys"); -} - -// From http://stackoverflow.com/questions/9524309/enumdisplaydevices-function-not-working-for-me -void GetGraphicsCardList( Array< String > &gpus) -{ - gpus.Clear(); - - DISPLAY_DEVICEA dd; - - dd.cb = sizeof(dd); - - DWORD deviceNum = 0; - while( EnumDisplayDevicesA(NULL, deviceNum, &dd, 0) ){ - if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) - gpus.PushBack(dd.DeviceString); - deviceNum++; - } -} -#else - -// used for driver files - -String GetFileVersionString(String /*filePath*/) -{ - return String(); -} - -String GetSystemFileVersionString(String /*filePath*/) -{ - return String(); -} - -String GetDisplayDriverVersion() -{ - return String(); -} - -String GetCameraDriverVersion() -{ - return String(); -} - -#ifdef OVR_OS_MAC - //use objective c source -#else - -//todo linux, this requires searching /var/ files -void GetGraphicsCardList(OVR::Array< OVR::String > &gpus) -{ - gpus.Clear(); -} -String OSVersionAsString() -{ - return String(); -} -#endif //OVR_OS_MAC -#endif // WIN32 - -} } // namespace OVR { namespace Util { diff --git a/LibOVR/Src/Util/Util_SystemInfo.h b/LibOVR/Src/Util/Util_SystemInfo.h deleted file mode 100644 index b150560..0000000 --- a/LibOVR/Src/Util/Util_SystemInfo.h +++ /dev/null @@ -1,51 +0,0 @@ -/************************************************************************************ - -Filename : Util_SystemInfo.h -Content : Various operations to get information about the system -Created : September 26, 2014 -Author : Kevin Jenkins - -Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - -Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); -you may not use the Oculus VR Rift SDK except in compliance with the License, -which is provided at the time of installation or download, or which -otherwise accompanies this software in either electronic or hard copy form. - -You may obtain a copy of the License at - -http://www.oculusvr.com/licenses/LICENSE-3.2 - -Unless required by applicable law or agreed to in writing, the Oculus VR SDK -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -************************************************************************************/ - - -#ifndef OVR_Util_SystemInfo_h -#define OVR_Util_SystemInfo_h - -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_Types.h" -#include "../Kernel/OVR_Array.h" - -namespace OVR { namespace Util { - -const char * OSAsString(); -String OSVersionAsString(); -uint64_t GetGuidInt(); -String GetGuidString(); -const char * GetProcessInfo(); -String GetFileVersionString(String filePath); -String GetSystemFileVersionString(String filePath); -String GetDisplayDriverVersion(); -String GetCameraDriverVersion(); -void GetGraphicsCardList(OVR::Array< OVR::String > &gpus); -String GetProcessorInfo(int* numcores = NULL); - -} } // namespace OVR { namespace Util { - -#endif // OVR_Util_SystemInfo_h diff --git a/LibOVR/Src/Util/Util_SystemInfo_OSX.mm b/LibOVR/Src/Util/Util_SystemInfo_OSX.mm deleted file mode 100644 index 46799fb..0000000 --- a/LibOVR/Src/Util/Util_SystemInfo_OSX.mm +++ /dev/null @@ -1,106 +0,0 @@ - /************************************************************************************ - - Filename : Util_SystemInfo_OSX.mm - Content : Various operations to get information about the mac system - Created : October 2, 2014 - - Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. - - Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); - you may not use the Oculus VR Rift SDK except in compliance with the License, - which is provided at the time of installation or download, or which - otherwise accompanies this software in either electronic or hard copy form. - - You may obtain a copy of the License at - - http://www.oculusvr.com/licenses/LICENSE-3.2 - - Unless required by applicable law or agreed to in writing, the Oculus VR SDK - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - ************************************************************************************/ - -#include "Util_SystemInfo.h" - -#include - -#include -#include - -#include "../Kernel/OVR_String.h" -#include "../Kernel/OVR_System.h" - -using namespace OVR; -namespace OVR { namespace Util { - -//from http://opensource.apple.com/source/CF/CF-744/CFUtilities.c -OVR::String OSVersionAsString(){ - - NSDictionary *systemVersionDictionary = - [NSDictionary dictionaryWithContentsOfFile: - @"/System/Library/CoreServices/SystemVersion.plist"]; - - NSString *systemVersion = - [systemVersionDictionary objectForKey:@"ProductVersion"]; - return OVR::String([systemVersion UTF8String]); -} - - -//from http://www.starcoder.com/wordpress/2011/10/using-iokit-to-detect-graphics-hardware/ -void GetGraphicsCardList(Array< String > &gpus) -{ - // Check the PCI devices for video cards. - CFMutableDictionaryRef match_dictionary = IOServiceMatching("IOPCIDevice"); - - // Create a iterator to go through the found devices. - io_iterator_t entry_iterator; - - if (IOServiceGetMatchingServices(kIOMasterPortDefault, - match_dictionary, - &entry_iterator) == kIOReturnSuccess) - { - // Actually iterate through the found devices. - io_registry_entry_t serviceObject; - while ((serviceObject = IOIteratorNext(entry_iterator))) - { - // Put this services object into a dictionary object. - CFMutableDictionaryRef serviceDictionary; - if (IORegistryEntryCreateCFProperties(serviceObject, - &serviceDictionary, - kCFAllocatorDefault, - kNilOptions) != kIOReturnSuccess) - { - // Failed to create a service dictionary, release and go on. - IOObjectRelease(serviceObject); - continue; - } - - // - // that points to a CFDataRef. - const void *modelarr = CFDictionaryGetValue(serviceDictionary, CFSTR("model")); - if (modelarr != nil) { - if(CFGetTypeID(modelarr) == CFDataGetTypeID()) - { - NSData *data = (__bridge NSData*)(CFDataRef)modelarr; - NSString *s = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; - gpus.PushBack([s UTF8String]); - } - } - - // Release the dictionary created by IORegistryEntryCreateCFProperties. - CFRelease(serviceDictionary); - - // Release the serviceObject returned by IOIteratorNext. - IOObjectRelease(serviceObject); - } - - // Release the entry_iterator created by IOServiceGetMatchingServices. - IOObjectRelease(entry_iterator); - } -} - -} } // namespace OVR { namespace Util { - diff --git a/LibOVR/Src/Vision/SensorFusion/Vision_SensorState.h b/LibOVR/Src/Vision/SensorFusion/Vision_SensorState.h new file mode 100755 index 0000000..13b0bb3 --- /dev/null +++ b/LibOVR/Src/Vision/SensorFusion/Vision_SensorState.h @@ -0,0 +1,161 @@ +/************************************************************************************ + +Filename : Vision_SensorState.h +Content : Sensor state information shared by tracking system with games +Created : May 13, 2014 +Authors : Dov Katz, Chris Taylor + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Vision_SensorState_h +#define OVR_Vision_SensorState_h + +#include "Vision/Vision_Common.h" +#include "Kernel/OVR_SharedMemory.h" +#include "Kernel/OVR_Lockless.h" +#include "Kernel/OVR_String.h" +#include "Util/Util_LatencyTest2State.h" +#include "Sensors/OVR_DeviceConstants.h" + + +namespace OVR { namespace Vision { + + +// Bit flags describing the current status of sensor tracking. +// These values must be the same as ovrStatusBits +enum StatusBits +{ + // Tracked bits: Toggled by SensorFusion + Status_OrientationTracked = 0x0001, // Orientation is currently tracked (connected and in use) + Status_PositionTracked = 0x0002, // Position is currently tracked (false if out of range) + Status_CameraPoseTracked = 0x0004, // Camera pose is currently tracked + + // Connected bits: Toggled by TrackingManager + Status_PositionConnected = 0x0020, // Position tracking HW is connected + Status_BuiltinConnected = 0x0040, // Builtin tracking HW is connected + Status_HMDConnected = 0x0080, // HMD is available & connected + + // Masks + Status_AllMask = 0xffff, + Status_TrackingMask = Status_PositionTracked | Status_OrientationTracked | Status_CameraPoseTracked, + Status_ConnectedMask = Status_PositionConnected | Status_HMDConnected, +}; + +#pragma pack(push, 8) + +// TrackedObject state stored in lockless updater "queue" and used for +// prediction by SensorStateReader +struct LocklessSensorState +{ + PoseState WorldFromImu; + SensorDataType RawSensorData; + + // DO NOT USE + // only preserved for backwards compatibility + Pose WorldFromCamera_DEPRECATED; + + uint32_t StatusFlags; + uint32_t _PAD_0_; + + // ImuFromCpf for HMD pose tracking + Posed ImuFromCpf; + + // Initialized to invalid state + LocklessSensorState() : + WorldFromImu() + , RawSensorData() + , WorldFromCamera_DEPRECATED() + , StatusFlags(0) + , _PAD_0_(0) // This assignment should be irrelevant, but it quells static/runtime analysis complaints. + , ImuFromCpf() + { + } +}; + +static_assert((sizeof(LocklessSensorState) == sizeof(PoseState) + sizeof(SensorDataType) + sizeof(Pose) + 2*sizeof(uint32_t) + sizeof(Posed)), "sizeof(LocklessSensorState) failure"); + +struct LocklessCameraState +{ + Pose WorldFromCamera; + + uint32_t StatusFlags; + uint32_t _PAD_0_; + + // Initialized to invalid state + LocklessCameraState() : + WorldFromCamera() + , StatusFlags(0) + , _PAD_0_(0) // This assignment should be irrelevant, but it quells static/runtime analysis complaints. + { + } +}; + +static_assert((sizeof(LocklessCameraState) == sizeof(Pose) + 2 * sizeof(uint32_t)), "sizeof(LocklessCameraState) failure"); + + +// Padded out version stored in the updater slots +// Designed to be a larger fixed size to allow the data to grow in the future +// without breaking older compiled code. +OVR_DISABLE_MSVC_WARNING(4351) +template +struct LocklessPadding +{ + uint8_t buffer[PaddingSize]; + + LocklessPadding() : buffer() { } + + LocklessPadding& operator=(const Payload& rhs) + { + // if this fires off, then increase PaddingSize + // IMPORTANT: this WILL break backwards compatibility + static_assert(sizeof(buffer) >= sizeof(Payload), "PaddingSize is too small"); + + memcpy(buffer, &rhs, sizeof(Payload)); + return *this; + } + + operator Payload() const + { + Payload result; + memcpy(&result, buffer, sizeof(Payload)); + return result; + } +}; +OVR_RESTORE_MSVC_WARNING() + +#pragma pack(pop) + +//// Lockless updaters + +struct CombinedHmdUpdater +{ + // IMPORTANT: do not add more data to this struct + // new objects should have their own shared memory blocks + LocklessUpdater > SensorState; + LocklessUpdater LatencyTest; +}; + + +typedef LocklessUpdater > CameraStateUpdater; + + +}} // namespace OVR::Vision + +#endif diff --git a/LibOVR/Src/Vision/SensorFusion/Vision_SensorStateReader.cpp b/LibOVR/Src/Vision/SensorFusion/Vision_SensorStateReader.cpp new file mode 100755 index 0000000..b60b500 --- /dev/null +++ b/LibOVR/Src/Vision/SensorFusion/Vision_SensorStateReader.cpp @@ -0,0 +1,253 @@ +/************************************************************************************ + +Filename : Vision_SensorStateReader.cpp +Content : Separate reader component that is able to recover sensor pose +Created : June 4, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Vision_SensorStateReader.h" + + +namespace OVR { namespace Vision { + + +//------------------------------------------------------------------------------------- + +// This is a "perceptually tuned predictive filter", which means that it is optimized +// for improvements in the VR experience, rather than pure error. In particular, +// jitter is more perceptible at lower speeds whereas latency is more perceptible +// after a high-speed motion. Therefore, the prediction interval is dynamically +// adjusted based on speed. Significant more research is needed to further improve +// this family of filters. +static Pose calcPredictedPose(const PoseState& poseState, double predictionDt) +{ + Pose pose = poseState.ThePose; + const double linearCoef = 1.0; + Vector3d angularVelocity = poseState.AngularVelocity; + double angularSpeed = angularVelocity.Length(); + + // This could be tuned so that linear and angular are combined with different coefficients + double speed = angularSpeed + linearCoef * poseState.LinearVelocity.Length(); + + const double slope = 0.2; // The rate at which the dynamic prediction interval varies + double candidateDt = slope * speed; // TODO: Replace with smoothstep function + + double dynamicDt = predictionDt; + + // Choose the candidate if it is shorter, to improve stability + if (candidateDt < predictionDt) + { + dynamicDt = candidateDt; + } + + if (angularSpeed > 0.001) + { + pose.Rotation = pose.Rotation * Quatd(angularVelocity, angularSpeed * dynamicDt); + } + + pose.Translation += poseState.LinearVelocity * dynamicDt; + + return pose; +} + +PoseState calcPredictedPoseState(const LocklessSensorState& sensorState, double absoluteTime, const Posed& centeredFromWorld) +{ + // Delta time from the last available data + double pdt = absoluteTime - sensorState.WorldFromImu.TimeInSeconds; + static const double maxPdt = 0.1; + + // If delta went negative due to synchronization problems between processes or just a lag spike, + if (pdt < 0) + { + pdt = 0; + } + else if (pdt > maxPdt) + { + pdt = maxPdt; + static double lastLatWarnTime = 0; + if (lastLatWarnTime != sensorState.WorldFromImu.TimeInSeconds) + { + lastLatWarnTime = sensorState.WorldFromImu.TimeInSeconds; + LogText("[TrackingStateReader] Prediction interval too high: %f s, clamping at %f s\n", pdt, maxPdt); + } + } + + PoseStatef result; + result = PoseStatef(sensorState.WorldFromImu); + result.TimeInSeconds = absoluteTime; + result.ThePose = Posef(centeredFromWorld * calcPredictedPose(sensorState.WorldFromImu, pdt) * sensorState.ImuFromCpf); + return result; +} + +//// TrackingStateReader + +// Pre-0.5.0 applications assume that the initial WorldFromCentered +// pose is always identity, because the WorldFromImu pose has a 180-degree flip in Y +// and a 1-meter offset in Z. See CAPI_HMDState.cpp +Posed TrackingStateReader::DefaultWorldFromCentered(Quatd::Identity(), Vector3d(0, 0, 0)); + +// At startup, we want an identity pose when the user is looking along the positive camera Z axis, one meter in front of camera. +// That is a 180 degree rotation about Y, with a -1 meter translation (the inverse of this pose, CenteredFromWorld, is actually used) +// (NOTE: This pose should be the same as SensorFusionFilter::DefaultWorldFromImu) +// +//Posed TrackingStateReader::DefaultWorldFromCentered(Quatd(0, 1, 0, 0), Vector3d(0, 0, -1)); + +TrackingStateReader::TrackingStateReader() : + HmdUpdater(nullptr), + CameraUpdater(nullptr) +{ + CenteredFromWorld = GetDefaultCenteredFromWorld(); +} + +void TrackingStateReader::SetUpdaters(const CombinedHmdUpdater *hmd, const CameraStateUpdater *camera) +{ + HmdUpdater = hmd; + CameraUpdater = camera; +} + + +// This function centers tracking on the current pose, such that when the +// headset is positioned at the current pose and looking level in the current direction, +// the tracking system pose will be identity. +// In other words, tracking is relative to this centered pose. +// +bool TrackingStateReader::RecenterPose(const Vector3d& neckModelOffset) +{ + if (!HmdUpdater) + return false; + + const LocklessSensorState lstate = HmdUpdater->SensorState.GetState(); + Posed worldFromCpf = (lstate.WorldFromImu.ThePose * lstate.ImuFromCpf); + + return ComputeCenteredFromWorld(worldFromCpf, neckModelOffset); +} + +bool TrackingStateReader::ComputeCenteredFromWorld(const Posed& worldFromCpf, const Vector3d& neckModel) +{ + // Position of CPF in the head rotation center frame + const Vector3d cpfInRotationCenter = neckModel; + + const Vector3d forward(0, 0, -1); + const Vector3d up(0, 1, 0); + Vector3d look = worldFromCpf.Rotate(forward); + + // If the headset is pointed straight up or straight down, + // it may be face down on a tabletop. In this case we + // can't reliably extract a heading angle. + // We assume straight ahead and return false so caller + // knows that recenter may not be reliable. + bool headingValid = true; + static const double lookTol = cos(DegreeToRad(20.0)); + if (fabs(look.Dot(up)) >= lookTol) // fabs(lookBack.Dot(up)) + { + look = forward; + headingValid = false; + } + + // Now compute the orientation of the headset when looking straight ahead: + // Extract the heading (yaw) component of the pose + Vector3d centeredLook = Vector3d(look.x, 0, look.z).Normalized(); + Quatd centeredOrientation = Quatd::Align(centeredLook, forward); + + // Compute the position in world space of the head rotation center: + // we assume the head rotates about this point in space. + Vector3d headRotationCenter = worldFromCpf.Transform(-cpfInRotationCenter); + + // Now apply the heading rotation to compute the reference position of the CPF + // relative to the head rotation center. + Vector3d centeredCpfPos = headRotationCenter + centeredOrientation.Rotate(cpfInRotationCenter); + + // Now compute the centered pose of the CPF. + Posed worldFromCentered(centeredOrientation, centeredCpfPos); + + // For tracking, we use the inverse of the centered pose + CenteredFromWorld = worldFromCentered.Inverted(); + + return headingValid; +} + +bool TrackingStateReader::GetTrackingStateAtTime(double absoluteTime, TrackingState& ss) const +{ + LocklessCameraState cameraState; + LocklessSensorState sensorState; + + if (CameraUpdater) + cameraState = CameraUpdater->GetState(); + if (HmdUpdater) + sensorState = HmdUpdater->SensorState.GetState(); + + // Update the status flags + ss.StatusFlags = cameraState.StatusFlags | sensorState.StatusFlags; + + // If no hardware is connected, override the tracking flags + if (0 == (ss.StatusFlags & Status_HMDConnected)) + { + ss.StatusFlags &= ~Status_TrackingMask; + } + if (0 == (ss.StatusFlags & Status_PositionConnected)) + { + ss.StatusFlags &= ~(Status_PositionTracked | Status_CameraPoseTracked); + } + + // If tracking info is invalid, + if (0 == (ss.StatusFlags & Status_TrackingMask)) + { + return false; + } + + ss.HeadPose = calcPredictedPoseState(sensorState, absoluteTime, CenteredFromWorld); + + ss.CameraPose = Posef(CenteredFromWorld * cameraState.WorldFromCamera); + ss.LeveledCameraPose = Posef(CenteredFromWorld * Posed(Quatd(), cameraState.WorldFromCamera.Translation)); + + ss.RawSensorData = sensorState.RawSensorData; + return true; +} + +bool TrackingStateReader::GetPoseAtTime(double absoluteTime, Posef& transform) const +{ + TrackingState ss; + + if (!GetTrackingStateAtTime(absoluteTime, ss)) + { + return false; + } + + transform = ss.HeadPose.ThePose; + + return true; +} + +uint32_t TrackingStateReader::GetStatus() const +{ + TrackingState ss; + + if (!GetTrackingStateAtTime(0, ss)) + { + return 0; + } + + return ss.StatusFlags; +} + + +}} // namespace OVR::Vision diff --git a/LibOVR/Src/Vision/SensorFusion/Vision_SensorStateReader.h b/LibOVR/Src/Vision/SensorFusion/Vision_SensorStateReader.h new file mode 100755 index 0000000..264a973 --- /dev/null +++ b/LibOVR/Src/Vision/SensorFusion/Vision_SensorStateReader.h @@ -0,0 +1,121 @@ +/************************************************************************************ + +Filename : Vision_SensorStateReader.h +Content : Separate reader component that is able to recover sensor pose +Created : June 4, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Vision_SensorStateReader_h +#define OVR_Vision_SensorStateReader_h + +#include "Kernel/OVR_Lockless.h" +#include "Vision_SensorState.h" + +#include "OVR_Profile.h" + + +// CAPI forward declarations. +struct ovrTrackingState_; +typedef struct ovrTrackingState_ ovrTrackingState; + +namespace OVR { namespace Vision { + + +//----------------------------------------------------------------------------- +// TrackingStateReader + +// Full output of tracking reported by GetSensorStateAtTime() +class TrackingState +{ +public: + TrackingState() : StatusFlags(0) { } + + // C-interop support + TrackingState(const ovrTrackingState& s); + operator ovrTrackingState () const; + + // HMD pose information for the requested time. + PoseStatef HeadPose; + + // Orientation and position of the external camera, if present. + Posef CameraPose; + // Orientation and position of the camera after alignment with gravity + Posef LeveledCameraPose; + + // Most recent sensor data received from the HMD + SensorDataType RawSensorData; + + // Sensor status described by ovrStatusBits. + uint32_t StatusFlags; + +}; + +// User interface to retrieve pose from the sensor fusion subsystem +class TrackingStateReader : public NewOverrideBase +{ +protected: + const CombinedHmdUpdater* HmdUpdater; + const CameraStateUpdater* CameraUpdater; + + // Transform from real-world coordinates to centered coordinates + Posed CenteredFromWorld; + static Posed DefaultWorldFromCentered; + +public: + TrackingStateReader(); + + // Initialize the updaters + void SetUpdaters(const CombinedHmdUpdater *hmd, const CameraStateUpdater *camera); + + + // Re-centers on the current yaw and translation, taking + // the head-neck model into account. + bool RecenterPose(const Vector3d& neckModeloffset); + + // Computes CenteredFromWorld from a worldFromCpf pose and neck model offset + bool ComputeCenteredFromWorld(const Posed& worldFromCpf, const Vector3d& neckModelOffset); + + // Get the full dynamical system state of the CPF, which includes velocities and accelerations, + // predicted at a specified absolute point in time. + bool GetTrackingStateAtTime(double absoluteTime, TrackingState& state) const; + + // Get the predicted pose (orientation, position) of the center pupil frame (CPF) at a specific point in time. + bool GetPoseAtTime(double absoluteTime, Posef& transform) const; + + // Get the sensor status (same as GetSensorStateAtTime(...).Status) + uint32_t GetStatus() const; + + Posed GetCenteredFromWorld() const + { + return CenteredFromWorld; + } + + Posed GetDefaultCenteredFromWorld() const + { + return DefaultWorldFromCentered.Inverted(); + } +}; + + +}} // namespace OVR::Vision + +#endif // Vision_SensorStateReader_h diff --git a/LibOVR/Src/Vision/Vision_Common.h b/LibOVR/Src/Vision/Vision_Common.h new file mode 100644 index 0000000..0610adb --- /dev/null +++ b/LibOVR/Src/Vision/Vision_Common.h @@ -0,0 +1,299 @@ +/************************************************************************************ + +Filename : OVR_Vision_Common.h +Content : Common data structures that are used in multiple vision files +Created : November 25, 2014 +Authors : Max Katsev + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Vision_Common_h +#define OVR_Vision_Common_h + +#include "Kernel/OVR_RefCount.h" +#include "Extras/OVR_Math.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Log.h" +#include "Sensors/OVR_DeviceConstants.h" + +// Compatible types (these are declared in global namespace) +typedef struct ovrPoseStatef_ ovrPoseStatef; +typedef struct ovrPoseStated_ ovrPoseStated; + +namespace OVR { namespace Vision { + +// Global "calibration mode" used by calibration tools to change +// the behavior of the SDK for calibration/experimentation purposes. +// This flag is set at system startup by calibration tools, and never changed. + +extern int BundleCalibrationMode; + +// Vision <-> OVR transform functions +// +// These transforms are required across the interface to many of the +// matching and reconstruction functions. +// +// OVR system is x+ right, y+ up, z+ back. +// Vision system is x+ right, y+ down, z+ forward. +// This is a 180 degree rotation about X axis. +// +template inline Vector3 VisionFromOvr(const Vector3& ovr) { return Vector3(ovr.x, -ovr.y, -ovr.z); } +template inline Vector3 OvrFromVision(const Vector3& vision) { return Vector3(vision.x, -vision.y, -vision.z); } + +template inline Quat VisionFromOvr(const Quat& ovr) { return Quat(ovr.x, -ovr.y, -ovr.z, ovr.w); } +template inline Quat OvrFromVision(const Quat& vision) { return Quat(vision.x, -vision.y, -vision.z, vision.w); } + +template inline Pose VisionFromOvr(const Pose& ovr) { return Pose(VisionFromOvr(ovr.Rotation), VisionFromOvr(ovr.Translation)); } +template inline Pose OvrFromVision(const Pose& vision) { return Pose(OvrFromVision(vision.Rotation), OvrFromVision(vision.Translation)); } + +struct ImuSample +{ + double Time; + + Vector3d Accelerometer; + Vector3d Gyro; + Vector3d Magnetometer; + double Temperature; + + ImuSample() : Time(-1), + Temperature(-1) {} + + ImuSample(const SensorDataType& data) : Time(data.AbsoluteTimeSeconds), + Accelerometer(data.Acceleration), + Gyro(data.RotationRate), + Magnetometer(data.MagneticField), + Temperature(data.Temperature) {} +}; + +struct PoseSample +{ + double Time; + Posed ThePose; + Vector3d LinearVelocity, AngularVelocity; + + // stats for LED tracking + int LedsCount; + double ObjectSpaceError; + // stats for sphere tracking + int ContourCount; + double CircleRadius; + + bool HasOrientation, HasPosition, HasVelocities; + // true => ThePose == WorldFromImu, false => ThePose == CameraFromImu + bool IsInWorldFrame; + + void ApplyWorldFromCamera(const Posed& worldFromCamera) + { + OVR_ASSERT(!IsInWorldFrame); + + IsInWorldFrame = true; + ThePose = worldFromCamera * ThePose; + if (HasVelocities) + { + LinearVelocity = worldFromCamera.Rotate(LinearVelocity); + AngularVelocity = worldFromCamera.Rotate(AngularVelocity); + } + } + + friend PoseSample operator*(const PoseSample& sample, const Posed& trans) + { + PoseSample result = sample; + result.ThePose = sample.ThePose * trans; + // if we don't have orientation, the result will be useless - this is probably not expected to happen + OVR_ASSERT(sample.HasOrientation); + result.HasPosition = sample.HasPosition && sample.HasOrientation; + return result; + } + + PoseSample(double time = -1) : Time(time), + LedsCount(-1), + ObjectSpaceError(-1), + ContourCount(-1), + CircleRadius(-1), + HasOrientation(false), + HasPosition(false), + HasVelocities(false), + IsInWorldFrame(false) {} +}; + +struct PoseEstimate +{ + Posed WorldFromImu, CameraFromWorld; + + bool HasPosition, HasOrientation, HasUp; + + Posed CameraFromImu() const + { + return CameraFromWorld * WorldFromImu; + } + + friend PoseEstimate operator*(const PoseEstimate& estimate, const Posed& trans) +{ + PoseEstimate result = estimate; + result.WorldFromImu = estimate.WorldFromImu * trans; + // if we don't have orientation, the result will be useless - this is probably not expected to happen + OVR_ASSERT(estimate.HasOrientation); + result.HasPosition = estimate.HasPosition && estimate.HasOrientation; + return result; + } + + PoseEstimate(const Posed& worldFromCamera) : + CameraFromWorld(worldFromCamera.Inverted()), + HasPosition(false), + HasOrientation(false), + HasUp(false) {} +}; + +} // namespace OVR::Vision + +// PoseState describes the complete pose, or a rigid body configuration, at a +// point in time, including first and second derivatives. It is used to specify +// instantaneous location and movement of the headset. +// SensorState is returned as a part of the sensor state. + +template +class PoseState +{ +public: + typedef typename CompatibleTypes >::Type CompatibleType; + + PoseState() : TimeInSeconds(0.0) { } + + // float <-> double conversion constructor. + explicit PoseState(const PoseState::OtherFloatType> &src) + : ThePose(src.ThePose), + AngularVelocity(src.AngularVelocity), LinearVelocity(src.LinearVelocity), + AngularAcceleration(src.AngularAcceleration), LinearAcceleration(src.LinearAcceleration), + TimeInSeconds(src.TimeInSeconds) + { } + + // C-interop support: PoseStatef <-> ovrPoseStatef + PoseState(const typename CompatibleTypes >::Type& src) + : ThePose(src.ThePose), + AngularVelocity(src.AngularVelocity), LinearVelocity(src.LinearVelocity), + AngularAcceleration(src.AngularAcceleration), LinearAcceleration(src.LinearAcceleration), + TimeInSeconds(src.TimeInSeconds) + { } + + operator typename CompatibleTypes >::Type() const + { + typename CompatibleTypes >::Type result; + result.ThePose = ThePose; + result.AngularVelocity = AngularVelocity; + result.LinearVelocity = LinearVelocity; + result.AngularAcceleration = AngularAcceleration; + result.LinearAcceleration = LinearAcceleration; + result.TimeInSeconds = TimeInSeconds; + return result; + } + + Pose ThePose; + Vector3 AngularVelocity; + Vector3 LinearVelocity; + Vector3 AngularAcceleration; + Vector3 LinearAcceleration; + // Absolute time of this state sample; always a double measured in seconds. + double TimeInSeconds; + + // ***** Helpers for Pose integration + + // Stores and integrates gyro angular velocity reading for a given time step. + void StoreAndIntegrateGyro(Vector3d angVel, double dt) + { + AngularVelocity = angVel; + ThePose.Rotation *= Quatd::FromRotationVector(angVel * dt); + } + + void StoreAndIntegrateAccelerometer(Vector3d linearAccel, double dt) + { + LinearAcceleration = linearAccel; + ThePose.Translation += LinearVelocity * dt + LinearAcceleration * (dt * dt * 0.5); + LinearVelocity += LinearAcceleration * dt; + } + + friend PoseState operator*(const Pose& trans, const PoseState& poseState) +{ + PoseState result; + result.ThePose = trans * poseState.ThePose; + result.LinearVelocity = trans.Rotate(poseState.LinearVelocity); + result.LinearAcceleration = trans.Rotate(poseState.LinearAcceleration); + result.AngularVelocity = trans.Rotate(poseState.AngularVelocity); + result.AngularAcceleration = trans.Rotate(poseState.AngularAcceleration); + return result; +} +}; + +// External API returns pose as float, but uses doubles internally for quaternion precision. +typedef PoseState PoseStatef; +typedef PoseState PoseStated; + +// Compatible types +template<> struct CompatibleTypes > { typedef ovrPoseStatef Type; }; +template<> struct CompatibleTypes > { typedef ovrPoseStated Type; }; + +// Handy debug output functions +template +void Dump(const char* label, const Pose& pose) +{ + auto t = pose.Translation * 1000; + auto r = pose.Rotation.ToRotationVector(); + double angle = RadToDegree(r.Length()); + if (r.LengthSq() > 0) + r.Normalize(); + LogText("%s: %.2f, %.2f, %.2f mm, %.2f deg %.2f, %.2f, %.2f\n", + label, t.x, t.y, t.z, angle, r.x, r.y, r.z); +} + +template +void Dump(const char* label, const Vector3& v) +{ + LogText("%s %.5g, %.5g, %.5g (%.5g)\n", label, v.x, v.y, v.z, v.Length()); +} + +template +void Dump(const char* label, const Quat& q) +{ + auto r = q.ToRotationVector(); + auto axis = r.Normalized(); + auto angle = RadToDegree(r.Length()); + LogText("%s %.2f (%.2f, %.2f, %.2f)\n", label, angle, axis.x, axis.y, axis.z); +} + +template +void Dump(const char* label, double time, const Pose& p) +{ + LogText("%.4f: ", time); + Dump(label, p); +} + +static_assert((sizeof(PoseState) == sizeof(Pose) + 4 * sizeof(Vector3) + sizeof(double)), "sizeof(PoseState) failure"); +#ifdef OVR_CPU_X86_64 +static_assert((sizeof(PoseState) == sizeof(Pose) + 4 * sizeof(Vector3) + sizeof(uint32_t)+sizeof(double)), "sizeof(PoseState) failure"); //TODO: Manually pad template. +#elif defined(OVR_OS_WIN32) // The Windows 32 bit ABI aligns 64 bit values on 64 bit boundaries +static_assert((sizeof(PoseState) == sizeof(Pose) + 4 * sizeof(Vector3) + sizeof(uint32_t)+sizeof(double)), "sizeof(PoseState) failure"); +#elif defined(OVR_CPU_ARM) // ARM aligns 64 bit values to 64 bit boundaries: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0472k/chr1359125009502.html +static_assert((sizeof(PoseState) == sizeof(Pose) + 4 * sizeof(Vector3) + sizeof(uint32_t)+sizeof(double)), "sizeof(PoseState) failure"); +#else // Else Unix/Apple 32 bit ABI, which aligns 64 bit values on 32 bit boundaries. +static_assert((sizeof(PoseState) == sizeof(Pose) + 4 * sizeof(Vector3) + sizeof(double)), "sizeof(PoseState) failure:"); +#endif + +} // namespace OVR + +#endif // OVR_Vision_Common_h diff --git a/LibOVRKernel/Projects/Mac/LibOVRKernel.xcodeproj/project.pbxproj b/LibOVRKernel/Projects/Mac/LibOVRKernel.xcodeproj/project.pbxproj new file mode 100644 index 0000000..45ef91b --- /dev/null +++ b/LibOVRKernel/Projects/Mac/LibOVRKernel.xcodeproj/project.pbxproj @@ -0,0 +1,792 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 160732801A3BA2C200BC3261 /* OVR_Alg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732471A3BA2C200BC3261 /* OVR_Alg.cpp */; }; + 160732811A3BA2C200BC3261 /* OVR_Alg.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732481A3BA2C200BC3261 /* OVR_Alg.h */; }; + 160732821A3BA2C200BC3261 /* OVR_Allocator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732491A3BA2C200BC3261 /* OVR_Allocator.cpp */; }; + 160732831A3BA2C200BC3261 /* OVR_Allocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607324A1A3BA2C200BC3261 /* OVR_Allocator.h */; }; + 160732841A3BA2C200BC3261 /* OVR_Array.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607324B1A3BA2C200BC3261 /* OVR_Array.h */; }; + 160732851A3BA2C200BC3261 /* OVR_Atomic.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607324C1A3BA2C200BC3261 /* OVR_Atomic.cpp */; }; + 160732861A3BA2C200BC3261 /* OVR_Atomic.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607324D1A3BA2C200BC3261 /* OVR_Atomic.h */; }; + 160732871A3BA2C200BC3261 /* OVR_Color.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607324E1A3BA2C200BC3261 /* OVR_Color.h */; }; + 160732881A3BA2C200BC3261 /* OVR_Compiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607324F1A3BA2C200BC3261 /* OVR_Compiler.h */; }; + 160732891A3BA2C200BC3261 /* OVR_ContainerAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732501A3BA2C200BC3261 /* OVR_ContainerAllocator.h */; }; + 1607328A1A3BA2C200BC3261 /* OVR_CRC32.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732511A3BA2C200BC3261 /* OVR_CRC32.cpp */; }; + 1607328B1A3BA2C200BC3261 /* OVR_CRC32.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732521A3BA2C200BC3261 /* OVR_CRC32.h */; }; + 1607328C1A3BA2C200BC3261 /* OVR_DebugHelp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732531A3BA2C200BC3261 /* OVR_DebugHelp.cpp */; }; + 1607328D1A3BA2C200BC3261 /* OVR_DebugHelp.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732541A3BA2C200BC3261 /* OVR_DebugHelp.h */; }; + 1607328E1A3BA2C200BC3261 /* OVR_Delegates.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732551A3BA2C200BC3261 /* OVR_Delegates.h */; }; + 1607328F1A3BA2C200BC3261 /* OVR_Deque.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732561A3BA2C200BC3261 /* OVR_Deque.h */; }; + 160732901A3BA2C200BC3261 /* OVR_File.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732571A3BA2C200BC3261 /* OVR_File.cpp */; }; + 160732911A3BA2C200BC3261 /* OVR_File.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732581A3BA2C200BC3261 /* OVR_File.h */; }; + 160732921A3BA2C200BC3261 /* OVR_FileFILE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732591A3BA2C200BC3261 /* OVR_FileFILE.cpp */; }; + 160732931A3BA2C200BC3261 /* OVR_Hash.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607325A1A3BA2C200BC3261 /* OVR_Hash.h */; }; + 160732941A3BA2C200BC3261 /* OVR_JSON.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607325B1A3BA2C200BC3261 /* OVR_JSON.cpp */; }; + 160732951A3BA2C200BC3261 /* OVR_JSON.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607325C1A3BA2C200BC3261 /* OVR_JSON.h */; }; + 160732961A3BA2C200BC3261 /* OVR_KeyCodes.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607325D1A3BA2C200BC3261 /* OVR_KeyCodes.h */; }; + 160732971A3BA2C200BC3261 /* OVR_List.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607325E1A3BA2C200BC3261 /* OVR_List.h */; }; + 160732981A3BA2C200BC3261 /* OVR_Lockless.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607325F1A3BA2C200BC3261 /* OVR_Lockless.cpp */; }; + 160732991A3BA2C200BC3261 /* OVR_Lockless.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732601A3BA2C200BC3261 /* OVR_Lockless.h */; }; + 1607329A1A3BA2C200BC3261 /* OVR_Log.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732611A3BA2C200BC3261 /* OVR_Log.cpp */; }; + 1607329B1A3BA2C200BC3261 /* OVR_Log.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732621A3BA2C200BC3261 /* OVR_Log.h */; }; + 1607329C1A3BA2C200BC3261 /* OVR_mach_exc_OSX.c in Sources */ = {isa = PBXBuildFile; fileRef = 160732631A3BA2C200BC3261 /* OVR_mach_exc_OSX.c */; }; + 1607329D1A3BA2C200BC3261 /* OVR_mach_exc_OSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732641A3BA2C200BC3261 /* OVR_mach_exc_OSX.h */; }; + 1607329E1A3BA2C200BC3261 /* OVR_Nullptr.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732651A3BA2C200BC3261 /* OVR_Nullptr.h */; }; + 160732A01A3BA2C200BC3261 /* OVR_RefCount.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732671A3BA2C200BC3261 /* OVR_RefCount.cpp */; }; + 160732A11A3BA2C200BC3261 /* OVR_RefCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732681A3BA2C200BC3261 /* OVR_RefCount.h */; }; + 160732A21A3BA2C200BC3261 /* OVR_SharedMemory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732691A3BA2C200BC3261 /* OVR_SharedMemory.cpp */; }; + 160732A31A3BA2C200BC3261 /* OVR_SharedMemory.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607326A1A3BA2C200BC3261 /* OVR_SharedMemory.h */; }; + 160732A41A3BA2C200BC3261 /* OVR_Std.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607326B1A3BA2C200BC3261 /* OVR_Std.cpp */; }; + 160732A51A3BA2C200BC3261 /* OVR_Std.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607326C1A3BA2C200BC3261 /* OVR_Std.h */; }; + 160732A61A3BA2C200BC3261 /* OVR_String_FormatUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607326D1A3BA2C200BC3261 /* OVR_String_FormatUtil.cpp */; }; + 160732A71A3BA2C200BC3261 /* OVR_String_PathUtil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607326E1A3BA2C200BC3261 /* OVR_String_PathUtil.cpp */; }; + 160732A81A3BA2C200BC3261 /* OVR_String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607326F1A3BA2C200BC3261 /* OVR_String.cpp */; }; + 160732A91A3BA2C200BC3261 /* OVR_String.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732701A3BA2C200BC3261 /* OVR_String.h */; }; + 160732AA1A3BA2C200BC3261 /* OVR_StringHash.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732711A3BA2C200BC3261 /* OVR_StringHash.h */; }; + 160732AB1A3BA2C200BC3261 /* OVR_SysFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732721A3BA2C200BC3261 /* OVR_SysFile.cpp */; }; + 160732AC1A3BA2C200BC3261 /* OVR_SysFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732731A3BA2C200BC3261 /* OVR_SysFile.h */; }; + 160732AD1A3BA2C200BC3261 /* OVR_System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732741A3BA2C200BC3261 /* OVR_System.cpp */; }; + 160732AE1A3BA2C200BC3261 /* OVR_System.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732751A3BA2C200BC3261 /* OVR_System.h */; }; + 160732AF1A3BA2C200BC3261 /* OVR_ThreadCommandQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732761A3BA2C200BC3261 /* OVR_ThreadCommandQueue.cpp */; }; + 160732B01A3BA2C200BC3261 /* OVR_ThreadCommandQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732771A3BA2C200BC3261 /* OVR_ThreadCommandQueue.h */; }; + 160732B11A3BA2C200BC3261 /* OVR_Threads.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732781A3BA2C200BC3261 /* OVR_Threads.h */; }; + 160732B21A3BA2C200BC3261 /* OVR_ThreadsPthread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732791A3BA2C200BC3261 /* OVR_ThreadsPthread.cpp */; }; + 160732B41A3BA2C200BC3261 /* OVR_Timer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607327B1A3BA2C200BC3261 /* OVR_Timer.cpp */; }; + 160732B51A3BA2C200BC3261 /* OVR_Timer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607327C1A3BA2C200BC3261 /* OVR_Timer.h */; }; + 160732B61A3BA2C200BC3261 /* OVR_Types.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607327D1A3BA2C200BC3261 /* OVR_Types.h */; }; + 160732B71A3BA2C200BC3261 /* OVR_UTF8Util.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1607327E1A3BA2C200BC3261 /* OVR_UTF8Util.cpp */; }; + 160732B81A3BA2C200BC3261 /* OVR_UTF8Util.h in Headers */ = {isa = PBXBuildFile; fileRef = 1607327F1A3BA2C200BC3261 /* OVR_UTF8Util.h */; }; + 160732BC1A3BA31E00BC3261 /* CAPI_GLE_GL.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732B91A3BA31E00BC3261 /* CAPI_GLE_GL.h */; }; + 160732BD1A3BA31E00BC3261 /* CAPI_GLE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732BA1A3BA31E00BC3261 /* CAPI_GLE.cpp */; }; + 160732BE1A3BA31E00BC3261 /* CAPI_GLE.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732BB1A3BA31E00BC3261 /* CAPI_GLE.h */; }; + 160732CF1A3BA32C00BC3261 /* Util_ImageWindow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732C11A3BA32C00BC3261 /* Util_ImageWindow.cpp */; }; + 160732D01A3BA32C00BC3261 /* Util_ImageWindow.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732C21A3BA32C00BC3261 /* Util_ImageWindow.h */; }; + 160732D11A3BA32C00BC3261 /* Util_LongPollThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732C31A3BA32C00BC3261 /* Util_LongPollThread.cpp */; }; + 160732D21A3BA32C00BC3261 /* Util_LongPollThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732C41A3BA32C00BC3261 /* Util_LongPollThread.h */; }; + 160732D31A3BA32C00BC3261 /* Util_SystemGUI_OSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 160732C51A3BA32C00BC3261 /* Util_SystemGUI_OSX.mm */; }; + 160732D41A3BA32C00BC3261 /* Util_SystemGUI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732C61A3BA32C00BC3261 /* Util_SystemGUI.cpp */; }; + 160732D51A3BA32C00BC3261 /* Util_SystemGUI.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732C71A3BA32C00BC3261 /* Util_SystemGUI.h */; }; + 160732D61A3BA32C00BC3261 /* Util_SystemInfo_OSX.mm in Sources */ = {isa = PBXBuildFile; fileRef = 160732C81A3BA32C00BC3261 /* Util_SystemInfo_OSX.mm */; }; + 160732D71A3BA32C00BC3261 /* Util_SystemInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732C91A3BA32C00BC3261 /* Util_SystemInfo.cpp */; }; + 160732D81A3BA32C00BC3261 /* Util_SystemInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732CA1A3BA32C00BC3261 /* Util_SystemInfo.h */; }; + 160732D91A3BA32C00BC3261 /* Util_Watchdog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 160732CB1A3BA32C00BC3261 /* Util_Watchdog.cpp */; }; + 160732DA1A3BA32C00BC3261 /* Util_Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = 160732CC1A3BA32C00BC3261 /* Util_Watchdog.h */; }; + 16535AD31A60A48700E57802 /* OVR_Rand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16535AD11A60A48700E57802 /* OVR_Rand.cpp */; }; + 16535AD41A60A48700E57802 /* OVR_Rand.h in Headers */ = {isa = PBXBuildFile; fileRef = 16535AD21A60A48700E57802 /* OVR_Rand.h */; }; + 16535BD11A69C3EB00E57802 /* OVR_Callbacks.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 16535BCE1A69C3EB00E57802 /* OVR_Callbacks.cpp */; }; + 16535BD21A69C3EB00E57802 /* OVR_Callbacks.h in Headers */ = {isa = PBXBuildFile; fileRef = 16535BCF1A69C3EB00E57802 /* OVR_Callbacks.h */; }; + 16535BD31A69C3EB00E57802 /* OVR_CallbacksInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 16535BD01A69C3EB00E57802 /* OVR_CallbacksInternal.h */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 160732471A3BA2C200BC3261 /* OVR_Alg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Alg.cpp; path = ../../Src/Kernel/OVR_Alg.cpp; sourceTree = ""; }; + 160732481A3BA2C200BC3261 /* OVR_Alg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Alg.h; path = ../../Src/Kernel/OVR_Alg.h; sourceTree = ""; }; + 160732491A3BA2C200BC3261 /* OVR_Allocator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Allocator.cpp; path = ../../Src/Kernel/OVR_Allocator.cpp; sourceTree = ""; }; + 1607324A1A3BA2C200BC3261 /* OVR_Allocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Allocator.h; path = ../../Src/Kernel/OVR_Allocator.h; sourceTree = ""; }; + 1607324B1A3BA2C200BC3261 /* OVR_Array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Array.h; path = ../../Src/Kernel/OVR_Array.h; sourceTree = ""; }; + 1607324C1A3BA2C200BC3261 /* OVR_Atomic.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Atomic.cpp; path = ../../Src/Kernel/OVR_Atomic.cpp; sourceTree = ""; }; + 1607324D1A3BA2C200BC3261 /* OVR_Atomic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Atomic.h; path = ../../Src/Kernel/OVR_Atomic.h; sourceTree = ""; }; + 1607324E1A3BA2C200BC3261 /* OVR_Color.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Color.h; path = ../../Src/Kernel/OVR_Color.h; sourceTree = ""; }; + 1607324F1A3BA2C200BC3261 /* OVR_Compiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Compiler.h; path = ../../Src/Kernel/OVR_Compiler.h; sourceTree = ""; }; + 160732501A3BA2C200BC3261 /* OVR_ContainerAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_ContainerAllocator.h; path = ../../Src/Kernel/OVR_ContainerAllocator.h; sourceTree = ""; }; + 160732511A3BA2C200BC3261 /* OVR_CRC32.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_CRC32.cpp; path = ../../Src/Kernel/OVR_CRC32.cpp; sourceTree = ""; }; + 160732521A3BA2C200BC3261 /* OVR_CRC32.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_CRC32.h; path = ../../Src/Kernel/OVR_CRC32.h; sourceTree = ""; }; + 160732531A3BA2C200BC3261 /* OVR_DebugHelp.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_DebugHelp.cpp; path = ../../Src/Kernel/OVR_DebugHelp.cpp; sourceTree = ""; }; + 160732541A3BA2C200BC3261 /* OVR_DebugHelp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_DebugHelp.h; path = ../../Src/Kernel/OVR_DebugHelp.h; sourceTree = ""; }; + 160732551A3BA2C200BC3261 /* OVR_Delegates.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Delegates.h; path = ../../Src/Kernel/OVR_Delegates.h; sourceTree = ""; }; + 160732561A3BA2C200BC3261 /* OVR_Deque.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Deque.h; path = ../../Src/Kernel/OVR_Deque.h; sourceTree = ""; }; + 160732571A3BA2C200BC3261 /* OVR_File.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_File.cpp; path = ../../Src/Kernel/OVR_File.cpp; sourceTree = ""; }; + 160732581A3BA2C200BC3261 /* OVR_File.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_File.h; path = ../../Src/Kernel/OVR_File.h; sourceTree = ""; }; + 160732591A3BA2C200BC3261 /* OVR_FileFILE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_FileFILE.cpp; path = ../../Src/Kernel/OVR_FileFILE.cpp; sourceTree = ""; }; + 1607325A1A3BA2C200BC3261 /* OVR_Hash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Hash.h; path = ../../Src/Kernel/OVR_Hash.h; sourceTree = ""; }; + 1607325B1A3BA2C200BC3261 /* OVR_JSON.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_JSON.cpp; path = ../../Src/Kernel/OVR_JSON.cpp; sourceTree = ""; }; + 1607325C1A3BA2C200BC3261 /* OVR_JSON.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_JSON.h; path = ../../Src/Kernel/OVR_JSON.h; sourceTree = ""; }; + 1607325D1A3BA2C200BC3261 /* OVR_KeyCodes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_KeyCodes.h; path = ../../Src/Kernel/OVR_KeyCodes.h; sourceTree = ""; }; + 1607325E1A3BA2C200BC3261 /* OVR_List.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_List.h; path = ../../Src/Kernel/OVR_List.h; sourceTree = ""; }; + 1607325F1A3BA2C200BC3261 /* OVR_Lockless.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Lockless.cpp; path = ../../Src/Kernel/OVR_Lockless.cpp; sourceTree = ""; }; + 160732601A3BA2C200BC3261 /* OVR_Lockless.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Lockless.h; path = ../../Src/Kernel/OVR_Lockless.h; sourceTree = ""; }; + 160732611A3BA2C200BC3261 /* OVR_Log.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Log.cpp; path = ../../Src/Kernel/OVR_Log.cpp; sourceTree = ""; }; + 160732621A3BA2C200BC3261 /* OVR_Log.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Log.h; path = ../../Src/Kernel/OVR_Log.h; sourceTree = ""; }; + 160732631A3BA2C200BC3261 /* OVR_mach_exc_OSX.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = OVR_mach_exc_OSX.c; path = ../../Src/Kernel/OVR_mach_exc_OSX.c; sourceTree = ""; }; + 160732641A3BA2C200BC3261 /* OVR_mach_exc_OSX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_mach_exc_OSX.h; path = ../../Src/Kernel/OVR_mach_exc_OSX.h; sourceTree = ""; }; + 160732651A3BA2C200BC3261 /* OVR_Nullptr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Nullptr.h; path = ../../Src/Kernel/OVR_Nullptr.h; sourceTree = ""; }; + 160732671A3BA2C200BC3261 /* OVR_RefCount.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_RefCount.cpp; path = ../../Src/Kernel/OVR_RefCount.cpp; sourceTree = ""; }; + 160732681A3BA2C200BC3261 /* OVR_RefCount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_RefCount.h; path = ../../Src/Kernel/OVR_RefCount.h; sourceTree = ""; }; + 160732691A3BA2C200BC3261 /* OVR_SharedMemory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SharedMemory.cpp; path = ../../Src/Kernel/OVR_SharedMemory.cpp; sourceTree = ""; }; + 1607326A1A3BA2C200BC3261 /* OVR_SharedMemory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SharedMemory.h; path = ../../Src/Kernel/OVR_SharedMemory.h; sourceTree = ""; }; + 1607326B1A3BA2C200BC3261 /* OVR_Std.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Std.cpp; path = ../../Src/Kernel/OVR_Std.cpp; sourceTree = ""; }; + 1607326C1A3BA2C200BC3261 /* OVR_Std.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Std.h; path = ../../Src/Kernel/OVR_Std.h; sourceTree = ""; }; + 1607326D1A3BA2C200BC3261 /* OVR_String_FormatUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_String_FormatUtil.cpp; path = ../../Src/Kernel/OVR_String_FormatUtil.cpp; sourceTree = ""; }; + 1607326E1A3BA2C200BC3261 /* OVR_String_PathUtil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_String_PathUtil.cpp; path = ../../Src/Kernel/OVR_String_PathUtil.cpp; sourceTree = ""; }; + 1607326F1A3BA2C200BC3261 /* OVR_String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_String.cpp; path = ../../Src/Kernel/OVR_String.cpp; sourceTree = ""; }; + 160732701A3BA2C200BC3261 /* OVR_String.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_String.h; path = ../../Src/Kernel/OVR_String.h; sourceTree = ""; }; + 160732711A3BA2C200BC3261 /* OVR_StringHash.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_StringHash.h; path = ../../Src/Kernel/OVR_StringHash.h; sourceTree = ""; }; + 160732721A3BA2C200BC3261 /* OVR_SysFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_SysFile.cpp; path = ../../Src/Kernel/OVR_SysFile.cpp; sourceTree = ""; }; + 160732731A3BA2C200BC3261 /* OVR_SysFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_SysFile.h; path = ../../Src/Kernel/OVR_SysFile.h; sourceTree = ""; }; + 160732741A3BA2C200BC3261 /* OVR_System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_System.cpp; path = ../../Src/Kernel/OVR_System.cpp; sourceTree = ""; }; + 160732751A3BA2C200BC3261 /* OVR_System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_System.h; path = ../../Src/Kernel/OVR_System.h; sourceTree = ""; }; + 160732761A3BA2C200BC3261 /* OVR_ThreadCommandQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_ThreadCommandQueue.cpp; path = ../../Src/Kernel/OVR_ThreadCommandQueue.cpp; sourceTree = ""; }; + 160732771A3BA2C200BC3261 /* OVR_ThreadCommandQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_ThreadCommandQueue.h; path = ../../Src/Kernel/OVR_ThreadCommandQueue.h; sourceTree = ""; }; + 160732781A3BA2C200BC3261 /* OVR_Threads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Threads.h; path = ../../Src/Kernel/OVR_Threads.h; sourceTree = ""; }; + 160732791A3BA2C200BC3261 /* OVR_ThreadsPthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_ThreadsPthread.cpp; path = ../../Src/Kernel/OVR_ThreadsPthread.cpp; sourceTree = ""; }; + 1607327B1A3BA2C200BC3261 /* OVR_Timer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Timer.cpp; path = ../../Src/Kernel/OVR_Timer.cpp; sourceTree = ""; }; + 1607327C1A3BA2C200BC3261 /* OVR_Timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Timer.h; path = ../../Src/Kernel/OVR_Timer.h; sourceTree = ""; }; + 1607327D1A3BA2C200BC3261 /* OVR_Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Types.h; path = ../../Src/Kernel/OVR_Types.h; sourceTree = ""; }; + 1607327E1A3BA2C200BC3261 /* OVR_UTF8Util.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_UTF8Util.cpp; path = ../../Src/Kernel/OVR_UTF8Util.cpp; sourceTree = ""; }; + 1607327F1A3BA2C200BC3261 /* OVR_UTF8Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_UTF8Util.h; path = ../../Src/Kernel/OVR_UTF8Util.h; sourceTree = ""; }; + 160732B91A3BA31E00BC3261 /* CAPI_GLE_GL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAPI_GLE_GL.h; path = ../../Src/GL/CAPI_GLE_GL.h; sourceTree = ""; }; + 160732BA1A3BA31E00BC3261 /* CAPI_GLE.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CAPI_GLE.cpp; path = ../../Src/GL/CAPI_GLE.cpp; sourceTree = ""; }; + 160732BB1A3BA31E00BC3261 /* CAPI_GLE.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CAPI_GLE.h; path = ../../Src/GL/CAPI_GLE.h; sourceTree = ""; }; + 160732C11A3BA32C00BC3261 /* Util_ImageWindow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Util_ImageWindow.cpp; path = ../../Src/Util/Util_ImageWindow.cpp; sourceTree = ""; }; + 160732C21A3BA32C00BC3261 /* Util_ImageWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util_ImageWindow.h; path = ../../Src/Util/Util_ImageWindow.h; sourceTree = ""; }; + 160732C31A3BA32C00BC3261 /* Util_LongPollThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Util_LongPollThread.cpp; path = ../../Src/Util/Util_LongPollThread.cpp; sourceTree = ""; }; + 160732C41A3BA32C00BC3261 /* Util_LongPollThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util_LongPollThread.h; path = ../../Src/Util/Util_LongPollThread.h; sourceTree = ""; }; + 160732C51A3BA32C00BC3261 /* Util_SystemGUI_OSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Util_SystemGUI_OSX.mm; path = ../../Src/Util/Util_SystemGUI_OSX.mm; sourceTree = ""; }; + 160732C61A3BA32C00BC3261 /* Util_SystemGUI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Util_SystemGUI.cpp; path = ../../Src/Util/Util_SystemGUI.cpp; sourceTree = ""; }; + 160732C71A3BA32C00BC3261 /* Util_SystemGUI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util_SystemGUI.h; path = ../../Src/Util/Util_SystemGUI.h; sourceTree = ""; }; + 160732C81A3BA32C00BC3261 /* Util_SystemInfo_OSX.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Util_SystemInfo_OSX.mm; path = ../../Src/Util/Util_SystemInfo_OSX.mm; sourceTree = ""; }; + 160732C91A3BA32C00BC3261 /* Util_SystemInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Util_SystemInfo.cpp; path = ../../Src/Util/Util_SystemInfo.cpp; sourceTree = ""; }; + 160732CA1A3BA32C00BC3261 /* Util_SystemInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util_SystemInfo.h; path = ../../Src/Util/Util_SystemInfo.h; sourceTree = ""; }; + 160732CB1A3BA32C00BC3261 /* Util_Watchdog.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Util_Watchdog.cpp; path = ../../Src/Util/Util_Watchdog.cpp; sourceTree = ""; }; + 160732CC1A3BA32C00BC3261 /* Util_Watchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Util_Watchdog.h; path = ../../Src/Util/Util_Watchdog.h; sourceTree = ""; }; + 16535AD11A60A48700E57802 /* OVR_Rand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Rand.cpp; path = ../../Src/Kernel/OVR_Rand.cpp; sourceTree = ""; }; + 16535AD21A60A48700E57802 /* OVR_Rand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Rand.h; path = ../../Src/Kernel/OVR_Rand.h; sourceTree = ""; }; + 16535BCD1A699BE800E57802 /* libOVRKernel.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libOVRKernel.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 16535BCE1A69C3EB00E57802 /* OVR_Callbacks.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OVR_Callbacks.cpp; path = ../../Src/Kernel/OVR_Callbacks.cpp; sourceTree = ""; }; + 16535BCF1A69C3EB00E57802 /* OVR_Callbacks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_Callbacks.h; path = ../../Src/Kernel/OVR_Callbacks.h; sourceTree = ""; }; + 16535BD01A69C3EB00E57802 /* OVR_CallbacksInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OVR_CallbacksInternal.h; path = ../../Src/Kernel/OVR_CallbacksInternal.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 160732271A3B991100BC3261 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 160732211A3B991100BC3261 = { + isa = PBXGroup; + children = ( + 160732461A3BA1D800BC3261 /* Util */, + 160732451A3BA1D200BC3261 /* Kernel */, + 160732441A3BA1CA00BC3261 /* GL */, + 16535BCD1A699BE800E57802 /* libOVRKernel.a */, + ); + sourceTree = ""; + }; + 160732441A3BA1CA00BC3261 /* GL */ = { + isa = PBXGroup; + children = ( + 160732B91A3BA31E00BC3261 /* CAPI_GLE_GL.h */, + 160732BA1A3BA31E00BC3261 /* CAPI_GLE.cpp */, + 160732BB1A3BA31E00BC3261 /* CAPI_GLE.h */, + ); + name = GL; + sourceTree = ""; + }; + 160732451A3BA1D200BC3261 /* Kernel */ = { + isa = PBXGroup; + children = ( + 160732471A3BA2C200BC3261 /* OVR_Alg.cpp */, + 160732481A3BA2C200BC3261 /* OVR_Alg.h */, + 160732491A3BA2C200BC3261 /* OVR_Allocator.cpp */, + 1607324A1A3BA2C200BC3261 /* OVR_Allocator.h */, + 1607324B1A3BA2C200BC3261 /* OVR_Array.h */, + 1607324C1A3BA2C200BC3261 /* OVR_Atomic.cpp */, + 1607324D1A3BA2C200BC3261 /* OVR_Atomic.h */, + 16535BCE1A69C3EB00E57802 /* OVR_Callbacks.cpp */, + 16535BCF1A69C3EB00E57802 /* OVR_Callbacks.h */, + 16535BD01A69C3EB00E57802 /* OVR_CallbacksInternal.h */, + 1607324E1A3BA2C200BC3261 /* OVR_Color.h */, + 1607324F1A3BA2C200BC3261 /* OVR_Compiler.h */, + 160732501A3BA2C200BC3261 /* OVR_ContainerAllocator.h */, + 160732511A3BA2C200BC3261 /* OVR_CRC32.cpp */, + 160732521A3BA2C200BC3261 /* OVR_CRC32.h */, + 160732531A3BA2C200BC3261 /* OVR_DebugHelp.cpp */, + 160732541A3BA2C200BC3261 /* OVR_DebugHelp.h */, + 160732551A3BA2C200BC3261 /* OVR_Delegates.h */, + 160732561A3BA2C200BC3261 /* OVR_Deque.h */, + 160732571A3BA2C200BC3261 /* OVR_File.cpp */, + 160732581A3BA2C200BC3261 /* OVR_File.h */, + 160732591A3BA2C200BC3261 /* OVR_FileFILE.cpp */, + 1607325A1A3BA2C200BC3261 /* OVR_Hash.h */, + 1607325B1A3BA2C200BC3261 /* OVR_JSON.cpp */, + 1607325C1A3BA2C200BC3261 /* OVR_JSON.h */, + 1607325D1A3BA2C200BC3261 /* OVR_KeyCodes.h */, + 1607325E1A3BA2C200BC3261 /* OVR_List.h */, + 1607325F1A3BA2C200BC3261 /* OVR_Lockless.cpp */, + 160732601A3BA2C200BC3261 /* OVR_Lockless.h */, + 160732611A3BA2C200BC3261 /* OVR_Log.cpp */, + 160732621A3BA2C200BC3261 /* OVR_Log.h */, + 160732631A3BA2C200BC3261 /* OVR_mach_exc_OSX.c */, + 160732641A3BA2C200BC3261 /* OVR_mach_exc_OSX.h */, + 160732651A3BA2C200BC3261 /* OVR_Nullptr.h */, + 16535AD11A60A48700E57802 /* OVR_Rand.cpp */, + 16535AD21A60A48700E57802 /* OVR_Rand.h */, + 160732671A3BA2C200BC3261 /* OVR_RefCount.cpp */, + 160732681A3BA2C200BC3261 /* OVR_RefCount.h */, + 160732691A3BA2C200BC3261 /* OVR_SharedMemory.cpp */, + 1607326A1A3BA2C200BC3261 /* OVR_SharedMemory.h */, + 1607326B1A3BA2C200BC3261 /* OVR_Std.cpp */, + 1607326C1A3BA2C200BC3261 /* OVR_Std.h */, + 1607326D1A3BA2C200BC3261 /* OVR_String_FormatUtil.cpp */, + 1607326E1A3BA2C200BC3261 /* OVR_String_PathUtil.cpp */, + 1607326F1A3BA2C200BC3261 /* OVR_String.cpp */, + 160732701A3BA2C200BC3261 /* OVR_String.h */, + 160732711A3BA2C200BC3261 /* OVR_StringHash.h */, + 160732721A3BA2C200BC3261 /* OVR_SysFile.cpp */, + 160732731A3BA2C200BC3261 /* OVR_SysFile.h */, + 160732741A3BA2C200BC3261 /* OVR_System.cpp */, + 160732751A3BA2C200BC3261 /* OVR_System.h */, + 160732761A3BA2C200BC3261 /* OVR_ThreadCommandQueue.cpp */, + 160732771A3BA2C200BC3261 /* OVR_ThreadCommandQueue.h */, + 160732781A3BA2C200BC3261 /* OVR_Threads.h */, + 160732791A3BA2C200BC3261 /* OVR_ThreadsPthread.cpp */, + 1607327B1A3BA2C200BC3261 /* OVR_Timer.cpp */, + 1607327C1A3BA2C200BC3261 /* OVR_Timer.h */, + 1607327D1A3BA2C200BC3261 /* OVR_Types.h */, + 1607327E1A3BA2C200BC3261 /* OVR_UTF8Util.cpp */, + 1607327F1A3BA2C200BC3261 /* OVR_UTF8Util.h */, + ); + name = Kernel; + sourceTree = ""; + }; + 160732461A3BA1D800BC3261 /* Util */ = { + isa = PBXGroup; + children = ( + 160732C11A3BA32C00BC3261 /* Util_ImageWindow.cpp */, + 160732C21A3BA32C00BC3261 /* Util_ImageWindow.h */, + 160732C31A3BA32C00BC3261 /* Util_LongPollThread.cpp */, + 160732C41A3BA32C00BC3261 /* Util_LongPollThread.h */, + 160732C51A3BA32C00BC3261 /* Util_SystemGUI_OSX.mm */, + 160732C61A3BA32C00BC3261 /* Util_SystemGUI.cpp */, + 160732C71A3BA32C00BC3261 /* Util_SystemGUI.h */, + 160732C81A3BA32C00BC3261 /* Util_SystemInfo_OSX.mm */, + 160732C91A3BA32C00BC3261 /* Util_SystemInfo.cpp */, + 160732CA1A3BA32C00BC3261 /* Util_SystemInfo.h */, + 160732CB1A3BA32C00BC3261 /* Util_Watchdog.cpp */, + 160732CC1A3BA32C00BC3261 /* Util_Watchdog.h */, + ); + name = Util; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 160732281A3B991100BC3261 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 160732A51A3BA2C200BC3261 /* OVR_Std.h in Headers */, + 160732AE1A3BA2C200BC3261 /* OVR_System.h in Headers */, + 160732871A3BA2C200BC3261 /* OVR_Color.h in Headers */, + 160732BC1A3BA31E00BC3261 /* CAPI_GLE_GL.h in Headers */, + 160732D51A3BA32C00BC3261 /* Util_SystemGUI.h in Headers */, + 160732AA1A3BA2C200BC3261 /* OVR_StringHash.h in Headers */, + 1607328E1A3BA2C200BC3261 /* OVR_Delegates.h in Headers */, + 16535BD21A69C3EB00E57802 /* OVR_Callbacks.h in Headers */, + 160732AC1A3BA2C200BC3261 /* OVR_SysFile.h in Headers */, + 160732B81A3BA2C200BC3261 /* OVR_UTF8Util.h in Headers */, + 1607329E1A3BA2C200BC3261 /* OVR_Nullptr.h in Headers */, + 160732971A3BA2C200BC3261 /* OVR_List.h in Headers */, + 1607329B1A3BA2C200BC3261 /* OVR_Log.h in Headers */, + 1607329D1A3BA2C200BC3261 /* OVR_mach_exc_OSX.h in Headers */, + 160732A91A3BA2C200BC3261 /* OVR_String.h in Headers */, + 160732B61A3BA2C200BC3261 /* OVR_Types.h in Headers */, + 160732B11A3BA2C200BC3261 /* OVR_Threads.h in Headers */, + 160732951A3BA2C200BC3261 /* OVR_JSON.h in Headers */, + 160732891A3BA2C200BC3261 /* OVR_ContainerAllocator.h in Headers */, + 160732841A3BA2C200BC3261 /* OVR_Array.h in Headers */, + 160732D01A3BA32C00BC3261 /* Util_ImageWindow.h in Headers */, + 16535AD41A60A48700E57802 /* OVR_Rand.h in Headers */, + 160732961A3BA2C200BC3261 /* OVR_KeyCodes.h in Headers */, + 160732A31A3BA2C200BC3261 /* OVR_SharedMemory.h in Headers */, + 160732861A3BA2C200BC3261 /* OVR_Atomic.h in Headers */, + 160732DA1A3BA32C00BC3261 /* Util_Watchdog.h in Headers */, + 16535BD31A69C3EB00E57802 /* OVR_CallbacksInternal.h in Headers */, + 1607328F1A3BA2C200BC3261 /* OVR_Deque.h in Headers */, + 1607328B1A3BA2C200BC3261 /* OVR_CRC32.h in Headers */, + 160732881A3BA2C200BC3261 /* OVR_Compiler.h in Headers */, + 160732991A3BA2C200BC3261 /* OVR_Lockless.h in Headers */, + 160732D81A3BA32C00BC3261 /* Util_SystemInfo.h in Headers */, + 160732A11A3BA2C200BC3261 /* OVR_RefCount.h in Headers */, + 160732831A3BA2C200BC3261 /* OVR_Allocator.h in Headers */, + 1607328D1A3BA2C200BC3261 /* OVR_DebugHelp.h in Headers */, + 160732911A3BA2C200BC3261 /* OVR_File.h in Headers */, + 160732811A3BA2C200BC3261 /* OVR_Alg.h in Headers */, + 160732D21A3BA32C00BC3261 /* Util_LongPollThread.h in Headers */, + 160732931A3BA2C200BC3261 /* OVR_Hash.h in Headers */, + 160732B01A3BA2C200BC3261 /* OVR_ThreadCommandQueue.h in Headers */, + 160732BE1A3BA31E00BC3261 /* CAPI_GLE.h in Headers */, + 160732B51A3BA2C200BC3261 /* OVR_Timer.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 160732291A3B991100BC3261 /* LibOVRKernel */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1607323E1A3B991100BC3261 /* Build configuration list for PBXNativeTarget "LibOVRKernel" */; + buildPhases = ( + 160732261A3B991100BC3261 /* Sources */, + 160732271A3B991100BC3261 /* Frameworks */, + 160732281A3B991100BC3261 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LibOVRKernel; + productName = LibOVRKernel; + productReference = 16535BCD1A699BE800E57802 /* libOVRKernel.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 160732221A3B991100BC3261 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = "Oculus VR"; + TargetAttributes = { + 160732291A3B991100BC3261 = { + CreatedOnToolsVersion = 6.1; + }; + }; + }; + buildConfigurationList = 160732251A3B991100BC3261 /* Build configuration list for PBXProject "LibOVRKernel" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 160732211A3B991100BC3261; + productRefGroup = 160732211A3B991100BC3261; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 160732291A3B991100BC3261 /* LibOVRKernel */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 160732261A3B991100BC3261 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 160732801A3BA2C200BC3261 /* OVR_Alg.cpp in Sources */, + 160732AF1A3BA2C200BC3261 /* OVR_ThreadCommandQueue.cpp in Sources */, + 160732D91A3BA32C00BC3261 /* Util_Watchdog.cpp in Sources */, + 160732901A3BA2C200BC3261 /* OVR_File.cpp in Sources */, + 1607328A1A3BA2C200BC3261 /* OVR_CRC32.cpp in Sources */, + 160732D11A3BA32C00BC3261 /* Util_LongPollThread.cpp in Sources */, + 160732D31A3BA32C00BC3261 /* Util_SystemGUI_OSX.mm in Sources */, + 160732BD1A3BA31E00BC3261 /* CAPI_GLE.cpp in Sources */, + 160732B71A3BA2C200BC3261 /* OVR_UTF8Util.cpp in Sources */, + 160732B41A3BA2C200BC3261 /* OVR_Timer.cpp in Sources */, + 160732921A3BA2C200BC3261 /* OVR_FileFILE.cpp in Sources */, + 1607329A1A3BA2C200BC3261 /* OVR_Log.cpp in Sources */, + 16535BD11A69C3EB00E57802 /* OVR_Callbacks.cpp in Sources */, + 160732B21A3BA2C200BC3261 /* OVR_ThreadsPthread.cpp in Sources */, + 160732D41A3BA32C00BC3261 /* Util_SystemGUI.cpp in Sources */, + 160732CF1A3BA32C00BC3261 /* Util_ImageWindow.cpp in Sources */, + 160732821A3BA2C200BC3261 /* OVR_Allocator.cpp in Sources */, + 160732941A3BA2C200BC3261 /* OVR_JSON.cpp in Sources */, + 160732AD1A3BA2C200BC3261 /* OVR_System.cpp in Sources */, + 160732D71A3BA32C00BC3261 /* Util_SystemInfo.cpp in Sources */, + 160732A41A3BA2C200BC3261 /* OVR_Std.cpp in Sources */, + 160732A21A3BA2C200BC3261 /* OVR_SharedMemory.cpp in Sources */, + 1607329C1A3BA2C200BC3261 /* OVR_mach_exc_OSX.c in Sources */, + 160732851A3BA2C200BC3261 /* OVR_Atomic.cpp in Sources */, + 160732A01A3BA2C200BC3261 /* OVR_RefCount.cpp in Sources */, + 1607328C1A3BA2C200BC3261 /* OVR_DebugHelp.cpp in Sources */, + 160732AB1A3BA2C200BC3261 /* OVR_SysFile.cpp in Sources */, + 160732A81A3BA2C200BC3261 /* OVR_String.cpp in Sources */, + 160732981A3BA2C200BC3261 /* OVR_Lockless.cpp in Sources */, + 160732D61A3BA32C00BC3261 /* Util_SystemInfo_OSX.mm in Sources */, + 160732A61A3BA2C200BC3261 /* OVR_String_FormatUtil.cpp in Sources */, + 16535AD31A60A48700E57802 /* OVR_Rand.cpp in Sources */, + 160732A71A3BA2C200BC3261 /* OVR_String_PathUtil.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1607323C1A3B991100BC3261 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + OVR_DLL_BUILD, + "DEBUG=1", + OVR_BUILD_DEBUG, + ); + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = macosx; + }; + name = Debug; + }; + 1607323D1A3B991100BC3261 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = OVR_DLL_BUILD; + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_ENABLE_DEBUG_INFO = NO; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = macosx; + }; + name = Release; + }; + 1607323F1A3B991100BC3261 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + COMBINE_HIDPI_IMAGES = YES; + CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + OVR_DLL_BUILD, + "DEBUG=1", + OVR_BUILD_DEBUG, + ); + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + ../../Src, + ); + LD_MAP_FILE_PATH = "$(TARGET_TEMP_DIR)/LinkMap.txt"; + OBJROOT = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = OVRKernel; + RUN_CLANG_STATIC_ANALYZER = YES; + SYMROOT = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + }; + name = Debug; + }; + 160732401A3B991100BC3261 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + COMBINE_HIDPI_IMAGES = YES; + CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = OVR_DLL_BUILD; + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_UNROLL_LOOPS = NO; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + ../../Src, + ); + LD_MAP_FILE_PATH = "$(TARGET_TEMP_DIR)/LinkMap.txt"; + OBJROOT = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + PRODUCT_NAME = OVRKernel; + RUN_CLANG_STATIC_ANALYZER = YES; + SYMROOT = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + }; + name = Release; + }; + 16073A5E1A42029500BC3261 /* DebugStatic */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + OVR_DLL_BUILD, + "DEBUG=1", + OVR_BUILD_DEBUG, + ); + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = macosx; + }; + name = DebugStatic; + }; + 16073A5F1A42029500BC3261 /* DebugStatic */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + COMBINE_HIDPI_IMAGES = YES; + CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = ( + OVR_DLL_BUILD, + "DEBUG=1", + OVR_BUILD_DEBUG, + ); + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + ../../Src, + ); + LD_MAP_FILE_PATH = "$(TARGET_TEMP_DIR)/LinkMap.txt"; + OBJROOT = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + ONLY_ACTIVE_ARCH = NO; + PRODUCT_NAME = OVRKernel; + RUN_CLANG_STATIC_ANALYZER = YES; + SYMROOT = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + }; + name = DebugStatic; + }; + 16073A601A42029C00BC3261 /* ReleaseStatic */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = NO; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_ENABLE_CPP_EXCEPTIONS = NO; + GCC_ENABLE_CPP_RTTI = NO; + GCC_PREPROCESSOR_DEFINITIONS = OVR_DLL_BUILD; + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + MACOSX_DEPLOYMENT_TARGET = 10.9; + MTL_ENABLE_DEBUG_INFO = NO; + RUN_CLANG_STATIC_ANALYZER = YES; + SDKROOT = macosx; + }; + name = ReleaseStatic; + }; + 16073A611A42029C00BC3261 /* ReleaseStatic */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_SECURITY_FLOATLOOPCOUNTER = YES; + CLANG_WARN_ASSIGN_ENUM = YES; + COMBINE_HIDPI_IMAGES = YES; + CONFIGURATION_BUILD_DIR = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + CONFIGURATION_TEMP_DIR = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + EXECUTABLE_PREFIX = lib; + GCC_PREPROCESSOR_DEFINITIONS = OVR_DLL_BUILD; + GCC_STRICT_ALIASING = NO; + GCC_SYMBOLS_PRIVATE_EXTERN = YES; + GCC_THREADSAFE_STATICS = NO; + GCC_TREAT_WARNINGS_AS_ERRORS = YES; + GCC_UNROLL_LOOPS = NO; + GCC_WARN_ABOUT_MISSING_NEWLINE = YES; + GCC_WARN_HIDDEN_VIRTUAL_FUNCTIONS = YES; + GCC_WARN_INITIALIZER_NOT_FULLY_BRACKETED = YES; + GCC_WARN_NON_VIRTUAL_DESTRUCTOR = YES; + GCC_WARN_SHADOW = YES; + GCC_WARN_UNUSED_LABEL = YES; + GCC_WARN_UNUSED_PARAMETER = YES; + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + ../../Src, + ); + LD_MAP_FILE_PATH = "$(TARGET_TEMP_DIR)/LinkMap.txt"; + OBJROOT = "$(SRCROOT)/../../Obj/Mac/$CONFIGURATION"; + PRODUCT_NAME = OVRKernel; + RUN_CLANG_STATIC_ANALYZER = YES; + SYMROOT = "$(SRCROOT)/../../Lib/Mac/$CONFIGURATION"; + }; + name = ReleaseStatic; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 160732251A3B991100BC3261 /* Build configuration list for PBXProject "LibOVRKernel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1607323C1A3B991100BC3261 /* Debug */, + 16073A5E1A42029500BC3261 /* DebugStatic */, + 1607323D1A3B991100BC3261 /* Release */, + 16073A601A42029C00BC3261 /* ReleaseStatic */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1607323E1A3B991100BC3261 /* Build configuration list for PBXNativeTarget "LibOVRKernel" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1607323F1A3B991100BC3261 /* Debug */, + 16073A5F1A42029500BC3261 /* DebugStatic */, + 160732401A3B991100BC3261 /* Release */, + 16073A611A42029C00BC3261 /* ReleaseStatic */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 160732221A3B991100BC3261 /* Project object */; +} diff --git a/LibOVRKernel/Projects/Mac/LibOVRKernel.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/LibOVRKernel/Projects/Mac/LibOVRKernel.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b6c8fcb --- /dev/null +++ b/LibOVRKernel/Projects/Mac/LibOVRKernel.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/LibOVRKernel/Src/GL/CAPI_GLE.cpp b/LibOVRKernel/Src/GL/CAPI_GLE.cpp new file mode 100644 index 0000000..cc04800 --- /dev/null +++ b/LibOVRKernel/Src/GL/CAPI_GLE.cpp @@ -0,0 +1,7894 @@ +/************************************************************************************ + +Filename : Render_GLE.cpp +Content : OpenGL Extensions support. Implements a stripped down glew-like + interface with some additional functionality. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "CAPI_GLE.h" +#include "Kernel/OVR_Log.h" +#if defined(OVR_OS_WIN32) + #include "Kernel/OVR_Win32_IncludeWindows.h" +#endif // OVR_OS_WIN32 +#include + + +#if defined(_WIN32) + #pragma comment(lib, "opengl32.lib") +#elif defined(__APPLE__) + #include + #include + #include + #include +#endif + + + +//namespace OVR +//{ + // OVRTypeof + // Acts the same as the C++11 decltype expression, though with reduced requirements. + #if !defined(OVRTypeof) + #if defined(_MSC_VER) + #define OVRTypeof(x) decltype(x) // VS2010+ unilaterally supports decltype + #else + #define OVRTypeof(x) __typeof__(x) // Other compilers support decltype, but usually not unless C++11 support is present and explicitly enabled. + #endif + #endif + + + // GLELoadProc + // Macro which implements dynamically looking up and assigning an OpenGL function. + // + // Example usage: + // GLELoadProc(glCopyTexSubImage3D, glCopyTexSubImage3D); + // Expands to: + // gleCopyTexSubImage3D = (OVRTypeof(gleCopyTexSubImage3D)) GLEGetProcAddress("glCopyTexSubImage3D"); + + #define GLELoadProc(var, name) var = (OVRTypeof(var))GLEGetProcAddress(#name) + + + // Disable some #defines, as we need to call these functions directly. + #if defined(GLE_HOOKING_ENABLED) + #if defined(_WIN32) + #undef wglGetProcAddress + extern "C" { GLAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc); } + #endif + + #undef glGetString + extern "C" { GLAPI const GLubyte * GLAPIENTRY glGetString(GLenum name); } + #endif + + + // Generic OpenGL GetProcAddress function interface. Maps to platform-specific functionality + // internally. On Windows this is equivalent to wglGetProcAddress as opposed to global GetProcAddress. + void* OVR::GLEGetProcAddress(const char* name) + { + #if defined(_WIN32) + return wglGetProcAddress(name); + + #elif defined(__APPLE__) + // Requires the OS 10.3 SDK or later. + static void* dlImage = NULL; + void* addr = nullptr; + + if(!dlImage) + dlImage = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); + + if(dlImage) + addr = dlsym(dlImage, name); + + return addr; + + #elif defined(__ANDROID__) + return eglGetProcAddress(name); + + #else + // This was glXGetProcAddressARB in GLX versions prior to v1.4, but that was ten years ago. + return (void*)glXGetProcAddress((const GLubyte*)name); + #endif + } + + + + // Current context functionality + static OVR::GLEContext* GLECurrentContext = NULL; + + OVR::GLEContext* OVR::GLEContext::GetCurrentContext() + { + return GLECurrentContext; + } + + void OVR::GLEContext::SetCurrentContext(OVR::GLEContext* p) + { + GLECurrentContext = p; + } + + + + OVR::GLEContext::GLEContext() + : MajorVersion(0) + , MinorVersion(0) + , WholeVersion(0) + , IsGLES(false) + , IsCoreProfile(false) + , EnableHookGetError(true) + , PlatformMajorVersion(0) + , PlatformMinorVersion(0) + , PlatformWholeVersion(0) + { + // The following sequence is not thread-safe. Two threads could set the context to this at the same time. + if(GetCurrentContext() == NULL) + SetCurrentContext(this); + } + + + OVR::GLEContext::~GLEContext() + { + // Currently empty + } + + + void OVR::GLEContext::Init() + { + PlatformInit(); + + if(!IsInitialized()) + { + InitVersion(); + InitExtensionLoad(); + InitExtensionSupport(); + } + } + + + bool OVR::GLEContext::IsInitialized() const + { + return (MajorVersion != 0); + } + + + void OVR::GLEContext::Shutdown() + { + // This memset is valid only if this class has no virtual functions (similar to concept of POD). + // We cannot assert this because restrictions prevent us from using C++11 type traits here. + memset(this, 0, sizeof(GLEContext)); + } + + + void OVR::GLEContext::PlatformInit() + { + if(!IsPlatformInitialized()) + { + InitPlatformExtensionLoad(); + InitPlatformExtensionSupport(); + InitPlatformVersion(); + } + } + + + bool OVR::GLEContext::IsPlatformInitialized() const + { + return (PlatformMajorVersion != 0); + } + + + void OVR::GLEContext::InitVersion() + { + const char* version = (const char*)glGetString(GL_VERSION); + int fields = 0, major = 0, minor = 0; + bool isGLES = false; + + OVR_ASSERT(version); + if (version) + { + OVR_DEBUG_LOG(("GL_VERSION: %s", (const char*)version)); + + // Skip all leading non-digits before reading %d. + // Example GL_VERSION strings: + // "1.5 ATI-1.4.18" + // "OpenGL ES-CM 3.2" + OVR_DISABLE_MSVC_WARNING(4996) // "scanf may be unsafe" + fields = sscanf(version, isdigit(*version) ? "%d.%d" : "%*[^0-9]%d.%d", &major, &minor); + isGLES = (strstr(version, "OpenGL ES") != NULL); + OVR_RESTORE_MSVC_WARNING() + } + else + { + LogText("Warning: GL_VERSION was NULL\n"); + } + + // If two fields were not found, + if (fields != 2) + { + static_assert(sizeof(major) == sizeof(GLint), "type mis-match"); + + glGetIntegerv(GL_MAJOR_VERSION, &major); + glGetIntegerv(GL_MINOR_VERSION, &minor); + } + + // Write version data + MajorVersion = major; + MinorVersion = minor; + WholeVersion = (major * 100) + minor; + + GLint profileMask = 0; + if(WholeVersion >= 302) + { + // Older NVidia drivers have a bug with this on at least Windows. + // https://www.opengl.org/discussion_boards/showthread.php/171380-NVIDIA-drivers-not-returning-the-right-profile-mas + // A workaround could be to check for the GL_ARB_compatibility extension, which indicates if OpenGL is in compatibility mode, + // and if not then we are in core profile mode. On Apple another solution would be to use NSOpeNGLPixelFormat + // NSOpenGLView::pixelFormat to get the core profile attribute. + glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profileMask); + } + IsCoreProfile = (profileMask == GL_CONTEXT_CORE_PROFILE_BIT); // There's also GL_CONTEXT_COMPATIBILITY_PROFILE_BIT + IsGLES = isGLES; + } + + + void OVR::GLEContext::InitExtensionLoad() + { + // GL_VERSION_1_1 + // We don't load these but rather link to them directly. + + // GL_VERSION_1_2 + GLELoadProc(glCopyTexSubImage3D_Impl, glCopyTexSubImage3D); // This expands to a get proc address call (e.g. wglGetProcAddress on Windows). + GLELoadProc(glDrawRangeElements_Impl, glDrawRangeElements); + GLELoadProc(glTexImage3D_Impl, glTexImage3D); + GLELoadProc(glTexSubImage3D_Impl, glTexSubImage3D); + + // GL_VERSION_1_3 + GLELoadProc(glActiveTexture_Impl, glActiveTexture); + GLELoadProc(glClientActiveTexture_Impl, glClientActiveTexture); + GLELoadProc(glCompressedTexImage1D_Impl, glCompressedTexImage1D); + GLELoadProc(glCompressedTexImage2D_Impl, glCompressedTexImage2D); + GLELoadProc(glCompressedTexImage3D_Impl, glCompressedTexImage3D); + GLELoadProc(glCompressedTexSubImage1D_Impl, glCompressedTexSubImage1D); + GLELoadProc(glCompressedTexSubImage2D_Impl, glCompressedTexSubImage2D); + GLELoadProc(glCompressedTexSubImage3D_Impl, glCompressedTexSubImage3D); + GLELoadProc(glGetCompressedTexImage_Impl, glGetCompressedTexImage); + GLELoadProc(glLoadTransposeMatrixd_Impl, glLoadTransposeMatrixd); + GLELoadProc(glLoadTransposeMatrixf_Impl, glLoadTransposeMatrixf); + GLELoadProc(glMultTransposeMatrixd_Impl, glMultTransposeMatrixd); + GLELoadProc(glMultTransposeMatrixf_Impl, glMultTransposeMatrixf); + GLELoadProc(glMultiTexCoord1d_Impl, glMultiTexCoord1d); + GLELoadProc(glMultiTexCoord1dv_Impl, glMultiTexCoord1dv); + GLELoadProc(glMultiTexCoord1f_Impl, glMultiTexCoord1f); + GLELoadProc(glMultiTexCoord1fv_Impl, glMultiTexCoord1fv); + GLELoadProc(glMultiTexCoord1i_Impl, glMultiTexCoord1i); + GLELoadProc(glMultiTexCoord1iv_Impl, glMultiTexCoord1iv); + GLELoadProc(glMultiTexCoord1s_Impl, glMultiTexCoord1s); + GLELoadProc(glMultiTexCoord1sv_Impl, glMultiTexCoord1sv); + GLELoadProc(glMultiTexCoord2d_Impl, glMultiTexCoord2d); + GLELoadProc(glMultiTexCoord2dv_Impl, glMultiTexCoord2dv); + GLELoadProc(glMultiTexCoord2f_Impl, glMultiTexCoord2f); + GLELoadProc(glMultiTexCoord2fv_Impl, glMultiTexCoord2fv); + GLELoadProc(glMultiTexCoord2i_Impl, glMultiTexCoord2i); + GLELoadProc(glMultiTexCoord2iv_Impl, glMultiTexCoord2iv); + GLELoadProc(glMultiTexCoord2s_Impl, glMultiTexCoord2s); + GLELoadProc(glMultiTexCoord2sv_Impl, glMultiTexCoord2sv); + GLELoadProc(glMultiTexCoord3d_Impl, glMultiTexCoord3d); + GLELoadProc(glMultiTexCoord3dv_Impl, glMultiTexCoord3dv); + GLELoadProc(glMultiTexCoord3f_Impl, glMultiTexCoord3f); + GLELoadProc(glMultiTexCoord3fv_Impl, glMultiTexCoord3fv); + GLELoadProc(glMultiTexCoord3i_Impl, glMultiTexCoord3i); + GLELoadProc(glMultiTexCoord3iv_Impl, glMultiTexCoord3iv); + GLELoadProc(glMultiTexCoord3s_Impl, glMultiTexCoord3s); + GLELoadProc(glMultiTexCoord3sv_Impl, glMultiTexCoord3sv); + GLELoadProc(glMultiTexCoord4d_Impl, glMultiTexCoord4d); + GLELoadProc(glMultiTexCoord4dv_Impl, glMultiTexCoord4dv); + GLELoadProc(glMultiTexCoord4f_Impl, glMultiTexCoord4f); + GLELoadProc(glMultiTexCoord4fv_Impl, glMultiTexCoord4fv); + GLELoadProc(glMultiTexCoord4i_Impl, glMultiTexCoord4i); + GLELoadProc(glMultiTexCoord4iv_Impl, glMultiTexCoord4iv); + GLELoadProc(glMultiTexCoord4s_Impl, glMultiTexCoord4s); + GLELoadProc(glMultiTexCoord4sv_Impl, glMultiTexCoord4sv); + GLELoadProc(glSampleCoverage_Impl, glSampleCoverage); + + // GL_VERSION_1_4 + GLELoadProc(glBlendColor_Impl, glBlendColor); + GLELoadProc(glBlendEquation_Impl, glBlendEquation); + GLELoadProc(glBlendFuncSeparate_Impl, glBlendFuncSeparate); + GLELoadProc(glFogCoordPointer_Impl, glFogCoordPointer); + GLELoadProc(glFogCoordd_Impl, glFogCoordd); + GLELoadProc(glFogCoorddv_Impl, glFogCoorddv); + GLELoadProc(glFogCoordf_Impl, glFogCoordf); + GLELoadProc(glFogCoordfv_Impl, glFogCoordfv); + GLELoadProc(glMultiDrawArrays_Impl, glMultiDrawArrays); + GLELoadProc(glMultiDrawElements_Impl, glMultiDrawElements); + GLELoadProc(glPointParameterf_Impl, glPointParameterf); + GLELoadProc(glPointParameterfv_Impl, glPointParameterfv); + GLELoadProc(glPointParameteri_Impl, glPointParameteri); + GLELoadProc(glPointParameteriv_Impl, glPointParameteriv); + GLELoadProc(glSecondaryColor3b_Impl, glSecondaryColor3b); + GLELoadProc(glSecondaryColor3bv_Impl, glSecondaryColor3bv); + GLELoadProc(glSecondaryColor3d_Impl, glSecondaryColor3d); + GLELoadProc(glSecondaryColor3dv_Impl, glSecondaryColor3dv); + GLELoadProc(glSecondaryColor3f_Impl, glSecondaryColor3f); + GLELoadProc(glSecondaryColor3fv_Impl, glSecondaryColor3fv); + GLELoadProc(glSecondaryColor3i_Impl, glSecondaryColor3i); + GLELoadProc(glSecondaryColor3iv_Impl, glSecondaryColor3iv); + GLELoadProc(glSecondaryColor3s_Impl, glSecondaryColor3s); + GLELoadProc(glSecondaryColor3sv_Impl, glSecondaryColor3sv); + GLELoadProc(glSecondaryColor3ub_Impl, glSecondaryColor3ub); + GLELoadProc(glSecondaryColor3ubv_Impl, glSecondaryColor3ubv); + GLELoadProc(glSecondaryColor3ui_Impl, glSecondaryColor3ui); + GLELoadProc(glSecondaryColor3uiv_Impl, glSecondaryColor3uiv); + GLELoadProc(glSecondaryColor3us_Impl, glSecondaryColor3us); + GLELoadProc(glSecondaryColor3usv_Impl, glSecondaryColor3usv); + GLELoadProc(glSecondaryColorPointer_Impl, glSecondaryColorPointer); + GLELoadProc(glWindowPos2d_Impl, glWindowPos2d); + GLELoadProc(glWindowPos2dv_Impl, glWindowPos2dv); + GLELoadProc(glWindowPos2f_Impl, glWindowPos2f); + GLELoadProc(glWindowPos2fv_Impl, glWindowPos2fv); + GLELoadProc(glWindowPos2i_Impl, glWindowPos2i); + GLELoadProc(glWindowPos2iv_Impl, glWindowPos2iv); + GLELoadProc(glWindowPos2s_Impl, glWindowPos2s); + GLELoadProc(glWindowPos2sv_Impl, glWindowPos2sv); + GLELoadProc(glWindowPos3d_Impl, glWindowPos3d); + GLELoadProc(glWindowPos3dv_Impl, glWindowPos3dv); + GLELoadProc(glWindowPos3f_Impl, glWindowPos3f); + GLELoadProc(glWindowPos3fv_Impl, glWindowPos3fv); + GLELoadProc(glWindowPos3i_Impl, glWindowPos3i); + GLELoadProc(glWindowPos3iv_Impl, glWindowPos3iv); + GLELoadProc(glWindowPos3s_Impl, glWindowPos3s); + GLELoadProc(glWindowPos3sv_Impl, glWindowPos3sv); + + // GL_VERSION_1_5 + GLELoadProc(glBeginQuery_Impl, glBeginQuery); + GLELoadProc(glBindBuffer_Impl, glBindBuffer); + GLELoadProc(glBufferData_Impl, glBufferData); + GLELoadProc(glBufferSubData_Impl, glBufferSubData); + GLELoadProc(glDeleteBuffers_Impl, glDeleteBuffers); + GLELoadProc(glDeleteQueries_Impl, glDeleteQueries); + GLELoadProc(glEndQuery_Impl, glEndQuery); + GLELoadProc(glGenBuffers_Impl, glGenBuffers); + GLELoadProc(glGenQueries_Impl, glGenQueries); + GLELoadProc(glGetBufferParameteriv_Impl, glGetBufferParameteriv); + GLELoadProc(glGetBufferPointerv_Impl, glGetBufferPointerv); + GLELoadProc(glGetBufferSubData_Impl, glGetBufferSubData); + GLELoadProc(glGetQueryObjectiv_Impl, glGetQueryObjectiv); + GLELoadProc(glGetQueryObjectuiv_Impl, glGetQueryObjectuiv); + GLELoadProc(glGetQueryiv_Impl, glGetQueryiv); + GLELoadProc(glIsBuffer_Impl, glIsBuffer); + GLELoadProc(glIsQuery_Impl, glIsQuery); + GLELoadProc(glMapBuffer_Impl, glMapBuffer); + GLELoadProc(glUnmapBuffer_Impl, glUnmapBuffer); + + // GL_VERSION_2_0 + GLELoadProc(glAttachShader_Impl, glAttachShader); + GLELoadProc(glBindAttribLocation_Impl, glBindAttribLocation); + GLELoadProc(glBlendEquationSeparate_Impl, glBlendEquationSeparate); + GLELoadProc(glCompileShader_Impl, glCompileShader); + GLELoadProc(glCreateProgram_Impl, glCreateProgram); + GLELoadProc(glCreateShader_Impl, glCreateShader); + GLELoadProc(glDeleteProgram_Impl, glDeleteProgram); + GLELoadProc(glDeleteShader_Impl, glDeleteShader); + GLELoadProc(glDetachShader_Impl, glDetachShader); + GLELoadProc(glDisableVertexAttribArray_Impl, glDisableVertexAttribArray); + GLELoadProc(glDrawBuffers_Impl, glDrawBuffers); + GLELoadProc(glEnableVertexAttribArray_Impl, glEnableVertexAttribArray); + GLELoadProc(glGetActiveAttrib_Impl, glGetActiveAttrib); + GLELoadProc(glGetActiveUniform_Impl, glGetActiveUniform); + GLELoadProc(glGetAttachedShaders_Impl, glGetAttachedShaders); + GLELoadProc(glGetAttribLocation_Impl, glGetAttribLocation); + GLELoadProc(glGetProgramInfoLog_Impl, glGetProgramInfoLog); + GLELoadProc(glGetProgramiv_Impl, glGetProgramiv); + GLELoadProc(glGetShaderInfoLog_Impl, glGetShaderInfoLog); + GLELoadProc(glGetShaderSource_Impl, glGetShaderSource); + GLELoadProc(glGetShaderiv_Impl, glGetShaderiv); + GLELoadProc(glGetUniformLocation_Impl, glGetUniformLocation); + GLELoadProc(glGetUniformfv_Impl, glGetUniformfv); + GLELoadProc(glGetUniformiv_Impl, glGetUniformiv); + GLELoadProc(glGetVertexAttribPointerv_Impl, glGetVertexAttribPointerv); + GLELoadProc(glGetVertexAttribdv_Impl, glGetVertexAttribdv); + GLELoadProc(glGetVertexAttribfv_Impl, glGetVertexAttribfv); + GLELoadProc(glGetVertexAttribiv_Impl, glGetVertexAttribiv); + GLELoadProc(glIsProgram_Impl, glIsProgram); + GLELoadProc(glIsShader_Impl, glIsShader); + GLELoadProc(glLinkProgram_Impl, glLinkProgram); + GLELoadProc(glShaderSource_Impl, glShaderSource); + GLELoadProc(glStencilFuncSeparate_Impl, glStencilFuncSeparate); + GLELoadProc(glStencilMaskSeparate_Impl, glStencilMaskSeparate); + GLELoadProc(glStencilOpSeparate_Impl, glStencilOpSeparate); + GLELoadProc(glUniform1f_Impl, glUniform1f); + GLELoadProc(glUniform1fv_Impl, glUniform1fv); + GLELoadProc(glUniform1i_Impl, glUniform1i); + GLELoadProc(glUniform1iv_Impl, glUniform1iv); + GLELoadProc(glUniform2f_Impl, glUniform2f); + GLELoadProc(glUniform2fv_Impl, glUniform2fv); + GLELoadProc(glUniform2i_Impl, glUniform2i); + GLELoadProc(glUniform2iv_Impl, glUniform2iv); + GLELoadProc(glUniform3f_Impl, glUniform3f); + GLELoadProc(glUniform3fv_Impl, glUniform3fv); + GLELoadProc(glUniform3i_Impl, glUniform3i); + GLELoadProc(glUniform3iv_Impl, glUniform3iv); + GLELoadProc(glUniform4f_Impl, glUniform4f); + GLELoadProc(glUniform4fv_Impl, glUniform4fv); + GLELoadProc(glUniform4i_Impl, glUniform4i); + GLELoadProc(glUniform4iv_Impl, glUniform4iv); + GLELoadProc(glUniformMatrix2fv_Impl, glUniformMatrix2fv); + GLELoadProc(glUniformMatrix3fv_Impl, glUniformMatrix3fv); + GLELoadProc(glUniformMatrix4fv_Impl, glUniformMatrix4fv); + GLELoadProc(glUseProgram_Impl, glUseProgram); + GLELoadProc(glValidateProgram_Impl, glValidateProgram); + GLELoadProc(glVertexAttrib1d_Impl, glVertexAttrib1d); + GLELoadProc(glVertexAttrib1dv_Impl, glVertexAttrib1dv); + GLELoadProc(glVertexAttrib1f_Impl, glVertexAttrib1f); + GLELoadProc(glVertexAttrib1fv_Impl, glVertexAttrib1fv); + GLELoadProc(glVertexAttrib1s_Impl, glVertexAttrib1s); + GLELoadProc(glVertexAttrib1sv_Impl, glVertexAttrib1sv); + GLELoadProc(glVertexAttrib2d_Impl, glVertexAttrib2d); + GLELoadProc(glVertexAttrib2dv_Impl, glVertexAttrib2dv); + GLELoadProc(glVertexAttrib2f_Impl, glVertexAttrib2f); + GLELoadProc(glVertexAttrib2fv_Impl, glVertexAttrib2fv); + GLELoadProc(glVertexAttrib2s_Impl, glVertexAttrib2s); + GLELoadProc(glVertexAttrib2sv_Impl, glVertexAttrib2sv); + GLELoadProc(glVertexAttrib3d_Impl, glVertexAttrib3d); + GLELoadProc(glVertexAttrib3dv_Impl, glVertexAttrib3dv); + GLELoadProc(glVertexAttrib3f_Impl, glVertexAttrib3f); + GLELoadProc(glVertexAttrib3fv_Impl, glVertexAttrib3fv); + GLELoadProc(glVertexAttrib3s_Impl, glVertexAttrib3s); + GLELoadProc(glVertexAttrib3sv_Impl, glVertexAttrib3sv); + GLELoadProc(glVertexAttrib4Nbv_Impl, glVertexAttrib4Nbv); + GLELoadProc(glVertexAttrib4Niv_Impl, glVertexAttrib4Niv); + GLELoadProc(glVertexAttrib4Nsv_Impl, glVertexAttrib4Nsv); + GLELoadProc(glVertexAttrib4Nub_Impl, glVertexAttrib4Nub); + GLELoadProc(glVertexAttrib4Nubv_Impl, glVertexAttrib4Nubv); + GLELoadProc(glVertexAttrib4Nuiv_Impl, glVertexAttrib4Nuiv); + GLELoadProc(glVertexAttrib4Nusv_Impl, glVertexAttrib4Nusv); + GLELoadProc(glVertexAttrib4bv_Impl, glVertexAttrib4bv); + GLELoadProc(glVertexAttrib4d_Impl, glVertexAttrib4d); + GLELoadProc(glVertexAttrib4dv_Impl, glVertexAttrib4dv); + GLELoadProc(glVertexAttrib4f_Impl, glVertexAttrib4f); + GLELoadProc(glVertexAttrib4fv_Impl, glVertexAttrib4fv); + GLELoadProc(glVertexAttrib4iv_Impl, glVertexAttrib4iv); + GLELoadProc(glVertexAttrib4s_Impl, glVertexAttrib4s); + GLELoadProc(glVertexAttrib4sv_Impl, glVertexAttrib4sv); + GLELoadProc(glVertexAttrib4ubv_Impl, glVertexAttrib4ubv); + GLELoadProc(glVertexAttrib4uiv_Impl, glVertexAttrib4uiv); + GLELoadProc(glVertexAttrib4usv_Impl, glVertexAttrib4usv); + GLELoadProc(glVertexAttribPointer_Impl, glVertexAttribPointer); + + // GL_VERSION_2_1 + GLELoadProc(glUniformMatrix2x3fv_Impl, glUniformMatrix2x3fv); + GLELoadProc(glUniformMatrix2x4fv_Impl, glUniformMatrix2x4fv); + GLELoadProc(glUniformMatrix3x2fv_Impl, glUniformMatrix3x2fv); + GLELoadProc(glUniformMatrix3x4fv_Impl, glUniformMatrix3x4fv); + GLELoadProc(glUniformMatrix4x2fv_Impl, glUniformMatrix4x2fv); + GLELoadProc(glUniformMatrix4x3fv_Impl, glUniformMatrix4x3fv); + + // GL_VERSION_3_0 + GLELoadProc(glBeginConditionalRender_Impl, glBeginConditionalRender); + GLELoadProc(glBeginTransformFeedback_Impl, glBeginTransformFeedback); + GLELoadProc(glBindFragDataLocation_Impl, glBindFragDataLocation); + GLELoadProc(glClampColor_Impl, glClampColor); + GLELoadProc(glClearBufferfi_Impl, glClearBufferfi); + GLELoadProc(glClearBufferfv_Impl, glClearBufferfv); + GLELoadProc(glClearBufferiv_Impl, glClearBufferiv); + GLELoadProc(glClearBufferuiv_Impl, glClearBufferuiv); + GLELoadProc(glColorMaski_Impl, glColorMaski); + GLELoadProc(glDisablei_Impl, glDisablei); + GLELoadProc(glEnablei_Impl, glEnablei); + GLELoadProc(glEndConditionalRender_Impl, glEndConditionalRender); + GLELoadProc(glEndTransformFeedback_Impl, glEndTransformFeedback); + GLELoadProc(glBindBufferRange_Impl, glBindBufferRange); + GLELoadProc(glBindBufferBase_Impl, glBindBufferBase); + GLELoadProc(glGetBooleani_v_Impl, glGetBooleani_v); + GLELoadProc(glGetIntegeri_v_Impl, glGetIntegeri_v); + GLELoadProc(glGetFragDataLocation_Impl, glGetFragDataLocation); + GLELoadProc(glGetStringi_Impl, glGetStringi); + GLELoadProc(glGetTexParameterIiv_Impl, glGetTexParameterIiv); + GLELoadProc(glGetTexParameterIuiv_Impl, glGetTexParameterIuiv); + GLELoadProc(glGetTransformFeedbackVarying_Impl, glGetTransformFeedbackVarying); + GLELoadProc(glGetUniformuiv_Impl, glGetUniformuiv); + GLELoadProc(glGetVertexAttribIiv_Impl, glGetVertexAttribIiv); + GLELoadProc(glGetVertexAttribIuiv_Impl, glGetVertexAttribIuiv); + GLELoadProc(glIsEnabledi_Impl, glIsEnabledi); + GLELoadProc(glTexParameterIiv_Impl, glTexParameterIiv); + GLELoadProc(glTexParameterIuiv_Impl, glTexParameterIuiv); + GLELoadProc(glTransformFeedbackVaryings_Impl, glTransformFeedbackVaryings); + GLELoadProc(glUniform1ui_Impl, glUniform1ui); + GLELoadProc(glUniform1uiv_Impl, glUniform1uiv); + GLELoadProc(glUniform2ui_Impl, glUniform2ui); + GLELoadProc(glUniform2uiv_Impl, glUniform2uiv); + GLELoadProc(glUniform3ui_Impl, glUniform3ui); + GLELoadProc(glUniform3uiv_Impl, glUniform3uiv); + GLELoadProc(glUniform4ui_Impl, glUniform4ui); + GLELoadProc(glUniform4uiv_Impl, glUniform4uiv); + GLELoadProc(glVertexAttribI1i_Impl, glVertexAttribI1i); + GLELoadProc(glVertexAttribI1iv_Impl, glVertexAttribI1iv); + GLELoadProc(glVertexAttribI1ui_Impl, glVertexAttribI1ui); + GLELoadProc(glVertexAttribI1uiv_Impl, glVertexAttribI1uiv); + GLELoadProc(glVertexAttribI2i_Impl, glVertexAttribI2i); + GLELoadProc(glVertexAttribI2iv_Impl, glVertexAttribI2iv); + GLELoadProc(glVertexAttribI2ui_Impl, glVertexAttribI2ui); + GLELoadProc(glVertexAttribI2uiv_Impl, glVertexAttribI2uiv); + GLELoadProc(glVertexAttribI3i_Impl, glVertexAttribI3i); + GLELoadProc(glVertexAttribI3iv_Impl, glVertexAttribI3iv); + GLELoadProc(glVertexAttribI3ui_Impl, glVertexAttribI3ui); + GLELoadProc(glVertexAttribI3uiv_Impl, glVertexAttribI3uiv); + GLELoadProc(glVertexAttribI4bv_Impl, glVertexAttribI4bv); + GLELoadProc(glVertexAttribI4i_Impl, glVertexAttribI4i); + GLELoadProc(glVertexAttribI4iv_Impl, glVertexAttribI4iv); + GLELoadProc(glVertexAttribI4sv_Impl, glVertexAttribI4sv); + GLELoadProc(glVertexAttribI4ubv_Impl, glVertexAttribI4ubv); + GLELoadProc(glVertexAttribI4ui_Impl, glVertexAttribI4ui); + GLELoadProc(glVertexAttribI4uiv_Impl, glVertexAttribI4uiv); + GLELoadProc(glVertexAttribI4usv_Impl, glVertexAttribI4usv); + GLELoadProc(glVertexAttribIPointer_Impl, glVertexAttribIPointer); + + // GL_VERSION_3_1 + GLELoadProc(glDrawArraysInstanced_Impl, glDrawArraysInstanced); + GLELoadProc(glDrawElementsInstanced_Impl, glDrawElementsInstanced); + GLELoadProc(glPrimitiveRestartIndex_Impl, glPrimitiveRestartIndex); + GLELoadProc(glTexBuffer_Impl, glTexBuffer); + + // GL_VERSION_3_2 + GLELoadProc(glFramebufferTexture_Impl, glFramebufferTexture); + GLELoadProc(glGetBufferParameteri64v_Impl, glGetBufferParameteri64v); + GLELoadProc(glGetInteger64i_v_Impl, glGetInteger64i_v); + + // GL_VERSION_3_3 + GLELoadProc(glVertexAttribDivisor_Impl, glVertexAttribDivisor); + + // GL_VERSION_4_0 + GLELoadProc(glBlendEquationSeparatei_Impl, glBlendEquationSeparatei); + GLELoadProc(glBlendEquationi_Impl, glBlendEquationi); + GLELoadProc(glBlendFuncSeparatei_Impl, glBlendFuncSeparatei); + GLELoadProc(glBlendFunci_Impl, glBlendFunci); + GLELoadProc(glMinSampleShading_Impl, glMinSampleShading); + + // GL_AMD_debug_output + GLELoadProc(glDebugMessageCallbackAMD_Impl, glDebugMessageCallbackAMD); + GLELoadProc(glDebugMessageEnableAMD_Impl, glDebugMessageEnableAMD); + GLELoadProc(glDebugMessageInsertAMD_Impl, glDebugMessageInsertAMD); + GLELoadProc(glGetDebugMessageLogAMD_Impl, glGetDebugMessageLogAMD); + + #if defined(GLE_CGL_ENABLED) + // GL_APPLE_element_array + GLELoadProc(glDrawElementArrayAPPLE_Impl, glDrawElementArrayAPPLE); + GLELoadProc(glDrawRangeElementArrayAPPLE_Impl, glDrawRangeElementArrayAPPLE); + GLELoadProc(glElementPointerAPPLE_Impl, glElementPointerAPPLE); + GLELoadProc(glMultiDrawElementArrayAPPLE_Impl, glMultiDrawElementArrayAPPLE); + GLELoadProc(glMultiDrawRangeElementArrayAPPLE_Impl, glMultiDrawRangeElementArrayAPPLE); + + // GL_APPLE_fence + GLELoadProc(glDeleteFencesAPPLE_Impl, glDeleteFencesAPPLE); + GLELoadProc(glFinishFenceAPPLE_Impl, glFinishFenceAPPLE); + GLELoadProc(glFinishObjectAPPLE_Impl, glFinishObjectAPPLE); + GLELoadProc(glGenFencesAPPLE_Impl, glGenFencesAPPLE); + GLELoadProc(glIsFenceAPPLE_Impl, glIsFenceAPPLE); + GLELoadProc(glSetFenceAPPLE_Impl, glSetFenceAPPLE); + GLELoadProc(glTestFenceAPPLE_Impl, glTestFenceAPPLE); + GLELoadProc(glTestObjectAPPLE_Impl, glTestObjectAPPLE); + + // GL_APPLE_flush_buffer_range + GLELoadProc(glBufferParameteriAPPLE_Impl, glMultiDrawRangeElementArrayAPPLE); + GLELoadProc(glFlushMappedBufferRangeAPPLE_Impl, glFlushMappedBufferRangeAPPLE); + + // GL_APPLE_object_purgeable + GLELoadProc(glGetObjectParameterivAPPLE_Impl, glGetObjectParameterivAPPLE); + GLELoadProc(glObjectPurgeableAPPLE_Impl, glObjectPurgeableAPPLE); + GLELoadProc(glObjectUnpurgeableAPPLE_Impl, glObjectUnpurgeableAPPLE); + + // GL_APPLE_texture_range + GLELoadProc(glGetTexParameterPointervAPPLE_Impl, glGetTexParameterPointervAPPLE); + GLELoadProc(glTextureRangeAPPLE_Impl, glTextureRangeAPPLE); + + // GL_APPLE_vertex_array_object + GLELoadProc(glBindVertexArrayAPPLE_Impl, glBindVertexArrayAPPLE); + GLELoadProc(glDeleteVertexArraysAPPLE_Impl, glDeleteVertexArraysAPPLE); + GLELoadProc(glGenVertexArraysAPPLE_Impl, glGenVertexArraysAPPLE); + GLELoadProc(glIsVertexArrayAPPLE_Impl, glIsVertexArrayAPPLE); + + // GL_APPLE_vertex_array_range + GLELoadProc(glFlushVertexArrayRangeAPPLE_Impl, glFlushVertexArrayRangeAPPLE); + GLELoadProc(glVertexArrayParameteriAPPLE_Impl, glVertexArrayParameteriAPPLE); + GLELoadProc(glVertexArrayRangeAPPLE_Impl, glVertexArrayRangeAPPLE); + + // GL_APPLE_vertex_program_evaluators + GLELoadProc(glDisableVertexAttribAPPLE_Impl, glDisableVertexAttribAPPLE); + GLELoadProc(glEnableVertexAttribAPPLE_Impl, glEnableVertexAttribAPPLE); + GLELoadProc(glIsVertexAttribEnabledAPPLE_Impl, glIsVertexAttribEnabledAPPLE); + GLELoadProc(glMapVertexAttrib1dAPPLE_Impl, glMapVertexAttrib1dAPPLE); + GLELoadProc(glMapVertexAttrib1fAPPLE_Impl, glMapVertexAttrib1fAPPLE); + GLELoadProc(glMapVertexAttrib2dAPPLE_Impl, glMapVertexAttrib2dAPPLE); + GLELoadProc(glMapVertexAttrib2fAPPLE_Impl, glMapVertexAttrib2fAPPLE); + + #endif // GLE_CGL_ENABLED + + // GL_ARB_copy_buffer + GLELoadProc(glCopyBufferSubData_Impl, glCopyBufferSubData); + + // GL_ARB_debug_output + GLELoadProc(glDebugMessageCallbackARB_Impl, glDebugMessageCallbackARB); + GLELoadProc(glDebugMessageControlARB_Impl, glDebugMessageControlARB); + GLELoadProc(glDebugMessageInsertARB_Impl, glDebugMessageInsertARB); + GLELoadProc(glGetDebugMessageLogARB_Impl, glGetDebugMessageLogARB); + + // GL_ARB_ES2_compatibility + GLELoadProc(glClearDepthf_Impl, glClearDepthf); + GLELoadProc(glDepthRangef_Impl, glDepthRangef); + GLELoadProc(glGetShaderPrecisionFormat_Impl, glGetShaderPrecisionFormat); + GLELoadProc(glReleaseShaderCompiler_Impl, glReleaseShaderCompiler); + GLELoadProc(glShaderBinary_Impl, glShaderBinary); + + // GL_ARB_framebuffer_object + GLELoadProc(glBindFramebuffer_Impl, glBindFramebuffer); + GLELoadProc(glBindRenderbuffer_Impl, glBindRenderbuffer); + GLELoadProc(glBlitFramebuffer_Impl, glBlitFramebuffer); + GLELoadProc(glCheckFramebufferStatus_Impl, glCheckFramebufferStatus); + GLELoadProc(glDeleteFramebuffers_Impl, glDeleteFramebuffers); + GLELoadProc(glDeleteRenderbuffers_Impl, glDeleteRenderbuffers); + GLELoadProc(glFramebufferRenderbuffer_Impl, glFramebufferRenderbuffer); + GLELoadProc(glFramebufferTexture1D_Impl, glFramebufferTexture1D); + GLELoadProc(glFramebufferTexture2D_Impl, glFramebufferTexture2D); + GLELoadProc(glFramebufferTexture3D_Impl, glFramebufferTexture3D); + GLELoadProc(glFramebufferTextureLayer_Impl, glFramebufferTextureLayer); + GLELoadProc(glGenFramebuffers_Impl, glGenFramebuffers); + GLELoadProc(glGenRenderbuffers_Impl, glGenRenderbuffers); + GLELoadProc(glGenerateMipmap_Impl, glGenerateMipmap); + GLELoadProc(glGetFramebufferAttachmentParameteriv_Impl, glGetFramebufferAttachmentParameteriv); + GLELoadProc(glGetRenderbufferParameteriv_Impl, glGetRenderbufferParameteriv); + GLELoadProc(glIsFramebuffer_Impl, glIsFramebuffer); + GLELoadProc(glIsRenderbuffer_Impl, glIsRenderbuffer); + GLELoadProc(glRenderbufferStorage_Impl, glRenderbufferStorage); + GLELoadProc(glRenderbufferStorageMultisample_Impl, glRenderbufferStorageMultisample); + + if(!glBindFramebuffer_Impl) // This will rarely if ever be the case in practice with modern computers and drivers. + { + // See if we can map GL_EXT_framebuffer_object to GL_ARB_framebuffer_object. The former is basically a subset of the latter, but we use only that subset. + GLELoadProc(glBindFramebuffer_Impl, glBindFramebufferEXT); + GLELoadProc(glBindRenderbuffer_Impl, glBindRenderbufferEXT); + //GLELoadProc(glBlitFramebuffer_Impl, glBlitFramebufferEXT (nonexistent)); + GLELoadProc(glCheckFramebufferStatus_Impl, glCheckFramebufferStatusEXT); + GLELoadProc(glDeleteFramebuffers_Impl, glDeleteFramebuffersEXT); + GLELoadProc(glDeleteRenderbuffers_Impl, glDeleteRenderbuffersEXT); + GLELoadProc(glFramebufferRenderbuffer_Impl, glFramebufferRenderbufferEXT); + GLELoadProc(glFramebufferTexture1D_Impl, glFramebufferTexture1DEXT); + GLELoadProc(glFramebufferTexture2D_Impl, glFramebufferTexture2DEXT); + GLELoadProc(glFramebufferTexture3D_Impl, glFramebufferTexture3DEXT); + //GLELoadProc(glFramebufferTextureLayer_Impl, glFramebufferTextureLayerEXT (nonexistent)); + GLELoadProc(glGenFramebuffers_Impl, glGenFramebuffersEXT); + GLELoadProc(glGenRenderbuffers_Impl, glGenRenderbuffersEXT); + GLELoadProc(glGenerateMipmap_Impl, glGenerateMipmapEXT); + GLELoadProc(glGetFramebufferAttachmentParameteriv_Impl, glGetFramebufferAttachmentParameterivEXT); + GLELoadProc(glGetRenderbufferParameteriv_Impl, glGetRenderbufferParameterivEXT); + GLELoadProc(glIsFramebuffer_Impl, glIsFramebufferEXT); + GLELoadProc(glIsRenderbuffer_Impl, glIsRenderbufferEXT); + GLELoadProc(glRenderbufferStorage_Impl, glRenderbufferStorageEXT); + //GLELoadProc(glRenderbufferStorageMultisample_Impl, glRenderbufferStorageMultisampleEXT (nonexistent)); + } + + // GL_ARB_texture_multisample + GLELoadProc(glGetMultisamplefv_Impl, glGetMultisamplefv); + GLELoadProc(glSampleMaski_Impl, glSampleMaski); + GLELoadProc(glTexImage2DMultisample_Impl, glTexImage2DMultisample); + GLELoadProc(glTexImage3DMultisample_Impl, glTexImage3DMultisample); + + // GL_ARB_timer_query + GLELoadProc(glGetQueryObjecti64v_Impl, glGetQueryObjecti64v); + GLELoadProc(glGetQueryObjectui64v_Impl, glGetQueryObjectui64v); + GLELoadProc(glQueryCounter_Impl, glQueryCounter); + + // GL_ARB_vertex_array_object + GLELoadProc(glBindVertexArray_Impl, glBindVertexArray); + GLELoadProc(glDeleteVertexArrays_Impl, glDeleteVertexArrays); + GLELoadProc(glGenVertexArrays_Impl, glGenVertexArrays); + GLELoadProc(glIsVertexArray_Impl, glIsVertexArray); + + #if defined(GLE_CGL_ENABLED) // Apple OpenGL... + if(WholeVersion < 302) // It turns out that Apple OpenGL versions prior to 3.2 have glBindVertexArray, etc. but they silently fail by default. So always use the APPLE version. + { + glBindVertexArray_Impl = glBindVertexArrayAPPLE_Impl; + glDeleteVertexArrays_Impl = glDeleteVertexArraysAPPLE_Impl; + glGenVertexArrays_Impl = (OVRTypeof(glGenVertexArrays_Impl)) glGenVertexArraysAPPLE_Impl; // There is a const cast of the arrays argument here due to a slight difference in the Apple behavior. For our purposes it should be OK. + glIsVertexArray_Impl = glIsVertexArrayAPPLE_Impl; + + if(glBindVertexArray_Impl) + gle_ARB_vertex_array_object = true; // We are routing the APPLE version through our version, with the assumption that we use the ARB version the same as we would use the APPLE version. + } + #endif + + // GL_EXT_draw_buffers2 + GLELoadProc(glColorMaskIndexedEXT_Impl, glColorMaskIndexedEXT); + GLELoadProc(glDisableIndexedEXT_Impl, glDisableIndexedEXT); + GLELoadProc(glEnableIndexedEXT_Impl, glEnableIndexedEXT); + GLELoadProc(glGetBooleanIndexedvEXT_Impl, glGetBooleanIndexedvEXT); + GLELoadProc(glGetIntegerIndexedvEXT_Impl, glGetIntegerIndexedvEXT); + GLELoadProc(glIsEnabledIndexedEXT_Impl, glIsEnabledIndexedEXT); + + // GL_KHR_debug + GLELoadProc(glDebugMessageCallback_Impl, glDebugMessageCallback); + GLELoadProc(glDebugMessageControl_Impl, glDebugMessageControl); + GLELoadProc(glDebugMessageInsert_Impl, glDebugMessageInsert); + GLELoadProc(glGetDebugMessageLog_Impl, glGetDebugMessageLog); + GLELoadProc(glGetObjectLabel_Impl, glGetObjectLabel); + GLELoadProc(glGetObjectPtrLabel_Impl, glGetObjectPtrLabel); + GLELoadProc(glObjectLabel_Impl, glObjectLabel); + GLELoadProc(glObjectPtrLabel_Impl, glObjectPtrLabel); + GLELoadProc(glPopDebugGroup_Impl, glPopDebugGroup); + GLELoadProc(glPushDebugGroup_Impl, glPushDebugGroup); + + // GL_WIN_swap_hint + GLELoadProc(glAddSwapHintRectWIN_Impl, glAddSwapHintRectWIN); + } + + + + OVR_DISABLE_MSVC_WARNING(4510 4512 4610) // default constructor could not be generated, + struct ValueStringPair + { + bool& IsPresent; + const char* ExtensionName; + }; + + + // Helper function for InitExtensionSupport. + static void CheckExtensions(ValueStringPair* pValueStringPairArray, size_t arrayCount, const char* extensions) + { + // We search the extesion list string for each of the individual extensions we are interested in. + // We do this by walking over the string and comparing each entry in turn to our array of entries of interest. + // Example string (with patholigical extra spaces): " ext1 ext2 ext3 " + + char extension[64]; + const char* p = extensions; // p points to the beginning of the current word + const char* pEnd; // pEnd points to one-past the last character of the current word. It is where the trailing '\0' of the string would be. + + while(*p) + { + while(*p == ' ') // Find the next word begin. + ++p; + + pEnd = p; + + while((*pEnd != '\0') && (*pEnd != ' ')) // Find the next word end. + ++pEnd; + + if(((pEnd - p) > 0) && ((size_t)(pEnd - p) < OVR_ARRAY_COUNT(extension))) + { + memcpy(extension, p, pEnd - p); // To consider: Revise this code to directly read from p/pEnd instead of doing a memcpy. + extension[pEnd - p] = '\0'; + + for(size_t i = 0; i < arrayCount; i++) // For each extension we are interested in... + { + ValueStringPair& vsp = pValueStringPairArray[i]; + + if(strcmp(extension, vsp.ExtensionName) == 0) // case-sensitive compare + pValueStringPairArray[i].IsPresent = true; + } + } + + p = pEnd; + } + } + + + void OVR::GLEContext::InitExtensionSupport() + { + // It may be better in the long run to use a member STL map. + // It would make this loading code cleaner, though it would make lookups slower. + + ValueStringPair vspArray[] = + { + { gle_AMD_debug_output, "GL_AMD_debug_output" }, + #if defined(GLE_CGL_ENABLED) + { gle_APPLE_aux_depth_stencil, "GL_APPLE_aux_depth_stencil" }, + { gle_APPLE_client_storage, "GL_APPLE_client_storage" }, + { gle_APPLE_element_array, "GL_APPLE_element_array" }, + { gle_APPLE_fence, "GL_APPLE_fence" }, + { gle_APPLE_float_pixels, "GL_APPLE_float_pixels" }, + { gle_APPLE_flush_buffer_range, "GL_APPLE_flush_buffer_range" }, + { gle_APPLE_object_purgeable, "GL_APPLE_object_purgeable" }, + { gle_APPLE_pixel_buffer, "GL_APPLE_pixel_buffer" }, + { gle_APPLE_rgb_422, "GL_APPLE_rgb_422" }, + { gle_APPLE_row_bytes, "GL_APPLE_row_bytes" }, + { gle_APPLE_specular_vector, "GL_APPLE_specular_vector" }, + { gle_APPLE_texture_range, "GL_APPLE_texture_range" }, + { gle_APPLE_transform_hint, "GL_APPLE_transform_hint" }, + { gle_APPLE_vertex_array_object, "GL_APPLE_vertex_array_object" }, + { gle_APPLE_vertex_array_range, "GL_APPLE_vertex_array_range" }, + { gle_APPLE_vertex_program_evaluators, "GL_APPLE_vertex_program_evaluators" }, + { gle_APPLE_ycbcr_422, "GL_APPLE_ycbcr_422" }, + #endif + { gle_ARB_copy_buffer, "GL_ARB_copy_buffer" }, + { gle_ARB_debug_output, "GL_ARB_debug_output" }, + { gle_ARB_depth_buffer_float, "GL_ARB_depth_buffer_float" }, + { gle_ARB_ES2_compatibility, "GL_ARB_ES2_compatibility" }, + { gle_ARB_framebuffer_object, "GL_ARB_framebuffer_object" }, + { gle_ARB_framebuffer_object, "GL_EXT_framebuffer_object" }, // We map glBindFramebuffer, etc. to glBindFramebufferEXT, etc. if necessary + { gle_ARB_framebuffer_sRGB, "GL_ARB_framebuffer_sRGB" }, + { gle_ARB_texture_multisample, "GL_ARB_texture_multisample" }, + { gle_ARB_texture_non_power_of_two, "GL_ARB_texture_non_power_of_two" }, + { gle_ARB_texture_rectangle, "GL_ARB_texture_rectangle" }, + { gle_ARB_texture_rectangle, "GL_EXT_texture_rectangle" }, // We also check for GL_EXT_texture_rectangle and GL_NV_texture_rectangle. + { gle_ARB_texture_rectangle, "GL_NV_texture_rectangle" }, + { gle_ARB_timer_query, "GL_ARB_timer_query" }, + { gle_ARB_vertex_array_object, "GL_ARB_vertex_array_object" }, + { gle_EXT_draw_buffers2, "GL_EXT_draw_buffers2" }, + { gle_EXT_texture_compression_s3tc, "GL_EXT_texture_compression_s3tc" }, + { gle_EXT_texture_filter_anisotropic, "GL_EXT_texture_filter_anisotropic" }, + { gle_KHR_debug, "GL_KHR_debug" }, + { gle_WIN_swap_hint, "GL_WIN_swap_hint" } + // Windows WGL, Unix GLX, and Apple CGL extensions are handled below, as they require different calls from glGetString(GL_EXTENSIONS). + }; + + // We cannot use glGetString(GL_EXTENSIONS) when an OpenGL core profile is active, + // as it's deprecated in favor of using OpenGL 3+ glGetStringi. + const char* extensions = (MajorVersion < 3) ? (const char*)glGetString(GL_EXTENSIONS) : ""; + + if (extensions && *extensions) // If we have a space-delimited extension string to search for individual extensions... + { + OVR_DEBUG_LOG(("GL_EXTENSIONS: %s", (const char*)extensions)); + CheckExtensions(vspArray, OVR_ARRAY_COUNT(vspArray), extensions); // Call our shared helper function for this. + } + else + { + if(MajorVersion >= 3) // If glGetIntegerv(GL_NUM_EXTENSIONS, ...) is supported... + { + // In this case we need to match an array of individual extensions against an array of + // externsions provided by glGetStringi. This is an O(n^2) operation, but at least we + // are doing this only once on startup. There are a few tricks we can employ to speed + // up the logic below, but they may not be worth much. + + GLint extensionCount = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &extensionCount); + GLenum err = glGetError(); + + if(err == 0) + { + #ifdef OVR_BUILD_DEBUG + OVR::StringBuffer extensionsStr; + #endif + + for(GLint e = 0; e != extensionCount; ++e) // For each extension supported... + { + const char* extension = (const char*)glGetStringi(GL_EXTENSIONS, (GLuint)e); + + if(extension) // glGetStringi returns NULL upon error. + { + #ifdef OVR_BUILD_DEBUG + extensionsStr.AppendFormat(" %s", extension); + #endif + + for(size_t i = 0; i < OVR_ARRAY_COUNT(vspArray); i++) // For each extension we are interested in... + { + ValueStringPair& vsp = vspArray[i]; + + if(strcmp(extension, vsp.ExtensionName) == 0) // case-sensitive compare + vspArray[i].IsPresent = true; + } + } + else + break; + } + + OVR_DEBUG_LOG(("GL_EXTENSIONS: %s", extensionsStr.ToCStr())); + } + } + // Else we have a problem: no means to read the extensions was successful. + } + + #if defined(GLE_CGL_ENABLED) + // The following are built into Apple OpenGL 3.2+ (declared in ) and not identified as extensions. + // On other platforms (e.g. Windows) these are identified as extensions and are detected above. + if(WholeVersion >= 302) + { + gle_ARB_copy_buffer = true; + gle_ARB_depth_buffer_float = true; + gle_ARB_framebuffer_object = true; + gle_ARB_framebuffer_sRGB = true; + gle_ARB_texture_multisample = true; + gle_ARB_texture_non_power_of_two = true; + gle_ARB_texture_rectangle = true; + gle_ARB_vertex_array_object = true; + } + #endif + + } // GLEContext::InitExtensionSupport() + + + void OVR::GLEContext::InitPlatformVersion() + { + #if defined(GLE_GLX_ENABLED) + const char* pGLXVersion = glXGetClientString(glXGetCurrentDisplay(), GLX_VERSION); // To do: Use a better mechanism to get the desired display. + sscanf(pGLXVersion, "%d.%d", &PlatformMajorVersion, &PlatformMinorVersion); + + #elif defined(GLE_EGL_ENABLED) + const char* pEGLVersion = eglQueryString(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_VERSION); + sscanf(pEGLVersion, "%d.%d", &PlatformMajorVersion, &PlatformMinorVersion); + + #else + PlatformMajorVersion = 1; + PlatformMinorVersion = 0; + PlatformWholeVersion = 100; + #endif + } + + + void OVR::GLEContext::InitPlatformExtensionLoad() + { + #if defined(GLE_WGL_ENABLED) + // WGL + // We don't load these as function pointers but rather statically link to them. + // These need to be loaded via LoadLibrary instead of wglLoadLibrary. + + #if 0 + HINSTANCE hOpenGL = LoadLibraryW(L"Opengl32.dll"); + if(hOpenGL) + { + wglCopyContext_Impl = (OVRTypeof(wglCopyContext_Impl)) GetProcAddress(hOpenGL, "wglCopyContext"); + wglCreateContext_Impl = (OVRTypeof(wglCreateContext_Impl)) GetProcAddress(hOpenGL, "wglCreateContext"); + wglCreateLayerContext_Impl = (OVRTypeof(wglCreateLayerContext_Impl)) GetProcAddress(hOpenGL, "wglCreateLayerContext"); + wglDeleteContext_Impl = (OVRTypeof(wglDeleteContext_Impl)) GetProcAddress(hOpenGL, "wglDeleteContext"); + wglGetCurrentContext_Impl = (OVRTypeof(wglGetCurrentContext_Impl)) GetProcAddress(hOpenGL, "wglGetCurrentContext"); + wglGetCurrentDC_Impl = (OVRTypeof(wglGetCurrentDC_Impl)) GetProcAddress(hOpenGL, "wglGetCurrentDC"); + wglGetProcAddress_Impl = (OVRTypeof(wglGetProcAddress_Impl)) GetProcAddress(hOpenGL, "wglGetProcAddress"); + wglMakeCurrent_Impl = (OVRTypeof(wglMakeCurrent_Impl)) GetProcAddress(hOpenGL, "wglMakeCurrent"); + wglShareLists_Impl = (OVRTypeof(wglShareLists_Impl)) GetProcAddress(hOpenGL, "wglShareLists"); + wglUseFontBitmapsA_Impl = (OVRTypeof(wglUseFontBitmapsA_Impl)) GetProcAddress(hOpenGL, "wglUseFontBitmapsA"); + wglUseFontBitmapsW_Impl = (OVRTypeof(wglUseFontBitmapsW_Impl)) GetProcAddress(hOpenGL, "wglUseFontBitmapsW"); + wglUseFontOutlinesA_Impl = (OVRTypeof(wglUseFontOutlinesA_Impl)) GetProcAddress(hOpenGL, "wglUseFontOutlinesA"); + wglUseFontOutlinesW_Impl = (OVRTypeof(wglUseFontOutlinesW_Impl)) GetProcAddress(hOpenGL, "wglUseFontOutlinesW"); + wglDescribeLayerPlane_Impl = (OVRTypeof(wglDescribeLayerPlane_Impl)) GetProcAddress(hOpenGL, "wglDescribeLayerPlane"); + wglSetLayerPaletteEntries_Impl = (OVRTypeof(wglSetLayerPaletteEntries_Impl)) GetProcAddress(hOpenGL, "wglSetLayerPaletteEntries"); + wglGetLayerPaletteEntries_Impl = (OVRTypeof(wglGetLayerPaletteEntries_Impl)) GetProcAddress(hOpenGL, "wglGetLayerPaletteEntries"); + wglRealizeLayerPalette_Impl = (OVRTypeof(wglRealizeLayerPalette_Impl)) GetProcAddress(hOpenGL, "wglRealizeLayerPalette"); + wglSwapLayerBuffers_Impl = (OVRTypeof(wglSwapLayerBuffers_Impl)) GetProcAddress(hOpenGL, "wglSwapLayerBuffers"); + wglSwapMultipleBuffers_Impl = (OVRTypeof(wglSwapMultipleBuffers_Impl)) GetProcAddress(hOpenGL, "wglSwapMultipleBuffers"); + FreeLibrary(hOpenGL); + } + #endif + + // WGL_ARB_buffer_region + GLELoadProc(wglCreateBufferRegionARB_Impl, wglCreateBufferRegionARB); + GLELoadProc(wglDeleteBufferRegionARB_Impl, wglDeleteBufferRegionARB); + GLELoadProc(wglSaveBufferRegionARB_Impl, wglSaveBufferRegionARB); + GLELoadProc(wglRestoreBufferRegionARB_Impl, wglRestoreBufferRegionARB); + + // WGL_ARB_extensions_string + GLELoadProc(wglGetExtensionsStringARB_Impl, wglGetExtensionsStringARB); + + // WGL_ARB_pixel_format + GLELoadProc(wglGetPixelFormatAttribivARB_Impl, wglGetPixelFormatAttribivARB); + GLELoadProc(wglGetPixelFormatAttribfvARB_Impl, wglGetPixelFormatAttribfvARB); + GLELoadProc(wglChoosePixelFormatARB_Impl, wglChoosePixelFormatARB); + + // WGL_ARB_make_current_read + GLELoadProc(wglMakeContextCurrentARB_Impl, wglMakeContextCurrentARB); + GLELoadProc(wglGetCurrentReadDCARB_Impl, wglGetCurrentReadDCARB); + + // WGL_ARB_pbuffer + GLELoadProc(wglCreatePbufferARB_Impl, wglCreatePbufferARB); + GLELoadProc(wglGetPbufferDCARB_Impl, wglGetPbufferDCARB); + GLELoadProc(wglReleasePbufferDCARB_Impl, wglReleasePbufferDCARB); + GLELoadProc(wglDestroyPbufferARB_Impl, wglDestroyPbufferARB); + GLELoadProc(wglQueryPbufferARB_Impl, wglQueryPbufferARB); + + // WGL_ARB_render_texture + GLELoadProc(wglBindTexImageARB_Impl, wglBindTexImageARB); + GLELoadProc(wglReleaseTexImageARB_Impl, wglReleaseTexImageARB); + GLELoadProc(wglSetPbufferAttribARB_Impl, wglSetPbufferAttribARB); + + // WGL_NV_present_video + GLELoadProc(wglEnumerateVideoDevicesNV_Impl, wglEnumerateVideoDevicesNV); + GLELoadProc(wglBindVideoDeviceNV_Impl, wglBindVideoDeviceNV); + GLELoadProc(wglQueryCurrentContextNV_Impl, wglQueryCurrentContextNV); + + // WGL_ARB_create_context + GLELoadProc(wglCreateContextAttribsARB_Impl, wglCreateContextAttribsARB); + + // WGL_EXT_extensions_string + GLELoadProc(wglGetExtensionsStringEXT_Impl, wglGetExtensionsStringEXT); + + // WGL_EXT_swap_control + GLELoadProc(wglGetSwapIntervalEXT_Impl, wglGetSwapIntervalEXT); + GLELoadProc(wglSwapIntervalEXT_Impl, wglSwapIntervalEXT); + + // WGL_OML_sync_control + GLELoadProc(wglGetSyncValuesOML_Impl, wglGetSyncValuesOML); + GLELoadProc(wglGetMscRateOML_Impl, wglGetMscRateOML); + GLELoadProc(wglSwapBuffersMscOML_Impl, wglSwapBuffersMscOML); + GLELoadProc(wglSwapLayerBuffersMscOML_Impl, wglSwapLayerBuffersMscOML); + GLELoadProc(wglWaitForMscOML_Impl, wglWaitForMscOML); + GLELoadProc(wglWaitForSbcOML_Impl, wglWaitForSbcOML); + + // WGL_NV_video_output + GLELoadProc(wglGetVideoDeviceNV_Impl, wglGetVideoDeviceNV); + GLELoadProc(wglReleaseVideoDeviceNV_Impl, wglReleaseVideoDeviceNV); + GLELoadProc(wglBindVideoImageNV_Impl, wglBindVideoImageNV); + GLELoadProc(wglReleaseVideoImageNV_Impl, wglReleaseVideoImageNV); + GLELoadProc(wglSendPbufferToVideoNV_Impl, wglSendPbufferToVideoNV); + GLELoadProc(wglGetVideoInfoNV_Impl, wglGetVideoInfoNV); + + // WGL_NV_swap_group + GLELoadProc(wglJoinSwapGroupNV_Impl, wglJoinSwapGroupNV); + GLELoadProc(wglBindSwapBarrierNV_Impl, wglBindSwapBarrierNV); + GLELoadProc(wglQuerySwapGroupNV_Impl, wglQuerySwapGroupNV); + GLELoadProc(wglQueryMaxSwapGroupsNV_Impl, wglQueryMaxSwapGroupsNV); + GLELoadProc(wglQueryFrameCountNV_Impl, wglQueryFrameCountNV); + GLELoadProc(wglResetFrameCountNV_Impl, wglResetFrameCountNV); + + // WGL_NV_video_capture + GLELoadProc(wglBindVideoCaptureDeviceNV_Impl, wglBindVideoCaptureDeviceNV); + GLELoadProc(wglEnumerateVideoCaptureDevicesNV_Impl, wglEnumerateVideoCaptureDevicesNV); + GLELoadProc(wglLockVideoCaptureDeviceNV_Impl, wglLockVideoCaptureDeviceNV); + GLELoadProc(wglQueryVideoCaptureDeviceNV_Impl, wglQueryVideoCaptureDeviceNV); + GLELoadProc(wglReleaseVideoCaptureDeviceNV_Impl, wglReleaseVideoCaptureDeviceNV); + + // WGL_NV_copy_image + GLELoadProc(wglCopyImageSubDataNV_Impl, wglCopyImageSubDataNV); + + // WGL_NV_DX_interop + GLELoadProc(wglDXCloseDeviceNV_Impl, wglDXCloseDeviceNV); + GLELoadProc(wglDXLockObjectsNV_Impl, wglDXLockObjectsNV); + GLELoadProc(wglDXObjectAccessNV_Impl, wglDXObjectAccessNV); + GLELoadProc(wglDXOpenDeviceNV_Impl, wglDXOpenDeviceNV); + GLELoadProc(wglDXRegisterObjectNV_Impl, wglDXRegisterObjectNV); + GLELoadProc(wglDXSetResourceShareHandleNV_Impl, wglDXSetResourceShareHandleNV); + GLELoadProc(wglDXUnlockObjectsNV_Impl, wglDXUnlockObjectsNV); + GLELoadProc(wglDXUnregisterObjectNV_Impl, wglDXUnregisterObjectNV); + + #elif defined(GLE_GLX_ENABLED) + // GLX_VERSION_1_1 + // We don't create any pointers_Impl, because we assume these functions are always present. + + // GLX_VERSION_1_2 + GLELoadProc(glXGetCurrentDisplay_Impl, glXGetCurrentDisplay); + + // GLX_VERSION_1_3 + GLELoadProc(glXChooseFBConfig_Impl, glXChooseFBConfig); + GLELoadProc(glXCreateNewContext_Impl, glXCreateNewContext); + GLELoadProc(glXCreatePbuffer_Impl, glXCreatePbuffer); + GLELoadProc(glXCreatePixmap_Impl, glXCreatePixmap); + GLELoadProc(glXCreateWindow_Impl, glXCreateWindow); + GLELoadProc(glXDestroyPbuffer_Impl, glXDestroyPbuffer); + GLELoadProc(glXDestroyPixmap_Impl, glXDestroyPixmap); + GLELoadProc(glXDestroyWindow_Impl, glXDestroyWindow); + GLELoadProc(glXGetCurrentReadDrawable_Impl, glXGetCurrentReadDrawable); + GLELoadProc(glXGetFBConfigAttrib_Impl, glXGetFBConfigAttrib); + GLELoadProc(glXGetFBConfigs_Impl, glXGetFBConfigs); + GLELoadProc(glXGetSelectedEvent_Impl, glXGetSelectedEvent); + GLELoadProc(glXGetVisualFromFBConfig_Impl, glXGetVisualFromFBConfig); + GLELoadProc(glXMakeContextCurrent_Impl, glXMakeContextCurrent); + GLELoadProc(glXQueryContext_Impl, glXQueryContext); + GLELoadProc(glXQueryDrawable_Impl, glXQueryDrawable); + GLELoadProc(glXSelectEvent_Impl, glXSelectEvent); + + // GLX_VERSION_1_4 + // Nothing to declare + + // GLX_ARB_create_context + GLELoadProc(glXCreateContextAttribsARB_Impl, glXCreateContextAttribsARB); + + // GLX_EXT_swap_control + GLELoadProc(glXSwapIntervalEXT_Impl, glXSwapIntervalEXT); + + // GLX_OML_sync_control + GLELoadProc(glXGetMscRateOML_Impl, glXGetMscRateOML); + GLELoadProc(glXGetSyncValuesOML_Impl, glXGetSyncValuesOML); + GLELoadProc(glXGetSyncValuesOML_Impl, glXSwapBuffersMscOML); + GLELoadProc(glXSwapBuffersMscOML_Impl, glXSwapBuffersMscOML); + GLELoadProc(glXWaitForSbcOML_Impl, glXWaitForSbcOML); + + // GLX_MESA_swap_control + GLELoadProc(glXGetSwapIntervalMESA_Impl, glXGetSwapIntervalMESA); + GLELoadProc(glXSwapIntervalMESA_Impl, glXSwapIntervalMESA); + #endif + } + + + void OVR::GLEContext::InitPlatformExtensionSupport() + { + #if defined(GLE_WGL_ENABLED) + // We need to use wglGetExtensionsStringARB or wglGetExtensionsStringEXT as opposed to above with glGetString(GL_EXTENSIONS). + ValueStringPair vspWGLArray[] = + { + { gle_WGL_ARB_buffer_region, "WGL_ARB_buffer_region" } + ,{ gle_WGL_ARB_create_context, "WGL_ARB_create_context" } + ,{ gle_WGL_ARB_create_context_profile, "WGL_ARB_create_context_profile" } + ,{ gle_WGL_ARB_create_context_robustness, "WGL_ARB_create_context_robustness" } + ,{ gle_WGL_ARB_extensions_string, "WGL_ARB_extensions_string" } + ,{ gle_WGL_ARB_framebuffer_sRGB, "WGL_ARB_framebuffer_sRGB" } + ,{ gle_WGL_ARB_framebuffer_sRGB, "WGL_EXT_framebuffer_sRGB" } // We map the EXT to the ARB. + ,{ gle_WGL_ARB_make_current_read, "WGL_ARB_make_current_read" } + ,{ gle_WGL_ARB_pbuffer, "WGL_ARB_pbuffer" } + ,{ gle_WGL_ARB_pixel_format, "WGL_ARB_pixel_format" } + ,{ gle_WGL_ARB_pixel_format_float, "WGL_ARB_pixel_format_float" } + ,{ gle_WGL_ARB_render_texture, "WGL_ARB_render_texture" } + ,{ gle_WGL_ATI_render_texture_rectangle, "WGL_ATI_render_texture_rectangle" } + ,{ gle_WGL_EXT_extensions_string, "WGL_EXT_extensions_string" } + ,{ gle_WGL_EXT_swap_control, "WGL_EXT_swap_control" } + ,{ gle_WGL_NV_copy_image, "WGL_NV_copy_image" } + ,{ gle_WGL_NV_DX_interop, "WGL_NV_DX_interop" } + ,{ gle_WGL_NV_DX_interop2, "WGL_NV_DX_interop2" } + ,{ gle_WGL_NV_present_video, "WGL_NV_present_video" } + ,{ gle_WGL_NV_render_texture_rectangle, "WGL_NV_render_texture_rectangle" } + ,{ gle_WGL_NV_swap_group, "WGL_NV_swap_group" } + ,{ gle_WGL_NV_video_capture, "WGL_NV_video_capture" } + ,{ gle_WGL_NV_video_output, "WGL_NV_video_output" } + ,{ gle_WGL_OML_sync_control, "WGL_OML_sync_control" } + }; + + const char* extensions = NULL; + + if(wglGetExtensionsStringARB_Impl) + extensions = wglGetExtensionsStringARB_Impl(wglGetCurrentDC()); // To do: Use a better mechanism to get the desired HDC. + else if(wglGetExtensionsStringEXT_Impl) + extensions = wglGetExtensionsStringEXT_Impl(); + + if (extensions && *extensions) + { + OVR_DEBUG_LOG(("WGL_EXTENSIONS: %s", (const char*)extensions)); + CheckExtensions(vspWGLArray, OVR_ARRAY_COUNT(vspWGLArray), extensions); + } + + #elif defined(GLE_GLX_ENABLED) + ValueStringPair vspGLXArray[] = + { + { gle_GLX_ARB_create_context, "GLX_ARB_create_context" } + ,{ gle_GLX_ARB_create_context_profile, "GLX_ARB_create_context_profile" } + ,{ gle_GLX_ARB_create_context_robustness, "GLX_ARB_create_context_robustness" } + ,{ gle_GLX_EXT_swap_control, "GLX_EXT_swap_control" } + ,{ gle_GLX_OML_sync_control, "GLX_OML_sync_control" } + ,{ gle_MESA_swap_control, "GLX_MESA_swap_control" } + }; + + const char* extensions = glXGetClientString(glXGetCurrentDisplay(), GLX_EXTENSIONS); // To do: Use a better mechanism to get the desired display. + + if (extensions && *extensions) + { + OVR_DEBUG_LOG(("GLX_EXTENSIONS: %s", (const char*)extensions)); + CheckExtensions(vspGLXArray, OVR_ARRAY_COUNT(vspGLXArray), extensions); + } + #endif + } + + + #if defined(GLE_HOOKING_ENABLED) + + #undef glGetError + extern "C" { GLAPI GLenum GLAPIENTRY glGetError(); } + + // Disabled until such time as it might be useful to enable for debug purposes. + //void OVR::GLEContext::PreHook(const char* functionName) + //{ + // if(EnableHookGetError) + // { + // int err = glGetError(); + // + // for(int i = 0; (i < 6) && (err != GL_NO_ERROR); i++) // 6 is an arbitrary cap to prevent infinite looping which would occur if the current GL context is invalid. + // { + // OVR_DEBUG_LOG(("GL Error prior to hook: %d (%#x) from %s", err, err, functionName ? functionName : "OpenGL")); OVR_UNUSED(functionName); + // err = glGetError(); + // } + // } + //} + + void OVR::GLEContext::PostHook(const char* functionName) + { + if(EnableHookGetError) + { + // OpenGL Standard regarding error state: To allow for distributed implementations, there may be several error flags. If any single error flag has recorded an error, the value of that flag + // is returned and that flag is reset to GL_NO_ERROR when glGetError is called. If more than one flag has recorded an error, glGetError returns and + // clears an arbitrary error flag value. Thus, glGetError should always be called in a loop, until it returns GL_NO_ERROR, if all error flags are to be reset. + int err = glGetError(); + + for(int i = 0; (i < 6) && (err != GL_NO_ERROR); i++) // 6 is an arbitrary cap to prevent infinite looping which would occur if the current GL context is invalid. + { + OVR_DEBUG_LOG(("GL Error: %d (%#x) from %s", err, err, functionName ? functionName : "OpenGL")); OVR_UNUSED(functionName); + err = glGetError(); + } + } + } + + + // OpenGL 1.1 link-based functions + #undef glAccum // Undefine the macro from our header so that we can directly call the real version of this function. + extern "C" { GLAPI void GLAPIENTRY glAccum(GLenum op, GLfloat value); } + void OVR::GLEContext::glAccum_Hook(GLenum op, GLfloat value) + { + glAccum(op, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glAlphaFunc + extern "C" { GLAPI void GLAPIENTRY glAlphaFunc(GLenum func, GLclampf ref); } + void OVR::GLEContext::glAlphaFunc_Hook(GLenum func, GLclampf ref) + { + glAlphaFunc(func, ref); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glAreTexturesResident + extern "C" { GLAPI GLboolean GLAPIENTRY glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences); } + GLboolean OVR::GLEContext::glAreTexturesResident_Hook(GLsizei n, const GLuint *textures, GLboolean *residences) + { + GLboolean b = glAreTexturesResident(n, textures, residences); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef glArrayElement + extern "C" { GLAPI void GLAPIENTRY glArrayElement(GLint i); } + void OVR::GLEContext::glArrayElement_Hook(GLint i) + { + glArrayElement(i); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glBegin + extern "C" { GLAPI void GLAPIENTRY glBegin(GLenum mode); } + void OVR::GLEContext::glBegin_Hook(GLenum mode) + { + glBegin(mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glBindTexture + extern "C" { GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture); } + void OVR::GLEContext::glBindTexture_Hook(GLenum target, GLuint texture) + { + glBindTexture(target, texture); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glBitmap + extern "C" { GLAPI void GLAPIENTRY glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); } + void OVR::GLEContext::glBitmap_Hook(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) + { + glBitmap(width, height, xorig, yorig, xmove, ymove, bitmap); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glBlendFunc + extern "C" { GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor); } + void OVR::GLEContext::glBlendFunc_Hook(GLenum sfactor, GLenum dfactor) + { + glBlendFunc(sfactor, dfactor); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glCallList + extern "C" { GLAPI void GLAPIENTRY glCallList(GLuint list); } + void OVR::GLEContext::glCallList_Hook(GLuint list) + { + glCallList(list); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glCallLists + extern "C" { GLAPI void GLAPIENTRY glCallLists(GLsizei n, GLenum type, const void *lists); } + void OVR::GLEContext::glCallLists_Hook(GLsizei n, GLenum type, const void *lists) + { + glCallLists(n, type, lists); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glClear + extern "C" { GLAPI void GLAPIENTRY glClear(GLbitfield mask); } + void OVR::GLEContext::glClear_Hook(GLbitfield mask) + { + glClear(mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glClearAccum + extern "C" { GLAPI void GLAPIENTRY glClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); } + void OVR::GLEContext::glClearAccum_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) + { + glClearAccum(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glClearColor + extern "C" { GLAPI void GLAPIENTRY glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); } + void OVR::GLEContext::glClearColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) + { + glClearColor(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glClearDepth + extern "C" { GLAPI void GLAPIENTRY glClearDepth(GLclampd depth); } + void OVR::GLEContext::glClearDepth_Hook(GLclampd depth) + { + glClearDepth(depth); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glClearIndex + extern "C" { GLAPI void GLAPIENTRY glClearIndex(GLfloat c); } + void OVR::GLEContext::glClearIndex_Hook(GLfloat c) + { + glClearIndex(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glClearStencil + extern "C" { GLAPI void GLAPIENTRY glClearStencil(GLint s); } + void OVR::GLEContext::glClearStencil_Hook(GLint s) + { + glClearStencil(s); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glClipPlane + extern "C" { GLAPI void GLAPIENTRY glClipPlane(GLenum plane, const GLdouble *equation); } + void OVR::GLEContext::glClipPlane_Hook(GLenum plane, const GLdouble *equation) + { + glClipPlane(plane, equation); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3b + extern "C" { GLAPI void GLAPIENTRY glColor3b(GLbyte red, GLbyte green, GLbyte blue); } + void OVR::GLEContext::glColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue) + { + glColor3b(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3bv + extern "C" { GLAPI void GLAPIENTRY glColor3bv(const GLbyte *v); } + void OVR::GLEContext::glColor3bv_Hook(const GLbyte *v) + { + glColor3bv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3d + extern "C" { GLAPI void GLAPIENTRY glColor3d(GLdouble red, GLdouble green, GLdouble blue); } + void OVR::GLEContext::glColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue) + { + glColor3d(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3dv + extern "C" { GLAPI void GLAPIENTRY glColor3dv(const GLdouble *v); } + void OVR::GLEContext::glColor3dv_Hook(const GLdouble *v) + { + glColor3dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3f + extern "C" { GLAPI void GLAPIENTRY glColor3f(GLfloat red, GLfloat green, GLfloat blue); } + void OVR::GLEContext::glColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue) + { + glColor3f(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3fv + extern "C" { GLAPI void GLAPIENTRY glColor3fv(const GLfloat *v); } + void OVR::GLEContext::glColor3fv_Hook(const GLfloat *v) + { + glColor3fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3i + extern "C" { GLAPI void GLAPIENTRY glColor3i(GLint red, GLint green, GLint blue); } + void OVR::GLEContext::glColor3i_Hook(GLint red, GLint green, GLint blue) + { + glColor3i(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3iv + extern "C" { GLAPI void GLAPIENTRY glColor3iv(const GLint *v); } + void OVR::GLEContext::glColor3iv_Hook(const GLint *v) + { + glColor3iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3s + extern "C" { GLAPI void GLAPIENTRY glColor3s(GLshort red, GLshort green, GLshort blue); } + void OVR::GLEContext::glColor3s_Hook(GLshort red, GLshort green, GLshort blue) + { + glColor3s(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3sv + extern "C" { GLAPI void GLAPIENTRY glColor3sv(const GLshort *v); } + void OVR::GLEContext::glColor3sv_Hook(const GLshort *v) + { + glColor3sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3ub + extern "C" { GLAPI void GLAPIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue); } + void OVR::GLEContext::glColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue) + { + glColor3ub(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3ubv + extern "C" { GLAPI void GLAPIENTRY glColor3ubv(const GLubyte *v); } + void OVR::GLEContext::glColor3ubv_Hook(const GLubyte *v) + { + glColor3ubv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3ui + extern "C" { GLAPI void GLAPIENTRY glColor3ui(GLuint red, GLuint green, GLuint blue); } + void OVR::GLEContext::glColor3ui_Hook(GLuint red, GLuint green, GLuint blue) + { + glColor3ui(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3uiv + extern "C" { GLAPI void GLAPIENTRY glColor3uiv(const GLuint *v); } + void OVR::GLEContext::glColor3uiv_Hook(const GLuint *v) + { + glColor3uiv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3us + extern "C" { GLAPI void GLAPIENTRY glColor3us(GLushort red, GLushort green, GLushort blue); } + void OVR::GLEContext::glColor3us_Hook(GLushort red, GLushort green, GLushort blue) + { + glColor3us(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor3usv + extern "C" { GLAPI void GLAPIENTRY glColor3usv(const GLushort *v); } + void OVR::GLEContext::glColor3usv_Hook(const GLushort *v) + { + glColor3usv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4b + extern "C" { GLAPI void GLAPIENTRY glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); } + void OVR::GLEContext::glColor4b_Hook(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) + { + glColor4b(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4bv + extern "C" { GLAPI void GLAPIENTRY glColor4bv(const GLbyte *v); } + void OVR::GLEContext::glColor4bv_Hook(const GLbyte *v) + { + glColor4bv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4d + extern "C" { GLAPI void GLAPIENTRY glColor4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); } + void OVR::GLEContext::glColor4d_Hook(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) + { + glColor4d(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4dv + extern "C" { GLAPI void GLAPIENTRY glColor4dv(const GLdouble *v); } + void OVR::GLEContext::glColor4dv_Hook(const GLdouble *v) + { + glColor4dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4f + extern "C" { GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); } + void OVR::GLEContext::glColor4f_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) + { + glColor4f(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4fv + extern "C" { GLAPI void GLAPIENTRY glColor4fv(const GLfloat *v); } + void OVR::GLEContext::glColor4fv_Hook(const GLfloat *v) + { + glColor4fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4i + extern "C" { GLAPI void GLAPIENTRY glColor4i(GLint red, GLint green, GLint blue, GLint alpha); } + void OVR::GLEContext::glColor4i_Hook(GLint red, GLint green, GLint blue, GLint alpha) + { + glColor4i(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4iv + extern "C" { GLAPI void GLAPIENTRY glColor4iv(const GLint *v); } + void OVR::GLEContext::glColor4iv_Hook(const GLint *v) + { + glColor4iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4s + extern "C" { GLAPI void GLAPIENTRY glColor4s(GLshort red, GLshort green, GLshort blue, GLshort alpha); } + void OVR::GLEContext::glColor4s_Hook(GLshort red, GLshort green, GLshort blue, GLshort alpha) + { + glColor4s(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4sv + extern "C" { GLAPI void GLAPIENTRY glColor4sv(const GLshort *v); } + void OVR::GLEContext::glColor4sv_Hook(const GLshort *v) + { + glColor4sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4ub + extern "C" { GLAPI void GLAPIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); } + void OVR::GLEContext::glColor4ub_Hook(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) + { + glColor4ub(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4ubv + extern "C" { GLAPI void GLAPIENTRY glColor4ubv(const GLubyte *v); } + void OVR::GLEContext::glColor4ubv_Hook(const GLubyte *v) + { + glColor4ubv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4ui + extern "C" { GLAPI void GLAPIENTRY glColor4ui(GLuint red, GLuint green, GLuint blue, GLuint alpha); } + void OVR::GLEContext::glColor4ui_Hook(GLuint red, GLuint green, GLuint blue, GLuint alpha) + { + glColor4ui(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4uiv + extern "C" { GLAPI void GLAPIENTRY glColor4uiv(const GLuint *v); } + void OVR::GLEContext::glColor4uiv_Hook(const GLuint *v) + { + glColor4uiv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4us + extern "C" { GLAPI void GLAPIENTRY glColor4us(GLushort red, GLushort green, GLushort blue, GLushort alpha); } + void OVR::GLEContext::glColor4us_Hook(GLushort red, GLushort green, GLushort blue, GLushort alpha) + { + glColor4us(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColor4usv + extern "C" { GLAPI void GLAPIENTRY glColor4usv(const GLushort *v); } + void OVR::GLEContext::glColor4usv_Hook(const GLushort *v) + { + glColor4usv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColorMask + extern "C" { GLAPI void GLAPIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); } + void OVR::GLEContext::glColorMask_Hook(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) + { + glColorMask(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColorMaterial + extern "C" { GLAPI void GLAPIENTRY glColorMaterial(GLenum face, GLenum mode); } + void OVR::GLEContext::glColorMaterial_Hook(GLenum face, GLenum mode) + { + glColorMaterial(face, mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glColorPointer + extern "C" { GLAPI void GLAPIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); } + void OVR::GLEContext::glColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer) + { + glColorPointer(size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glCopyPixels + extern "C" { GLAPI void GLAPIENTRY glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); } + void OVR::GLEContext::glCopyPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) + { + glCopyPixels(x, y, width, height, type); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glCopyTexImage1D + extern "C" { GLAPI void GLAPIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); } + void OVR::GLEContext::glCopyTexImage1D_Hook(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border) + { + glCopyTexImage1D(target, level, internalFormat, x, y, width, border); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glCopyTexImage2D + extern "C" { GLAPI void GLAPIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); } + void OVR::GLEContext::glCopyTexImage2D_Hook(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) + { + glCopyTexImage2D(target, level, internalFormat, x, y, width, height, border); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glCopyTexSubImage1D + extern "C" { GLAPI void GLAPIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); } + void OVR::GLEContext::glCopyTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) + { + glCopyTexSubImage1D(target, level, xoffset, x, y, width); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glCopyTexSubImage2D + extern "C" { GLAPI void GLAPIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); } + void OVR::GLEContext::glCopyTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) + { + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glCullFace + extern "C" { GLAPI void GLAPIENTRY glCullFace(GLenum mode); } + void OVR::GLEContext::glCullFace_Hook(GLenum mode) + { + glCullFace(mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDeleteLists + extern "C" { GLAPI void GLAPIENTRY glDeleteLists(GLuint list, GLsizei range); } + void OVR::GLEContext::glDeleteLists_Hook(GLuint list, GLsizei range) + { + glDeleteLists(list, range); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDeleteTextures + extern "C" { GLAPI void GLAPIENTRY glDeleteTextures(GLsizei n, const GLuint *textures); } + void OVR::GLEContext::glDeleteTextures_Hook(GLsizei n, const GLuint *textures) + { + glDeleteTextures(n, textures); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDepthFunc + extern "C" { GLAPI void GLAPIENTRY glDepthFunc(GLenum func); } + void OVR::GLEContext::glDepthFunc_Hook(GLenum func) + { + glDepthFunc(func); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDepthMask + extern "C" { GLAPI void GLAPIENTRY glDepthMask(GLboolean flag); } + void OVR::GLEContext::glDepthMask_Hook(GLboolean flag) + { + glDepthMask(flag); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDepthRange + extern "C" { GLAPI void GLAPIENTRY glDepthRange(GLclampd zNear, GLclampd zFar); } + void OVR::GLEContext::glDepthRange_Hook(GLclampd zNear, GLclampd zFar) + { + glDepthRange(zNear, zFar); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDisable + extern "C" { GLAPI void GLAPIENTRY glDisable(GLenum cap); } + void OVR::GLEContext::glDisable_Hook(GLenum cap) + { + glDisable(cap); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDisableClientState + extern "C" { GLAPI void GLAPIENTRY glDisableClientState(GLenum array); } + void OVR::GLEContext::glDisableClientState_Hook(GLenum array) + { + glDisableClientState(array); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDrawArrays + extern "C" { GLAPI void GLAPIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count); } + void OVR::GLEContext::glDrawArrays_Hook(GLenum mode, GLint first, GLsizei count) + { + glDrawArrays(mode, first, count); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDrawBuffer + extern "C" { GLAPI void GLAPIENTRY glDrawBuffer(GLenum mode); } + void OVR::GLEContext::glDrawBuffer_Hook(GLenum mode) + { + glDrawBuffer(mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDrawElements + extern "C" { GLAPI void GLAPIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const void *indices); } + void OVR::GLEContext::glDrawElements_Hook(GLenum mode, GLsizei count, GLenum type, const void *indices) + { + glDrawElements(mode, count, type, indices); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glDrawPixels + extern "C" { GLAPI void GLAPIENTRY glDrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); } + void OVR::GLEContext::glDrawPixels_Hook(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) + { + glDrawPixels(width, height, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEdgeFlag + extern "C" { GLAPI void GLAPIENTRY glEdgeFlag(GLboolean flag); } + void OVR::GLEContext::glEdgeFlag_Hook(GLboolean flag) + { + glEdgeFlag(flag); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEdgeFlagPointer + extern "C" { GLAPI void GLAPIENTRY glEdgeFlagPointer(GLsizei stride, const void *pointer); } + void OVR::GLEContext::glEdgeFlagPointer_Hook(GLsizei stride, const void *pointer) + { + glEdgeFlagPointer(stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEdgeFlagv + extern "C" { GLAPI void GLAPIENTRY glEdgeFlagv(const GLboolean *flag); } + void OVR::GLEContext::glEdgeFlagv_Hook(const GLboolean *flag) + { + glEdgeFlagv(flag); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEnable + extern "C" { GLAPI void GLAPIENTRY glEnable(GLenum cap); } + namespace OVR { + void GLEContext::glEnable_Hook(GLenum cap) + { + glEnable(cap); + PostHook(GLE_CURRENT_FUNCTION); + } + } + + #undef glEnableClientState + extern "C" { GLAPI void GLAPIENTRY glEnableClientState(GLenum array); } + void OVR::GLEContext::glEnableClientState_Hook(GLenum array) + { + glEnableClientState(array); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEnd + extern "C" { GLAPI void GLAPIENTRY glEnd(); } + void OVR::GLEContext::glEnd_Hook() + { + glEnd(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEndList + extern "C" { GLAPI void GLAPIENTRY glEndList(); } + void OVR::GLEContext::glEndList_Hook() + { + glEndList(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalCoord1d + extern "C" { GLAPI void GLAPIENTRY glEvalCoord1d(GLdouble u); } + void OVR::GLEContext::glEvalCoord1d_Hook(GLdouble u) + { + glEvalCoord1d(u); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalCoord1dv + extern "C" { GLAPI void GLAPIENTRY glEvalCoord1dv(const GLdouble *u); } + void OVR::GLEContext::glEvalCoord1dv_Hook(const GLdouble *u) + { + glEvalCoord1dv(u); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalCoord1f + extern "C" { GLAPI void GLAPIENTRY glEvalCoord1f(GLfloat u); } + void OVR::GLEContext::glEvalCoord1f_Hook(GLfloat u) + { + glEvalCoord1f(u); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalCoord1fv + extern "C" { GLAPI void GLAPIENTRY glEvalCoord1fv(const GLfloat *u); } + void OVR::GLEContext::glEvalCoord1fv_Hook(const GLfloat *u) + { + glEvalCoord1fv(u); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalCoord2d + extern "C" { GLAPI void GLAPIENTRY glEvalCoord2d(GLdouble u, GLdouble v); } + void OVR::GLEContext::glEvalCoord2d_Hook(GLdouble u, GLdouble v) + { + glEvalCoord2d(u, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalCoord2dv + extern "C" { GLAPI void GLAPIENTRY glEvalCoord2dv(const GLdouble *u); } + void OVR::GLEContext::glEvalCoord2dv_Hook(const GLdouble *u) + { + glEvalCoord2dv(u); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalCoord2f + extern "C" { GLAPI void GLAPIENTRY glEvalCoord2f(GLfloat u, GLfloat v); } + void OVR::GLEContext::glEvalCoord2f_Hook(GLfloat u, GLfloat v) + { + glEvalCoord2f(u, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalCoord2fv + extern "C" { GLAPI void GLAPIENTRY glEvalCoord2fv(const GLfloat *u); } + void OVR::GLEContext::glEvalCoord2fv_Hook(const GLfloat *u) + { + glEvalCoord2fv(u); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalMesh1 + extern "C" { GLAPI void GLAPIENTRY glEvalMesh1(GLenum mode, GLint i1, GLint i2); } + void OVR::GLEContext::glEvalMesh1_Hook(GLenum mode, GLint i1, GLint i2) + { + glEvalMesh1(mode, i1, i2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalMesh2 + extern "C" { GLAPI void GLAPIENTRY glEvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); } + void OVR::GLEContext::glEvalMesh2_Hook(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) + { + glEvalMesh2(mode, i1, i2, j1, j2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalPoint1 + extern "C" { GLAPI void GLAPIENTRY glEvalPoint1(GLint i); } + void OVR::GLEContext::glEvalPoint1_Hook(GLint i) + { + glEvalPoint1(i); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glEvalPoint2 + extern "C" { GLAPI void GLAPIENTRY glEvalPoint2(GLint i, GLint j); } + void OVR::GLEContext::glEvalPoint2_Hook(GLint i, GLint j) + { + glEvalPoint2(i, j); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFeedbackBuffer + extern "C" { GLAPI void GLAPIENTRY glFeedbackBuffer(GLsizei size, GLenum type, GLfloat *buffer); } + void OVR::GLEContext::glFeedbackBuffer_Hook(GLsizei size, GLenum type, GLfloat *buffer) + { + glFeedbackBuffer(size, type, buffer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFinish + extern "C" { GLAPI void GLAPIENTRY glFinish(); } + void OVR::GLEContext::glFinish_Hook() + { + glFinish(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFlush + extern "C" { GLAPI void GLAPIENTRY glFlush(); } + void OVR::GLEContext::glFlush_Hook() + { + glFlush(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFogf + extern "C" { GLAPI void GLAPIENTRY glFogf(GLenum pname, GLfloat param); } + void OVR::GLEContext::glFogf_Hook(GLenum pname, GLfloat param) + { + glFogf(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFogfv + extern "C" { GLAPI void GLAPIENTRY glFogfv(GLenum pname, const GLfloat *params); } + void OVR::GLEContext::glFogfv_Hook(GLenum pname, const GLfloat *params) + { + glFogfv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFogi + extern "C" { GLAPI void GLAPIENTRY glFogi(GLenum pname, GLint param); } + void OVR::GLEContext::glFogi_Hook(GLenum pname, GLint param) + { + glFogi(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFogiv + extern "C" { GLAPI void GLAPIENTRY glFogiv(GLenum pname, const GLint *params); } + void OVR::GLEContext::glFogiv_Hook(GLenum pname, const GLint *params) + { + glFogiv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFrontFace + extern "C" { GLAPI void GLAPIENTRY glFrontFace(GLenum mode); } + void OVR::GLEContext::glFrontFace_Hook(GLenum mode) + { + glFrontFace(mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glFrustum + extern "C" { GLAPI void GLAPIENTRY glFrustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); } + void OVR::GLEContext::glFrustum_Hook(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) + { + glFrustum(left, right, bottom, top, zNear, zFar); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGenLists + extern "C" { GLAPI GLuint GLAPIENTRY glGenLists(GLsizei range); } + GLuint OVR::GLEContext::glGenLists_Hook(GLsizei range) + { + GLuint u = glGenLists(range); + PostHook(GLE_CURRENT_FUNCTION); + return u; + } + + #undef glGenTextures + extern "C" { GLAPI void GLAPIENTRY glGenTextures(GLsizei n, GLuint *textures); } + void OVR::GLEContext::glGenTextures_Hook(GLsizei n, GLuint *textures) + { + glGenTextures(n, textures); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetBooleanv + extern "C" { GLAPI void GLAPIENTRY glGetBooleanv(GLenum pname, GLboolean *params); } + void OVR::GLEContext::glGetBooleanv_Hook(GLenum pname, GLboolean *params) + { + glGetBooleanv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetClipPlane + extern "C" { GLAPI void GLAPIENTRY glGetClipPlane(GLenum plane, GLdouble *equation); } + void OVR::GLEContext::glGetClipPlane_Hook(GLenum plane, GLdouble *equation) + { + glGetClipPlane(plane, equation); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetDoublev + extern "C" { GLAPI void GLAPIENTRY glGetDoublev(GLenum pname, GLdouble *params); } + void OVR::GLEContext::glGetDoublev_Hook(GLenum pname, GLdouble *params) + { + glGetDoublev(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + //#undef glGetError Not needed because we happen to do this above already. + //extern "C" { GLAPI GLenum GLAPIENTRY glGetError(); } + GLenum OVR::GLEContext::glGetError_Hook() + { + GLenum e = glGetError(); + PostHook(GLE_CURRENT_FUNCTION); + return e; + } + + #undef glGetFloatv + extern "C" { GLAPI void GLAPIENTRY glGetFloatv(GLenum pname, GLfloat *params); } + void OVR::GLEContext::glGetFloatv_Hook(GLenum pname, GLfloat *params) + { + glGetFloatv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetIntegerv + extern "C" { GLAPI void GLAPIENTRY glGetIntegerv(GLenum pname, GLint *params); } + void OVR::GLEContext::glGetIntegerv_Hook(GLenum pname, GLint *params) + { + glGetIntegerv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetLightfv + extern "C" { GLAPI void GLAPIENTRY glGetLightfv(GLenum light, GLenum pname, GLfloat *params); } + void OVR::GLEContext::glGetLightfv_Hook(GLenum light, GLenum pname, GLfloat *params) + { + glGetLightfv(light, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetLightiv + extern "C" { GLAPI void GLAPIENTRY glGetLightiv(GLenum light, GLenum pname, GLint *params); } + void OVR::GLEContext::glGetLightiv_Hook(GLenum light, GLenum pname, GLint *params) + { + glGetLightiv(light, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetMapdv + extern "C" { GLAPI void GLAPIENTRY glGetMapdv(GLenum target, GLenum query, GLdouble *v); } + void OVR::GLEContext::glGetMapdv_Hook(GLenum target, GLenum query, GLdouble *v) + { + glGetMapdv(target, query, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetMapfv + extern "C" { GLAPI void GLAPIENTRY glGetMapfv(GLenum target, GLenum query, GLfloat *v); } + void OVR::GLEContext::glGetMapfv_Hook(GLenum target, GLenum query, GLfloat *v) + { + glGetMapfv(target, query, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetMapiv + extern "C" { GLAPI void GLAPIENTRY glGetMapiv(GLenum target, GLenum query, GLint *v); } + void OVR::GLEContext::glGetMapiv_Hook(GLenum target, GLenum query, GLint *v) + { + glGetMapiv(target, query, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetMaterialfv + extern "C" { GLAPI void GLAPIENTRY glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params); } + void OVR::GLEContext::glGetMaterialfv_Hook(GLenum face, GLenum pname, GLfloat *params) + { + glGetMaterialfv(face, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetMaterialiv + extern "C" { GLAPI void GLAPIENTRY glGetMaterialiv(GLenum face, GLenum pname, GLint *params); } + void OVR::GLEContext::glGetMaterialiv_Hook(GLenum face, GLenum pname, GLint *params) + { + glGetMaterialiv(face, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetPixelMapfv + extern "C" { GLAPI void GLAPIENTRY glGetPixelMapfv(GLenum map, GLfloat *values); } + void OVR::GLEContext::glGetPixelMapfv_Hook(GLenum map, GLfloat *values) + { + glGetPixelMapfv(map, values); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetPixelMapuiv + extern "C" { GLAPI void GLAPIENTRY glGetPixelMapuiv(GLenum map, GLuint *values); } + void OVR::GLEContext::glGetPixelMapuiv_Hook(GLenum map, GLuint *values) + { + glGetPixelMapuiv(map, values); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetPixelMapusv + extern "C" { GLAPI void GLAPIENTRY glGetPixelMapusv(GLenum map, GLushort *values); } + void OVR::GLEContext::glGetPixelMapusv_Hook(GLenum map, GLushort *values) + { + glGetPixelMapusv(map, values); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetPointerv + extern "C" { GLAPI void GLAPIENTRY glGetPointerv(GLenum pname, void* *params); } + void OVR::GLEContext::glGetPointerv_Hook(GLenum pname, void* *params) + { + glGetPointerv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetPolygonStipple + extern "C" { GLAPI void GLAPIENTRY glGetPolygonStipple(GLubyte *mask); } + void OVR::GLEContext::glGetPolygonStipple_Hook(GLubyte *mask) + { + glGetPolygonStipple(mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + // #undef glGetString // This was already disabled above. + // extern "C" { GLAPI const GLubyte * GLAPIENTRY glGetString(GLenum name); } + const GLubyte * OVR::GLEContext::glGetString_Hook(GLenum name) + { + const GLubyte * p = glGetString(name); + PostHook(GLE_CURRENT_FUNCTION); + return p; + } + + #undef glGetTexEnvfv + extern "C" { GLAPI void GLAPIENTRY glGetTexEnvfv(GLenum target, GLenum pname, GLfloat *params); } + void OVR::GLEContext::glGetTexEnvfv_Hook(GLenum target, GLenum pname, GLfloat *params) + { + glGetTexEnvfv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexEnviv + extern "C" { GLAPI void GLAPIENTRY glGetTexEnviv(GLenum target, GLenum pname, GLint *params); } + void OVR::GLEContext::glGetTexEnviv_Hook(GLenum target, GLenum pname, GLint *params) + { + glGetTexEnviv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexGendv + extern "C" { GLAPI void GLAPIENTRY glGetTexGendv(GLenum coord, GLenum pname, GLdouble *params); } + void OVR::GLEContext::glGetTexGendv_Hook(GLenum coord, GLenum pname, GLdouble *params) + { + glGetTexGendv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexGenfv + extern "C" { GLAPI void GLAPIENTRY glGetTexGenfv(GLenum coord, GLenum pname, GLfloat *params); } + void OVR::GLEContext::glGetTexGenfv_Hook(GLenum coord, GLenum pname, GLfloat *params) + { + glGetTexGenfv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexGeniv + extern "C" { GLAPI void GLAPIENTRY glGetTexGeniv(GLenum coord, GLenum pname, GLint *params); } + void OVR::GLEContext::glGetTexGeniv_Hook(GLenum coord, GLenum pname, GLint *params) + { + glGetTexGeniv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexImage + extern "C" { GLAPI void GLAPIENTRY glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, void *pixels); } + void OVR::GLEContext::glGetTexImage_Hook(GLenum target, GLint level, GLenum format, GLenum type, void *pixels) + { + glGetTexImage(target, level, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexLevelParameterfv + extern "C" { GLAPI void GLAPIENTRY glGetTexLevelParameterfv(GLenum target, GLint level, GLenum pname, GLfloat *params); } + void OVR::GLEContext::glGetTexLevelParameterfv_Hook(GLenum target, GLint level, GLenum pname, GLfloat *params) + { + glGetTexLevelParameterfv(target, level, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexLevelParameteriv + extern "C" { GLAPI void GLAPIENTRY glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params); } + void OVR::GLEContext::glGetTexLevelParameteriv_Hook(GLenum target, GLint level, GLenum pname, GLint *params) + { + glGetTexLevelParameteriv(target, level, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexParameterfv + extern "C" { GLAPI void GLAPIENTRY glGetTexParameterfv(GLenum target, GLenum pname, GLfloat *params); } + void OVR::GLEContext::glGetTexParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) + { + glGetTexParameterfv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glGetTexParameteriv + extern "C" { GLAPI void GLAPIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint *params); } + void OVR::GLEContext::glGetTexParameteriv_Hook(GLenum target, GLenum pname, GLint *params) + { + glGetTexParameteriv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glHint + extern "C" { GLAPI void GLAPIENTRY glHint(GLenum target, GLenum mode); } + void OVR::GLEContext::glHint_Hook(GLenum target, GLenum mode) + { + glHint(target, mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexMask + extern "C" { GLAPI void GLAPIENTRY glIndexMask(GLuint mask); } + void OVR::GLEContext::glIndexMask_Hook(GLuint mask) + { + glIndexMask(mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexPointer + extern "C" { GLAPI void GLAPIENTRY glIndexPointer(GLenum type, GLsizei stride, const void *pointer); } + void OVR::GLEContext::glIndexPointer_Hook(GLenum type, GLsizei stride, const void *pointer) + { + glIndexPointer(type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexd + extern "C" { GLAPI void GLAPIENTRY glIndexd(GLdouble c); } + void OVR::GLEContext::glIndexd_Hook(GLdouble c) + { + glIndexd(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexdv + extern "C" { GLAPI void GLAPIENTRY glIndexdv(const GLdouble *c); } + void OVR::GLEContext::glIndexdv_Hook(const GLdouble *c) + { + glIndexdv(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexf + extern "C" { GLAPI void GLAPIENTRY glIndexf(GLfloat c); } + void OVR::GLEContext::glIndexf_Hook(GLfloat c) + { + glIndexf(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexfv + extern "C" { GLAPI void GLAPIENTRY glIndexfv(const GLfloat *c); } + void OVR::GLEContext::glIndexfv_Hook(const GLfloat *c) + { + glIndexfv(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexi + extern "C" { GLAPI void GLAPIENTRY glIndexi(GLint c); } + void OVR::GLEContext::glIndexi_Hook(GLint c) + { + glIndexi(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexiv + extern "C" { GLAPI void GLAPIENTRY glIndexiv(const GLint *c); } + void OVR::GLEContext::glIndexiv_Hook(const GLint *c) + { + glIndexiv(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexs + extern "C" { GLAPI void GLAPIENTRY glIndexs(GLshort c); } + void OVR::GLEContext::glIndexs_Hook(GLshort c) + { + glIndexs(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexsv + extern "C" { GLAPI void GLAPIENTRY glIndexsv(const GLshort *c); } + void OVR::GLEContext::glIndexsv_Hook(const GLshort *c) + { + glIndexsv(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexub + extern "C" { GLAPI void GLAPIENTRY glIndexub(GLubyte c); } + void OVR::GLEContext::glIndexub_Hook(GLubyte c) + { + glIndexub(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIndexubv + extern "C" { GLAPI void GLAPIENTRY glIndexubv(const GLubyte *c); } + void OVR::GLEContext::glIndexubv_Hook(const GLubyte *c) + { + glIndexubv(c); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glInitNames + extern "C" { GLAPI void GLAPIENTRY glInitNames(); } + void OVR::GLEContext::glInitNames_Hook() + { + glInitNames(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glInterleavedArrays + extern "C" { GLAPI void GLAPIENTRY glInterleavedArrays(GLenum format, GLsizei stride, const void *pointer); } + void OVR::GLEContext::glInterleavedArrays_Hook(GLenum format, GLsizei stride, const void *pointer) + { + glInterleavedArrays(format, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glIsEnabled + extern "C" { GLAPI GLboolean GLAPIENTRY glIsEnabled(GLenum cap); } + GLboolean OVR::GLEContext::glIsEnabled_Hook(GLenum cap) + { + GLboolean b = glIsEnabled(cap); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef glIsList + extern "C" { GLAPI GLboolean GLAPIENTRY glIsList(GLuint list); } + GLboolean OVR::GLEContext::glIsList_Hook(GLuint list) + { + GLboolean b = glIsList(list); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef glIsTexture + extern "C" { GLAPI GLboolean GLAPIENTRY glIsTexture(GLuint texture); } + GLboolean OVR::GLEContext::glIsTexture_Hook(GLuint texture) + { + GLboolean b = glIsTexture(texture); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef glLightModelf + extern "C" { GLAPI void GLAPIENTRY glLightModelf(GLenum pname, GLfloat param); } + void OVR::GLEContext::glLightModelf_Hook(GLenum pname, GLfloat param) + { + glLightModelf(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLightModelfv + extern "C" { GLAPI void GLAPIENTRY glLightModelfv(GLenum pname, const GLfloat *params); } + void OVR::GLEContext::glLightModelfv_Hook(GLenum pname, const GLfloat *params) + { + glLightModelfv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLightModeli + extern "C" { GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param); } + void OVR::GLEContext::glLightModeli_Hook(GLenum pname, GLint param) + { + glLightModeli(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLightModeliv + extern "C" { GLAPI void GLAPIENTRY glLightModeliv(GLenum pname, const GLint *params); } + void OVR::GLEContext::glLightModeliv_Hook(GLenum pname, const GLint *params) + { + glLightModeliv(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLightf + extern "C" { GLAPI void GLAPIENTRY glLightf(GLenum light, GLenum pname, GLfloat param); } + void OVR::GLEContext::glLightf_Hook(GLenum light, GLenum pname, GLfloat param) + { + glLightf(light, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLightfv + extern "C" { GLAPI void GLAPIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params); } + void OVR::GLEContext::glLightfv_Hook(GLenum light, GLenum pname, const GLfloat *params) + { + glLightfv(light, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLighti + extern "C" { GLAPI void GLAPIENTRY glLighti(GLenum light, GLenum pname, GLint param); } + void OVR::GLEContext::glLighti_Hook(GLenum light, GLenum pname, GLint param) + { + glLighti(light, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLightiv + extern "C" { GLAPI void GLAPIENTRY glLightiv(GLenum light, GLenum pname, const GLint *params); } + void OVR::GLEContext::glLightiv_Hook(GLenum light, GLenum pname, const GLint *params) + { + glLightiv(light, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLineStipple + extern "C" { GLAPI void GLAPIENTRY glLineStipple(GLint factor, GLushort pattern); } + void OVR::GLEContext::glLineStipple_Hook(GLint factor, GLushort pattern) + { + glLineStipple(factor, pattern); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLineWidth + extern "C" { GLAPI void GLAPIENTRY glLineWidth(GLfloat width); } + void OVR::GLEContext::glLineWidth_Hook(GLfloat width) + { + glLineWidth(width); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glListBase + extern "C" { GLAPI void GLAPIENTRY glListBase(GLuint base); } + void OVR::GLEContext::glListBase_Hook(GLuint base) + { + glListBase(base); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLoadIdentity + extern "C" { GLAPI void GLAPIENTRY glLoadIdentity(); } + void OVR::GLEContext::glLoadIdentity_Hook() + { + glLoadIdentity(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLoadMatrixd + extern "C" { GLAPI void GLAPIENTRY glLoadMatrixd(const GLdouble *m); } + void OVR::GLEContext::glLoadMatrixd_Hook(const GLdouble *m) + { + glLoadMatrixd(m); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLoadMatrixf + extern "C" { GLAPI void GLAPIENTRY glLoadMatrixf(const GLfloat *m); } + void OVR::GLEContext::glLoadMatrixf_Hook(const GLfloat *m) + { + glLoadMatrixf(m); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLoadName + extern "C" { GLAPI void GLAPIENTRY glLoadName(GLuint name); } + void OVR::GLEContext::glLoadName_Hook(GLuint name) + { + glLoadName(name); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glLogicOp + extern "C" { GLAPI void GLAPIENTRY glLogicOp(GLenum opcode); } + void OVR::GLEContext::glLogicOp_Hook(GLenum opcode) + { + glLogicOp(opcode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMap1d + extern "C" { GLAPI void GLAPIENTRY glMap1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); } + void OVR::GLEContext::glMap1d_Hook(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) + { + glMap1d(target, u1, u2, stride, order, points); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMap1f + extern "C" { GLAPI void GLAPIENTRY glMap1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); } + void OVR::GLEContext::glMap1f_Hook(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) + { + glMap1f(target, u1, u2, stride, order, points); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMap2d + extern "C" { GLAPI void GLAPIENTRY glMap2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); } + void OVR::GLEContext::glMap2d_Hook(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) + { + glMap2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMap2f + extern "C" { GLAPI void GLAPIENTRY glMap2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); } + void OVR::GLEContext::glMap2f_Hook(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) + { + glMap2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMapGrid1d + extern "C" { GLAPI void GLAPIENTRY glMapGrid1d(GLint un, GLdouble u1, GLdouble u2); } + void OVR::GLEContext::glMapGrid1d_Hook(GLint un, GLdouble u1, GLdouble u2) + { + glMapGrid1d(un, u1, u2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMapGrid1f + extern "C" { GLAPI void GLAPIENTRY glMapGrid1f(GLint un, GLfloat u1, GLfloat u2); } + void OVR::GLEContext::glMapGrid1f_Hook(GLint un, GLfloat u1, GLfloat u2) + { + glMapGrid1f(un, u1, u2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMapGrid2d + extern "C" { GLAPI void GLAPIENTRY glMapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); } + void OVR::GLEContext::glMapGrid2d_Hook(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) + { + glMapGrid2d(un, u1, u2, vn, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMapGrid2f + extern "C" { GLAPI void GLAPIENTRY glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); } + void OVR::GLEContext::glMapGrid2f_Hook(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) + { + glMapGrid2f(un, u1, u2, vn, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMaterialf + extern "C" { GLAPI void GLAPIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param); } + void OVR::GLEContext::glMaterialf_Hook(GLenum face, GLenum pname, GLfloat param) + { + glMaterialf(face, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMaterialfv + extern "C" { GLAPI void GLAPIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params); } + void OVR::GLEContext::glMaterialfv_Hook(GLenum face, GLenum pname, const GLfloat *params) + { + glMaterialfv(face, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMateriali + extern "C" { GLAPI void GLAPIENTRY glMateriali(GLenum face, GLenum pname, GLint param); } + void OVR::GLEContext::glMateriali_Hook(GLenum face, GLenum pname, GLint param) + { + glMateriali(face, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMaterialiv + extern "C" { GLAPI void GLAPIENTRY glMaterialiv(GLenum face, GLenum pname, const GLint *params); } + void OVR::GLEContext::glMaterialiv_Hook(GLenum face, GLenum pname, const GLint *params) + { + glMaterialiv(face, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMatrixMode + extern "C" { GLAPI void GLAPIENTRY glMatrixMode(GLenum mode); } + void OVR::GLEContext::glMatrixMode_Hook(GLenum mode) + { + glMatrixMode(mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMultMatrixd + extern "C" { GLAPI void GLAPIENTRY glMultMatrixd(const GLdouble *m); } + void OVR::GLEContext::glMultMatrixd_Hook(const GLdouble *m) + { + glMultMatrixd(m); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glMultMatrixf + extern "C" { GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat *m); } + void OVR::GLEContext::glMultMatrixf_Hook(const GLfloat *m) + { + glMultMatrixf(m); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNewList + extern "C" { GLAPI void GLAPIENTRY glNewList(GLuint list, GLenum mode); } + void OVR::GLEContext::glNewList_Hook(GLuint list, GLenum mode) + { + glNewList(list, mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3b + extern "C" { GLAPI void GLAPIENTRY glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz); } + void OVR::GLEContext::glNormal3b_Hook(GLbyte nx, GLbyte ny, GLbyte nz) + { + glNormal3b(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3bv + extern "C" { GLAPI void GLAPIENTRY glNormal3bv(const GLbyte *v); } + void OVR::GLEContext::glNormal3bv_Hook(const GLbyte *v) + { + glNormal3bv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3d + extern "C" { GLAPI void GLAPIENTRY glNormal3d(GLdouble nx, GLdouble ny, GLdouble nz); } + void OVR::GLEContext::glNormal3d_Hook(GLdouble nx, GLdouble ny, GLdouble nz) + { + glNormal3d(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3dv + extern "C" { GLAPI void GLAPIENTRY glNormal3dv(const GLdouble *v); } + void OVR::GLEContext::glNormal3dv_Hook(const GLdouble *v) + { + glNormal3dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3f + extern "C" { GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz); } + void OVR::GLEContext::glNormal3f_Hook(GLfloat nx, GLfloat ny, GLfloat nz) + { + glNormal3f(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3fv + extern "C" { GLAPI void GLAPIENTRY glNormal3fv(const GLfloat *v); } + void OVR::GLEContext::glNormal3fv_Hook(const GLfloat *v) + { + glNormal3fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3i + extern "C" { GLAPI void GLAPIENTRY glNormal3i(GLint nx, GLint ny, GLint nz); } + void OVR::GLEContext::glNormal3i_Hook(GLint nx, GLint ny, GLint nz) + { + glNormal3i(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3iv + extern "C" { GLAPI void GLAPIENTRY glNormal3iv(const GLint *v); } + void OVR::GLEContext::glNormal3iv_Hook(const GLint *v) + { + glNormal3iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3s + extern "C" { GLAPI void GLAPIENTRY glNormal3s(GLshort nx, GLshort ny, GLshort nz); } + void OVR::GLEContext::glNormal3s_Hook(GLshort nx, GLshort ny, GLshort nz) + { + glNormal3s(nx, ny, nz); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormal3sv + extern "C" { GLAPI void GLAPIENTRY glNormal3sv(const GLshort *v); } + void OVR::GLEContext::glNormal3sv_Hook(const GLshort *v) + { + glNormal3sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glNormalPointer + extern "C" { GLAPI void GLAPIENTRY glNormalPointer(GLenum type, GLsizei stride, const void *pointer); } + void OVR::GLEContext::glNormalPointer_Hook(GLenum type, GLsizei stride, const void *pointer) + { + glNormalPointer(type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glOrtho + extern "C" { GLAPI void GLAPIENTRY glOrtho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); } + void OVR::GLEContext::glOrtho_Hook(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) + { + glOrtho(left, right, bottom, top, zNear, zFar); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPassThrough + extern "C" { GLAPI void GLAPIENTRY glPassThrough(GLfloat token); } + void OVR::GLEContext::glPassThrough_Hook(GLfloat token) + { + glPassThrough(token); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPixelMapfv + extern "C" { GLAPI void GLAPIENTRY glPixelMapfv(GLenum map, GLsizei mapsize, const GLfloat *values); } + void OVR::GLEContext::glPixelMapfv_Hook(GLenum map, GLsizei mapsize, const GLfloat *values) + { + glPixelMapfv(map, mapsize, values); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPixelMapuiv + extern "C" { GLAPI void GLAPIENTRY glPixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values); } + void OVR::GLEContext::glPixelMapuiv_Hook(GLenum map, GLsizei mapsize, const GLuint *values) + { + glPixelMapuiv(map, mapsize, values); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPixelMapusv + extern "C" { GLAPI void GLAPIENTRY glPixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values); } + void OVR::GLEContext::glPixelMapusv_Hook(GLenum map, GLsizei mapsize, const GLushort *values) + { + glPixelMapusv(map, mapsize, values); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPixelStoref + extern "C" { GLAPI void GLAPIENTRY glPixelStoref(GLenum pname, GLfloat param); } + void OVR::GLEContext::glPixelStoref_Hook(GLenum pname, GLfloat param) + { + glPixelStoref(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPixelStorei + extern "C" { GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param); } + void OVR::GLEContext::glPixelStorei_Hook(GLenum pname, GLint param) + { + glPixelStorei(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPixelTransferf + extern "C" { GLAPI void GLAPIENTRY glPixelTransferf(GLenum pname, GLfloat param); } + void OVR::GLEContext::glPixelTransferf_Hook(GLenum pname, GLfloat param) + { + glPixelTransferf(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPixelTransferi + extern "C" { GLAPI void GLAPIENTRY glPixelTransferi(GLenum pname, GLint param); } + void OVR::GLEContext::glPixelTransferi_Hook(GLenum pname, GLint param) + { + glPixelTransferi(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPixelZoom + extern "C" { GLAPI void GLAPIENTRY glPixelZoom(GLfloat xfactor, GLfloat yfactor); } + void OVR::GLEContext::glPixelZoom_Hook(GLfloat xfactor, GLfloat yfactor) + { + glPixelZoom(xfactor, yfactor); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPointSize + extern "C" { GLAPI void GLAPIENTRY glPointSize(GLfloat size); } + void OVR::GLEContext::glPointSize_Hook(GLfloat size) + { + glPointSize(size); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPolygonMode + extern "C" { GLAPI void GLAPIENTRY glPolygonMode(GLenum face, GLenum mode); } + void OVR::GLEContext::glPolygonMode_Hook(GLenum face, GLenum mode) + { + glPolygonMode(face, mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPolygonOffset + extern "C" { GLAPI void GLAPIENTRY glPolygonOffset(GLfloat factor, GLfloat units); } + void OVR::GLEContext::glPolygonOffset_Hook(GLfloat factor, GLfloat units) + { + glPolygonOffset(factor, units); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPolygonStipple + extern "C" { GLAPI void GLAPIENTRY glPolygonStipple(const GLubyte *mask); } + void OVR::GLEContext::glPolygonStipple_Hook(const GLubyte *mask) + { + glPolygonStipple(mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPopAttrib + extern "C" { GLAPI void GLAPIENTRY glPopAttrib(); } + void OVR::GLEContext::glPopAttrib_Hook() + { + glPopAttrib(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPopClientAttrib + extern "C" { GLAPI void GLAPIENTRY glPopClientAttrib(); } + void OVR::GLEContext::glPopClientAttrib_Hook() + { + glPopClientAttrib(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPopMatrix + extern "C" { GLAPI void GLAPIENTRY glPopMatrix(); } + void OVR::GLEContext::glPopMatrix_Hook() + { + glPopMatrix(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPopName + extern "C" { GLAPI void GLAPIENTRY glPopName(); } + void OVR::GLEContext::glPopName_Hook() + { + glPopName(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPrioritizeTextures + extern "C" { GLAPI void GLAPIENTRY glPrioritizeTextures(GLsizei n, const GLuint *textures, const GLclampf *priorities); } + void OVR::GLEContext::glPrioritizeTextures_Hook(GLsizei n, const GLuint *textures, const GLclampf *priorities) + { + glPrioritizeTextures(n, textures, priorities); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPushAttrib + extern "C" { GLAPI void GLAPIENTRY glPushAttrib(GLbitfield mask); } + void OVR::GLEContext::glPushAttrib_Hook(GLbitfield mask) + { + glPushAttrib(mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPushClientAttrib + extern "C" { GLAPI void GLAPIENTRY glPushClientAttrib(GLbitfield mask); } + void OVR::GLEContext::glPushClientAttrib_Hook(GLbitfield mask) + { + glPushClientAttrib(mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPushMatrix + extern "C" { GLAPI void GLAPIENTRY glPushMatrix(); } + void OVR::GLEContext::glPushMatrix_Hook() + { + glPushMatrix(); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glPushName + extern "C" { GLAPI void GLAPIENTRY glPushName(GLuint name); } + void OVR::GLEContext::glPushName_Hook(GLuint name) + { + glPushName(name); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos2d + extern "C" { GLAPI void GLAPIENTRY glRasterPos2d(GLdouble x, GLdouble y); } + void OVR::GLEContext::glRasterPos2d_Hook(GLdouble x, GLdouble y) + { + glRasterPos2d(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos2dv + extern "C" { GLAPI void GLAPIENTRY glRasterPos2dv(const GLdouble *v); } + void OVR::GLEContext::glRasterPos2dv_Hook(const GLdouble *v) + { + glRasterPos2dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos2f + extern "C" { GLAPI void GLAPIENTRY glRasterPos2f(GLfloat x, GLfloat y); } + void OVR::GLEContext::glRasterPos2f_Hook(GLfloat x, GLfloat y) + { + glRasterPos2f(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos2fv + extern "C" { GLAPI void GLAPIENTRY glRasterPos2fv(const GLfloat *v); } + void OVR::GLEContext::glRasterPos2fv_Hook(const GLfloat *v) + { + glRasterPos2fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos2i + extern "C" { GLAPI void GLAPIENTRY glRasterPos2i(GLint x, GLint y); } + void OVR::GLEContext::glRasterPos2i_Hook(GLint x, GLint y) + { + glRasterPos2i(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos2iv + extern "C" { GLAPI void GLAPIENTRY glRasterPos2iv(const GLint *v); } + void OVR::GLEContext::glRasterPos2iv_Hook(const GLint *v) + { + glRasterPos2iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos2s + extern "C" { GLAPI void GLAPIENTRY glRasterPos2s(GLshort x, GLshort y); } + void OVR::GLEContext::glRasterPos2s_Hook(GLshort x, GLshort y) + { + glRasterPos2s(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos2sv + extern "C" { GLAPI void GLAPIENTRY glRasterPos2sv(const GLshort *v); } + void OVR::GLEContext::glRasterPos2sv_Hook(const GLshort *v) + { + glRasterPos2sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos3d + extern "C" { GLAPI void GLAPIENTRY glRasterPos3d(GLdouble x, GLdouble y, GLdouble z); } + void OVR::GLEContext::glRasterPos3d_Hook(GLdouble x, GLdouble y, GLdouble z) + { + glRasterPos3d(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos3dv + extern "C" { GLAPI void GLAPIENTRY glRasterPos3dv(const GLdouble *v); } + void OVR::GLEContext::glRasterPos3dv_Hook(const GLdouble *v) + { + glRasterPos3dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos3f + extern "C" { GLAPI void GLAPIENTRY glRasterPos3f(GLfloat x, GLfloat y, GLfloat z); } + void OVR::GLEContext::glRasterPos3f_Hook(GLfloat x, GLfloat y, GLfloat z) + { + glRasterPos3f(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos3fv + extern "C" { GLAPI void GLAPIENTRY glRasterPos3fv(const GLfloat *v); } + void OVR::GLEContext::glRasterPos3fv_Hook(const GLfloat *v) + { + glRasterPos3fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos3i + extern "C" { GLAPI void GLAPIENTRY glRasterPos3i(GLint x, GLint y, GLint z); } + void OVR::GLEContext::glRasterPos3i_Hook(GLint x, GLint y, GLint z) + { + glRasterPos3i(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos3iv + extern "C" { GLAPI void GLAPIENTRY glRasterPos3iv(const GLint *v); } + void OVR::GLEContext::glRasterPos3iv_Hook(const GLint *v) + { + glRasterPos3iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos3s + extern "C" { GLAPI void GLAPIENTRY glRasterPos3s(GLshort x, GLshort y, GLshort z); } + void OVR::GLEContext::glRasterPos3s_Hook(GLshort x, GLshort y, GLshort z) + { + glRasterPos3s(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos3sv + extern "C" { GLAPI void GLAPIENTRY glRasterPos3sv(const GLshort *v); } + void OVR::GLEContext::glRasterPos3sv_Hook(const GLshort *v) + { + glRasterPos3sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos4d + extern "C" { GLAPI void GLAPIENTRY glRasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); } + void OVR::GLEContext::glRasterPos4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w) + { + glRasterPos4d(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos4dv + extern "C" { GLAPI void GLAPIENTRY glRasterPos4dv(const GLdouble *v); } + void OVR::GLEContext::glRasterPos4dv_Hook(const GLdouble *v) + { + glRasterPos4dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos4f + extern "C" { GLAPI void GLAPIENTRY glRasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); } + void OVR::GLEContext::glRasterPos4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w) + { + glRasterPos4f(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos4fv + extern "C" { GLAPI void GLAPIENTRY glRasterPos4fv(const GLfloat *v); } + void OVR::GLEContext::glRasterPos4fv_Hook(const GLfloat *v) + { + glRasterPos4fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos4i + extern "C" { GLAPI void GLAPIENTRY glRasterPos4i(GLint x, GLint y, GLint z, GLint w); } + void OVR::GLEContext::glRasterPos4i_Hook(GLint x, GLint y, GLint z, GLint w) + { + glRasterPos4i(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos4iv + extern "C" { GLAPI void GLAPIENTRY glRasterPos4iv(const GLint *v); } + void OVR::GLEContext::glRasterPos4iv_Hook(const GLint *v) + { + glRasterPos4iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos4s + extern "C" { GLAPI void GLAPIENTRY glRasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); } + void OVR::GLEContext::glRasterPos4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w) + { + glRasterPos4s(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRasterPos4sv + extern "C" { GLAPI void GLAPIENTRY glRasterPos4sv(const GLshort *v); } + void OVR::GLEContext::glRasterPos4sv_Hook(const GLshort *v) + { + glRasterPos4sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glReadBuffer + extern "C" { GLAPI void GLAPIENTRY glReadBuffer(GLenum mode); } + void OVR::GLEContext::glReadBuffer_Hook(GLenum mode) + { + glReadBuffer(mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glReadPixels + extern "C" { GLAPI void GLAPIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); } + void OVR::GLEContext::glReadPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels) + { + glReadPixels(x, y, width, height, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRectd + extern "C" { GLAPI void GLAPIENTRY glRectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); } + void OVR::GLEContext::glRectd_Hook(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2) + { + glRectd(x1, y1, x2, y2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRectdv + extern "C" { GLAPI void GLAPIENTRY glRectdv(const GLdouble *v1, const GLdouble *v2); } + void OVR::GLEContext::glRectdv_Hook(const GLdouble *v1, const GLdouble *v2) + { + glRectdv(v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRectf + extern "C" { GLAPI void GLAPIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); } + void OVR::GLEContext::glRectf_Hook(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) + { + glRectf(x1, y1, x2, y2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRectfv + extern "C" { GLAPI void GLAPIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2); } + void OVR::GLEContext::glRectfv_Hook(const GLfloat *v1, const GLfloat *v2) + { + glRectfv(v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRecti + extern "C" { GLAPI void GLAPIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2); } + void OVR::GLEContext::glRecti_Hook(GLint x1, GLint y1, GLint x2, GLint y2) + { + glRecti(x1, y1, x2, y2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRectiv + extern "C" { GLAPI void GLAPIENTRY glRectiv(const GLint *v1, const GLint *v2); } + void OVR::GLEContext::glRectiv_Hook(const GLint *v1, const GLint *v2) + { + glRectiv(v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRects + extern "C" { GLAPI void GLAPIENTRY glRects(GLshort x1, GLshort y1, GLshort x2, GLshort y2); } + void OVR::GLEContext::glRects_Hook(GLshort x1, GLshort y1, GLshort x2, GLshort y2) + { + glRects(x1, y1, x2, y2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRectsv + extern "C" { GLAPI void GLAPIENTRY glRectsv(const GLshort *v1, const GLshort *v2); } + void OVR::GLEContext::glRectsv_Hook(const GLshort *v1, const GLshort *v2) + { + glRectsv(v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRenderMode + extern "C" { GLAPI GLint GLAPIENTRY glRenderMode(GLenum mode); } + GLint OVR::GLEContext::glRenderMode_Hook(GLenum mode) + { + GLint i = glRenderMode(mode); + PostHook(GLE_CURRENT_FUNCTION); + return i; + } + + #undef glRotated + extern "C" { GLAPI void GLAPIENTRY glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); } + void OVR::GLEContext::glRotated_Hook(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) + { + glRotated(angle, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glRotatef + extern "C" { GLAPI void GLAPIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); } + void OVR::GLEContext::glRotatef_Hook(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) + { + glRotatef(angle, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glScaled + extern "C" { GLAPI void GLAPIENTRY glScaled(GLdouble x, GLdouble y, GLdouble z); } + void OVR::GLEContext::glScaled_Hook(GLdouble x, GLdouble y, GLdouble z) + { + glScaled(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glScalef + extern "C" { GLAPI void GLAPIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z); } + void OVR::GLEContext::glScalef_Hook(GLfloat x, GLfloat y, GLfloat z) + { + glScalef(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glScissor + extern "C" { GLAPI void GLAPIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height); } + void OVR::GLEContext::glScissor_Hook(GLint x, GLint y, GLsizei width, GLsizei height) + { + glScissor(x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glSelectBuffer + extern "C" { GLAPI void GLAPIENTRY glSelectBuffer(GLsizei size, GLuint *buffer); } + void OVR::GLEContext::glSelectBuffer_Hook(GLsizei size, GLuint *buffer) + { + glSelectBuffer(size, buffer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glShadeModel + extern "C" { GLAPI void GLAPIENTRY glShadeModel(GLenum mode); } + void OVR::GLEContext::glShadeModel_Hook(GLenum mode) + { + glShadeModel(mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glStencilFunc + extern "C" { GLAPI void GLAPIENTRY glStencilFunc(GLenum func, GLint ref, GLuint mask); } + void OVR::GLEContext::glStencilFunc_Hook(GLenum func, GLint ref, GLuint mask) + { + glStencilFunc(func, ref, mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glStencilMask + extern "C" { GLAPI void GLAPIENTRY glStencilMask(GLuint mask); } + void OVR::GLEContext::glStencilMask_Hook(GLuint mask) + { + glStencilMask(mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glStencilOp + extern "C" { GLAPI void GLAPIENTRY glStencilOp(GLenum fail, GLenum zfail, GLenum zpass); } + void OVR::GLEContext::glStencilOp_Hook(GLenum fail, GLenum zfail, GLenum zpass) + { + glStencilOp(fail, zfail, zpass); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord1d + extern "C" { GLAPI void GLAPIENTRY glTexCoord1d(GLdouble s); } + void OVR::GLEContext::glTexCoord1d_Hook(GLdouble s) + { + glTexCoord1d(s); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord1dv + extern "C" { GLAPI void GLAPIENTRY glTexCoord1dv(const GLdouble *v); } + void OVR::GLEContext::glTexCoord1dv_Hook(const GLdouble *v) + { + glTexCoord1dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord1f + extern "C" { GLAPI void GLAPIENTRY glTexCoord1f(GLfloat s); } + void OVR::GLEContext::glTexCoord1f_Hook(GLfloat s) + { + glTexCoord1f(s); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord1fv + extern "C" { GLAPI void GLAPIENTRY glTexCoord1fv(const GLfloat *v); } + void OVR::GLEContext::glTexCoord1fv_Hook(const GLfloat *v) + { + glTexCoord1fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord1i + extern "C" { GLAPI void GLAPIENTRY glTexCoord1i(GLint s); } + void OVR::GLEContext::glTexCoord1i_Hook(GLint s) + { + glTexCoord1i(s); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord1iv + extern "C" { GLAPI void GLAPIENTRY glTexCoord1iv(const GLint *v); } + void OVR::GLEContext::glTexCoord1iv_Hook(const GLint *v) + { + glTexCoord1iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord1s + extern "C" { GLAPI void GLAPIENTRY glTexCoord1s(GLshort s); } + void OVR::GLEContext::glTexCoord1s_Hook(GLshort s) + { + glTexCoord1s(s); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord1sv + extern "C" { GLAPI void GLAPIENTRY glTexCoord1sv(const GLshort *v); } + void OVR::GLEContext::glTexCoord1sv_Hook(const GLshort *v) + { + glTexCoord1sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord2d + extern "C" { GLAPI void GLAPIENTRY glTexCoord2d(GLdouble s, GLdouble t); } + void OVR::GLEContext::glTexCoord2d_Hook(GLdouble s, GLdouble t) + { + glTexCoord2d(s, t); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord2dv + extern "C" { GLAPI void GLAPIENTRY glTexCoord2dv(const GLdouble *v); } + void OVR::GLEContext::glTexCoord2dv_Hook(const GLdouble *v) + { + glTexCoord2dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord2f + extern "C" { GLAPI void GLAPIENTRY glTexCoord2f(GLfloat s, GLfloat t); } + void OVR::GLEContext::glTexCoord2f_Hook(GLfloat s, GLfloat t) + { + glTexCoord2f(s, t); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord2fv + extern "C" { GLAPI void GLAPIENTRY glTexCoord2fv(const GLfloat *v); } + void OVR::GLEContext::glTexCoord2fv_Hook(const GLfloat *v) + { + glTexCoord2fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord2i + extern "C" { GLAPI void GLAPIENTRY glTexCoord2i(GLint s, GLint t); } + void OVR::GLEContext::glTexCoord2i_Hook(GLint s, GLint t) + { + glTexCoord2i(s, t); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord2iv + extern "C" { GLAPI void GLAPIENTRY glTexCoord2iv(const GLint *v); } + void OVR::GLEContext::glTexCoord2iv_Hook(const GLint *v) + { + glTexCoord2iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord2s + extern "C" { GLAPI void GLAPIENTRY glTexCoord2s(GLshort s, GLshort t); } + void OVR::GLEContext::glTexCoord2s_Hook(GLshort s, GLshort t) + { + glTexCoord2s(s, t); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord2sv + extern "C" { GLAPI void GLAPIENTRY glTexCoord2sv(const GLshort *v); } + void OVR::GLEContext::glTexCoord2sv_Hook(const GLshort *v) + { + glTexCoord2sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord3d + extern "C" { GLAPI void GLAPIENTRY glTexCoord3d(GLdouble s, GLdouble t, GLdouble r); } + void OVR::GLEContext::glTexCoord3d_Hook(GLdouble s, GLdouble t, GLdouble r) + { + glTexCoord3d(s, t, r); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord3dv + extern "C" { GLAPI void GLAPIENTRY glTexCoord3dv(const GLdouble *v); } + void OVR::GLEContext::glTexCoord3dv_Hook(const GLdouble *v) + { + glTexCoord3dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord3f + extern "C" { GLAPI void GLAPIENTRY glTexCoord3f(GLfloat s, GLfloat t, GLfloat r); } + void OVR::GLEContext::glTexCoord3f_Hook(GLfloat s, GLfloat t, GLfloat r) + { + glTexCoord3f(s, t, r); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord3fv + extern "C" { GLAPI void GLAPIENTRY glTexCoord3fv(const GLfloat *v); } + void OVR::GLEContext::glTexCoord3fv_Hook(const GLfloat *v) + { + glTexCoord3fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord3i + extern "C" { GLAPI void GLAPIENTRY glTexCoord3i(GLint s, GLint t, GLint r); } + void OVR::GLEContext::glTexCoord3i_Hook(GLint s, GLint t, GLint r) + { + glTexCoord3i(s, t, r); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord3iv + extern "C" { GLAPI void GLAPIENTRY glTexCoord3iv(const GLint *v); } + void OVR::GLEContext::glTexCoord3iv_Hook(const GLint *v) + { + glTexCoord3iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord3s + extern "C" { GLAPI void GLAPIENTRY glTexCoord3s(GLshort s, GLshort t, GLshort r); } + void OVR::GLEContext::glTexCoord3s_Hook(GLshort s, GLshort t, GLshort r) + { + glTexCoord3s(s, t, r); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord3sv + extern "C" { GLAPI void GLAPIENTRY glTexCoord3sv(const GLshort *v); } + void OVR::GLEContext::glTexCoord3sv_Hook(const GLshort *v) + { + glTexCoord3sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord4d + extern "C" { GLAPI void GLAPIENTRY glTexCoord4d(GLdouble s, GLdouble t, GLdouble r, GLdouble q); } + void OVR::GLEContext::glTexCoord4d_Hook(GLdouble s, GLdouble t, GLdouble r, GLdouble q) + { + glTexCoord4d(s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord4dv + extern "C" { GLAPI void GLAPIENTRY glTexCoord4dv(const GLdouble *v); } + void OVR::GLEContext::glTexCoord4dv_Hook(const GLdouble *v) + { + glTexCoord4dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord4f + extern "C" { GLAPI void GLAPIENTRY glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q); } + void OVR::GLEContext::glTexCoord4f_Hook(GLfloat s, GLfloat t, GLfloat r, GLfloat q) + { + glTexCoord4f(s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord4fv + extern "C" { GLAPI void GLAPIENTRY glTexCoord4fv(const GLfloat *v); } + void OVR::GLEContext::glTexCoord4fv_Hook(const GLfloat *v) + { + glTexCoord4fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord4i + extern "C" { GLAPI void GLAPIENTRY glTexCoord4i(GLint s, GLint t, GLint r, GLint q); } + void OVR::GLEContext::glTexCoord4i_Hook(GLint s, GLint t, GLint r, GLint q) + { + glTexCoord4i(s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord4iv + extern "C" { GLAPI void GLAPIENTRY glTexCoord4iv(const GLint *v); } + void OVR::GLEContext::glTexCoord4iv_Hook(const GLint *v) + { + glTexCoord4iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord4s + extern "C" { GLAPI void GLAPIENTRY glTexCoord4s(GLshort s, GLshort t, GLshort r, GLshort q); } + void OVR::GLEContext::glTexCoord4s_Hook(GLshort s, GLshort t, GLshort r, GLshort q) + { + glTexCoord4s(s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoord4sv + extern "C" { GLAPI void GLAPIENTRY glTexCoord4sv(const GLshort *v); } + void OVR::GLEContext::glTexCoord4sv_Hook(const GLshort *v) + { + glTexCoord4sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexCoordPointer + extern "C" { GLAPI void GLAPIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); } + void OVR::GLEContext::glTexCoordPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer) + { + glTexCoordPointer(size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexEnvf + extern "C" { GLAPI void GLAPIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param); } + void OVR::GLEContext::glTexEnvf_Hook(GLenum target, GLenum pname, GLfloat param) + { + glTexEnvf(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexEnvfv + extern "C" { GLAPI void GLAPIENTRY glTexEnvfv(GLenum target, GLenum pname, const GLfloat *params); } + void OVR::GLEContext::glTexEnvfv_Hook(GLenum target, GLenum pname, const GLfloat *params) + { + glTexEnvfv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexEnvi + extern "C" { GLAPI void GLAPIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param); } + void OVR::GLEContext::glTexEnvi_Hook(GLenum target, GLenum pname, GLint param) + { + glTexEnvi(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexEnviv + extern "C" { GLAPI void GLAPIENTRY glTexEnviv(GLenum target, GLenum pname, const GLint *params); } + void OVR::GLEContext::glTexEnviv_Hook(GLenum target, GLenum pname, const GLint *params) + { + glTexEnviv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexGend + extern "C" { GLAPI void GLAPIENTRY glTexGend(GLenum coord, GLenum pname, GLdouble param); } + void OVR::GLEContext::glTexGend_Hook(GLenum coord, GLenum pname, GLdouble param) + { + glTexGend(coord, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexGendv + extern "C" { GLAPI void GLAPIENTRY glTexGendv(GLenum coord, GLenum pname, const GLdouble *params); } + void OVR::GLEContext::glTexGendv_Hook(GLenum coord, GLenum pname, const GLdouble *params) + { + glTexGendv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexGenf + extern "C" { GLAPI void GLAPIENTRY glTexGenf(GLenum coord, GLenum pname, GLfloat param); } + void OVR::GLEContext::glTexGenf_Hook(GLenum coord, GLenum pname, GLfloat param) + { + glTexGenf(coord, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexGenfv + extern "C" { GLAPI void GLAPIENTRY glTexGenfv(GLenum coord, GLenum pname, const GLfloat *params); } + void OVR::GLEContext::glTexGenfv_Hook(GLenum coord, GLenum pname, const GLfloat *params) + { + glTexGenfv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexGeni + extern "C" { GLAPI void GLAPIENTRY glTexGeni(GLenum coord, GLenum pname, GLint param); } + void OVR::GLEContext::glTexGeni_Hook(GLenum coord, GLenum pname, GLint param) + { + glTexGeni(coord, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexGeniv + extern "C" { GLAPI void GLAPIENTRY glTexGeniv(GLenum coord, GLenum pname, const GLint *params); } + void OVR::GLEContext::glTexGeniv_Hook(GLenum coord, GLenum pname, const GLint *params) + { + glTexGeniv(coord, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexImage1D + extern "C" { GLAPI void GLAPIENTRY glTexImage1D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); } + void OVR::GLEContext::glTexImage1D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels) + { + glTexImage1D(target, level, internalformat, width, border, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexImage2D + extern "C" { GLAPI void GLAPIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); } + void OVR::GLEContext::glTexImage2D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels) + { + glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexParameterf + extern "C" { GLAPI void GLAPIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param); } + void OVR::GLEContext::glTexParameterf_Hook(GLenum target, GLenum pname, GLfloat param) + { + glTexParameterf(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexParameterfv + extern "C" { GLAPI void GLAPIENTRY glTexParameterfv(GLenum target, GLenum pname, const GLfloat *params); } + void OVR::GLEContext::glTexParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params) + { + glTexParameterfv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexParameteri + extern "C" { GLAPI void GLAPIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param); } + void OVR::GLEContext::glTexParameteri_Hook(GLenum target, GLenum pname, GLint param) + { + glTexParameteri(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexParameteriv + extern "C" { GLAPI void GLAPIENTRY glTexParameteriv(GLenum target, GLenum pname, const GLint *params); } + void OVR::GLEContext::glTexParameteriv_Hook(GLenum target, GLenum pname, const GLint *params) + { + glTexParameteriv(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexSubImage1D + extern "C" { GLAPI void GLAPIENTRY glTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); } + void OVR::GLEContext::glTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels) + { + glTexSubImage1D(target, level, xoffset, width, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTexSubImage2D + extern "C" { GLAPI void GLAPIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); } + void OVR::GLEContext::glTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels) + { + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTranslated + extern "C" { GLAPI void GLAPIENTRY glTranslated(GLdouble x, GLdouble y, GLdouble z); } + void OVR::GLEContext::glTranslated_Hook(GLdouble x, GLdouble y, GLdouble z) + { + glTranslated(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glTranslatef + extern "C" { GLAPI void GLAPIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z); } + void OVR::GLEContext::glTranslatef_Hook(GLfloat x, GLfloat y, GLfloat z) + { + glTranslatef(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex2d + extern "C" { GLAPI void GLAPIENTRY glVertex2d(GLdouble x, GLdouble y); } + void OVR::GLEContext::glVertex2d_Hook(GLdouble x, GLdouble y) + { + glVertex2d(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex2dv + extern "C" { GLAPI void GLAPIENTRY glVertex2dv(const GLdouble *v); } + void OVR::GLEContext::glVertex2dv_Hook(const GLdouble *v) + { + glVertex2dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex2f + extern "C" { GLAPI void GLAPIENTRY glVertex2f(GLfloat x, GLfloat y); } + void OVR::GLEContext::glVertex2f_Hook(GLfloat x, GLfloat y) + { + glVertex2f(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex2fv + extern "C" { GLAPI void GLAPIENTRY glVertex2fv(const GLfloat *v); } + void OVR::GLEContext::glVertex2fv_Hook(const GLfloat *v) + { + glVertex2fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex2i + extern "C" { GLAPI void GLAPIENTRY glVertex2i(GLint x, GLint y); } + void OVR::GLEContext::glVertex2i_Hook(GLint x, GLint y) + { + glVertex2i(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex2iv + extern "C" { GLAPI void GLAPIENTRY glVertex2iv(const GLint *v); } + void OVR::GLEContext::glVertex2iv_Hook(const GLint *v) + { + glVertex2iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex2s + extern "C" { GLAPI void GLAPIENTRY glVertex2s(GLshort x, GLshort y); } + void OVR::GLEContext::glVertex2s_Hook(GLshort x, GLshort y) + { + glVertex2s(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex2sv + extern "C" { GLAPI void GLAPIENTRY glVertex2sv(const GLshort *v); } + void OVR::GLEContext::glVertex2sv_Hook(const GLshort *v) + { + glVertex2sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex3d + extern "C" { GLAPI void GLAPIENTRY glVertex3d(GLdouble x, GLdouble y, GLdouble z); } + void OVR::GLEContext::glVertex3d_Hook(GLdouble x, GLdouble y, GLdouble z) + { + glVertex3d(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex3dv + extern "C" { GLAPI void GLAPIENTRY glVertex3dv(const GLdouble *v); } + void OVR::GLEContext::glVertex3dv_Hook(const GLdouble *v) + { + glVertex3dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex3f + extern "C" { GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z); } + void OVR::GLEContext::glVertex3f_Hook(GLfloat x, GLfloat y, GLfloat z) + { + glVertex3f(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex3fv + extern "C" { GLAPI void GLAPIENTRY glVertex3fv(const GLfloat *v); } + void OVR::GLEContext::glVertex3fv_Hook(const GLfloat *v) + { + glVertex3fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex3i + extern "C" { GLAPI void GLAPIENTRY glVertex3i(GLint x, GLint y, GLint z); } + void OVR::GLEContext::glVertex3i_Hook(GLint x, GLint y, GLint z) + { + glVertex3i(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex3iv + extern "C" { GLAPI void GLAPIENTRY glVertex3iv(const GLint *v); } + void OVR::GLEContext::glVertex3iv_Hook(const GLint *v) + { + glVertex3iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex3s + extern "C" { GLAPI void GLAPIENTRY glVertex3s(GLshort x, GLshort y, GLshort z); } + void OVR::GLEContext::glVertex3s_Hook(GLshort x, GLshort y, GLshort z) + { + glVertex3s(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex3sv + extern "C" { GLAPI void GLAPIENTRY glVertex3sv(const GLshort *v); } + void OVR::GLEContext::glVertex3sv_Hook(const GLshort *v) + { + glVertex3sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex4d + extern "C" { GLAPI void GLAPIENTRY glVertex4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); } + void OVR::GLEContext::glVertex4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w) + { + glVertex4d(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex4dv + extern "C" { GLAPI void GLAPIENTRY glVertex4dv(const GLdouble *v); } + void OVR::GLEContext::glVertex4dv_Hook(const GLdouble *v) + { + glVertex4dv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex4f + extern "C" { GLAPI void GLAPIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); } + void OVR::GLEContext::glVertex4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w) + { + glVertex4f(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex4fv + extern "C" { GLAPI void GLAPIENTRY glVertex4fv(const GLfloat *v); } + void OVR::GLEContext::glVertex4fv_Hook(const GLfloat *v) + { + glVertex4fv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex4i + extern "C" { GLAPI void GLAPIENTRY glVertex4i(GLint x, GLint y, GLint z, GLint w); } + void OVR::GLEContext::glVertex4i_Hook(GLint x, GLint y, GLint z, GLint w) + { + glVertex4i(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex4iv + extern "C" { GLAPI void GLAPIENTRY glVertex4iv(const GLint *v); } + void OVR::GLEContext::glVertex4iv_Hook(const GLint *v) + { + glVertex4iv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex4s + extern "C" { GLAPI void GLAPIENTRY glVertex4s(GLshort x, GLshort y, GLshort z, GLshort w); } + void OVR::GLEContext::glVertex4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w) + { + glVertex4s(x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertex4sv + extern "C" { GLAPI void GLAPIENTRY glVertex4sv(const GLshort *v); } + void OVR::GLEContext::glVertex4sv_Hook(const GLshort *v) + { + glVertex4sv(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glVertexPointer + extern "C" { GLAPI void GLAPIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const void *pointer); } + void OVR::GLEContext::glVertexPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer) + { + glVertexPointer(size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + #undef glViewport + extern "C" { GLAPI void GLAPIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height); } + void OVR::GLEContext::glViewport_Hook(GLint x, GLint y, GLsizei width, GLsizei height) + { + glViewport(x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); + } + + + + // Pointer-based functions + void OVR::GLEContext::glBlendColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) + { + if(glBlendColor_Impl) + glBlendColor_Impl(red, green, blue, alpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBlendEquation_Hook(GLenum mode) + { + if(glBlendEquation_Impl) + glBlendEquation_Impl(mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDrawRangeElements_Hook(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) + { + if(glDrawRangeElements_Impl) + glDrawRangeElements_Impl(mode, start, end, count, type, indices); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glTexImage3D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels) + { + if(glTexImage3D_Impl) + glTexImage3D_Impl(target, level, internalformat, width, height, depth, border, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels) + { + if(glTexSubImage3D_Impl) + glTexSubImage3D_Impl(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + PostHook(GLE_CURRENT_FUNCTION); + } + + + void OVR::GLEContext::glCopyTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height) + { + if(glCopyTexSubImage3D_Impl) + glCopyTexSubImage3D_Impl(target, level, xoffset, yoffset, zoffset, x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); + } + + // GL_VERSION_1_2 deprecated functions + /* Not currently supported + void OVR::GLEContext::glColorTable_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table) + { + if(glColorTable_Impl) + glColorTable_Impl(target, internalformat, width, format, type, table); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glColorTableParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params) + { + if(glColorTableParameterfv_Impl) + glColorTableParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glColorTableParameteriv_Hook(GLenum target, GLenum pname, const GLint *params) + { + if(glColorTableParameteriv_Impl) + glColorTableParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCopyColorTable_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) + { + if(glCopyColorTable_Impl) + glCopyColorTable_Impl(target, internalformat, x, y, width); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetColorTable_Hook(GLenum target, GLenum format, GLenum type, GLvoid *table) + { + if(glGetColorTable_Impl) + glGetColorTable_Impl(target, format, type, table); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetColorTableParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) + { + if(glGetColorTableParameterfv_Impl) + glGetColorTableParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetColorTableParameteriv_Hook(GLenum target, GLenum pname, GLint *params) + { + if(glGetColorTableParameteriv_Impl) + glGetColorTableParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glColorSubTable_Hook(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) + { + if(glColorSubTable_Impl) + glColorSubTable_Impl(target, start, count, format, type, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCopyColorSubTable_Hook(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width) + { + if(glCopyColorSubTable_Impl) + glCopyColorSubTable_Impl(target, start, x, y, width); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) + { + if(glConvolutionFilter1D_Impl) + glConvolutionFilter1D_Impl(target, internalformat, width, format, type, image); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) + { + if(glConvolutionFilter2D_Impl) + glConvolutionFilter2D_Impl(target, internalformat, width, height, format, type, image); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glConvolutionParameterf_Hook(GLenum target, GLenum pname, GLfloat params) + { + if(glConvolutionParameterf_Impl) + glConvolutionParameterf_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glConvolutionParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params) + { + if(glConvolutionParameterfv_Impl) + glConvolutionParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glConvolutionParameteri_Hook(GLenum target, GLenum pname, GLint params) + { + if(glConvolutionParameteri_Impl) + glConvolutionParameteri_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glConvolutionParameteriv_Hook(GLenum target, GLenum pname, const GLint *params) + { + if(glConvolutionParameteriv_Impl) + glConvolutionParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCopyConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width) + { + if(glCopyConvolutionFilter1D_Impl) + glCopyConvolutionFilter1D_Impl(target, internalformat, x, y, width); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCopyConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height) + { + if(glCopyConvolutionFilter2D_Impl) + glCopyConvolutionFilter2D_Impl(target, internalformat, x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetConvolutionFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *image) + { + if(glGetConvolutionFilter_Impl) + glGetConvolutionFilter_Impl(target, format, type, image); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetConvolutionParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) + { + if(glGetConvolutionParameterfv_Impl) + glGetConvolutionParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetConvolutionParameteriv_Hook(GLenum target, GLenum pname, GLint *params) + { + if(glGetConvolutionParameteriv_Impl) + glGetConvolutionParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetSeparableFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span) + { + if(glGetSeparableFilter_Impl) + glGetSeparableFilter_Impl(target, format, type, row, column, span); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSeparableFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) + { + if(glSeparableFilter2D_Impl) + glSeparableFilter2D_Impl(target, internalformat, width, height, format, type, row, column); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetHistogram_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) + { + if(glGetHistogram_Impl) + glGetHistogram_Impl(target, reset, format, type, values); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetHistogramParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) + { + if(glGetHistogramParameterfv_Impl) + glGetHistogramParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetHistogramParameteriv_Hook(GLenum target, GLenum pname, GLint *params) + { + if(glGetHistogramParameteriv_Impl) + glGetHistogramParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetMinmax_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values) + { + if(glGetMinmax_Impl) + glGetMinmax_Impl(target, reset, format, type, values); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetMinmaxParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params) + { + if(glGetMinmaxParameterfv_Impl) + glGetMinmaxParameterfv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetMinmaxParameteriv_Hook(GLenum target, GLenum pname, GLint *params) + { + if(glGetMinmaxParameteriv_Impl) + glGetMinmaxParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glHistogram_Hook(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink) + { + if(glHistogram_Impl) + glHistogram_Impl(target, width, internalformat, sink); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMinmax_Hook(GLenum target, GLenum internalformat, GLboolean sink) + { + if(glMinmax_Impl) + glMinmax_Impl(target, internalformat, sink); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glResetHistogram_Hook(GLenum target) + { + if(glResetHistogram_Impl) + glResetHistogram_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glResetMinmax_Hook(GLenum target) + { + if(glResetMinmax_Impl) + glResetMinmax_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); + } + */ + + // GL_VERSION_1_3 + void OVR::GLEContext::glActiveTexture_Hook(GLenum texture) + { + if(glActiveTexture_Impl) + glActiveTexture_Impl(texture); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSampleCoverage_Hook(GLclampf value, GLboolean invert) + { + if(glSampleCoverage_Impl) + glSampleCoverage_Impl(value, invert); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCompressedTexImage3D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data) + { + if(glCompressedTexImage3D_Impl) + glCompressedTexImage3D_Impl(target, level, internalformat, width, height, depth, border, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCompressedTexImage2D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) + { + if(glCompressedTexImage2D_Impl) + glCompressedTexImage2D_Impl(target, level, internalformat, width, height, border, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCompressedTexImage1D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data) + { + if(glCompressedTexImage1D_Impl) + glCompressedTexImage1D_Impl(target, level, internalformat, width, border, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCompressedTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data) + { + if(glCompressedTexSubImage3D_Impl) + glCompressedTexSubImage3D_Impl(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCompressedTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) + { + if(glCompressedTexSubImage2D_Impl) + glCompressedTexSubImage2D_Impl(target, level, xoffset, yoffset, width, height, format, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCompressedTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data) + { + if(glCompressedTexSubImage1D_Impl) + glCompressedTexSubImage1D_Impl(target, level, xoffset, width, format, imageSize, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetCompressedTexImage_Hook(GLenum target, GLint level, GLvoid *img) + { + if(glGetCompressedTexImage_Impl) + glGetCompressedTexImage_Impl(target, level, img); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_1_3 deprecated functions + void OVR::GLEContext::glClientActiveTexture_Hook(GLenum texture) + { + if(glClientActiveTexture_Impl) + glClientActiveTexture_Impl(texture); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord1d_Hook(GLenum target, GLdouble s) + { + if(glMultiTexCoord1d_Impl) + glMultiTexCoord1d_Impl(target, s); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord1dv_Hook(GLenum target, const GLdouble *v) + { + if(glMultiTexCoord1dv_Impl) + glMultiTexCoord1dv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord1f_Hook(GLenum target, GLfloat s) + { + if(glMultiTexCoord1f_Impl) + glMultiTexCoord1f_Impl(target, s); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord1fv_Hook(GLenum target, const GLfloat *v) + { + if(glMultiTexCoord1fv_Impl) + glMultiTexCoord1fv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord1i_Hook(GLenum target, GLint s) + { + if(glMultiTexCoord1i_Impl) + glMultiTexCoord1i_Impl(target, s); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord1iv_Hook(GLenum target, const GLint *v) + { + if(glMultiTexCoord1iv_Impl) + glMultiTexCoord1iv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord1s_Hook(GLenum target, GLshort s) + { + if(glMultiTexCoord1s_Impl) + glMultiTexCoord1s_Impl(target, s); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord1sv_Hook(GLenum target, const GLshort *v) + { + if(glMultiTexCoord1sv_Impl) + glMultiTexCoord1sv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord2d_Hook(GLenum target, GLdouble s, GLdouble t) + { + if(glMultiTexCoord2d_Impl) + glMultiTexCoord2d_Impl(target, s, t); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord2dv_Hook(GLenum target, const GLdouble *v) + { + if(glMultiTexCoord2dv_Impl) + glMultiTexCoord2dv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord2f_Hook(GLenum target, GLfloat s, GLfloat t) + { + if(glMultiTexCoord2f_Impl) + glMultiTexCoord2f_Impl(target, s, t); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord2fv_Hook(GLenum target, const GLfloat *v) + { + if(glMultiTexCoord2fv_Impl) + glMultiTexCoord2fv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord2i_Hook(GLenum target, GLint s, GLint t) + { + if(glMultiTexCoord2i_Impl) + glMultiTexCoord2i_Impl(target, s, t); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord2iv_Hook(GLenum target, const GLint *v) + { + if(glMultiTexCoord2iv_Impl) + glMultiTexCoord2iv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord2s_Hook(GLenum target, GLshort s, GLshort t) + { + if(glMultiTexCoord2s_Impl) + glMultiTexCoord2s_Impl(target, s, t); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord2sv_Hook(GLenum target, const GLshort *v) + { + if(glMultiTexCoord2sv_Impl) + glMultiTexCoord2sv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord3d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r) + { + if(glMultiTexCoord3d_Impl) + glMultiTexCoord3d_Impl(target, s, t, r); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord3dv_Hook(GLenum target, const GLdouble *v) + { + if(glMultiTexCoord3dv_Impl) + glMultiTexCoord3dv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord3f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r) + { + if(glMultiTexCoord3f_Impl) + glMultiTexCoord3f_Impl(target, s, t, r); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord3fv_Hook(GLenum target, const GLfloat *v) + { + if(glMultiTexCoord3fv_Impl) + glMultiTexCoord3fv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord3i_Hook(GLenum target, GLint s, GLint t, GLint r) + { + if(glMultiTexCoord3i_Impl) + glMultiTexCoord3i_Impl(target, s, t, r); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord3iv_Hook(GLenum target, const GLint *v) + { + if(glMultiTexCoord3iv_Impl) + glMultiTexCoord3iv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord3s_Hook(GLenum target, GLshort s, GLshort t, GLshort r) + { + if(glMultiTexCoord3s_Impl) + glMultiTexCoord3s_Impl(target, s, t, r); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord3sv_Hook(GLenum target, const GLshort *v) + { + if(glMultiTexCoord3sv_Impl) + glMultiTexCoord3sv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord4d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q) + { + if(glMultiTexCoord4d_Impl) + glMultiTexCoord4d_Impl(target, s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord4dv_Hook(GLenum target, const GLdouble *v) + { + if(glMultiTexCoord4dv_Impl) + glMultiTexCoord4dv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord4f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) + { + if(glMultiTexCoord4f_Impl) + glMultiTexCoord4f_Impl(target, s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord4fv_Hook(GLenum target, const GLfloat *v) + { + if(glMultiTexCoord4fv_Impl) + glMultiTexCoord4fv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord4i_Hook(GLenum target, GLint s, GLint t, GLint r, GLint q) + { + if(glMultiTexCoord4i_Impl) + glMultiTexCoord4i_Impl(target, s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord4iv_Hook(GLenum target, const GLint *v) + { + if(glMultiTexCoord4iv_Impl) + glMultiTexCoord4iv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord4s_Hook(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q) + { + if(glMultiTexCoord4s_Impl) + glMultiTexCoord4s_Impl(target, s, t, r, q); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiTexCoord4sv_Hook(GLenum target, const GLshort *v) + { + if(glMultiTexCoord4sv_Impl) + glMultiTexCoord4sv_Impl(target, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glLoadTransposeMatrixf_Hook(const GLfloat *m) + { + if(glLoadTransposeMatrixf_Impl) + glLoadTransposeMatrixf_Impl(m); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glLoadTransposeMatrixd_Hook(const GLdouble *m) + { + if(glLoadTransposeMatrixd_Impl) + glLoadTransposeMatrixd_Impl(m); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultTransposeMatrixf_Hook(const GLfloat *m) + { + if(glMultTransposeMatrixf_Impl) + glMultTransposeMatrixf_Impl(m); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultTransposeMatrixd_Hook(const GLdouble *m) + { + if(glMultTransposeMatrixd_Impl) + glMultTransposeMatrixd_Impl(m); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_1_4 + void OVR::GLEContext::glBlendFuncSeparate_Hook(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha) + { + if(glBlendFuncSeparate_Impl) + glBlendFuncSeparate_Impl(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiDrawArrays_Hook(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) + { + if(glMultiDrawArrays_Impl) + glMultiDrawArrays_Impl(mode, first, count, primcount); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiDrawElements_Hook(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount) + { + if(glMultiDrawElements_Impl) + glMultiDrawElements_Impl(mode, count, type, indices, primcount); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glPointParameterf_Hook(GLenum pname, GLfloat param) + { + if(glPointParameterf_Impl) + glPointParameterf_Impl(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glPointParameterfv_Hook(GLenum pname, const GLfloat *params) + { + if(glPointParameterfv_Impl) + glPointParameterfv_Impl(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glPointParameteri_Hook(GLenum pname, GLint param) + { + if(glPointParameteri_Impl) + glPointParameteri_Impl(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glPointParameteriv_Hook(GLenum pname, const GLint *params) + { + if(glPointParameteriv_Impl) + glPointParameteriv_Impl(pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_1_4 deprecated functions + void OVR::GLEContext::glFogCoordf_Hook(GLfloat coord) + { + if(glFogCoordf_Impl) + glFogCoordf_Impl(coord); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFogCoordfv_Hook(const GLfloat *coord) + { + if(glFogCoordfv_Impl) + glFogCoordfv_Impl(coord); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFogCoordd_Hook(GLdouble coord) + { + if(glFogCoordd_Impl) + glFogCoordd_Impl(coord); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFogCoorddv_Hook(const GLdouble *coord) + { + if(glFogCoorddv_Impl) + glFogCoorddv_Impl(coord); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFogCoordPointer_Hook(GLenum type, GLsizei stride, const GLvoid *pointer) + { + if(glFogCoordPointer_Impl) + glFogCoordPointer_Impl(type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue) + { + if(glSecondaryColor3b_Impl) + glSecondaryColor3b_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3bv_Hook(const GLbyte *v) + { + if(glSecondaryColor3bv_Impl) + glSecondaryColor3bv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue) + { + if(glSecondaryColor3d_Impl) + glSecondaryColor3d_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3dv_Hook(const GLdouble *v) + { + if(glSecondaryColor3dv_Impl) + glSecondaryColor3dv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue) + { + if(glSecondaryColor3f_Impl) + glSecondaryColor3f_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3fv_Hook(const GLfloat *v) + { + if(glSecondaryColor3fv_Impl) + glSecondaryColor3fv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3i_Hook(GLint red, GLint green, GLint blue) + { + if(glSecondaryColor3i_Impl) + glSecondaryColor3i_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3iv_Hook(const GLint *v) + { + if(glSecondaryColor3iv_Impl) + glSecondaryColor3iv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3s_Hook(GLshort red, GLshort green, GLshort blue) + { + if(glSecondaryColor3s_Impl) + glSecondaryColor3s_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3sv_Hook(const GLshort *v) + { + if(glSecondaryColor3sv_Impl) + glSecondaryColor3sv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue) + { + if(glSecondaryColor3ub_Impl) + glSecondaryColor3ub_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3ubv_Hook(const GLubyte *v) + { + if(glSecondaryColor3ubv_Impl) + glSecondaryColor3ubv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3ui_Hook(GLuint red, GLuint green, GLuint blue) + { + if(glSecondaryColor3ui_Impl) + glSecondaryColor3ui_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3uiv_Hook(const GLuint *v) + { + if(glSecondaryColor3uiv_Impl) + glSecondaryColor3uiv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3us_Hook(GLushort red, GLushort green, GLushort blue) + { + if(glSecondaryColor3us_Impl) + glSecondaryColor3us_Impl(red, green, blue); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColor3usv_Hook(const GLushort *v) + { + if(glSecondaryColor3usv_Impl) + glSecondaryColor3usv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSecondaryColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) + { + if(glSecondaryColorPointer_Impl) + glSecondaryColorPointer_Impl(size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos2d_Hook(GLdouble x, GLdouble y) + { + if(glWindowPos2d_Impl) + glWindowPos2d_Impl(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos2dv_Hook(const GLdouble *v) + { + if(glWindowPos2dv_Impl) + glWindowPos2dv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos2f_Hook(GLfloat x, GLfloat y) + { + if(glWindowPos2f_Impl) + glWindowPos2f_Impl(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos2fv_Hook(const GLfloat *v) + { + if(glWindowPos2fv_Impl) + glWindowPos2fv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos2i_Hook(GLint x, GLint y) + { + if(glWindowPos2i_Impl) + glWindowPos2i_Impl(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos2iv_Hook(const GLint *v) + { + if(glWindowPos2iv_Impl) + glWindowPos2iv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos2s_Hook(GLshort x, GLshort y) + { + if(glWindowPos2s_Impl) + glWindowPos2s_Impl(x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos2sv_Hook(const GLshort *v) + { + if(glWindowPos2sv_Impl) + glWindowPos2sv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos3d_Hook(GLdouble x, GLdouble y, GLdouble z) + { + if(glWindowPos3d_Impl) + glWindowPos3d_Impl(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos3dv_Hook(const GLdouble *v) + { + if(glWindowPos3dv_Impl) + glWindowPos3dv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos3f_Hook(GLfloat x, GLfloat y, GLfloat z) + { + if(glWindowPos3f_Impl) + glWindowPos3f_Impl(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos3fv_Hook(const GLfloat *v) + { + if(glWindowPos3fv_Impl) + glWindowPos3fv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos3i_Hook(GLint x, GLint y, GLint z) + { + if(glWindowPos3i_Impl) + glWindowPos3i_Impl(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos3iv_Hook(const GLint *v) + { + if(glWindowPos3iv_Impl) + glWindowPos3iv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos3s_Hook(GLshort x, GLshort y, GLshort z) + { + if(glWindowPos3s_Impl) + glWindowPos3s_Impl(x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glWindowPos3sv_Hook(const GLshort *v) + { + if(glWindowPos3sv_Impl) + glWindowPos3sv_Impl(v); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_1_5 + void OVR::GLEContext::glGenQueries_Hook(GLsizei n, GLuint *ids) + { + if(glGenQueries_Impl) + glGenQueries_Impl(n, ids); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDeleteQueries_Hook(GLsizei n, const GLuint *ids) + { + if(glDeleteQueries_Impl) + glDeleteQueries_Impl(n, ids); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsQuery_Hook(GLuint id) + { + GLboolean b = GL_FALSE; + if(glIsQuery_Impl) + b = glIsQuery_Impl(id); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glBeginQuery_Hook(GLenum target, GLuint id) + { + if(glBeginQuery_Impl) + glBeginQuery_Impl(target, id); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glEndQuery_Hook(GLenum target) + { + if(glEndQuery_Impl) + glEndQuery_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetQueryiv_Hook(GLenum target, GLenum pname, GLint *params) + { + if(glGetQueryiv_Impl) + glGetQueryiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetQueryObjectiv_Hook(GLuint id, GLenum pname, GLint *params) + { + if(glGetQueryObjectiv_Impl) + glGetQueryObjectiv_Impl(id, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetQueryObjectuiv_Hook(GLuint id, GLenum pname, GLuint *params) + { + if(glGetQueryObjectuiv_Impl) + glGetQueryObjectuiv_Impl(id, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBindBuffer_Hook(GLenum target, GLuint buffer) + { + if(glBindBuffer_Impl) + glBindBuffer_Impl(target, buffer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDeleteBuffers_Hook(GLsizei n, const GLuint *buffers) + { + if(glDeleteBuffers_Impl) + glDeleteBuffers_Impl(n, buffers); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGenBuffers_Hook(GLsizei n, GLuint *buffers) + { + if(glGenBuffers_Impl) + glGenBuffers_Impl(n, buffers); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsBuffer_Hook(GLuint buffer) + { + GLboolean b = GL_FALSE; + if(glIsBuffer_Impl) + b = glIsBuffer_Impl(buffer); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glBufferData_Hook(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage) + { + if(glBufferData_Impl) + glBufferData_Impl(target, size, data, usage); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data) + { + if(glBufferSubData_Impl) + glBufferSubData_Impl(target, offset, size, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data) + { + if(glGetBufferSubData_Impl) + glGetBufferSubData_Impl(target, offset, size, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLvoid* OVR::GLEContext::glMapBuffer_Hook(GLenum target, GLenum access) + { + GLvoid* p = NULL; + if(glMapBuffer_Impl) + p = glMapBuffer_Impl(target, access); + PostHook(GLE_CURRENT_FUNCTION); + return p; + } + + GLboolean OVR::GLEContext::glUnmapBuffer_Hook(GLenum target) + { + GLboolean b = GL_FALSE; + if(glUnmapBuffer_Impl) + b = glUnmapBuffer_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glGetBufferParameteriv_Hook(GLenum target, GLenum pname, GLint *params) + { + if(glGetBufferParameteriv_Impl) + glGetBufferParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetBufferPointerv_Hook(GLenum target, GLenum pname, GLvoid* *params) + { + if(glGetBufferPointerv_Impl) + glGetBufferPointerv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_2_0 + void OVR::GLEContext::glBlendEquationSeparate_Hook(GLenum modeRGB, GLenum modeAlpha) + { + if(glBlendEquationSeparate_Impl) + glBlendEquationSeparate_Impl(modeRGB, modeAlpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDrawBuffers_Hook(GLsizei n, const GLenum *bufs) + { + if(glDrawBuffers_Impl) + glDrawBuffers_Impl(n, bufs); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glStencilOpSeparate_Hook(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass) + { + if(glStencilOpSeparate_Impl) + glStencilOpSeparate_Impl(face, sfail, dpfail, dppass); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glStencilFuncSeparate_Hook(GLenum face, GLenum func, GLint ref, GLuint mask) + { + if(glStencilFuncSeparate_Impl) + glStencilFuncSeparate_Impl(face, func, ref, mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glStencilMaskSeparate_Hook(GLenum face, GLuint mask) + { + if(glStencilMaskSeparate_Impl) + glStencilMaskSeparate_Impl(face, mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glAttachShader_Hook(GLuint program, GLuint shader) + { + if(glAttachShader_Impl) + glAttachShader_Impl(program, shader); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBindAttribLocation_Hook(GLuint program, GLuint index, const GLchar *name) + { + if(glBindAttribLocation_Impl) + glBindAttribLocation_Impl(program, index, name); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glCompileShader_Hook(GLuint shader) + { + if(glCompileShader_Impl) + glCompileShader_Impl(shader); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLuint OVR::GLEContext::glCreateProgram_Hook() + { + GLuint u = 0; + if(glCreateProgram_Impl) + u = glCreateProgram_Impl(); + PostHook(GLE_CURRENT_FUNCTION); + return u; + } + + GLuint OVR::GLEContext::glCreateShader_Hook(GLenum type) + { + GLuint u = 0; + if(glCreateShader_Impl) + u = glCreateShader_Impl(type); + PostHook(GLE_CURRENT_FUNCTION); + return u; + } + + void OVR::GLEContext::glDeleteProgram_Hook(GLuint program) + { + if(glDeleteProgram_Impl) + glDeleteProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDeleteShader_Hook(GLuint shader) + { + if(glDeleteShader_Impl) + glDeleteShader_Impl(shader); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDetachShader_Hook(GLuint program, GLuint shader) + { + if(glDetachShader_Impl) + glDetachShader_Impl(program, shader); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDisableVertexAttribArray_Hook(GLuint index) + { + if(glDisableVertexAttribArray_Impl) + glDisableVertexAttribArray_Impl(index); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glEnableVertexAttribArray_Hook(GLuint index) + { + if(glEnableVertexAttribArray_Impl) + glEnableVertexAttribArray_Impl(index); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetActiveAttrib_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) + { + if(glGetActiveAttrib_Impl) + glGetActiveAttrib_Impl(program, index, bufSize, length, size, type, name); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetActiveUniform_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) + { + if(glGetActiveUniform_Impl) + glGetActiveUniform_Impl(program, index, bufSize, length, size, type, name); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetAttachedShaders_Hook(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj) + { + if(glGetAttachedShaders_Impl) + glGetAttachedShaders_Impl(program, maxCount, count, obj); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLint OVR::GLEContext::glGetAttribLocation_Hook(GLuint program, const GLchar *name) + { + GLint i = 0; + if(glGetAttribLocation_Impl) + i = glGetAttribLocation_Impl(program, name); + PostHook(GLE_CURRENT_FUNCTION); + return i; + } + + void OVR::GLEContext::glGetProgramiv_Hook(GLuint program, GLenum pname, GLint *params) + { + if(glGetProgramiv_Impl) + glGetProgramiv_Impl(program, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetProgramInfoLog_Hook(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog) + { + if(glGetProgramInfoLog_Impl) + glGetProgramInfoLog_Impl(program, bufSize, length, infoLog); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetShaderiv_Hook(GLuint shader, GLenum pname, GLint *params) + { + if(glGetShaderiv_Impl) + glGetShaderiv_Impl(shader, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetShaderInfoLog_Hook(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog) + { + if(glGetShaderInfoLog_Impl) + glGetShaderInfoLog_Impl(shader, bufSize, length, infoLog); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetShaderSource_Hook(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source) + { + if(glGetShaderSource_Impl) + glGetShaderSource_Impl(shader, bufSize, length, source); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLint OVR::GLEContext::glGetUniformLocation_Hook(GLuint program, const GLchar *name) + { + GLint i = 0; + if(glGetUniformLocation_Impl) + i = glGetUniformLocation_Impl(program, name); + PostHook(GLE_CURRENT_FUNCTION); + return i; + } + + void OVR::GLEContext::glGetUniformfv_Hook(GLuint program, GLint location, GLfloat *params) + { + if(glGetUniformfv_Impl) + glGetUniformfv_Impl(program, location, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetUniformiv_Hook(GLuint program, GLint location, GLint *params) + { + if(glGetUniformiv_Impl) + glGetUniformiv_Impl(program, location, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetVertexAttribdv_Hook(GLuint index, GLenum pname, GLdouble *params) + { + if(glGetVertexAttribdv_Impl) + glGetVertexAttribdv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetVertexAttribfv_Hook(GLuint index, GLenum pname, GLfloat *params) + { + if(glGetVertexAttribfv_Impl) + glGetVertexAttribfv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetVertexAttribiv_Hook(GLuint index, GLenum pname, GLint *params) + { + if(glGetVertexAttribiv_Impl) + glGetVertexAttribiv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetVertexAttribPointerv_Hook(GLuint index, GLenum pname, GLvoid* *pointer) + { + if(glGetVertexAttribPointerv_Impl) + glGetVertexAttribPointerv_Impl(index, pname, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsProgram_Hook(GLuint program) + { + GLboolean b = GL_FALSE; + if(glIsProgram_Impl) + b = glIsProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + GLboolean OVR::GLEContext::glIsShader_Hook(GLuint shader) + { + GLboolean b = GL_FALSE; + if(glIsShader_Impl) + b = glIsShader_Impl(shader); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glLinkProgram_Hook(GLuint program) + { + if(glLinkProgram_Impl) + glLinkProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glShaderSource_Hook(GLuint shader, GLsizei count, const GLchar* *string, const GLint *length) + { + if(glShaderSource_Impl) + glShaderSource_Impl(shader, count, string, length); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUseProgram_Hook(GLuint program) + { + if(glUseProgram_Impl) + glUseProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform1f_Hook(GLint location, GLfloat v0) + { + if(glUniform1f_Impl) + glUniform1f_Impl(location, v0); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform2f_Hook(GLint location, GLfloat v0, GLfloat v1) + { + if(glUniform2f_Impl) + glUniform2f_Impl(location, v0, v1); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform3f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2) + { + if(glUniform3f_Impl) + glUniform3f_Impl(location, v0, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform4f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) + { + if(glUniform4f_Impl) + glUniform4f_Impl(location, v0, v1, v2, v3); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform1i_Hook(GLint location, GLint v0) + { + if(glUniform1i_Impl) + glUniform1i_Impl(location, v0); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform2i_Hook(GLint location, GLint v0, GLint v1) + { + if(glUniform2i_Impl) + glUniform2i_Impl(location, v0, v1); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform3i_Hook(GLint location, GLint v0, GLint v1, GLint v2) + { + if(glUniform3i_Impl) + glUniform3i_Impl(location, v0, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform4i_Hook(GLint location, GLint v0, GLint v1, GLint v2, GLint v3) + { + if(glUniform4i_Impl) + glUniform4i_Impl(location, v0, v1, v2, v3); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform1fv_Hook(GLint location, GLsizei count, const GLfloat *value) + { + if(glUniform1fv_Impl) + glUniform1fv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform2fv_Hook(GLint location, GLsizei count, const GLfloat *value) + { + if(glUniform2fv_Impl) + glUniform2fv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform3fv_Hook(GLint location, GLsizei count, const GLfloat *value) + { + if(glUniform3fv_Impl) + glUniform3fv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform4fv_Hook(GLint location, GLsizei count, const GLfloat *value) + { + if(glUniform4fv_Impl) + glUniform4fv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform1iv_Hook(GLint location, GLsizei count, const GLint *value) + { + if(glUniform1iv_Impl) + glUniform1iv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform2iv_Hook(GLint location, GLsizei count, const GLint *value) + { + if(glUniform2iv_Impl) + glUniform2iv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform3iv_Hook(GLint location, GLsizei count, const GLint *value) + { + if(glUniform3iv_Impl) + glUniform3iv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform4iv_Hook(GLint location, GLsizei count, const GLint *value) + { + if(glUniform4iv_Impl) + glUniform4iv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniformMatrix2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix2fv_Impl) + glUniformMatrix2fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniformMatrix3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix3fv_Impl) + glUniformMatrix3fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniformMatrix4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix4fv_Impl) + glUniformMatrix4fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glValidateProgram_Hook(GLuint program) + { + if(glValidateProgram_Impl) + glValidateProgram_Impl(program); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib1d_Hook(GLuint index, GLdouble x) + { + if(glVertexAttrib1d_Impl) + glVertexAttrib1d_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib1dv_Hook(GLuint index, const GLdouble *v) + { + if(glVertexAttrib1dv_Impl) + glVertexAttrib1dv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib1f_Hook(GLuint index, GLfloat x) + { + if(glVertexAttrib1f_Impl) + glVertexAttrib1f_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib1fv_Hook(GLuint index, const GLfloat *v) + { + if(glVertexAttrib1fv_Impl) + glVertexAttrib1fv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib1s_Hook(GLuint index, GLshort x) + { + if(glVertexAttrib1s_Impl) + glVertexAttrib1s_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib1sv_Hook(GLuint index, const GLshort *v) + { + if(glVertexAttrib1sv_Impl) + glVertexAttrib1sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib2d_Hook(GLuint index, GLdouble x, GLdouble y) + { + if(glVertexAttrib2d_Impl) + glVertexAttrib2d_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib2dv_Hook(GLuint index, const GLdouble *v) + { + if(glVertexAttrib2dv_Impl) + glVertexAttrib2dv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib2f_Hook(GLuint index, GLfloat x, GLfloat y) + { + if(glVertexAttrib2f_Impl) + glVertexAttrib2f_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib2fv_Hook(GLuint index, const GLfloat *v) + { + if(glVertexAttrib2fv_Impl) + glVertexAttrib2fv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib2s_Hook(GLuint index, GLshort x, GLshort y) + { + if(glVertexAttrib2s_Impl) + glVertexAttrib2s_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib2sv_Hook(GLuint index, const GLshort *v) + { + if(glVertexAttrib2sv_Impl) + glVertexAttrib2sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib3d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z) + { + if(glVertexAttrib3d_Impl) + glVertexAttrib3d_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib3dv_Hook(GLuint index, const GLdouble *v) + { + if(glVertexAttrib3dv_Impl) + glVertexAttrib3dv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib3f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z) + { + if(glVertexAttrib3f_Impl) + glVertexAttrib3f_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib3fv_Hook(GLuint index, const GLfloat *v) + { + if(glVertexAttrib3fv_Impl) + glVertexAttrib3fv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib3s_Hook(GLuint index, GLshort x, GLshort y, GLshort z) + { + if(glVertexAttrib3s_Impl) + glVertexAttrib3s_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib3sv_Hook(GLuint index, const GLshort *v) + { + if(glVertexAttrib3sv_Impl) + glVertexAttrib3sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4Nbv_Hook(GLuint index, const GLbyte *v) + { + if(glVertexAttrib4Nbv_Impl) + glVertexAttrib4Nbv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4Niv_Hook(GLuint index, const GLint *v) + { + if(glVertexAttrib4Niv_Impl) + glVertexAttrib4Niv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4Nsv_Hook(GLuint index, const GLshort *v) + { + if(glVertexAttrib4Nsv_Impl) + glVertexAttrib4Nsv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4Nub_Hook(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w) + { + if(glVertexAttrib4Nub_Impl) + glVertexAttrib4Nub_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4Nubv_Hook(GLuint index, const GLubyte *v) + { + if(glVertexAttrib4Nubv_Impl) + glVertexAttrib4Nubv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4Nuiv_Hook(GLuint index, const GLuint *v) + { + if(glVertexAttrib4Nuiv_Impl) + glVertexAttrib4Nuiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4Nusv_Hook(GLuint index, const GLushort *v) + { + if(glVertexAttrib4Nusv_Impl) + glVertexAttrib4Nusv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4bv_Hook(GLuint index, const GLbyte *v) + { + if(glVertexAttrib4bv_Impl) + glVertexAttrib4bv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) + { + if(glVertexAttrib4d_Impl) + glVertexAttrib4d_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4dv_Hook(GLuint index, const GLdouble *v) + { + if(glVertexAttrib4dv_Impl) + glVertexAttrib4dv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) + { + if(glVertexAttrib4f_Impl) + glVertexAttrib4f_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4fv_Hook(GLuint index, const GLfloat *v) + { + if(glVertexAttrib4fv_Impl) + glVertexAttrib4fv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4iv_Hook(GLuint index, const GLint *v) + { + if(glVertexAttrib4iv_Impl) + glVertexAttrib4iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4s_Hook(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w) + { + if(glVertexAttrib4s_Impl) + glVertexAttrib4s_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4sv_Hook(GLuint index, const GLshort *v) + { + if(glVertexAttrib4sv_Impl) + glVertexAttrib4sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4ubv_Hook(GLuint index, const GLubyte *v) + { + if(glVertexAttrib4ubv_Impl) + glVertexAttrib4ubv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4uiv_Hook(GLuint index, const GLuint *v) + { + if(glVertexAttrib4uiv_Impl) + glVertexAttrib4uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttrib4usv_Hook(GLuint index, const GLushort *v) + { + if(glVertexAttrib4usv_Impl) + glVertexAttrib4usv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribPointer_Hook(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer) + { + if(glVertexAttribPointer_Impl) + glVertexAttribPointer_Impl(index, size, type, normalized, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_2_1 + void OVR::GLEContext::glUniformMatrix2x3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix2x3fv_Impl) + glUniformMatrix2x3fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniformMatrix3x2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix3x2fv_Impl) + glUniformMatrix3x2fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniformMatrix2x4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix2x4fv_Impl) + glUniformMatrix2x4fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniformMatrix4x2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix4x2fv_Impl) + glUniformMatrix4x2fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniformMatrix3x4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix3x4fv_Impl) + glUniformMatrix3x4fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniformMatrix4x3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value) + { + if(glUniformMatrix4x3fv_Impl) + glUniformMatrix4x3fv_Impl(location, count, transpose, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_3_0 + void OVR::GLEContext::glColorMaski_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) + { + if(glColorMaski_Impl) + glColorMaski_Impl(index, r, g, b, a); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetBooleani_v_Hook(GLenum target, GLuint index, GLboolean *data) + { + if(glGetBooleani_v_Impl) + glGetBooleani_v_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetIntegeri_v_Hook(GLenum target, GLuint index, GLint *data) + { + if(glGetIntegeri_v_Impl) + glGetIntegeri_v_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glEnablei_Hook(GLenum target, GLuint index) + { + if(glEnablei_Impl) + glEnablei_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDisablei_Hook(GLenum target, GLuint index) + { + if(glDisablei_Impl) + glDisablei_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsEnabledi_Hook(GLenum target, GLuint index) + { + GLboolean b = GL_FALSE; + if(glIsEnabledi_Impl) + b = glIsEnabledi_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glBeginTransformFeedback_Hook(GLenum primitiveMode) + { + if(glBeginTransformFeedback_Impl) + glBeginTransformFeedback_Impl(primitiveMode); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glEndTransformFeedback_Hook() + { + if(glEndTransformFeedback_Impl) + glEndTransformFeedback_Impl(); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBindBufferRange_Hook(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) + { + if(glBindBufferRange_Impl) + glBindBufferRange_Impl(target, index, buffer, offset, size); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBindBufferBase_Hook(GLenum target, GLuint index, GLuint buffer) + { + if(glBindBufferBase_Impl) + glBindBufferBase_Impl(target, index, buffer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glTransformFeedbackVaryings_Hook(GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode) + { + if(glTransformFeedbackVaryings_Impl) + glTransformFeedbackVaryings_Impl(program, count, varyings, bufferMode); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetTransformFeedbackVarying_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) + { + if(glGetTransformFeedbackVarying_Impl) + glGetTransformFeedbackVarying_Impl(program, index, bufSize, length, size, type, name); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glClampColor_Hook(GLenum target, GLenum clamp) + { + if(glClampColor_Impl) + glClampColor_Impl(target, clamp); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBeginConditionalRender_Hook(GLuint id, GLenum mode) + { + if(glBeginConditionalRender_Impl) + glBeginConditionalRender_Impl(id, mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glEndConditionalRender_Hook() + { + if(glEndConditionalRender_Impl) + glEndConditionalRender_Impl(); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribIPointer_Hook(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) + { + if(glVertexAttribIPointer_Impl) + glVertexAttribIPointer_Impl(index, size, type, stride, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetVertexAttribIiv_Hook(GLuint index, GLenum pname, GLint *params) + { + if(glGetVertexAttribIiv_Impl) + glGetVertexAttribIiv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetVertexAttribIuiv_Hook(GLuint index, GLenum pname, GLuint *params) + { + if(glGetVertexAttribIuiv_Impl) + glGetVertexAttribIuiv_Impl(index, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI1i_Hook(GLuint index, GLint x) + { + if(glVertexAttribI1i_Impl) + glVertexAttribI1i_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI2i_Hook(GLuint index, GLint x, GLint y) + { + if(glVertexAttribI2i_Impl) + glVertexAttribI2i_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI3i_Hook(GLuint index, GLint x, GLint y, GLint z) + { + if(glVertexAttribI3i_Impl) + glVertexAttribI3i_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI4i_Hook(GLuint index, GLint x, GLint y, GLint z, GLint w) + { + if(glVertexAttribI4i_Impl) + glVertexAttribI4i_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI1ui_Hook(GLuint index, GLuint x) + { + if(glVertexAttribI1ui_Impl) + glVertexAttribI1ui_Impl(index, x); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI2ui_Hook(GLuint index, GLuint x, GLuint y) + { + if(glVertexAttribI2ui_Impl) + glVertexAttribI2ui_Impl(index, x, y); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI3ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z) + { + if(glVertexAttribI3ui_Impl) + glVertexAttribI3ui_Impl(index, x, y, z); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI4ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w) + { + if(glVertexAttribI4ui_Impl) + glVertexAttribI4ui_Impl(index, x, y, z, w); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI1iv_Hook(GLuint index, const GLint *v) + { + if(glVertexAttribI1iv_Impl) + glVertexAttribI1iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI2iv_Hook(GLuint index, const GLint *v) + { + if(glVertexAttribI2iv_Impl) + glVertexAttribI2iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI3iv_Hook(GLuint index, const GLint *v) + { + if(glVertexAttribI3iv_Impl) + glVertexAttribI3iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI4iv_Hook(GLuint index, const GLint *v) + { + if(glVertexAttribI4iv_Impl) + glVertexAttribI4iv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI1uiv_Hook(GLuint index, const GLuint *v) + { + if(glVertexAttribI1uiv_Impl) + glVertexAttribI1uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI2uiv_Hook(GLuint index, const GLuint *v) + { + if(glVertexAttribI2uiv_Impl) + glVertexAttribI2uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI3uiv_Hook(GLuint index, const GLuint *v) + { + if(glVertexAttribI3uiv_Impl) + glVertexAttribI3uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI4uiv_Hook(GLuint index, const GLuint *v) + { + if(glVertexAttribI4uiv_Impl) + glVertexAttribI4uiv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI4bv_Hook(GLuint index, const GLbyte *v) + { + if(glVertexAttribI4bv_Impl) + glVertexAttribI4bv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI4sv_Hook(GLuint index, const GLshort *v) + { + if(glVertexAttribI4sv_Impl) + glVertexAttribI4sv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI4ubv_Hook(GLuint index, const GLubyte *v) + { + if(glVertexAttribI4ubv_Impl) + glVertexAttribI4ubv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexAttribI4usv_Hook(GLuint index, const GLushort *v) + { + if(glVertexAttribI4usv_Impl) + glVertexAttribI4usv_Impl(index, v); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetUniformuiv_Hook(GLuint program, GLint location, GLuint *params) + { + if(glGetUniformuiv_Impl) + glGetUniformuiv_Impl(program, location, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBindFragDataLocation_Hook(GLuint program, GLuint color, const GLchar *name) + { + if(glBindFragDataLocation_Impl) + glBindFragDataLocation_Impl(program, color, name); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLint OVR::GLEContext::glGetFragDataLocation_Hook(GLuint program, const GLchar *name) + { + GLint i = 0; + if(glGetFragDataLocation_Impl) + i = glGetFragDataLocation_Impl(program, name); + PostHook(GLE_CURRENT_FUNCTION); + return i; + } + + void OVR::GLEContext::glUniform1ui_Hook(GLint location, GLuint v0) + { + if(glUniform1ui_Impl) + glUniform1ui_Impl(location, v0); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform2ui_Hook(GLint location, GLuint v0, GLuint v1) + { + if(glUniform2ui_Impl) + glUniform2ui_Impl(location, v0, v1); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform3ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2) + { + if(glUniform3ui_Impl) + glUniform3ui_Impl(location, v0, v1, v2); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform4ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3) + { + if(glUniform4ui_Impl) + glUniform4ui_Impl(location, v0, v1, v2, v3); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform1uiv_Hook(GLint location, GLsizei count, const GLuint *value) + { + if(glUniform1uiv_Impl) + glUniform1uiv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform2uiv_Hook(GLint location, GLsizei count, const GLuint *value) + { + if(glUniform2uiv_Impl) + glUniform2uiv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform3uiv_Hook(GLint location, GLsizei count, const GLuint *value) + { + if(glUniform3uiv_Impl) + glUniform3uiv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glUniform4uiv_Hook(GLint location, GLsizei count, const GLuint *value) + { + if(glUniform4uiv_Impl) + glUniform4uiv_Impl(location, count, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glTexParameterIiv_Hook(GLenum target, GLenum pname, const GLint *params) + { + if(glTexParameterIiv_Impl) + glTexParameterIiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glTexParameterIuiv_Hook(GLenum target, GLenum pname, const GLuint *params) + { + if(glTexParameterIuiv_Impl) + glTexParameterIuiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetTexParameterIiv_Hook(GLenum target, GLenum pname, GLint *params) + { + if(glGetTexParameterIiv_Impl) + glGetTexParameterIiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetTexParameterIuiv_Hook(GLenum target, GLenum pname, GLuint *params) + { + if(glGetTexParameterIuiv_Impl) + glGetTexParameterIuiv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glClearBufferiv_Hook(GLenum buffer, GLint drawbuffer, const GLint *value) + { + if(glClearBufferiv_Impl) + glClearBufferiv_Impl(buffer, drawbuffer, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glClearBufferuiv_Hook(GLenum buffer, GLint drawbuffer, const GLuint *value) + { + if(glClearBufferuiv_Impl) + glClearBufferuiv_Impl(buffer, drawbuffer, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glClearBufferfv_Hook(GLenum buffer, GLint drawbuffer, const GLfloat *value) + { + if(glClearBufferfv_Impl) + glClearBufferfv_Impl(buffer, drawbuffer, value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glClearBufferfi_Hook(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) + { + if(glClearBufferfi_Impl) + glClearBufferfi_Impl(buffer, drawbuffer, depth, stencil); + PostHook(GLE_CURRENT_FUNCTION); + } + + const GLubyte* OVR::GLEContext::glGetStringi_Hook(GLenum name, GLuint index) + { + const GLubyte* p = NULL; + if(glGetStringi_Impl) + p = glGetStringi_Impl(name, index); + PostHook(GLE_CURRENT_FUNCTION); + return p; + } + + + // GL_VERSION_3_1 + void OVR::GLEContext::glDrawArraysInstanced_Hook(GLenum mode, GLint first, GLsizei count, GLsizei primcount) + { + if(glDrawArraysInstanced_Impl) + glDrawArraysInstanced_Impl(mode, first, count, primcount); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDrawElementsInstanced_Hook(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount) + { + if(glDrawElementsInstanced_Impl) + glDrawElementsInstanced_Impl(mode, count, type, indices, primcount); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glTexBuffer_Hook(GLenum target, GLenum internalformat, GLuint buffer) + { + if(glTexBuffer_Impl) + glTexBuffer_Impl(target, internalformat, buffer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glPrimitiveRestartIndex_Hook(GLuint index) + { + if(glPrimitiveRestartIndex_Impl) + glPrimitiveRestartIndex_Impl(index); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_3_2 + void OVR::GLEContext::glGetInteger64i_v_Hook(GLenum target, GLuint index, GLint64 *data) + { + if(glGetInteger64i_v_Impl) + glGetInteger64i_v_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetBufferParameteri64v_Hook(GLenum target, GLenum pname, GLint64 *params) + { + if(glGetBufferParameteri64v_Impl) + glGetBufferParameteri64v_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFramebufferTexture_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level) + { + if(glFramebufferTexture_Impl) + glFramebufferTexture_Impl(target, attachment, texture, level); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_3_3 + void OVR::GLEContext::glVertexAttribDivisor_Hook(GLuint index, GLuint divisor) + { + if(glVertexAttribDivisor_Impl) + glVertexAttribDivisor_Impl(index, divisor); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_VERSION_4_0 + void OVR::GLEContext::glMinSampleShading_Hook(GLclampf value) + { + if(glMinSampleShading_Impl) + glMinSampleShading_Impl(value); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBlendEquationi_Hook(GLuint buf, GLenum mode) + { + if(glBlendEquationi_Impl) + glBlendEquationi_Impl(buf, mode); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBlendEquationSeparatei_Hook(GLuint buf, GLenum modeRGB, GLenum modeAlpha) + { + if(glBlendEquationSeparatei_Impl) + glBlendEquationSeparatei_Impl(buf, modeRGB, modeAlpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBlendFunci_Hook(GLuint buf, GLenum src, GLenum dst) + { + if(glBlendFunci_Impl) + glBlendFunci_Impl(buf, src, dst); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBlendFuncSeparatei_Hook(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) + { + if(glBlendFuncSeparatei_Impl) + glBlendFuncSeparatei_Impl(buf, srcRGB, dstRGB, srcAlpha, dstAlpha); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_AMD_debug_output + void OVR::GLEContext::glDebugMessageEnableAMD_Hook(GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled) + { + if(glDebugMessageEnableAMD_Impl) + glDebugMessageEnableAMD_Impl(category, severity, count, ids, enabled); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDebugMessageInsertAMD_Hook(GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf) + { + if(glDebugMessageInsertAMD_Impl) + glDebugMessageInsertAMD_Impl(category, severity, id, length, buf); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDebugMessageCallbackAMD_Hook(GLDEBUGPROCAMD callback, GLvoid *userParam) + { + if(glDebugMessageCallbackAMD_Impl) + glDebugMessageCallbackAMD_Impl(callback, userParam); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLuint OVR::GLEContext::glGetDebugMessageLogAMD_Hook(GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message) + { + GLuint u = 0; + if(glGetDebugMessageLogAMD_Impl) + u = glGetDebugMessageLogAMD_Impl(count, bufsize, categories, severities, ids, lengths, message); + PostHook(GLE_CURRENT_FUNCTION); + return u; + } + + + #if defined(GLE_CGL_ENABLED) + // GL_APPLE_element_array + void OVR::GLEContext::glElementPointerAPPLE_Hook(GLenum type, const GLvoid *pointer) + { + if(glElementPointerAPPLE_Impl) + glElementPointerAPPLE_Impl(type, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDrawElementArrayAPPLE_Hook(GLenum mode, GLint first, GLsizei count) + { + if(glDrawElementArrayAPPLE_Impl) + glDrawElementArrayAPPLE_Impl(mode, first, count); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDrawRangeElementArrayAPPLE_Hook(GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count) + { + if(glDrawRangeElementArrayAPPLE_Impl) + glDrawRangeElementArrayAPPLE_Impl(mode, start, end, first, count); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiDrawElementArrayAPPLE_Hook(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) + { + if(glMultiDrawElementArrayAPPLE_Impl) + glMultiDrawElementArrayAPPLE_Impl(mode, first, count, primcount); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMultiDrawRangeElementArrayAPPLE_Hook(GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount) + { + if(glMultiDrawRangeElementArrayAPPLE_Impl) + glMultiDrawRangeElementArrayAPPLE_Impl(mode, start, end, first, count, primcount); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_APPLE_fence + void OVR::GLEContext::glGenFencesAPPLE_Hook(GLsizei n, GLuint *fences) + { + if(glGenFencesAPPLE_Impl) + glGenFencesAPPLE_Impl(n, fences); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDeleteFencesAPPLE_Hook(GLsizei n, const GLuint *fences) + { + if(glDeleteFencesAPPLE_Impl) + glDeleteFencesAPPLE_Impl(n, fences); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSetFenceAPPLE_Hook(GLuint fence) + { + if(glSetFenceAPPLE_Impl) + glSetFenceAPPLE_Impl(fence); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsFenceAPPLE_Hook(GLuint fence) + { + GLboolean b = GL_FALSE; + if(glIsFenceAPPLE_Impl) + b = glIsFenceAPPLE_Impl(fence); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + GLboolean OVR::GLEContext::glTestFenceAPPLE_Hook(GLuint fence) + { + GLboolean b = GL_FALSE; + if(glTestFenceAPPLE_Impl) + b = glTestFenceAPPLE_Impl(fence); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glFinishFenceAPPLE_Hook(GLuint fence) + { + if(glFinishFenceAPPLE_Impl) + glFinishFenceAPPLE_Impl(fence); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glTestObjectAPPLE_Hook(GLenum object, GLuint name) + { + GLboolean b = GL_FALSE; + if(glTestObjectAPPLE_Impl) + b = glTestObjectAPPLE_Impl(object, name); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glFinishObjectAPPLE_Hook(GLenum object, GLint name) + { + if(glFinishObjectAPPLE_Impl) + glFinishObjectAPPLE_Impl(object, name); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_APPLE_flush_buffer_range + void OVR::GLEContext::glBufferParameteriAPPLE_Hook(GLenum target, GLenum pname, GLint param) + { + if(glBufferParameteriAPPLE_Impl) + glBufferParameteriAPPLE_Impl(target, pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFlushMappedBufferRangeAPPLE_Hook(GLenum target, GLintptr offset, GLsizeiptr size) + { + if(glFlushMappedBufferRangeAPPLE_Impl) + glFlushMappedBufferRangeAPPLE_Impl(target, offset, size); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_APPLE_object_purgeable + GLenum OVR::GLEContext::glObjectPurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option) + { + GLenum e = 0; + if(glObjectPurgeableAPPLE_Impl) + e = glObjectPurgeableAPPLE_Impl(objectType, name, option); + PostHook(GLE_CURRENT_FUNCTION); + return e; + } + + GLenum OVR::GLEContext::glObjectUnpurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option) + { + GLenum e = 0; + if(glObjectUnpurgeableAPPLE_Impl) + e =glObjectUnpurgeableAPPLE_Impl(objectType, name, option); + PostHook(GLE_CURRENT_FUNCTION); + return e; + } + + void OVR::GLEContext::glGetObjectParameterivAPPLE_Hook(GLenum objectType, GLuint name, GLenum pname, GLint *params) + { + if(glGetObjectParameterivAPPLE_Impl) + glGetObjectParameterivAPPLE_Impl(objectType, name, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_APPLE_texture_range + void OVR::GLEContext::glTextureRangeAPPLE_Hook(GLenum target, GLsizei length, const GLvoid *pointer) + { + if(glTextureRangeAPPLE_Impl) + glTextureRangeAPPLE_Impl(target, length, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetTexParameterPointervAPPLE_Hook(GLenum target, GLenum pname, GLvoid **params) + { + if(glGetTexParameterPointervAPPLE_Impl) + glGetTexParameterPointervAPPLE_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_APPLE_vertex_array_object + void OVR::GLEContext::glBindVertexArrayAPPLE_Hook(GLuint array) + { + if(glBindVertexArrayAPPLE_Impl) + glBindVertexArrayAPPLE_Impl(array); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDeleteVertexArraysAPPLE_Hook(GLsizei n, const GLuint *arrays) + { + if(glDeleteVertexArraysAPPLE_Impl) + glDeleteVertexArraysAPPLE_Impl(n, arrays); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGenVertexArraysAPPLE_Hook(GLsizei n, GLuint *arrays) + { + if(glGenVertexArraysAPPLE_Impl) + glGenVertexArraysAPPLE_Impl(n, arrays); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsVertexArrayAPPLE_Hook(GLuint array) + { + GLboolean b = GL_FALSE; + if(glIsVertexArrayAPPLE_Impl) + b = glIsVertexArrayAPPLE_Impl(array); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + + // GL_APPLE_vertex_array_range + void OVR::GLEContext::glVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid *pointer) + { + if(glVertexArrayRangeAPPLE_Impl) + glVertexArrayRangeAPPLE_Impl(length, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFlushVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid *pointer) + { + if(glFlushVertexArrayRangeAPPLE_Impl) + glFlushVertexArrayRangeAPPLE_Impl(length, pointer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glVertexArrayParameteriAPPLE_Hook(GLenum pname, GLint param) + { + if(glVertexArrayParameteriAPPLE_Impl) + glVertexArrayParameteriAPPLE_Impl(pname, param); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_APPLE_vertex_program_evaluators + void OVR::GLEContext::glEnableVertexAttribAPPLE_Hook(GLuint index, GLenum pname) + { + if(glEnableVertexAttribAPPLE_Impl) + glEnableVertexAttribAPPLE_Impl(index, pname); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDisableVertexAttribAPPLE_Hook(GLuint index, GLenum pname) + { + if(glDisableVertexAttribAPPLE_Impl) + glDisableVertexAttribAPPLE_Impl(index, pname); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsVertexAttribEnabledAPPLE_Hook(GLuint index, GLenum pname) + { + GLboolean b = GL_FALSE; + if(glIsVertexAttribEnabledAPPLE_Impl) + b = glIsVertexAttribEnabledAPPLE_Impl(index, pname); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glMapVertexAttrib1dAPPLE_Hook(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points) + { + if(glMapVertexAttrib1dAPPLE_Impl) + glMapVertexAttrib1dAPPLE_Impl(index, size, u1, u2, stride, order, points); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMapVertexAttrib1fAPPLE_Hook(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points) + { + if(glMapVertexAttrib1fAPPLE_Impl) + glMapVertexAttrib1fAPPLE_Impl(index, size, u1, u2, stride, order, points); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMapVertexAttrib2dAPPLE_Hook(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points) + { + if(glMapVertexAttrib2dAPPLE_Impl) + glMapVertexAttrib2dAPPLE_Impl(index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glMapVertexAttrib2fAPPLE_Hook(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points) + { + if(glMapVertexAttrib2fAPPLE_Impl) + glMapVertexAttrib2fAPPLE_Impl(index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points); + PostHook(GLE_CURRENT_FUNCTION); + } + #endif // GLE_CGL_ENABLED + + + // GL_ARB_copy_buffer + void OVR::GLEContext::glCopyBufferSubData_Hook(GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size) + { + if(glCopyBufferSubData_Impl) + glCopyBufferSubData_Impl(readtarget, writetarget, readoffset, writeoffset, size); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_ARB_debug_output + void OVR::GLEContext::glDebugMessageControlARB_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled) + { + if(glDebugMessageControlARB_Impl) + glDebugMessageControlARB_Impl(source, type, severity, count, ids, enabled); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDebugMessageInsertARB_Hook(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf) + { + if(glDebugMessageInsertARB_Impl) + glDebugMessageInsertARB_Impl(source, type, id, severity, length, buf); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDebugMessageCallbackARB_Hook(GLDEBUGPROCARB callback, const GLvoid *userParam) + { + if(glDebugMessageCallbackARB_Impl) + glDebugMessageCallbackARB_Impl(callback, userParam); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLuint OVR::GLEContext::glGetDebugMessageLogARB_Hook(GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog) + { + GLuint u = 0; + if(glGetDebugMessageLogARB_Impl) + u = glGetDebugMessageLogARB_Impl(count, bufsize, sources, types, ids, severities, lengths, messageLog); + PostHook(GLE_CURRENT_FUNCTION); + return u; + } + + + // GL_ARB_ES2_compatibility + void OVR::GLEContext::glReleaseShaderCompiler_Hook() + { + if(glReleaseShaderCompiler_Impl) + glReleaseShaderCompiler_Impl(); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glShaderBinary_Hook(GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length) + { + if(glShaderBinary_Impl) + glShaderBinary_Impl(count, shaders, binaryformat, binary, length); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetShaderPrecisionFormat_Hook(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision) + { + if(glGetShaderPrecisionFormat_Impl) + glGetShaderPrecisionFormat_Impl(shadertype, precisiontype, range, precision); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDepthRangef_Hook(GLclampf n, GLclampf f) + { + if(glDepthRangef_Impl) + glDepthRangef_Impl(n, f); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glClearDepthf_Hook(GLclampf d) + { + if(glClearDepthf_Impl) + glClearDepthf_Impl(d); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_ARB_framebuffer_object + GLboolean OVR::GLEContext::glIsRenderbuffer_Hook(GLuint renderbuffer) + { + GLboolean b = GL_FALSE; + if(glIsRenderbuffer_Impl) + b = glIsRenderbuffer_Impl(renderbuffer); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glBindRenderbuffer_Hook(GLenum target, GLuint renderbuffer) + { + if(glBindRenderbuffer_Impl) + glBindRenderbuffer_Impl(target, renderbuffer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDeleteRenderbuffers_Hook(GLsizei n, const GLuint *renderbuffers) + { + if(glDeleteRenderbuffers_Impl) + glDeleteRenderbuffers_Impl(n, renderbuffers); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGenRenderbuffers_Hook(GLsizei n, GLuint *renderbuffers) + { + if(glGenRenderbuffers_Impl) + glGenRenderbuffers_Impl(n, renderbuffers); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glRenderbufferStorage_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height) + { + if(glRenderbufferStorage_Impl) + glRenderbufferStorage_Impl(target, internalformat, width, height); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetRenderbufferParameteriv_Hook(GLenum target, GLenum pname, GLint *params) + { + if(glGetRenderbufferParameteriv_Impl) + glGetRenderbufferParameteriv_Impl(target, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsFramebuffer_Hook(GLuint framebuffer) + { + GLboolean b = GL_FALSE; + if(glIsFramebuffer_Impl) + b = glIsFramebuffer_Impl(framebuffer); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + void OVR::GLEContext::glBindFramebuffer_Hook(GLenum target, GLuint framebuffer) + { + if(glBindFramebuffer_Impl) + glBindFramebuffer_Impl(target, framebuffer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDeleteFramebuffers_Hook(GLsizei n, const GLuint *framebuffers) + { + if(glDeleteFramebuffers_Impl) + glDeleteFramebuffers_Impl(n, framebuffers); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGenFramebuffers_Hook(GLsizei n, GLuint *framebuffers) + { + if(glGenFramebuffers_Impl) + glGenFramebuffers_Impl(n, framebuffers); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLenum OVR::GLEContext::glCheckFramebufferStatus_Hook(GLenum target) + { + GLenum e = 0; + if(glCheckFramebufferStatus_Impl) + e = glCheckFramebufferStatus_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); + return e; + } + + void OVR::GLEContext::glFramebufferTexture1D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) + { + if(glFramebufferTexture1D_Impl) + glFramebufferTexture1D_Impl(target, attachment, textarget, texture, level); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFramebufferTexture2D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) + { + if(glFramebufferTexture2D_Impl) + glFramebufferTexture2D_Impl(target, attachment, textarget, texture, level); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFramebufferTexture3D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset) + { + if(glFramebufferTexture3D_Impl) + glFramebufferTexture3D_Impl(target, attachment, textarget, texture, level, zoffset); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFramebufferRenderbuffer_Hook(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) + { + if(glFramebufferRenderbuffer_Impl) + glFramebufferRenderbuffer_Impl(target, attachment, renderbuffertarget, renderbuffer); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetFramebufferAttachmentParameteriv_Hook(GLenum target, GLenum attachment, GLenum pname, GLint *params) + { + if(glGetFramebufferAttachmentParameteriv_Impl) + glGetFramebufferAttachmentParameteriv_Impl(target, attachment, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGenerateMipmap_Hook(GLenum target) + { + if(glGenerateMipmap_Impl) + glGenerateMipmap_Impl(target); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glBlitFramebuffer_Hook(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) + { + if(glBlitFramebuffer_Impl) + glBlitFramebuffer_Impl(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glRenderbufferStorageMultisample_Hook(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) + { + if(glRenderbufferStorageMultisample_Impl) + glRenderbufferStorageMultisample_Impl(target, samples, internalformat, width, height); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glFramebufferTextureLayer_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) + { + if(glFramebufferTextureLayer_Impl) + glFramebufferTextureLayer_Impl(target, attachment, texture, level, layer); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_ARB_texture_multisample + void OVR::GLEContext::glTexImage2DMultisample_Hook(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) + { + if(glTexImage2DMultisample_Impl) + glTexImage2DMultisample_Impl(target, samples, internalformat, width, height, fixedsamplelocations); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glTexImage3DMultisample_Hook(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) + { + if(glTexImage3DMultisample_Impl) + glTexImage3DMultisample_Impl(target, samples, internalformat, width, height, depth, fixedsamplelocations); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetMultisamplefv_Hook(GLenum pname, GLuint index, GLfloat *val) + { + if(glGetMultisamplefv_Impl) + glGetMultisamplefv_Impl(pname, index, val); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glSampleMaski_Hook(GLuint index, GLbitfield mask) + { + if(glSampleMaski_Impl) + glSampleMaski_Impl(index, mask); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_ARB_timer_query + void OVR::GLEContext::glQueryCounter_Hook(GLuint id, GLenum target) + { + if(glQueryCounter_Impl) + glQueryCounter_Impl(id, target); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetQueryObjecti64v_Hook(GLuint id, GLenum pname, GLint64 *params) + { + if(glGetQueryObjecti64v_Impl) + glGetQueryObjecti64v_Impl(id, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetQueryObjectui64v_Hook(GLuint id, GLenum pname, GLuint64 *params) + { + if(glGetQueryObjectui64v_Impl) + glGetQueryObjectui64v_Impl(id, pname, params); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_ARB_vertex_array_object + void OVR::GLEContext::glBindVertexArray_Hook(GLuint array) + { + if(glBindVertexArray_Impl) + glBindVertexArray_Impl(array); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDeleteVertexArrays_Hook(GLsizei n, const GLuint *arrays) + { + if(glDeleteVertexArrays_Impl) + glDeleteVertexArrays_Impl(n, arrays); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGenVertexArrays_Hook(GLsizei n, GLuint *arrays) + { + if(glGenVertexArrays_Impl) + glGenVertexArrays_Impl(n, arrays); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsVertexArray_Hook(GLuint array) + { + GLboolean b = GL_FALSE; + if(glIsVertexArray_Impl) + b = glIsVertexArray_Impl(array); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + + // GL_EXT_draw_buffers2 + void OVR::GLEContext::glColorMaskIndexedEXT_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a) + { + if(glColorMaskIndexedEXT_Impl) + glColorMaskIndexedEXT_Impl(index, r, g, b, a); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetBooleanIndexedvEXT_Hook(GLenum target, GLuint index, GLboolean *data) + { + if(glGetBooleanIndexedvEXT_Impl) + glGetBooleanIndexedvEXT_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetIntegerIndexedvEXT_Hook(GLenum target, GLuint index, GLint *data) + { + if(glGetIntegerIndexedvEXT_Impl) + glGetIntegerIndexedvEXT_Impl(target, index, data); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glEnableIndexedEXT_Hook(GLenum target, GLuint index) + { + if(glEnableIndexedEXT_Impl) + glEnableIndexedEXT_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDisableIndexedEXT_Hook(GLenum target, GLuint index) + { + if(glDisableIndexedEXT_Impl) + glDisableIndexedEXT_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLboolean OVR::GLEContext::glIsEnabledIndexedEXT_Hook(GLenum target, GLuint index) + { + GLboolean b = GL_FALSE; + if(glIsEnabledIndexedEXT_Impl) + b = glIsEnabledIndexedEXT_Impl(target, index); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + + // GL_KHR_debug + void OVR::GLEContext::glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled) + { + if(glDebugMessageControl_Impl) + glDebugMessageControl_Impl(source, type, severity, count, ids, enabled); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDebugMessageInsert_Hook(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* buf) + { + if(glDebugMessageInsert_Impl) + glDebugMessageInsert_Impl(source, type, id, severity, length, buf); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glDebugMessageCallback_Hook(GLDEBUGPROC callback, const void* userParam) + { + if(glDebugMessageCallback_Impl) + glDebugMessageCallback_Impl(callback, userParam); + PostHook(GLE_CURRENT_FUNCTION); + } + + GLuint OVR::GLEContext::glGetDebugMessageLog_Hook(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, char* messageLog) + { + GLuint u = 0; + if(glGetDebugMessageLog_Impl) + u = glGetDebugMessageLog_Impl(count, bufSize, sources, types, ids, severities, lengths, messageLog); + PostHook(GLE_CURRENT_FUNCTION); + return u; + } + + void OVR::GLEContext::glPushDebugGroup_Hook(GLenum source, GLuint id, GLsizei length, const char * message) + { + if(glPushDebugGroup_Impl) + glPushDebugGroup_Impl(source, id, length, message); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glPopDebugGroup_Hook() + { + if(glPopDebugGroup_Impl) + glPopDebugGroup_Impl(); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei length, const char *label) + { + if(glObjectLabel_Impl) + glObjectLabel_Impl(identifier, name, length, label); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, char *label) + { + if(glGetObjectLabel_Impl) + glGetObjectLabel_Impl(identifier, name, bufSize, length, label); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glObjectPtrLabel_Hook(void* ptr, GLsizei length, const char *label) + { + if(glObjectPtrLabel_Impl) + glObjectPtrLabel_Impl(ptr, length, label); + PostHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glGetObjectPtrLabel_Hook(void* ptr, GLsizei bufSize, GLsizei *length, char *label) + { + if(glGetObjectPtrLabel_Impl) + glGetObjectPtrLabel_Impl(ptr, bufSize, length, label); + PostHook(GLE_CURRENT_FUNCTION); + } + + + // GL_WIN_swap_hint + void OVR::GLEContext::glAddSwapHintRectWIN_Hook(GLint x, GLint y, GLsizei width, GLsizei height) + { + if(glAddSwapHintRectWIN_Impl) + glAddSwapHintRectWIN_Impl(x, y, width, height); + PostHook(GLE_CURRENT_FUNCTION); + } + + + #if defined(GLE_WGL_ENABLED) + // WGL + void OVR::GLEContext::PostWGLHook(const char* /*function*/) + { + // Empty for now. WGL functions don't have a function like glGetError(). + } + + /* We currently don't hook these + #undef wglCopyContext + extern "C" { GLAPI BOOL GLAPIENTRY wglCopyContext(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask); } + BOOL OVR::GLEContext::wglCopyContext_Hook(HGLRC hglrcSrc, HGLRC hglrcDst, UINT mask) + { + BOOL b = wglCopyContext(hglrcSrc, hglrcDst, mask); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglCreateContext + extern "C" { GLAPI HGLRC GLAPIENTRY wglCreateContext(HDC hdc); } + HGLRC OVR::GLEContext::wglCreateContext_Hook(HDC hdc) + { + HGLRC h = wglCreateContext(hdc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + #undef wglCreateLayerContext + extern "C" { GLAPI HGLRC GLAPIENTRY wglCreateLayerContext(HDC hdc, int iLayerPlane); } + HGLRC OVR::GLEContext::wglCreateLayerContext_Hook(HDC hdc, int iLayerPlane) + { + HGLRC h = wglCreateLayerContext(hdc, iLayerPlane); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + #undef wglDeleteContext + extern "C" { GLAPI BOOL GLAPIENTRY wglDeleteContext(HGLRC hglrc); } + BOOL OVR::GLEContext::wglDeleteContext_Hook(HGLRC hglrc) + { + BOOL b = wglDeleteContext(hglrc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglGetCurrentContext + extern "C" { GLAPI HGLRC GLAPIENTRY wglGetCurrentContext(); } + HGLRC OVR::GLEContext::wglGetCurrentContext_Hook() + { + HGLRC h = wglGetCurrentContext(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + #undef wglGetCurrentDC + extern "C" { GLAPI HDC GLAPIENTRY wglGetCurrentDC(); } + HDC OVR::GLEContext::wglGetCurrentDC_Hook() + { + HDC h = wglGetCurrentDC(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + //#undef wglGetProcAddress Not needed because we happen to do it above already. + //extern "C" { GLAPI PROC GLAPIENTRY wglGetProcAddress(LPCSTR lpszProc); } + PROC OVR::GLEContext::wglGetProcAddress_Hook(LPCSTR lpszProc) + { + PROC p = wglGetProcAddress(lpszProc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return p; + } + + #undef wglMakeCurrent + extern "C" { GLAPI BOOL GLAPIENTRY wglMakeCurrent(HDC hdc, HGLRC hglrc); } + BOOL OVR::GLEContext::wglMakeCurrent_Hook(HDC hdc, HGLRC hglrc) + { + BOOL b = wglMakeCurrent(hdc, hglrc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglShareLists + extern "C" { GLAPI BOOL GLAPIENTRY wglShareLists(HGLRC hglrc1, HGLRC hglrc2); } + BOOL OVR::GLEContext::wglShareLists_Hook(HGLRC hglrc1, HGLRC hglrc2) + { + BOOL b = wglShareLists(hglrc1, hglrc2); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglUseFontBitmapsA + extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontBitmapsA(HDC hdc, DWORD first, DWORD count, DWORD listBase); } + BOOL OVR::GLEContext::wglUseFontBitmapsA_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase) + { + BOOL b = wglUseFontBitmapsA(hdc, first, count, listBase); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglUseFontBitmapsW + extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontBitmapsW(HDC hdc, DWORD first, DWORD count, DWORD listBase); } + BOOL OVR::GLEContext::wglUseFontBitmapsW_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase) + { + BOOL b = wglUseFontBitmapsW(hdc, first, count, listBase); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglUseFontOutlinesA + extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontOutlinesA(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf); } + BOOL OVR::GLEContext::wglUseFontOutlinesA_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) + { + BOOL b = wglUseFontOutlinesA(hdc, first, count, listBase, deviation, extrusion, format, lpgmf); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglUseFontOutlinesW + extern "C" { GLAPI BOOL GLAPIENTRY wglUseFontOutlinesW(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf); } + BOOL OVR::GLEContext::wglUseFontOutlinesW_Hook(HDC hdc, DWORD first, DWORD count, DWORD listBase, FLOAT deviation, FLOAT extrusion, int format, LPGLYPHMETRICSFLOAT lpgmf) + { + BOOL b = wglUseFontOutlinesW(hdc, first, count, listBase, deviation, extrusion, format, lpgmf); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglDescribeLayerPlane + extern "C" { GLAPI BOOL GLAPIENTRY wglDescribeLayerPlane(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd); } + BOOL OVR::GLEContext::wglDescribeLayerPlane_Hook(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nBytes, LPLAYERPLANEDESCRIPTOR plpd) + { + BOOL b = wglDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglSetLayerPaletteEntries + extern "C" { GLAPI int GLAPIENTRY wglSetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr); } + int OVR::GLEContext::wglSetLayerPaletteEntries_Hook(HDC hdc, int iLayerPlane, int iStart, int cEntries, const COLORREF *pcr) + { + int i = wglSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; + } + + #undef wglGetLayerPaletteEntries + extern "C" { GLAPI int GLAPIENTRY wglGetLayerPaletteEntries(HDC hdc, int iLayerPlane, int iStart, int cEntries, COLORREF *pcr); } + int OVR::GLEContext::wglGetLayerPaletteEntries_Hook(HDC hdc, int iLayerPlane, int iStart, int cEntries, COLORREF *pcr) + { + int i = wglGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; + } + + #undef wglRealizeLayerPalette + extern "C" { GLAPI BOOL GLAPIENTRY wglRealizeLayerPalette(HDC hdc, int iLayerPlane, BOOL bRealize); } + BOOL OVR::GLEContext::wglRealizeLayerPalette_Hook(HDC hdc, int iLayerPlane, BOOL bRealize) + { + BOOL b = wglRealizeLayerPalette(hdc, iLayerPlane, bRealize); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglSwapLayerBuffers + extern "C" { GLAPI BOOL GLAPIENTRY wglSwapLayerBuffers(HDC hdc, UINT fuPlanes); } + BOOL OVR::GLEContext::wglSwapLayerBuffers_Hook(HDC hdc, UINT fuPlanes) + { + BOOL b = wglSwapLayerBuffers(hdc, fuPlanes); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #undef wglSwapMultipleBuffers + extern "C" { GLAPI DWORD GLAPIENTRY wglSwapMultipleBuffers(UINT i, CONST WGLSWAP* p); } + DWORD OVR::GLEContext::wglSwapMultipleBuffers_Hook(UINT i, CONST WGLSWAP* p) + { + DWORD dw = wglSwapMultipleBuffers(i, p); + PostWGLHook(GLE_CURRENT_FUNCTION); + return dw; + } + */ + + // The rest of the functions are pointer-based. + + // WGL_ARB_buffer_region + HANDLE OVR::GLEContext::wglCreateBufferRegionARB_Hook(HDC hDC, int iLayerPlane, UINT uType) + { + HANDLE h = NULL; + if(wglCreateBufferRegionARB_Impl) + h = wglCreateBufferRegionARB_Impl(hDC, iLayerPlane, uType); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + VOID OVR::GLEContext::wglDeleteBufferRegionARB_Hook(HANDLE hRegion) + { + if(wglDeleteBufferRegionARB_Impl) + wglDeleteBufferRegionARB_Impl(hRegion); + PostWGLHook(GLE_CURRENT_FUNCTION); + } + + BOOL OVR::GLEContext::wglSaveBufferRegionARB_Hook(HANDLE hRegion, int x, int y, int width, int height) + { + BOOL b = FALSE; + if(wglSaveBufferRegionARB_Impl) + b = wglSaveBufferRegionARB_Impl(hRegion, x, y, width, height); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglRestoreBufferRegionARB_Hook(HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc) + { + BOOL b = FALSE; + if(wglRestoreBufferRegionARB_Impl) + b = wglRestoreBufferRegionARB_Impl(hRegion, x, y, width, height, xSrc, ySrc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_ARB_extensions_string + const char * OVR::GLEContext::wglGetExtensionsStringARB_Hook(HDC hdc) + { + const char * p = NULL; + if(wglGetExtensionsStringARB_Impl) + p = wglGetExtensionsStringARB_Impl(hdc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return p; + } + + // WGL_ARB_pixel_format + BOOL OVR::GLEContext::wglGetPixelFormatAttribivARB_Hook(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues) + { + BOOL b = FALSE; + if(wglGetPixelFormatAttribivARB_Impl) + b = wglGetPixelFormatAttribivARB_Impl(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglGetPixelFormatAttribfvARB_Hook(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues) + { + BOOL b = FALSE; + if(wglGetPixelFormatAttribfvARB_Impl) + b = wglGetPixelFormatAttribfvARB_Impl(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglChoosePixelFormatARB_Hook(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats) + { + BOOL b = FALSE; + if(wglChoosePixelFormatARB_Impl) + b = wglChoosePixelFormatARB_Impl(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_ARB_make_current_read + BOOL OVR::GLEContext::wglMakeContextCurrentARB_Hook(HDC hDrawDC, HDC hReadDC, HGLRC hglrc) + { + BOOL b = FALSE; + if(wglMakeContextCurrentARB_Impl) + b = wglMakeContextCurrentARB_Impl(hDrawDC, hReadDC, hglrc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + HDC OVR::GLEContext::wglGetCurrentReadDCARB_Hook() + { + HDC h = NULL; + if(wglGetCurrentReadDCARB_Impl) + h = wglGetCurrentReadDCARB_Impl(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + // WGL_ARB_pbuffer + HPBUFFERARB OVR::GLEContext::wglCreatePbufferARB_Hook(HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList) + { + HPBUFFERARB h = NULL; + if(wglCreatePbufferARB_Impl) + h = wglCreatePbufferARB_Impl(hDC, iPixelFormat, iWidth, iHeight, piAttribList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + HDC OVR::GLEContext::wglGetPbufferDCARB_Hook(HPBUFFERARB hPbuffer) + { + HDC h = NULL; + if(wglGetPbufferDCARB_Impl) + h = wglGetPbufferDCARB_Impl(hPbuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + int OVR::GLEContext::wglReleasePbufferDCARB_Hook(HPBUFFERARB hPbuffer, HDC hDC) + { + int i = 0; + if(wglReleasePbufferDCARB_Impl) + i = wglReleasePbufferDCARB_Impl(hPbuffer, hDC); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; + } + + BOOL OVR::GLEContext::wglDestroyPbufferARB_Hook(HPBUFFERARB hPbuffer) + { + BOOL b = FALSE; + if(wglDestroyPbufferARB_Impl) + b = wglDestroyPbufferARB_Impl(hPbuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglQueryPbufferARB_Hook(HPBUFFERARB hPbuffer, int iAttribute, int *piValue) + { + BOOL b = FALSE; + if(wglQueryPbufferARB_Impl) + b = wglQueryPbufferARB_Impl(hPbuffer, iAttribute, piValue); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_ARB_render_texture + BOOL OVR::GLEContext::wglBindTexImageARB_Hook(HPBUFFERARB hPbuffer, int iBuffer) + { + BOOL b = FALSE; + if(wglBindTexImageARB_Impl) + b = wglBindTexImageARB_Impl(hPbuffer, iBuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglReleaseTexImageARB_Hook(HPBUFFERARB hPbuffer, int iBuffer) + { + BOOL b = FALSE; + if(wglReleaseTexImageARB_Impl) + b = wglReleaseTexImageARB_Impl(hPbuffer, iBuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglSetPbufferAttribARB_Hook(HPBUFFERARB hPbuffer, const int *piAttribList) + { + BOOL b = FALSE; + if(wglSetPbufferAttribARB_Impl) + b = wglSetPbufferAttribARB_Impl(hPbuffer, piAttribList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_NV_present_video + int OVR::GLEContext::wglEnumerateVideoDevicesNV_Hook(HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList) + { + int i = 0; + if(wglEnumerateVideoDevicesNV_Impl) + i = wglEnumerateVideoDevicesNV_Impl(hDC, phDeviceList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; + } + + BOOL OVR::GLEContext::wglBindVideoDeviceNV_Hook(HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList) + { + BOOL b = FALSE; + if(wglBindVideoDeviceNV_Impl) + b = wglBindVideoDeviceNV_Impl(hDC, uVideoSlot, hVideoDevice, piAttribList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglQueryCurrentContextNV_Hook(int iAttribute, int *piValue) + { + BOOL b = FALSE; + if(wglQueryCurrentContextNV_Impl) + b = wglQueryCurrentContextNV_Impl(iAttribute, piValue); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_ARB_create_context + HGLRC OVR::GLEContext::wglCreateContextAttribsARB_Hook(HDC hDC, HGLRC hShareContext, const int *attribList) + { + HGLRC h = NULL; + if(wglCreateContextAttribsARB_Impl) + h = wglCreateContextAttribsARB_Impl(hDC, hShareContext, attribList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + // WGL_EXT_extensions_string + const char * OVR::GLEContext::wglGetExtensionsStringEXT_Hook() + { + const char * p = NULL; + if(wglGetExtensionsStringEXT_Impl) + p = wglGetExtensionsStringEXT_Impl(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return p; + } + + // WGL_EXT_swap_control + BOOL OVR::GLEContext::wglSwapIntervalEXT_Hook(int interval) + { + BOOL b = FALSE; + if(wglSwapIntervalEXT_Impl) + b = wglSwapIntervalEXT_Impl(interval); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + int OVR::GLEContext::wglGetSwapIntervalEXT_Hook() + { + int i = 0; + if(wglGetSwapIntervalEXT_Impl) + i = wglGetSwapIntervalEXT_Impl(); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; + } + + // WGL_OML_sync_control + BOOL OVR::GLEContext::wglGetSyncValuesOML_Hook(HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc) + { + BOOL b = FALSE; + if(wglGetSyncValuesOML_Impl) + b = wglGetSyncValuesOML_Impl(hdc, ust, msc, sbc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglGetMscRateOML_Hook(HDC hdc, INT32 *numerator, INT32 *denominator) + { + BOOL b = FALSE; + if(wglGetMscRateOML_Impl) + b = wglGetMscRateOML_Impl(hdc, numerator, denominator); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + INT64 OVR::GLEContext::wglSwapBuffersMscOML_Hook(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder) + { + INT64 i = 0; + if(wglSwapBuffersMscOML_Impl) + i = wglSwapBuffersMscOML_Impl(hdc, target_msc, divisor, remainder); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; + } + + INT64 OVR::GLEContext::wglSwapLayerBuffersMscOML_Hook(HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder) + { + INT64 i = 0; + if(wglSwapLayerBuffersMscOML_Impl) + i = wglSwapLayerBuffersMscOML_Impl(hdc, fuPlanes, target_msc, divisor, remainder); + PostWGLHook(GLE_CURRENT_FUNCTION); + return i; + } + + BOOL OVR::GLEContext::wglWaitForMscOML_Hook(HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc) + { + BOOL b = FALSE; + if(wglWaitForMscOML_Impl) + b = wglWaitForMscOML_Impl(hdc, target_msc, divisor, remainder, ust, msc, sbc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglWaitForSbcOML_Hook(HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc) + { + BOOL b = FALSE; + if(wglWaitForSbcOML_Impl) + b = wglWaitForSbcOML_Impl(hdc, target_sbc, ust, msc, sbc); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_NV_video_output + BOOL OVR::GLEContext::wglGetVideoDeviceNV_Hook(HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice) + { + BOOL b = FALSE; + if(wglGetVideoDeviceNV_Impl) + b = wglGetVideoDeviceNV_Impl(hDC, numDevices, hVideoDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglReleaseVideoDeviceNV_Hook(HPVIDEODEV hVideoDevice) + { + BOOL b = FALSE; + if(wglReleaseVideoDeviceNV_Impl) + b = wglReleaseVideoDeviceNV_Impl(hVideoDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglBindVideoImageNV_Hook(HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer) + { + BOOL b = FALSE; + if(wglBindVideoImageNV_Impl) + b = wglBindVideoImageNV_Impl(hVideoDevice, hPbuffer, iVideoBuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglReleaseVideoImageNV_Hook(HPBUFFERARB hPbuffer, int iVideoBuffer) + { + BOOL b = FALSE; + if(wglReleaseVideoImageNV_Impl) + b = wglReleaseVideoImageNV_Impl(hPbuffer, iVideoBuffer); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglSendPbufferToVideoNV_Hook(HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock) + { + BOOL b = FALSE; + if(wglSendPbufferToVideoNV_Impl) + b = wglSendPbufferToVideoNV_Impl(hPbuffer, iBufferType, pulCounterPbuffer, bBlock); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglGetVideoInfoNV_Hook(HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo) + { + BOOL b = FALSE; + if(wglGetVideoInfoNV_Impl) + b = wglGetVideoInfoNV_Impl(hpVideoDevice, pulCounterOutputPbuffer, pulCounterOutputVideo); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_NV_swap_group + BOOL OVR::GLEContext::wglJoinSwapGroupNV_Hook(HDC hDC, GLuint group) + { + BOOL b = FALSE; + if(wglJoinSwapGroupNV_Impl) + b = wglJoinSwapGroupNV_Impl(hDC, group); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglBindSwapBarrierNV_Hook(GLuint group, GLuint barrier) + { + BOOL b = FALSE; + if(wglBindSwapBarrierNV_Impl) + b = wglBindSwapBarrierNV_Impl(group, barrier); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglQuerySwapGroupNV_Hook(HDC hDC, GLuint *group, GLuint *barrier) + { + BOOL b = FALSE; + if(wglQuerySwapGroupNV_Impl) + b = wglQuerySwapGroupNV_Impl(hDC, group, barrier); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglQueryMaxSwapGroupsNV_Hook(HDC hDC, GLuint *maxGroups, GLuint *maxBarriers) + { + BOOL b = FALSE; + if(wglQueryMaxSwapGroupsNV_Impl) + b = wglQueryMaxSwapGroupsNV_Impl(hDC, maxGroups, maxBarriers); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglQueryFrameCountNV_Hook(HDC hDC, GLuint *count) + { + BOOL b = FALSE; + if(wglQueryFrameCountNV_Impl) + b = wglQueryFrameCountNV_Impl(hDC, count); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglResetFrameCountNV_Hook(HDC hDC) + { + BOOL b = FALSE; + if(wglResetFrameCountNV_Impl) + b = wglResetFrameCountNV_Impl(hDC); + PostHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_NV_video_capture + BOOL OVR::GLEContext::wglBindVideoCaptureDeviceNV_Hook(UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice) + { + BOOL b = FALSE; + if(wglBindVideoCaptureDeviceNV_Impl) + b = wglBindVideoCaptureDeviceNV_Impl(uVideoSlot, hDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + UINT OVR::GLEContext::wglEnumerateVideoCaptureDevicesNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList) + { + UINT u = 0; + if(wglEnumerateVideoCaptureDevicesNV_Impl) + u = wglEnumerateVideoCaptureDevicesNV_Impl(hDc, phDeviceList); + PostWGLHook(GLE_CURRENT_FUNCTION); + return u; + } + + BOOL OVR::GLEContext::wglLockVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice) + { + BOOL b = FALSE; + if(wglLockVideoCaptureDeviceNV_Impl) + b = wglLockVideoCaptureDeviceNV_Impl(hDc, hDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglQueryVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue) + { + BOOL b = FALSE; + if(wglQueryVideoCaptureDeviceNV_Impl) + b = wglQueryVideoCaptureDeviceNV_Impl(hDc, hDevice, iAttribute, piValue); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglReleaseVideoCaptureDeviceNV_Hook(HDC hDc, HVIDEOINPUTDEVICENV hDevice) + { + BOOL b = FALSE; + if(wglReleaseVideoCaptureDeviceNV_Impl) + b = wglReleaseVideoCaptureDeviceNV_Impl(hDc, hDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_NV_copy_image + BOOL OVR::GLEContext::wglCopyImageSubDataNV_Hook(HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, + GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth) + { + BOOL b = FALSE; + if(wglCopyImageSubDataNV_Impl) + b = wglCopyImageSubDataNV_Impl(hSrcRC, srcName, srcTarget, srcLevel, srcX, srcY, srcZ, hDstRC, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, width, height, depth); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + // WGL_NV_DX_interop + BOOL OVR::GLEContext::wglDXSetResourceShareHandleNV_Hook(void *dxObject, HANDLE shareHandle) + { + BOOL b = FALSE; + if(wglDXSetResourceShareHandleNV_Impl) + b = wglDXSetResourceShareHandleNV_Impl(dxObject, shareHandle); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + HANDLE OVR::GLEContext::wglDXOpenDeviceNV_Hook(void *dxDevice) + { + HANDLE h = NULL; + if(wglDXOpenDeviceNV_Impl) + h = wglDXOpenDeviceNV_Impl(dxDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + BOOL OVR::GLEContext::wglDXCloseDeviceNV_Hook(HANDLE hDevice) + { + BOOL b = FALSE; + if(wglDXCloseDeviceNV_Impl) + b = wglDXCloseDeviceNV_Impl(hDevice); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + HANDLE OVR::GLEContext::wglDXRegisterObjectNV_Hook(HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access) + { + HANDLE h = NULL; + if(wglDXRegisterObjectNV_Impl) + h = wglDXRegisterObjectNV_Impl(hDevice, dxObject, name, type, access); + PostWGLHook(GLE_CURRENT_FUNCTION); + return h; + } + + BOOL OVR::GLEContext::wglDXUnregisterObjectNV_Hook(HANDLE hDevice, HANDLE hObject) + { + BOOL b = FALSE; + if(wglDXUnregisterObjectNV_Impl) + b = wglDXUnregisterObjectNV_Impl(hDevice, hObject); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglDXObjectAccessNV_Hook(HANDLE hObject, GLenum access) + { + BOOL b = FALSE; + if(wglDXObjectAccessNV_Impl) + b = wglDXObjectAccessNV_Impl(hObject, access); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglDXLockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE *hObjects) + { + BOOL b = FALSE; + if(wglDXLockObjectsNV_Impl) + b = wglDXLockObjectsNV_Impl(hDevice, count, hObjects); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + BOOL OVR::GLEContext::wglDXUnlockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE *hObjects) + { + BOOL b = FALSE; + if(wglDXUnlockObjectsNV_Impl) + b = wglDXUnlockObjectsNV_Impl(hDevice, count, hObjects); + PostWGLHook(GLE_CURRENT_FUNCTION); + return b; + } + + #endif // defined(GLE_WGL_ENABLED) + + #if defined(GLE_GLX_ENABLED) + void OVR::GLEContext::PostGLXHook(const char* /*function*/) + { + // Empty for now. GLX functions don't have a function like glGetError(). + } + + // GLX_VERSION_1_0 + // GLX_VERSION_1_1 + // We don't currently implement hooking of these. + + // GLX_VERSION_1_2 + ::Display* OVR::GLEContext::glXGetCurrentDisplay_Hook(void) + { + ::Display* p = NULL; + if(glXGetCurrentDisplay_Impl) + p = glXGetCurrentDisplay_Impl(); + PostGLXHook(GLE_CURRENT_FUNCTION); + return p; + } + + // GLX_VERSION_1_3 + GLXFBConfig* OVR::GLEContext::glXChooseFBConfig_Hook(Display *dpy, int screen, const int *attrib_list, int *nelements) + { + GLXFBConfig* p = NULL; + if(glXChooseFBConfig_Impl) + p = glXChooseFBConfig_Impl(dpy, screen, attrib_list, nelements); + PostGLXHook(GLE_CURRENT_FUNCTION); + return p; + } + + GLXContext OVR::GLEContext::glXCreateNewContext_Hook(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct) + { + GLXContext c = 0; + if(glXCreateNewContext_Impl) + c = glXCreateNewContext_Impl(dpy, config, render_type, share_list, direct); + PostGLXHook(GLE_CURRENT_FUNCTION); + return c; + } + + GLXPbuffer OVR::GLEContext::glXCreatePbuffer_Hook(Display *dpy, GLXFBConfig config, const int *attrib_list) + { + GLXPbuffer b = 0; + if(glXCreatePbuffer_Impl) + b = glXCreatePbuffer_Impl(dpy, config, attrib_list); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; + } + + GLXPixmap OVR::GLEContext::glXCreatePixmap_Hook(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list) + { + GLXPixmap m = 0; + if(glXCreatePixmap_Impl) + m = glXCreatePixmap_Impl(dpy, config, pixmap, attrib_list); + PostGLXHook(GLE_CURRENT_FUNCTION); + return m; + } + + GLXWindow OVR::GLEContext::glXCreateWindow_Hook(Display *dpy, GLXFBConfig config, Window win, const int *attrib_list) + { + GLXWindow w = 0; + if(glXCreateWindow_Impl) + w = glXCreateWindow_Impl(dpy, config, win, attrib_list); + PostGLXHook(GLE_CURRENT_FUNCTION); + return w; + } + + void OVR::GLEContext::glXDestroyPbuffer_Hook(Display *dpy, GLXPbuffer pbuf) + { + if(glXDestroyPbuffer_Impl) + glXDestroyPbuffer_Impl(dpy, pbuf); + PostGLXHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glXDestroyPixmap_Hook(Display *dpy, GLXPixmap pixmap) + { + if(glXDestroyPixmap_Impl) + glXDestroyPixmap_Impl(dpy, pixmap); + PostGLXHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glXDestroyWindow_Hook(Display *dpy, GLXWindow win) + { + if(glXDestroyWindow_Impl) + glXDestroyWindow_Impl(dpy, win); + PostGLXHook(GLE_CURRENT_FUNCTION); + } + + GLXDrawable OVR::GLEContext::glXGetCurrentReadDrawable_Hook(void) + { + GLXDrawable d; + if(glXGetCurrentReadDrawable_Impl) + d = glXGetCurrentReadDrawable_Impl(); + PostGLXHook(GLE_CURRENT_FUNCTION); + return d; + } + + int OVR::GLEContext::glXGetFBConfigAttrib_Hook(Display *dpy, GLXFBConfig config, int attribute, int *value) + { + int i = -1; + if(glXGetFBConfigAttrib_Impl) + i = glXGetFBConfigAttrib_Impl(dpy, config, attribute, value); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; + } + + GLXFBConfig* OVR::GLEContext::glXGetFBConfigs_Hook(Display *dpy, int screen, int *nelements) + { + GLXFBConfig* p = NULL; + if(glXGetFBConfigs_Impl) + p = glXGetFBConfigs_Impl(dpy, screen, nelements); + PostGLXHook(GLE_CURRENT_FUNCTION); + return p; + } + + void OVR::GLEContext::glXGetSelectedEvent_Hook(Display *dpy, GLXDrawable draw, unsigned long *event_mask) + { + if(glXGetSelectedEvent_Impl) + glXGetSelectedEvent_Impl(dpy, draw, event_mask); + PostGLXHook(GLE_CURRENT_FUNCTION); + } + + XVisualInfo* OVR::GLEContext::glXGetVisualFromFBConfig_Hook(Display *dpy, GLXFBConfig config) + { + XVisualInfo* p = NULL; + if(glXGetVisualFromFBConfig_Impl) + p = glXGetVisualFromFBConfig_Impl(dpy, config); + PostGLXHook(GLE_CURRENT_FUNCTION); + return p; + } + + Bool OVR::GLEContext::glXMakeContextCurrent_Hook(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx) + { + Bool b = False; + if(glXMakeContextCurrent_Impl) + b = glXMakeContextCurrent_Impl(dpy, draw, read, ctx); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; + } + + int OVR::GLEContext::glXQueryContext_Hook(Display *dpy, GLXContext ctx, int attribute, int *value) + { + int i = GLX_BAD_ATTRIBUTE; + if(glXQueryContext_Impl) + i = glXQueryContext_Impl(dpy, ctx, attribute, value); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; + } + + void OVR::GLEContext::glXQueryDrawable_Hook(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) + { + if(glXQueryDrawable_Impl) + glXQueryDrawable_Impl(dpy, draw, attribute, value); + PostGLXHook(GLE_CURRENT_FUNCTION); + } + + void OVR::GLEContext::glXSelectEvent_Hook(Display *dpy, GLXDrawable draw, unsigned long event_mask) + { + if(glXSelectEvent_Impl) + glXSelectEvent_Impl(dpy, draw, event_mask); + PostGLXHook(GLE_CURRENT_FUNCTION); + } + + // GLX_VERSION_1_4 + // We don't do hooking of this. + + // GLX_ARB_create_context + GLXContext OVR::GLEContext::glXCreateContextAttribsARB_Hook(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list) + { + GLXContext c = 0; + if(glXCreateContextAttribsARB_Impl) + c = glXCreateContextAttribsARB_Impl(dpy, config, share_context, direct, attrib_list); + PostGLXHook(GLE_CURRENT_FUNCTION); + return c; + } + + // GLX_EXT_swap_control + void OVR::GLEContext::glXSwapIntervalEXT_Hook(Display* dpy, GLXDrawable drawable, int interval) + { + if(glXSwapIntervalEXT_Impl) + glXSwapIntervalEXT_Impl(dpy, drawable, interval); + PostGLXHook(GLE_CURRENT_FUNCTION); + } + + // GLX_OML_sync_control + Bool OVR::GLEContext::glXGetMscRateOML_Hook(Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator) + { + Bool b = False; + if(glXGetMscRateOML_Impl) + b = glXGetMscRateOML_Impl(dpy, drawable, numerator, denominator); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; + } + + Bool OVR::GLEContext::glXGetSyncValuesOML_Hook(Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc) + { + Bool b = False; + if(glXGetSyncValuesOML_Impl) + b = glXGetSyncValuesOML_Impl(dpy, drawable, ust, msc, sbc); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; + } + + int64_t OVR::GLEContext::glXSwapBuffersMscOML_Hook(Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder) + { + int64_t i = 0; + if(glXSwapBuffersMscOML_Impl) + i = glXSwapBuffersMscOML_Impl(dpy, drawable, target_msc, divisor, remainder); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; + } + + Bool OVR::GLEContext::glXWaitForMscOML_Hook(Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc) + { + Bool b = False; + if(glXWaitForMscOML_Impl) + b = glXWaitForMscOML_Impl(dpy, drawable, target_msc, divisor, remainder, ust, msc, sbc); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; + } + + Bool OVR::GLEContext::glXWaitForSbcOML_Hook(Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc) + { + Bool b = False; + if(glXWaitForSbcOML_Impl) + b = glXWaitForSbcOML_Impl(dpy, drawable, target_sbc, ust, msc, sbc); + PostGLXHook(GLE_CURRENT_FUNCTION); + return b; + } + + // GLX_MESA_swap_control + int OVR::GLEContext::glXGetSwapIntervalMESA_Hook() + { + int i = 0; + if(glXGetSwapIntervalMESA_Impl) + i = glXGetSwapIntervalMESA_Impl(); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; + } + + + int OVR::GLEContext::glXSwapIntervalMESA_Hook(unsigned int interval) + { + int i = 0; + if(glXSwapIntervalMESA_Impl) + i = glXSwapIntervalMESA_Impl(interval); + PostGLXHook(GLE_CURRENT_FUNCTION); + return i; + } + + #endif // defined(GLE_GLX_ENABLED) + + #endif // GLE_HOOKING_ENABLED + +//} // namespace OVR + + + diff --git a/LibOVRKernel/Src/GL/CAPI_GLE.h b/LibOVRKernel/Src/GL/CAPI_GLE.h new file mode 100644 index 0000000..a2a353e --- /dev/null +++ b/LibOVRKernel/Src/GL/CAPI_GLE.h @@ -0,0 +1,2016 @@ +/************************************************************************************ + +Filename : CAPI_GLE.h +Content : OpenGL extensions support. Implements a stripped down glew-like + interface with some additional functionality. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +// This file provides functionality similar to a reduced version of GLEW, plus some +// additional functionality that's useful to us, such as function hooking. + +#ifndef OVR_CAPI_GLE_h +#define OVR_CAPI_GLE_h + + +#include "Kernel/OVR_Types.h" +#include "CAPI_GLE_GL.h" + + +/////////////////////////////////////////////////////////////////////////////// +// How to use this functionality +// +// - You #include this header instead of gl.h, glext.h, wglext.h (Windows), gl3.h (Apple), gl3ext.h (Apple), glx.h (Unix), and glxext.h (Unix). +// Currently you still would #include for the base wgl functions on Windows and OpenGL.h or NSOpenGL for the +// base Apple cgl functions. +// +// - You call OpenGL functions just like you would if you were directly using OpenGL +// headers and declarations. The difference is that this module automatically loads +// extensions on init and so you should never need to use GetProcAddress, wglGetProcAddress, etc. +// +// - OpenGL 1.1 functions can be called unilaterally without checking if they are present, +// as it's assumed they are always present. +// +// - In order to use an OpenGL 1.2 or later function you can check the GLEContext::WholeVersion +// variable to tell what version of OpenGL is present and active. Example usage: +// if(GLEContext::GetCurrentContext()->WholeVersion >= 302) // If OpenGL 3.2 or later... +// +// - In order to use an OpenGL extension, you can check the GLE_ helper macro that exists for each +// extension. For example, in order to check of the KHR_debug is present you could do this: +// if(GLE_KHR_debug) ... +// You cannot check for the presence of extensions by testing the function pointer, because +// when hooking is enabled then we aren't using function pointers and thus all functions will +// look like they are present. +// +// - You can test if the OpenGL implementation is OpenGL ES by checking the GLEContext IsGLES +// member variable. For example: if(GLEContext::GetCurrentContext()->IsGLES) ... +// +// - You can test if the OpenGL implementation is a core profile ES by checking the GLEContext IsCoreProfile +// member variable. For example: if(GLEContext::GetCurrentContext()->IsCoreProfile) ... +// +/////////////////////////////////////////////////////////////////////////////// + + +/////////////////////////////////////////////////////////////////////////////// +// How to add support for additional functions to this module. +// +// For an example of how to do this, search the source files for all cases of KHR_Debug and just copy +// the things that it does but for your new extension. +// +// 1) Add the appropriate extension declaration to CAPI_GLE_GL.h, preferably by +// copying it from the standard header file it normally comes from. If it's +// platform-specific (e.g. a Windows wgl function) then make sure it's declared +// within the given platform section. Note that there are potentially #defines, typedefs, +// function typedefs, and function #defines. There is always a GLE_ macro declared which +// lets the user know at runtime whether the extension is present. +// Note that entries are alphabetically sorted in these files. +// e.g. #ifndef GL_KHR_debug +// #define GL_KHR_debug 1 +// #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 etc. +// typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (); +// #define glPopDebugGroup GLEGetCurrentFunction(glPopDebugGroup) +// #define GLE_KHR_debug GLEGetCurrentVariable(gl_KHR_debug) +// #endif etc. +// +// 2) Add a hook function for in the hook section of the GLEContext class in this header, +// ideally in the same order it's declared in the CAPI_GLE_GL.h so it's easily readable. +// e.g. void glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); etc. +// +// 3) Add a declaration for each interface function to the GLEContext class in this header. +// e.g. PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback_Impl; etc. +// +// 4) Add code to GLEContext::InitExtensionLoad to load the function pointer. +// e.g. GLELoadProc(glDebugMessageCallback_Impl, glDebugMessageCallback); etc. +// +// 5) Add code to GLEContext::InitExtensionSupport to detect the extension support. +// On Mac, core profile functions aren't identified as extensions and so in addition +// to detecting them you need to unilaterally set them as available when using 3.2+ +// by adding them to the section at the bottom of InitExtensionSupport. +// e.g. { gl_KHR_debug, "GL_KHR_debug" }, etc. +// +// 6) Implement the GLEContext hook function(s) you declared. +// e.g. void OVR::GLEContext::glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled) +// { +// if(glDebugMessageControl_Impl) +// glDebugMessageControl_Impl(source, type, severity, count, ids, enabled); +// PostHook(); +// } +// +// In order to test this, build with GLE_HOOKING_ENABLED defined and not defined. +// +// Note that if the extension is a WGL-, GLX-, or CGL-specific extension, they are handled like above +// but are in their own section below the section for regular OpenGL extensions. +// +// In some cases the given interface may already be present by currently commented out, +// in which case you can simply un-comment it to enable it. +/////////////////////////////////////////////////////////////////////////////// + + +namespace OVR +{ + // Generic OpenGL GetProcAddress function interface. Maps to platform-specific functionality + // internally. On Windows this is equivalent to wglGetProcAddress as opposed to global GetProcAddress. + void* GLEGetProcAddress(const char* name); + + + // GLEContext + // + // Manages a collection of OpenGL extension interfaces. + // If the application has multiple OpenGL unrelated contexts then you will want to create a + // different instance of this class for each one you intend to use it with. + // + // Example usage: + // GLEContext gGLEContext; + // + // GLEContext::SetCurrentContext(&gGLEContext); + // gGLEContext.PlatformInit(); // Initializes WGL/GLX/etc. platform-specific OpenGL functionality + // + // if(GLE_WGL_ARB_create_context) // If wglCreateContextAttribsARB is available... + // { + // int attribList[] = { WGL_CONTEXT_MAJOR_VERSION_ARB, 3, WGL_CONTEXT_MINOR_VERSION_ARB, 2, WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB, None }; + // HGLRC h = wglCreateContextAttribsARB(hDC, 0, attribList); + // [...] + // } + // + // gGLEContext.Init(); // Must be called after an OpenGL context has been created. + // + // if(GLE_WHOLE_VERSION() >= 302) // If OpenGL 3.2 or later + // { + // glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, someTexture, 0); // This is an OpenGL 3.2 function. + // [...] + // } + // + // if(GLE_GL_ARB_texture_multisample) // If the GL_ARB_texture_multisample extension is available... + // { + // glEnable(GL_SAMPLE_MASK); + // glSampleMaski(0, 0x1); + // [...] + // } + // + // [...] + // + // gGLEContext.Shutdown(); + // + GLE_CLASS_EXPORT class GLEContext + { + public: + GLEContext(); + ~GLEContext(); + + // Initializes platform-specific functionality (e.g. Windows WGL, Unix GLX, Android EGL, Apple CGL). + // You would typically call this before creating an OpenGL context and using platform-specific functions. + void PlatformInit(); + bool IsPlatformInitialized() const; + + // Loads all the extensions from the current OpenGL context. This must be called after an OpenGL context + // has been created and made current. + void Init(); + bool IsInitialized() const; + + // Clears all the extensions initialized by PlatformInit and Init. + void Shutdown(); + + void SetEnableHookGetError(bool enabled) + { EnableHookGetError = enabled; } + + // Returns the default instance of this class. + static GLEContext* GetCurrentContext(); + + // Sets the default instance of this class. This should be called after enabling a new OpenGL context. + // This sets the current GLEContext; it does not set the underlying OpenGL context itself. + static void SetCurrentContext(GLEContext*); + + public: + // OpenGL version information + int MajorVersion; // OpenGL major version + int MinorVersion; // OpenGL minor version + int WholeVersion; // Equals ((MajorVersion * 100) + MinorVersion). Example usage: if(glv.WholeVersion >= 302) // If OpenGL v3.02+ ... + bool IsGLES; // Open GL ES? + bool IsCoreProfile; // Is the current OpenGL context a core profile context? Its trueness may be a false positive but will never be a false negative. + bool EnableHookGetError; // If enabled then hook functions call glGetError after making the call. + + int PlatformMajorVersion; // GLX/WGL/EGL/CGL version. Not the same as OpenGL version. + int PlatformMinorVersion; + int PlatformWholeVersion; + + void InitVersion(); // Initializes the version information (e.g. MajorVersion). Called by the public Init function. + void InitExtensionLoad(); // Loads the function addresses into the function pointers. + void InitExtensionSupport(); // Loads the boolean extension support booleans. + + void InitPlatformVersion(); + void InitPlatformExtensionLoad(); + void InitPlatformExtensionSupport(); + + public: + // GL_VERSION_1_1 + // Not normally included because all OpenGL 1.1 functionality is always present. But if we have + // hooking enabled then we implement our own version of each function. + #if defined(GLE_HOOKING_ENABLED) + //void PreHook(const char* functionName); // Called at the beginning of a hook function. + void PostHook(const char* functionName); // Called at the end of a hook function. + + void glAccum_Hook(GLenum op, GLfloat value); + void glAlphaFunc_Hook(GLenum func, GLclampf ref); + GLboolean glAreTexturesResident_Hook(GLsizei n, const GLuint *textures, GLboolean *residences); + void glArrayElement_Hook(GLint i); + void glBegin_Hook(GLenum mode); + void glBindTexture_Hook(GLenum target, GLuint texture); + void glBitmap_Hook(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); + void glBlendFunc_Hook(GLenum sfactor, GLenum dfactor); + void glCallList_Hook(GLuint list); + void glCallLists_Hook(GLsizei n, GLenum type, const void *lists); + void glClear_Hook(GLbitfield mask); + void glClearAccum_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void glClearColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void glClearDepth_Hook(GLclampd depth); + void glClearIndex_Hook(GLfloat c); + void glClearStencil_Hook(GLint s); + void glClipPlane_Hook(GLenum plane, const GLdouble *equation); + void glColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue); + void glColor3bv_Hook(const GLbyte *v); + void glColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue); + void glColor3dv_Hook(const GLdouble *v); + void glColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue); + void glColor3fv_Hook(const GLfloat *v); + void glColor3i_Hook(GLint red, GLint green, GLint blue); + void glColor3iv_Hook(const GLint *v); + void glColor3s_Hook(GLshort red, GLshort green, GLshort blue); + void glColor3sv_Hook(const GLshort *v); + void glColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue); + void glColor3ubv_Hook(const GLubyte *v); + void glColor3ui_Hook(GLuint red, GLuint green, GLuint blue); + void glColor3uiv_Hook(const GLuint *v); + void glColor3us_Hook(GLushort red, GLushort green, GLushort blue); + void glColor3usv_Hook(const GLushort *v); + void glColor4b_Hook(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); + void glColor4bv_Hook(const GLbyte *v); + void glColor4d_Hook(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); + void glColor4dv_Hook(const GLdouble *v); + void glColor4f_Hook(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + void glColor4fv_Hook(const GLfloat *v); + void glColor4i_Hook(GLint red, GLint green, GLint blue, GLint alpha); + void glColor4iv_Hook(const GLint *v); + void glColor4s_Hook(GLshort red, GLshort green, GLshort blue, GLshort alpha); + void glColor4sv_Hook(const GLshort *v); + void glColor4ub_Hook(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); + void glColor4ubv_Hook(const GLubyte *v); + void glColor4ui_Hook(GLuint red, GLuint green, GLuint blue, GLuint alpha); + void glColor4uiv_Hook(const GLuint *v); + void glColor4us_Hook(GLushort red, GLushort green, GLushort blue, GLushort alpha); + void glColor4usv_Hook(const GLushort *v); + void glColorMask_Hook(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + void glColorMaterial_Hook(GLenum face, GLenum mode); + void glColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer); + void glCopyPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); + void glCopyTexImage1D_Hook(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); + void glCopyTexImage2D_Hook(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + void glCopyTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + void glCopyTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + void glCullFace_Hook(GLenum mode); + void glDeleteLists_Hook(GLuint list, GLsizei range); + void glDeleteTextures_Hook(GLsizei n, const GLuint *textures); + void glDepthFunc_Hook(GLenum func); + void glDepthMask_Hook(GLboolean flag); + void glDepthRange_Hook(GLclampd zNear, GLclampd zFar); + void glDisable_Hook(GLenum cap); + void glDisableClientState_Hook(GLenum array); + void glDrawArrays_Hook(GLenum mode, GLint first, GLsizei count); + void glDrawBuffer_Hook(GLenum mode); + void glDrawElements_Hook(GLenum mode, GLsizei count, GLenum type, const void *indices); + void glDrawPixels_Hook(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); + void glEdgeFlag_Hook(GLboolean flag); + void glEdgeFlagPointer_Hook(GLsizei stride, const void *pointer); + void glEdgeFlagv_Hook(const GLboolean *flag); + void glEnable_Hook(GLenum cap); + void glEnableClientState_Hook(GLenum array); + void glEnd_Hook(void); + void glEndList_Hook(void); + void glEvalCoord1d_Hook(GLdouble u); + void glEvalCoord1dv_Hook(const GLdouble *u); + void glEvalCoord1f_Hook(GLfloat u); + void glEvalCoord1fv_Hook(const GLfloat *u); + void glEvalCoord2d_Hook(GLdouble u, GLdouble v); + void glEvalCoord2dv_Hook(const GLdouble *u); + void glEvalCoord2f_Hook(GLfloat u, GLfloat v); + void glEvalCoord2fv_Hook(const GLfloat *u); + void glEvalMesh1_Hook(GLenum mode, GLint i1, GLint i2); + void glEvalMesh2_Hook(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); + void glEvalPoint1_Hook(GLint i); + void glEvalPoint2_Hook(GLint i, GLint j); + void glFeedbackBuffer_Hook(GLsizei size, GLenum type, GLfloat *buffer); + void glFinish_Hook(void); + void glFlush_Hook(void); + void glFogf_Hook(GLenum pname, GLfloat param); + void glFogfv_Hook(GLenum pname, const GLfloat *params); + void glFogi_Hook(GLenum pname, GLint param); + void glFogiv_Hook(GLenum pname, const GLint *params); + void glFrontFace_Hook(GLenum mode); + void glFrustum_Hook(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + GLuint glGenLists_Hook(GLsizei range); + void glGenTextures_Hook(GLsizei n, GLuint *textures); + void glGetBooleanv_Hook(GLenum pname, GLboolean *params); + void glGetClipPlane_Hook(GLenum plane, GLdouble *equation); + void glGetDoublev_Hook(GLenum pname, GLdouble *params); + GLenum glGetError_Hook(void); + void glGetFloatv_Hook(GLenum pname, GLfloat *params); + void glGetIntegerv_Hook(GLenum pname, GLint *params); + void glGetLightfv_Hook(GLenum light, GLenum pname, GLfloat *params); + void glGetLightiv_Hook(GLenum light, GLenum pname, GLint *params); + void glGetMapdv_Hook(GLenum target, GLenum query, GLdouble *v); + void glGetMapfv_Hook(GLenum target, GLenum query, GLfloat *v); + void glGetMapiv_Hook(GLenum target, GLenum query, GLint *v); + void glGetMaterialfv_Hook(GLenum face, GLenum pname, GLfloat *params); + void glGetMaterialiv_Hook(GLenum face, GLenum pname, GLint *params); + void glGetPixelMapfv_Hook(GLenum map, GLfloat *values); + void glGetPixelMapuiv_Hook(GLenum map, GLuint *values); + void glGetPixelMapusv_Hook(GLenum map, GLushort *values); + void glGetPointerv_Hook(GLenum pname, void* *params); + void glGetPolygonStipple_Hook(GLubyte *mask); + const GLubyte * glGetString_Hook(GLenum name); + void glGetTexEnvfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetTexEnviv_Hook(GLenum target, GLenum pname, GLint *params); + void glGetTexGendv_Hook(GLenum coord, GLenum pname, GLdouble *params); + void glGetTexGenfv_Hook(GLenum coord, GLenum pname, GLfloat *params); + void glGetTexGeniv_Hook(GLenum coord, GLenum pname, GLint *params); + void glGetTexImage_Hook(GLenum target, GLint level, GLenum format, GLenum type, void *pixels); + void glGetTexLevelParameterfv_Hook(GLenum target, GLint level, GLenum pname, GLfloat *params); + void glGetTexLevelParameteriv_Hook(GLenum target, GLint level, GLenum pname, GLint *params); + void glGetTexParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetTexParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glHint_Hook(GLenum target, GLenum mode); + void glIndexMask_Hook(GLuint mask); + void glIndexPointer_Hook(GLenum type, GLsizei stride, const void *pointer); + void glIndexd_Hook(GLdouble c); + void glIndexdv_Hook(const GLdouble *c); + void glIndexf_Hook(GLfloat c); + void glIndexfv_Hook(const GLfloat *c); + void glIndexi_Hook(GLint c); + void glIndexiv_Hook(const GLint *c); + void glIndexs_Hook(GLshort c); + void glIndexsv_Hook(const GLshort *c); + void glIndexub_Hook(GLubyte c); + void glIndexubv_Hook(const GLubyte *c); + void glInitNames_Hook(void); + void glInterleavedArrays_Hook(GLenum format, GLsizei stride, const void *pointer); + GLboolean glIsEnabled_Hook(GLenum cap); + GLboolean glIsList_Hook(GLuint list); + GLboolean glIsTexture_Hook(GLuint texture); + void glLightModelf_Hook(GLenum pname, GLfloat param); + void glLightModelfv_Hook(GLenum pname, const GLfloat *params); + void glLightModeli_Hook(GLenum pname, GLint param); + void glLightModeliv_Hook(GLenum pname, const GLint *params); + void glLightf_Hook(GLenum light, GLenum pname, GLfloat param); + void glLightfv_Hook(GLenum light, GLenum pname, const GLfloat *params); + void glLighti_Hook(GLenum light, GLenum pname, GLint param); + void glLightiv_Hook(GLenum light, GLenum pname, const GLint *params); + void glLineStipple_Hook(GLint factor, GLushort pattern); + void glLineWidth_Hook(GLfloat width); + void glListBase_Hook(GLuint base); + void glLoadIdentity_Hook(void); + void glLoadMatrixd_Hook(const GLdouble *m); + void glLoadMatrixf_Hook(const GLfloat *m); + void glLoadName_Hook(GLuint name); + void glLogicOp_Hook(GLenum opcode); + void glMap1d_Hook(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); + void glMap1f_Hook(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); + void glMap2d_Hook(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); + void glMap2f_Hook(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); + void glMapGrid1d_Hook(GLint un, GLdouble u1, GLdouble u2); + void glMapGrid1f_Hook(GLint un, GLfloat u1, GLfloat u2); + void glMapGrid2d_Hook(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); + void glMapGrid2f_Hook(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); + void glMaterialf_Hook(GLenum face, GLenum pname, GLfloat param); + void glMaterialfv_Hook(GLenum face, GLenum pname, const GLfloat *params); + void glMateriali_Hook(GLenum face, GLenum pname, GLint param); + void glMaterialiv_Hook(GLenum face, GLenum pname, const GLint *params); + void glMatrixMode_Hook(GLenum mode); + void glMultMatrixd_Hook(const GLdouble *m); + void glMultMatrixf_Hook(const GLfloat *m); + void glNewList_Hook(GLuint list, GLenum mode); + void glNormal3b_Hook(GLbyte nx, GLbyte ny, GLbyte nz); + void glNormal3bv_Hook(const GLbyte *v); + void glNormal3d_Hook(GLdouble nx, GLdouble ny, GLdouble nz); + void glNormal3dv_Hook(const GLdouble *v); + void glNormal3f_Hook(GLfloat nx, GLfloat ny, GLfloat nz); + void glNormal3fv_Hook(const GLfloat *v); + void glNormal3i_Hook(GLint nx, GLint ny, GLint nz); + void glNormal3iv_Hook(const GLint *v); + void glNormal3s_Hook(GLshort nx, GLshort ny, GLshort nz); + void glNormal3sv_Hook(const GLshort *v); + void glNormalPointer_Hook(GLenum type, GLsizei stride, const void *pointer); + void glOrtho_Hook(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + void glPassThrough_Hook(GLfloat token); + void glPixelMapfv_Hook(GLenum map, GLsizei mapsize, const GLfloat *values); + void glPixelMapuiv_Hook(GLenum map, GLsizei mapsize, const GLuint *values); + void glPixelMapusv_Hook(GLenum map, GLsizei mapsize, const GLushort *values); + void glPixelStoref_Hook(GLenum pname, GLfloat param); + void glPixelStorei_Hook(GLenum pname, GLint param); + void glPixelTransferf_Hook(GLenum pname, GLfloat param); + void glPixelTransferi_Hook(GLenum pname, GLint param); + void glPixelZoom_Hook(GLfloat xfactor, GLfloat yfactor); + void glPointSize_Hook(GLfloat size); + void glPolygonMode_Hook(GLenum face, GLenum mode); + void glPolygonOffset_Hook(GLfloat factor, GLfloat units); + void glPolygonStipple_Hook(const GLubyte *mask); + void glPopAttrib_Hook(void); + void glPopClientAttrib_Hook(void); + void glPopMatrix_Hook(void); + void glPopName_Hook(void); + void glPrioritizeTextures_Hook(GLsizei n, const GLuint *textures, const GLclampf *priorities); + void glPushAttrib_Hook(GLbitfield mask); + void glPushClientAttrib_Hook(GLbitfield mask); + void glPushMatrix_Hook(void); + void glPushName_Hook(GLuint name); + void glRasterPos2d_Hook(GLdouble x, GLdouble y); + void glRasterPos2dv_Hook(const GLdouble *v); + void glRasterPos2f_Hook(GLfloat x, GLfloat y); + void glRasterPos2fv_Hook(const GLfloat *v); + void glRasterPos2i_Hook(GLint x, GLint y); + void glRasterPos2iv_Hook(const GLint *v); + void glRasterPos2s_Hook(GLshort x, GLshort y); + void glRasterPos2sv_Hook(const GLshort *v); + void glRasterPos3d_Hook(GLdouble x, GLdouble y, GLdouble z); + void glRasterPos3dv_Hook(const GLdouble *v); + void glRasterPos3f_Hook(GLfloat x, GLfloat y, GLfloat z); + void glRasterPos3fv_Hook(const GLfloat *v); + void glRasterPos3i_Hook(GLint x, GLint y, GLint z); + void glRasterPos3iv_Hook(const GLint *v); + void glRasterPos3s_Hook(GLshort x, GLshort y, GLshort z); + void glRasterPos3sv_Hook(const GLshort *v); + void glRasterPos4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + void glRasterPos4dv_Hook(const GLdouble *v); + void glRasterPos4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void glRasterPos4fv_Hook(const GLfloat *v); + void glRasterPos4i_Hook(GLint x, GLint y, GLint z, GLint w); + void glRasterPos4iv_Hook(const GLint *v); + void glRasterPos4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w); + void glRasterPos4sv_Hook(const GLshort *v); + void glReadBuffer_Hook(GLenum mode); + void glReadPixels_Hook(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); + void glRectd_Hook(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); + void glRectdv_Hook(const GLdouble *v1, const GLdouble *v2); + void glRectf_Hook(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); + void glRectfv_Hook(const GLfloat *v1, const GLfloat *v2); + void glRecti_Hook(GLint x1, GLint y1, GLint x2, GLint y2); + void glRectiv_Hook(const GLint *v1, const GLint *v2); + void glRects_Hook(GLshort x1, GLshort y1, GLshort x2, GLshort y2); + void glRectsv_Hook(const GLshort *v1, const GLshort *v2); + GLint glRenderMode_Hook(GLenum mode); + void glRotated_Hook(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); + void glRotatef_Hook(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); + void glScaled_Hook(GLdouble x, GLdouble y, GLdouble z); + void glScalef_Hook(GLfloat x, GLfloat y, GLfloat z); + void glScissor_Hook(GLint x, GLint y, GLsizei width, GLsizei height); + void glSelectBuffer_Hook(GLsizei size, GLuint *buffer); + void glShadeModel_Hook(GLenum mode); + void glStencilFunc_Hook(GLenum func, GLint ref, GLuint mask); + void glStencilMask_Hook(GLuint mask); + void glStencilOp_Hook(GLenum fail, GLenum zfail, GLenum zpass); + void glTexCoord1d_Hook(GLdouble s); + void glTexCoord1dv_Hook(const GLdouble *v); + void glTexCoord1f_Hook(GLfloat s); + void glTexCoord1fv_Hook(const GLfloat *v); + void glTexCoord1i_Hook(GLint s); + void glTexCoord1iv_Hook(const GLint *v); + void glTexCoord1s_Hook(GLshort s); + void glTexCoord1sv_Hook(const GLshort *v); + void glTexCoord2d_Hook(GLdouble s, GLdouble t); + void glTexCoord2dv_Hook(const GLdouble *v); + void glTexCoord2f_Hook(GLfloat s, GLfloat t); + void glTexCoord2fv_Hook(const GLfloat *v); + void glTexCoord2i_Hook(GLint s, GLint t); + void glTexCoord2iv_Hook(const GLint *v); + void glTexCoord2s_Hook(GLshort s, GLshort t); + void glTexCoord2sv_Hook(const GLshort *v); + void glTexCoord3d_Hook(GLdouble s, GLdouble t, GLdouble r); + void glTexCoord3dv_Hook(const GLdouble *v); + void glTexCoord3f_Hook(GLfloat s, GLfloat t, GLfloat r); + void glTexCoord3fv_Hook(const GLfloat *v); + void glTexCoord3i_Hook(GLint s, GLint t, GLint r); + void glTexCoord3iv_Hook(const GLint *v); + void glTexCoord3s_Hook(GLshort s, GLshort t, GLshort r); + void glTexCoord3sv_Hook(const GLshort *v); + void glTexCoord4d_Hook(GLdouble s, GLdouble t, GLdouble r, GLdouble q); + void glTexCoord4dv_Hook(const GLdouble *v); + void glTexCoord4f_Hook(GLfloat s, GLfloat t, GLfloat r, GLfloat q); + void glTexCoord4fv_Hook(const GLfloat *v); + void glTexCoord4i_Hook(GLint s, GLint t, GLint r, GLint q); + void glTexCoord4iv_Hook(const GLint *v); + void glTexCoord4s_Hook(GLshort s, GLshort t, GLshort r, GLshort q); + void glTexCoord4sv_Hook(const GLshort *v); + void glTexCoordPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer); + void glTexEnvf_Hook(GLenum target, GLenum pname, GLfloat param); + void glTexEnvfv_Hook(GLenum target, GLenum pname, const GLfloat *params); + void glTexEnvi_Hook(GLenum target, GLenum pname, GLint param); + void glTexEnviv_Hook(GLenum target, GLenum pname, const GLint *params); + void glTexGend_Hook(GLenum coord, GLenum pname, GLdouble param); + void glTexGendv_Hook(GLenum coord, GLenum pname, const GLdouble *params); + void glTexGenf_Hook(GLenum coord, GLenum pname, GLfloat param); + void glTexGenfv_Hook(GLenum coord, GLenum pname, const GLfloat *params); + void glTexGeni_Hook(GLenum coord, GLenum pname, GLint param); + void glTexGeniv_Hook(GLenum coord, GLenum pname, const GLint *params); + void glTexImage1D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); + void glTexImage2D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); + void glTexParameterf_Hook(GLenum target, GLenum pname, GLfloat param); + void glTexParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params); + void glTexParameteri_Hook(GLenum target, GLenum pname, GLint param); + void glTexParameteriv_Hook(GLenum target, GLenum pname, const GLint *params); + void glTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); + void glTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); + void glTranslated_Hook(GLdouble x, GLdouble y, GLdouble z); + void glTranslatef_Hook(GLfloat x, GLfloat y, GLfloat z); + void glVertex2d_Hook(GLdouble x, GLdouble y); + void glVertex2dv_Hook(const GLdouble *v); + void glVertex2f_Hook(GLfloat x, GLfloat y); + void glVertex2fv_Hook(const GLfloat *v); + void glVertex2i_Hook(GLint x, GLint y); + void glVertex2iv_Hook(const GLint *v); + void glVertex2s_Hook(GLshort x, GLshort y); + void glVertex2sv_Hook(const GLshort *v); + void glVertex3d_Hook(GLdouble x, GLdouble y, GLdouble z); + void glVertex3dv_Hook(const GLdouble *v); + void glVertex3f_Hook(GLfloat x, GLfloat y, GLfloat z); + void glVertex3fv_Hook(const GLfloat *v); + void glVertex3i_Hook(GLint x, GLint y, GLint z); + void glVertex3iv_Hook(const GLint *v); + void glVertex3s_Hook(GLshort x, GLshort y, GLshort z); + void glVertex3sv_Hook(const GLshort *v); + void glVertex4d_Hook(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + void glVertex4dv_Hook(const GLdouble *v); + void glVertex4f_Hook(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void glVertex4fv_Hook(const GLfloat *v); + void glVertex4i_Hook(GLint x, GLint y, GLint z, GLint w); + void glVertex4iv_Hook(const GLint *v); + void glVertex4s_Hook(GLshort x, GLshort y, GLshort z, GLshort w); + void glVertex4sv_Hook(const GLshort *v); + void glVertexPointer_Hook(GLint size, GLenum type, GLsizei stride, const void *pointer); + void glViewport_Hook(GLint x, GLint y, GLsizei width, GLsizei height); + + // GL_VERSION_1_2 + void glBlendColor_Hook(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + void glBlendEquation_Hook(GLenum mode); + void glDrawRangeElements_Hook(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); + void glTexImage3D_Hook(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const GLvoid *pixels); + void glTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *pixels); + void glCopyTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + + // GL_VERSION_1_2 deprecated functions + /* Not currently supported + void glColorTable_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); + void glColorTableParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params); + void glColorTableParameteriv_Hook(GLenum target, GLenum pname, const GLint *params); + void glCopyColorTable_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + void glGetColorTable_Hook(GLenum target, GLenum format, GLenum type, GLvoid *table); + void glGetColorTableParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetColorTableParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glColorSubTable_Hook(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); + void glCopyColorSubTable_Hook(GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + void glConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); + void glConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); + void glConvolutionParameterf_Hook(GLenum target, GLenum pname, GLfloat params); + void glConvolutionParameterfv_Hook(GLenum target, GLenum pname, const GLfloat *params); + void glConvolutionParameteri_Hook(GLenum target, GLenum pname, GLint params); + void glConvolutionParameteriv_Hook(GLenum target, GLenum pname, const GLint *params); + void glCopyConvolutionFilter1D_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + void glCopyConvolutionFilter2D_Hook(GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); + void glGetConvolutionFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *image); + void glGetConvolutionParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetConvolutionParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glGetSeparableFilter_Hook(GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); + void glSeparableFilter2D_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); + void glGetHistogram_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); + void glGetHistogramParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetHistogramParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glGetMinmax_Hook(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); + void glGetMinmaxParameterfv_Hook(GLenum target, GLenum pname, GLfloat *params); + void glGetMinmaxParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glHistogram_Hook(GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); + void glMinmax_Hook(GLenum target, GLenum internalformat, GLboolean sink); + void glResetHistogram_Hook(GLenum target); + void glResetMinmax_Hook(GLenum target); + */ + + // GL_VERSION_1_3 + void glActiveTexture_Hook(GLenum texture); + void glSampleCoverage_Hook(GLclampf value, GLboolean invert); + void glCompressedTexImage3D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data); + void glCompressedTexImage2D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); + void glCompressedTexImage1D_Hook(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data); + void glCompressedTexSubImage3D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data); + void glCompressedTexSubImage2D_Hook(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data); + void glCompressedTexSubImage1D_Hook(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data); + void glGetCompressedTexImage_Hook(GLenum target, GLint level, GLvoid *img); + + // GL_VERSION_1_3 deprecated functions + void glClientActiveTexture_Hook(GLenum texture); + void glMultiTexCoord1d_Hook(GLenum target, GLdouble s); + void glMultiTexCoord1dv_Hook(GLenum target, const GLdouble *v); + void glMultiTexCoord1f_Hook(GLenum target, GLfloat s); + void glMultiTexCoord1fv_Hook(GLenum target, const GLfloat *v); + void glMultiTexCoord1i_Hook(GLenum target, GLint s); + void glMultiTexCoord1iv_Hook(GLenum target, const GLint *v); + void glMultiTexCoord1s_Hook(GLenum target, GLshort s); + void glMultiTexCoord1sv_Hook(GLenum target, const GLshort *v); + void glMultiTexCoord2d_Hook(GLenum target, GLdouble s, GLdouble t); + void glMultiTexCoord2dv_Hook(GLenum target, const GLdouble *v); + void glMultiTexCoord2f_Hook(GLenum target, GLfloat s, GLfloat t); + void glMultiTexCoord2fv_Hook(GLenum target, const GLfloat *v); + void glMultiTexCoord2i_Hook(GLenum target, GLint s, GLint t); + void glMultiTexCoord2iv_Hook(GLenum target, const GLint *v); + void glMultiTexCoord2s_Hook(GLenum target, GLshort s, GLshort t); + void glMultiTexCoord2sv_Hook(GLenum target, const GLshort *v); + void glMultiTexCoord3d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r); + void glMultiTexCoord3dv_Hook(GLenum target, const GLdouble *v); + void glMultiTexCoord3f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r); + void glMultiTexCoord3fv_Hook(GLenum target, const GLfloat *v); + void glMultiTexCoord3i_Hook(GLenum target, GLint s, GLint t, GLint r); + void glMultiTexCoord3iv_Hook(GLenum target, const GLint *v); + void glMultiTexCoord3s_Hook(GLenum target, GLshort s, GLshort t, GLshort r); + void glMultiTexCoord3sv_Hook(GLenum target, const GLshort *v); + void glMultiTexCoord4d_Hook(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); + void glMultiTexCoord4dv_Hook(GLenum target, const GLdouble *v); + void glMultiTexCoord4f_Hook(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); + void glMultiTexCoord4fv_Hook(GLenum target, const GLfloat *v); + void glMultiTexCoord4i_Hook(GLenum target, GLint s, GLint t, GLint r, GLint q); + void glMultiTexCoord4iv_Hook(GLenum target, const GLint *v); + void glMultiTexCoord4s_Hook(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); + void glMultiTexCoord4sv_Hook(GLenum target, const GLshort *v); + void glLoadTransposeMatrixf_Hook(const GLfloat *m); + void glLoadTransposeMatrixd_Hook(const GLdouble *m); + void glMultTransposeMatrixf_Hook(const GLfloat *m); + void glMultTransposeMatrixd_Hook(const GLdouble *m); + + // GL_VERSION_1_4 + void glBlendFuncSeparate_Hook(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + void glMultiDrawArrays_Hook(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); + void glMultiDrawElements_Hook(GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount); + void glPointParameterf_Hook(GLenum pname, GLfloat param); + void glPointParameterfv_Hook(GLenum pname, const GLfloat *params); + void glPointParameteri_Hook(GLenum pname, GLint param); + void glPointParameteriv_Hook(GLenum pname, const GLint *params); + + // GL_VERSION_1_4 deprecated functions + void glFogCoordf_Hook(GLfloat coord); + void glFogCoordfv_Hook(const GLfloat *coord); + void glFogCoordd_Hook(GLdouble coord); + void glFogCoorddv_Hook(const GLdouble *coord); + void glFogCoordPointer_Hook(GLenum type, GLsizei stride, const GLvoid *pointer); + void glSecondaryColor3b_Hook(GLbyte red, GLbyte green, GLbyte blue); + void glSecondaryColor3bv_Hook(const GLbyte *v); + void glSecondaryColor3d_Hook(GLdouble red, GLdouble green, GLdouble blue); + void glSecondaryColor3dv_Hook(const GLdouble *v); + void glSecondaryColor3f_Hook(GLfloat red, GLfloat green, GLfloat blue); + void glSecondaryColor3fv_Hook(const GLfloat *v); + void glSecondaryColor3i_Hook(GLint red, GLint green, GLint blue); + void glSecondaryColor3iv_Hook(const GLint *v); + void glSecondaryColor3s_Hook(GLshort red, GLshort green, GLshort blue); + void glSecondaryColor3sv_Hook(const GLshort *v); + void glSecondaryColor3ub_Hook(GLubyte red, GLubyte green, GLubyte blue); + void glSecondaryColor3ubv_Hook(const GLubyte *v); + void glSecondaryColor3ui_Hook(GLuint red, GLuint green, GLuint blue); + void glSecondaryColor3uiv_Hook(const GLuint *v); + void glSecondaryColor3us_Hook(GLushort red, GLushort green, GLushort blue); + void glSecondaryColor3usv_Hook(const GLushort *v); + void glSecondaryColorPointer_Hook(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + void glWindowPos2d_Hook(GLdouble x, GLdouble y); + void glWindowPos2dv_Hook(const GLdouble *v); + void glWindowPos2f_Hook(GLfloat x, GLfloat y); + void glWindowPos2fv_Hook(const GLfloat *v); + void glWindowPos2i_Hook(GLint x, GLint y); + void glWindowPos2iv_Hook(const GLint *v); + void glWindowPos2s_Hook(GLshort x, GLshort y); + void glWindowPos2sv_Hook(const GLshort *v); + void glWindowPos3d_Hook(GLdouble x, GLdouble y, GLdouble z); + void glWindowPos3dv_Hook(const GLdouble *v); + void glWindowPos3f_Hook(GLfloat x, GLfloat y, GLfloat z); + void glWindowPos3fv_Hook(const GLfloat *v); + void glWindowPos3i_Hook(GLint x, GLint y, GLint z); + void glWindowPos3iv_Hook(const GLint *v); + void glWindowPos3s_Hook(GLshort x, GLshort y, GLshort z); + void glWindowPos3sv_Hook(const GLshort *v); + + // GL_VERSION_1_5 + void glGenQueries_Hook(GLsizei n, GLuint *ids); + void glDeleteQueries_Hook(GLsizei n, const GLuint *ids); + GLboolean glIsQuery_Hook(GLuint id); + void glBeginQuery_Hook(GLenum target, GLuint id); + void glEndQuery_Hook(GLenum target); + void glGetQueryiv_Hook(GLenum target, GLenum pname, GLint *params); + void glGetQueryObjectiv_Hook(GLuint id, GLenum pname, GLint *params); + void glGetQueryObjectuiv_Hook(GLuint id, GLenum pname, GLuint *params); + void glBindBuffer_Hook(GLenum target, GLuint buffer); + void glDeleteBuffers_Hook(GLsizei n, const GLuint *buffers); + void glGenBuffers_Hook(GLsizei n, GLuint *buffers); + GLboolean glIsBuffer_Hook(GLuint buffer); + void glBufferData_Hook(GLenum target, GLsizeiptr size, const GLvoid *data, GLenum usage); + void glBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data); + void glGetBufferSubData_Hook(GLenum target, GLintptr offset, GLsizeiptr size, GLvoid *data); + GLvoid* glMapBuffer_Hook(GLenum target, GLenum access); + GLboolean glUnmapBuffer_Hook(GLenum target); + void glGetBufferParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + void glGetBufferPointerv_Hook(GLenum target, GLenum pname, GLvoid* *params); + + // GL_VERSION_2_0 + void glBlendEquationSeparate_Hook(GLenum modeRGB, GLenum modeAlpha); + void glDrawBuffers_Hook(GLsizei n, const GLenum *bufs); + void glStencilOpSeparate_Hook(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + void glStencilFuncSeparate_Hook(GLenum face, GLenum func, GLint ref, GLuint mask); + void glStencilMaskSeparate_Hook(GLenum face, GLuint mask); + void glAttachShader_Hook(GLuint program, GLuint shader); + void glBindAttribLocation_Hook(GLuint program, GLuint index, const GLchar *name); + void glCompileShader_Hook(GLuint shader); + GLuint glCreateProgram_Hook(void); + GLuint glCreateShader_Hook(GLenum type); + void glDeleteProgram_Hook(GLuint program); + void glDeleteShader_Hook(GLuint shader); + void glDetachShader_Hook(GLuint program, GLuint shader); + void glDisableVertexAttribArray_Hook(GLuint index); + void glEnableVertexAttribArray_Hook(GLuint index); + void glGetActiveAttrib_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + void glGetActiveUniform_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + void glGetAttachedShaders_Hook(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *obj); + GLint glGetAttribLocation_Hook(GLuint program, const GLchar *name); + void glGetProgramiv_Hook(GLuint program, GLenum pname, GLint *params); + void glGetProgramInfoLog_Hook(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + void glGetShaderiv_Hook(GLuint shader, GLenum pname, GLint *params); + void glGetShaderInfoLog_Hook(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + void glGetShaderSource_Hook(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); + GLint glGetUniformLocation_Hook(GLuint program, const GLchar *name); + void glGetUniformfv_Hook(GLuint program, GLint location, GLfloat *params); + void glGetUniformiv_Hook(GLuint program, GLint location, GLint *params); + void glGetVertexAttribdv_Hook(GLuint index, GLenum pname, GLdouble *params); + void glGetVertexAttribfv_Hook(GLuint index, GLenum pname, GLfloat *params); + void glGetVertexAttribiv_Hook(GLuint index, GLenum pname, GLint *params); + void glGetVertexAttribPointerv_Hook(GLuint index, GLenum pname, GLvoid* *pointer); + GLboolean glIsProgram_Hook(GLuint program); + GLboolean glIsShader_Hook(GLuint shader); + void glLinkProgram_Hook(GLuint program); + void glShaderSource_Hook(GLuint shader, GLsizei count, const GLchar* *string, const GLint *length); + void glUseProgram_Hook(GLuint program); + void glUniform1f_Hook(GLint location, GLfloat v0); + void glUniform2f_Hook(GLint location, GLfloat v0, GLfloat v1); + void glUniform3f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + void glUniform4f_Hook(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + void glUniform1i_Hook(GLint location, GLint v0); + void glUniform2i_Hook(GLint location, GLint v0, GLint v1); + void glUniform3i_Hook(GLint location, GLint v0, GLint v1, GLint v2); + void glUniform4i_Hook(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + void glUniform1fv_Hook(GLint location, GLsizei count, const GLfloat *value); + void glUniform2fv_Hook(GLint location, GLsizei count, const GLfloat *value); + void glUniform3fv_Hook(GLint location, GLsizei count, const GLfloat *value); + void glUniform4fv_Hook(GLint location, GLsizei count, const GLfloat *value); + void glUniform1iv_Hook(GLint location, GLsizei count, const GLint *value); + void glUniform2iv_Hook(GLint location, GLsizei count, const GLint *value); + void glUniform3iv_Hook(GLint location, GLsizei count, const GLint *value); + void glUniform4iv_Hook(GLint location, GLsizei count, const GLint *value); + void glUniformMatrix2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glValidateProgram_Hook(GLuint program); + void glVertexAttrib1d_Hook(GLuint index, GLdouble x); + void glVertexAttrib1dv_Hook(GLuint index, const GLdouble *v); + void glVertexAttrib1f_Hook(GLuint index, GLfloat x); + void glVertexAttrib1fv_Hook(GLuint index, const GLfloat *v); + void glVertexAttrib1s_Hook(GLuint index, GLshort x); + void glVertexAttrib1sv_Hook(GLuint index, const GLshort *v); + void glVertexAttrib2d_Hook(GLuint index, GLdouble x, GLdouble y); + void glVertexAttrib2dv_Hook(GLuint index, const GLdouble *v); + void glVertexAttrib2f_Hook(GLuint index, GLfloat x, GLfloat y); + void glVertexAttrib2fv_Hook(GLuint index, const GLfloat *v); + void glVertexAttrib2s_Hook(GLuint index, GLshort x, GLshort y); + void glVertexAttrib2sv_Hook(GLuint index, const GLshort *v); + void glVertexAttrib3d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z); + void glVertexAttrib3dv_Hook(GLuint index, const GLdouble *v); + void glVertexAttrib3f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z); + void glVertexAttrib3fv_Hook(GLuint index, const GLfloat *v); + void glVertexAttrib3s_Hook(GLuint index, GLshort x, GLshort y, GLshort z); + void glVertexAttrib3sv_Hook(GLuint index, const GLshort *v); + void glVertexAttrib4Nbv_Hook(GLuint index, const GLbyte *v); + void glVertexAttrib4Niv_Hook(GLuint index, const GLint *v); + void glVertexAttrib4Nsv_Hook(GLuint index, const GLshort *v); + void glVertexAttrib4Nub_Hook(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); + void glVertexAttrib4Nubv_Hook(GLuint index, const GLubyte *v); + void glVertexAttrib4Nuiv_Hook(GLuint index, const GLuint *v); + void glVertexAttrib4Nusv_Hook(GLuint index, const GLushort *v); + void glVertexAttrib4bv_Hook(GLuint index, const GLbyte *v); + void glVertexAttrib4d_Hook(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + void glVertexAttrib4dv_Hook(GLuint index, const GLdouble *v); + void glVertexAttrib4f_Hook(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + void glVertexAttrib4fv_Hook(GLuint index, const GLfloat *v); + void glVertexAttrib4iv_Hook(GLuint index, const GLint *v); + void glVertexAttrib4s_Hook(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); + void glVertexAttrib4sv_Hook(GLuint index, const GLshort *v); + void glVertexAttrib4ubv_Hook(GLuint index, const GLubyte *v); + void glVertexAttrib4uiv_Hook(GLuint index, const GLuint *v); + void glVertexAttrib4usv_Hook(GLuint index, const GLushort *v); + void glVertexAttribPointer_Hook(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid *pointer); + + // GL_VERSION_2_1 + void glUniformMatrix2x3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix3x2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix2x4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix4x2fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix3x4fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + void glUniformMatrix4x3fv_Hook(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + + // GL_VERSION_3_0 + void glColorMaski_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + void glGetBooleani_v_Hook(GLenum target, GLuint index, GLboolean *data); + void glGetIntegeri_v_Hook(GLenum target, GLuint index, GLint *data); + void glEnablei_Hook(GLenum target, GLuint index); + void glDisablei_Hook(GLenum target, GLuint index); + GLboolean glIsEnabledi_Hook(GLenum target, GLuint index); + void glBeginTransformFeedback_Hook(GLenum primitiveMode); + void glEndTransformFeedback_Hook(void); + void glBindBufferRange_Hook(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + void glBindBufferBase_Hook(GLenum target, GLuint index, GLuint buffer); + void glTransformFeedbackVaryings_Hook(GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode); + void glGetTransformFeedbackVarying_Hook(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + void glClampColor_Hook(GLenum target, GLenum clamp); + void glBeginConditionalRender_Hook(GLuint id, GLenum mode); + void glEndConditionalRender_Hook(void); + void glVertexAttribIPointer_Hook(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); + void glGetVertexAttribIiv_Hook(GLuint index, GLenum pname, GLint *params); + void glGetVertexAttribIuiv_Hook(GLuint index, GLenum pname, GLuint *params); + void glVertexAttribI1i_Hook(GLuint index, GLint x); + void glVertexAttribI2i_Hook(GLuint index, GLint x, GLint y); + void glVertexAttribI3i_Hook(GLuint index, GLint x, GLint y, GLint z); + void glVertexAttribI4i_Hook(GLuint index, GLint x, GLint y, GLint z, GLint w); + void glVertexAttribI1ui_Hook(GLuint index, GLuint x); + void glVertexAttribI2ui_Hook(GLuint index, GLuint x, GLuint y); + void glVertexAttribI3ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z); + void glVertexAttribI4ui_Hook(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + void glVertexAttribI1iv_Hook(GLuint index, const GLint *v); + void glVertexAttribI2iv_Hook(GLuint index, const GLint *v); + void glVertexAttribI3iv_Hook(GLuint index, const GLint *v); + void glVertexAttribI4iv_Hook(GLuint index, const GLint *v); + void glVertexAttribI1uiv_Hook(GLuint index, const GLuint *v); + void glVertexAttribI2uiv_Hook(GLuint index, const GLuint *v); + void glVertexAttribI3uiv_Hook(GLuint index, const GLuint *v); + void glVertexAttribI4uiv_Hook(GLuint index, const GLuint *v); + void glVertexAttribI4bv_Hook(GLuint index, const GLbyte *v); + void glVertexAttribI4sv_Hook(GLuint index, const GLshort *v); + void glVertexAttribI4ubv_Hook(GLuint index, const GLubyte *v); + void glVertexAttribI4usv_Hook(GLuint index, const GLushort *v); + void glGetUniformuiv_Hook(GLuint program, GLint location, GLuint *params); + void glBindFragDataLocation_Hook(GLuint program, GLuint color, const GLchar *name); + GLint glGetFragDataLocation_Hook(GLuint program, const GLchar *name); + void glUniform1ui_Hook(GLint location, GLuint v0); + void glUniform2ui_Hook(GLint location, GLuint v0, GLuint v1); + void glUniform3ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2); + void glUniform4ui_Hook(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + void glUniform1uiv_Hook(GLint location, GLsizei count, const GLuint *value); + void glUniform2uiv_Hook(GLint location, GLsizei count, const GLuint *value); + void glUniform3uiv_Hook(GLint location, GLsizei count, const GLuint *value); + void glUniform4uiv_Hook(GLint location, GLsizei count, const GLuint *value); + void glTexParameterIiv_Hook(GLenum target, GLenum pname, const GLint *params); + void glTexParameterIuiv_Hook(GLenum target, GLenum pname, const GLuint *params); + void glGetTexParameterIiv_Hook(GLenum target, GLenum pname, GLint *params); + void glGetTexParameterIuiv_Hook(GLenum target, GLenum pname, GLuint *params); + void glClearBufferiv_Hook(GLenum buffer, GLint drawbuffer, const GLint *value); + void glClearBufferuiv_Hook(GLenum buffer, GLint drawbuffer, const GLuint *value); + void glClearBufferfv_Hook(GLenum buffer, GLint drawbuffer, const GLfloat *value); + void glClearBufferfi_Hook(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + const GLubyte* glGetStringi_Hook(GLenum name, GLuint index); + + // GL_VERSION_3_1 + void glDrawArraysInstanced_Hook(GLenum mode, GLint first, GLsizei count, GLsizei primcount); + void glDrawElementsInstanced_Hook(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount); + void glTexBuffer_Hook(GLenum target, GLenum internalformat, GLuint buffer); + void glPrimitiveRestartIndex_Hook(GLuint index); + + // GL_VERSION_3_2 + void glGetInteger64i_v_Hook(GLenum target, GLuint index, GLint64 *data); + void glGetBufferParameteri64v_Hook(GLenum target, GLenum pname, GLint64 *params); + void glFramebufferTexture_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level); + + // GL_VERSION_3_3 + void glVertexAttribDivisor_Hook(GLuint index, GLuint divisor); + + // GL_VERSION_4_0 + void glMinSampleShading_Hook(GLclampf value); + void glBlendEquationi_Hook(GLuint buf, GLenum mode); + void glBlendEquationSeparatei_Hook(GLuint buf, GLenum modeRGB, GLenum modeAlpha); + void glBlendFunci_Hook(GLuint buf, GLenum src, GLenum dst); + void glBlendFuncSeparatei_Hook(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + + // GL_AMD_debug_output + void glDebugMessageEnableAMD_Hook(GLenum category, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); + void glDebugMessageInsertAMD_Hook(GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar *buf); + void glDebugMessageCallbackAMD_Hook(GLDEBUGPROCAMD callback, GLvoid *userParam); + GLuint glGetDebugMessageLogAMD_Hook(GLuint count, GLsizei bufsize, GLenum *categories, GLuint *severities, GLuint *ids, GLsizei *lengths, GLchar *message); + + #if defined(GLE_CGL_ENABLED) + // GL_APPLE_element_array + void glElementPointerAPPLE_Hook(GLenum type, const GLvoid *pointer); + void glDrawElementArrayAPPLE_Hook(GLenum mode, GLint first, GLsizei count); + void glDrawRangeElementArrayAPPLE_Hook(GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); + void glMultiDrawElementArrayAPPLE_Hook(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount); + void glMultiDrawRangeElementArrayAPPLE_Hook(GLenum mode, GLuint start, GLuint end, const GLint *first, const GLsizei *count, GLsizei primcount); + + // GL_APPLE_fence + void glGenFencesAPPLE_Hook(GLsizei n, GLuint *fences); + void glDeleteFencesAPPLE_Hook(GLsizei n, const GLuint *fences); + void glSetFenceAPPLE_Hook(GLuint fence); + GLboolean glIsFenceAPPLE_Hook(GLuint fence); + GLboolean glTestFenceAPPLE_Hook(GLuint fence); + void glFinishFenceAPPLE_Hook(GLuint fence); + GLboolean glTestObjectAPPLE_Hook(GLenum object, GLuint name); + void glFinishObjectAPPLE_Hook(GLenum object, GLint name); + + // GL_APPLE_flush_buffer_range + void glBufferParameteriAPPLE_Hook(GLenum target, GLenum pname, GLint param); + void glFlushMappedBufferRangeAPPLE_Hook(GLenum target, GLintptr offset, GLsizeiptr size); + + // GL_APPLE_object_purgeable + GLenum glObjectPurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option); + GLenum glObjectUnpurgeableAPPLE_Hook(GLenum objectType, GLuint name, GLenum option); + void glGetObjectParameterivAPPLE_Hook(GLenum objectType, GLuint name, GLenum pname, GLint *params); + + // GL_APPLE_texture_range + void glTextureRangeAPPLE_Hook(GLenum target, GLsizei length, const GLvoid *pointer); + void glGetTexParameterPointervAPPLE_Hook(GLenum target, GLenum pname, GLvoid **params); + + // GL_APPLE_vertex_array_object + void glBindVertexArrayAPPLE_Hook(GLuint array); + void glDeleteVertexArraysAPPLE_Hook(GLsizei n, const GLuint *arrays); + void glGenVertexArraysAPPLE_Hook(GLsizei n, GLuint *arrays); + GLboolean glIsVertexArrayAPPLE_Hook(GLuint array); + + // GL_APPLE_vertex_array_range + void glVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid *pointer); + void glFlushVertexArrayRangeAPPLE_Hook(GLsizei length, GLvoid *pointer); + void glVertexArrayParameteriAPPLE_Hook(GLenum pname, GLint param); + + // GL_APPLE_vertex_program_evaluators + void glEnableVertexAttribAPPLE_Hook(GLuint index, GLenum pname); + void glDisableVertexAttribAPPLE_Hook(GLuint index, GLenum pname); + GLboolean glIsVertexAttribEnabledAPPLE_Hook(GLuint index, GLenum pname); + void glMapVertexAttrib1dAPPLE_Hook(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); + void glMapVertexAttrib1fAPPLE_Hook(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); + void glMapVertexAttrib2dAPPLE_Hook(GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); + void glMapVertexAttrib2fAPPLE_Hook(GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); + #endif // GLE_CGL_ENABLED + + // GL_ARB_copy_buffer + void glCopyBufferSubData_Hook(GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); + + // GL_ARB_debug_output + void glDebugMessageControlARB_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); + void glDebugMessageInsertARB_Hook(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); + void glDebugMessageCallbackARB_Hook(GLDEBUGPROCARB callback, const GLvoid *userParam); + GLuint glGetDebugMessageLogARB_Hook(GLuint count, GLsizei bufsize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); + + // GL_ARB_ES2_compatibility + void glReleaseShaderCompiler_Hook(); + void glShaderBinary_Hook(GLsizei count, const GLuint *shaders, GLenum binaryformat, const GLvoid *binary, GLsizei length); + void glGetShaderPrecisionFormat_Hook(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); + void glDepthRangef_Hook(GLclampf n, GLclampf f); + void glClearDepthf_Hook(GLclampf d); + + // GL_ARB_framebuffer_object + GLboolean glIsRenderbuffer_Hook(GLuint renderbuffer); + void glBindRenderbuffer_Hook(GLenum target, GLuint renderbuffer); + void glDeleteRenderbuffers_Hook(GLsizei n, const GLuint *renderbuffers); + void glGenRenderbuffers_Hook(GLsizei n, GLuint *renderbuffers); + void glRenderbufferStorage_Hook(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + void glGetRenderbufferParameteriv_Hook(GLenum target, GLenum pname, GLint *params); + GLboolean glIsFramebuffer_Hook(GLuint framebuffer); + void glBindFramebuffer_Hook(GLenum target, GLuint framebuffer); + void glDeleteFramebuffers_Hook(GLsizei n, const GLuint *framebuffers); + void glGenFramebuffers_Hook(GLsizei n, GLuint *framebuffers); + GLenum glCheckFramebufferStatus_Hook(GLenum target); + void glFramebufferTexture1D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + void glFramebufferTexture2D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + void glFramebufferTexture3D_Hook(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); + void glFramebufferRenderbuffer_Hook(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + void glGetFramebufferAttachmentParameteriv_Hook(GLenum target, GLenum attachment, GLenum pname, GLint *params); + void glGenerateMipmap_Hook(GLenum target); + void glBlitFramebuffer_Hook(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + void glRenderbufferStorageMultisample_Hook(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + void glFramebufferTextureLayer_Hook(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + + // GL_ARB_texture_multisample + void glTexImage2DMultisample_Hook(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + void glTexImage3DMultisample_Hook(GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + void glGetMultisamplefv_Hook(GLenum pname, GLuint index, GLfloat *val); + void glSampleMaski_Hook(GLuint index, GLbitfield mask); + + // GL_ARB_timer_query + void glQueryCounter_Hook(GLuint id, GLenum target); + void glGetQueryObjecti64v_Hook(GLuint id, GLenum pname, GLint64 *params); + void glGetQueryObjectui64v_Hook(GLuint id, GLenum pname, GLuint64 *params); + + // GL_ARB_vertex_array_object + void glBindVertexArray_Hook(GLuint array); + void glDeleteVertexArrays_Hook(GLsizei n, const GLuint *arrays); + void glGenVertexArrays_Hook(GLsizei n, GLuint *arrays); + GLboolean glIsVertexArray_Hook(GLuint array); + + // GL_EXT_draw_buffers2 + void glColorMaskIndexedEXT_Hook(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + void glGetBooleanIndexedvEXT_Hook(GLenum target, GLuint index, GLboolean *data); + void glGetIntegerIndexedvEXT_Hook(GLenum target, GLuint index, GLint *data); + void glEnableIndexedEXT_Hook(GLenum target, GLuint index); + void glDisableIndexedEXT_Hook(GLenum target, GLuint index); + GLboolean glIsEnabledIndexedEXT_Hook(GLenum target, GLuint index); + + // GL_KHR_debug + void glDebugMessageControl_Hook(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); + void glDebugMessageInsert_Hook(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* buf); + void glDebugMessageCallback_Hook(GLDEBUGPROC callback, const void* userParam); + GLuint glGetDebugMessageLog_Hook(GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, char* messageLog); + void glPushDebugGroup_Hook(GLenum source, GLuint id, GLsizei length, const char * message); + void glPopDebugGroup_Hook(void); + void glObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei length, const char *label); + void glGetObjectLabel_Hook(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, char *label); + void glObjectPtrLabel_Hook(void* ptr, GLsizei length, const char *label); + void glGetObjectPtrLabel_Hook(void* ptr, GLsizei bufSize, GLsizei *length, char *label); + + // GL_WIN_swap_hint + void glAddSwapHintRectWIN_Hook(GLint x, GLint y, GLsizei width, GLsizei height); + + #if defined(GLE_WGL_ENABLED) + void PostWGLHook(const char* functionName); + + // WGL + /* Hooking of these is currently disabled. + BOOL wglCopyContext_Hook(HGLRC, HGLRC, UINT); + HGLRC wglCreateContext_Hook(HDC); + HGLRC wglCreateLayerContext_Hook(HDC, int); + BOOL wglDeleteContext_Hook(HGLRC); + HGLRC wglGetCurrentContext_Hook(VOID); + HDC wglGetCurrentDC_Hook(VOID); + PROC wglGetProcAddress_Hook(LPCSTR); + BOOL wglMakeCurrent_Hook(HDC, HGLRC); + BOOL wglShareLists_Hook(HGLRC, HGLRC); + BOOL wglUseFontBitmapsA_Hook(HDC, DWORD, DWORD, DWORD); + BOOL wglUseFontBitmapsW_Hook(HDC, DWORD, DWORD, DWORD); + BOOL wglUseFontOutlinesA_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); + BOOL wglUseFontOutlinesW_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); + BOOL wglDescribeLayerPlane_Hook(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); + int wglSetLayerPaletteEntries_Hook(HDC, int, int, int, CONST COLORREF *); + int wglGetLayerPaletteEntries_Hook(HDC, int, int, int, COLORREF *); + BOOL wglRealizeLayerPalette_Hook(HDC, int, BOOL); + BOOL wglSwapLayerBuffers_Hook(HDC, UINT); + DWORD wglSwapMultipleBuffers_Hook(UINT, CONST WGLSWAP *); + */ + + // WGL_ARB_buffer_region + HANDLE wglCreateBufferRegionARB_Hook (HDC hDC, int iLayerPlane, UINT uType); + VOID wglDeleteBufferRegionARB_Hook (HANDLE hRegion); + BOOL wglSaveBufferRegionARB_Hook (HANDLE hRegion, int x, int y, int width, int height); + BOOL wglRestoreBufferRegionARB_Hook (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); + + // WGL_ARB_extensions_string + const char * wglGetExtensionsStringARB_Hook (HDC hdc); + + // WGL_ARB_pixel_format + BOOL wglGetPixelFormatAttribivARB_Hook (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); + BOOL wglGetPixelFormatAttribfvARB_Hook (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); + BOOL wglChoosePixelFormatARB_Hook (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); + + // WGL_ARB_make_current_read + BOOL wglMakeContextCurrentARB_Hook (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + HDC wglGetCurrentReadDCARB_Hook (void); + + // WGL_ARB_pbuffer + HPBUFFERARB wglCreatePbufferARB_Hook (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); + HDC wglGetPbufferDCARB_Hook (HPBUFFERARB hPbuffer); + int wglReleasePbufferDCARB_Hook (HPBUFFERARB hPbuffer, HDC hDC); + BOOL wglDestroyPbufferARB_Hook (HPBUFFERARB hPbuffer); + BOOL wglQueryPbufferARB_Hook (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); + + // WGL_ARB_render_texture + BOOL wglBindTexImageARB_Hook (HPBUFFERARB hPbuffer, int iBuffer); + BOOL wglReleaseTexImageARB_Hook (HPBUFFERARB hPbuffer, int iBuffer); + BOOL wglSetPbufferAttribARB_Hook (HPBUFFERARB hPbuffer, const int *piAttribList); + + // WGL_NV_present_video + int wglEnumerateVideoDevicesNV_Hook (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); + BOOL wglBindVideoDeviceNV_Hook (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); + BOOL wglQueryCurrentContextNV_Hook (int iAttribute, int *piValue); + + // WGL_ARB_create_context + HGLRC wglCreateContextAttribsARB_Hook (HDC hDC, HGLRC hShareContext, const int *attribList); + + // WGL_EXT_extensions_string + const char * wglGetExtensionsStringEXT_Hook (); + + // WGL_EXT_swap_control + BOOL wglSwapIntervalEXT_Hook(int interval); + int wglGetSwapIntervalEXT_Hook(); + + // WGL_OML_sync_control + BOOL wglGetSyncValuesOML_Hook (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); + BOOL wglGetMscRateOML_Hook (HDC hdc, INT32 *numerator, INT32 *denominator); + INT64 wglSwapBuffersMscOML_Hook (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); + INT64 wglSwapLayerBuffersMscOML_Hook (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); + BOOL wglWaitForMscOML_Hook (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); + BOOL wglWaitForSbcOML_Hook (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); + + // WGL_NV_video_output + BOOL wglGetVideoDeviceNV_Hook (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); + BOOL wglReleaseVideoDeviceNV_Hook (HPVIDEODEV hVideoDevice); + BOOL wglBindVideoImageNV_Hook (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); + BOOL wglReleaseVideoImageNV_Hook (HPBUFFERARB hPbuffer, int iVideoBuffer); + BOOL wglSendPbufferToVideoNV_Hook (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); + BOOL wglGetVideoInfoNV_Hook (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); + + // WGL_NV_swap_group + BOOL wglJoinSwapGroupNV_Hook (HDC hDC, GLuint group); + BOOL wglBindSwapBarrierNV_Hook (GLuint group, GLuint barrier); + BOOL wglQuerySwapGroupNV_Hook (HDC hDC, GLuint *group, GLuint *barrier); + BOOL wglQueryMaxSwapGroupsNV_Hook (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); + BOOL wglQueryFrameCountNV_Hook (HDC hDC, GLuint *count); + BOOL wglResetFrameCountNV_Hook (HDC hDC); + + // WGL_NV_video_capture + BOOL wglBindVideoCaptureDeviceNV_Hook (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); + UINT wglEnumerateVideoCaptureDevicesNV_Hook (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); + BOOL wglLockVideoCaptureDeviceNV_Hook (HDC hDc, HVIDEOINPUTDEVICENV hDevice); + BOOL wglQueryVideoCaptureDeviceNV_Hook (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); + BOOL wglReleaseVideoCaptureDeviceNV_Hook (HDC hDc, HVIDEOINPUTDEVICENV hDevice); + + // WGL_NV_copy_image + BOOL wglCopyImageSubDataNV_Hook (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + + // WGL_NV_DX_interop + BOOL wglDXSetResourceShareHandleNV_Hook(void *dxObject, HANDLE shareHandle); + HANDLE wglDXOpenDeviceNV_Hook(void *dxDevice); + BOOL wglDXCloseDeviceNV_Hook(HANDLE hDevice); + HANDLE wglDXRegisterObjectNV_Hook(HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access); + BOOL wglDXUnregisterObjectNV_Hook(HANDLE hDevice, HANDLE hObject); + BOOL wglDXObjectAccessNV_Hook(HANDLE hObject, GLenum access); + BOOL wglDXLockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE *hObjects); + BOOL wglDXUnlockObjectsNV_Hook(HANDLE hDevice, GLint count, HANDLE *hObjects); + #endif // GLE_WGL_ENABLED + + #if defined(GLE_GLX_ENABLED) + void PostGLXHook(const char* functionName); + + // GLX_VERSION_1_0 + // GLX_VERSION_1_1 + // We don't currently do hooking of these. + + // GLX_VERSION_1_2 + ::Display* glXGetCurrentDisplay_Hook(void); + + // GLX_VERSION_1_3 + GLXFBConfig* glXChooseFBConfig_Hook(::Display *dpy, int screen, const int *attrib_list, int *nelements); + GLXContext glXCreateNewContext_Hook(::Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); + GLXPbuffer glXCreatePbuffer_Hook(::Display *dpy, GLXFBConfig config, const int *attrib_list); + GLXPixmap glXCreatePixmap_Hook(::Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); + GLXWindow glXCreateWindow_Hook(::Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); + void glXDestroyPbuffer_Hook(::Display *dpy, GLXPbuffer pbuf); + void glXDestroyPixmap_Hook(::Display *dpy, GLXPixmap pixmap); + void glXDestroyWindow_Hook(::Display *dpy, GLXWindow win); + GLXDrawable glXGetCurrentReadDrawable_Hook(void); + int glXGetFBConfigAttrib_Hook(::Display *dpy, GLXFBConfig config, int attribute, int *value); + GLXFBConfig* glXGetFBConfigs_Hook(::Display *dpy, int screen, int *nelements); + void glXGetSelectedEvent_Hook(::Display *dpy, GLXDrawable draw, unsigned long *event_mask); + XVisualInfo* glXGetVisualFromFBConfig_Hook(::Display *dpy, GLXFBConfig config); + Bool glXMakeContextCurrent_Hook(::Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + int glXQueryContext_Hook(::Display *dpy, GLXContext ctx, int attribute, int *value); + void glXQueryDrawable_Hook(::Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); + void glXSelectEvent_Hook(::Display *dpy, GLXDrawable draw, unsigned long event_mask); + + // GLX_VERSION_1_4 + // We don't do hooking of this. + + // GLX_ARB_create_context + GLXContext glXCreateContextAttribsARB_Hook(Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); + + // GLX_EXT_swap_control + void glXSwapIntervalEXT_Hook(::Display* dpy, GLXDrawable drawable, int interval); + + // GLX_OML_sync_control + Bool glXGetMscRateOML_Hook(::Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); + Bool glXGetSyncValuesOML_Hook(::Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); + int64_t glXSwapBuffersMscOML_Hook(::Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); + Bool glXWaitForMscOML_Hook(::Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); + Bool glXWaitForSbcOML_Hook(::Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); + + // GLX_MESA_swap_control + int glXGetSwapIntervalMESA_Hook(); + int glXSwapIntervalMESA_Hook(unsigned int interval); + + #endif // GLE_GLX_ENABLED + + #endif // #if defined(GLE_HOOKING_ENABLED) + + // GL_VERSION_1_1 + // These are not represented by function pointers. + + // GL_VERSION_1_2 + PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D_Impl; + PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements_Impl; + PFNGLTEXIMAGE3DPROC glTexImage3D_Impl; + PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D_Impl; + + // GL_VERSION_1_2 deprecated functions + /* Not currently supported + PFNGLCOLORTABLEPROC glColorTable_Impl; + PFNGLCOLORTABLEPARAMETERFVPROC glColorTableParameterfv_Impl; + PFNGLCOLORTABLEPARAMETERIVPROC glColorTableParameteriv_Impl; + PFNGLCOPYCOLORTABLEPROC glCopyColorTable_Impl; + PFNGLGETCOLORTABLEPROC glGetColorTable_Impl; + PFNGLGETCOLORTABLEPARAMETERFVPROC glGetColorTableParameterfv_Impl; + PFNGLGETCOLORTABLEPARAMETERIVPROC glGetColorTableParameteriv_Impl; + PFNGLCOLORSUBTABLEPROC glColorSubTable_Impl; + PFNGLCOPYCOLORSUBTABLEPROC glCopyColorSubTable_Impl; + PFNGLCONVOLUTIONFILTER1DPROC glConvolutionFilter1D_Impl; + PFNGLCONVOLUTIONFILTER2DPROC glConvolutionFilter2D_Impl; + PFNGLCONVOLUTIONPARAMETERFPROC glConvolutionParameterf_Impl; + PFNGLCONVOLUTIONPARAMETERFVPROC glConvolutionParameterfv_Impl; + PFNGLCONVOLUTIONPARAMETERIPROC glConvolutionParameteri_Impl; + PFNGLCONVOLUTIONPARAMETERIVPROC glConvolutionParameteriv_Impl; + PFNGLCOPYCONVOLUTIONFILTER1DPROC glCopyConvolutionFilter1D_Impl; + PFNGLCOPYCONVOLUTIONFILTER2DPROC glCopyConvolutionFilter2D_Impl; + PFNGLGETCONVOLUTIONFILTERPROC glGetConvolutionFilter_Impl; + PFNGLGETCONVOLUTIONPARAMETERFVPROC glGetConvolutionParameterfv_Impl; + PFNGLGETCONVOLUTIONPARAMETERIVPROC glGetConvolutionParameteriv_Impl; + PFNGLGETSEPARABLEFILTERPROC glGetSeparableFilter_Impl; + PFNGLSEPARABLEFILTER2DPROC glSeparableFilter2D_Impl; + PFNGLGETHISTOGRAMPROC glGetHistogram_Impl; + PFNGLGETHISTOGRAMPARAMETERFVPROC glGetHistogramParameterfv_Impl; + PFNGLGETHISTOGRAMPARAMETERIVPROC glGetHistogramParameteriv_Impl; + PFNGLGETMINMAXPROC glGetMinmax_Impl; + PFNGLGETMINMAXPARAMETERFVPROC glGetMinmaxParameterfv_Impl; + PFNGLGETMINMAXPARAMETERIVPROC glGetMinmaxParameteriv_Impl; + PFNGLHISTOGRAMPROC glHistogram_Impl; + PFNGLMINMAXPROC glMinmax_Impl; + PFNGLRESETHISTOGRAMPROC glResetHistogram_Impl; + PFNGLRESETMINMAXPROC glResetMinmax_Impl; + */ + + // GL_VERSION_1_3 + PFNGLACTIVETEXTUREPROC glActiveTexture_Impl; + PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture_Impl; + PFNGLCOMPRESSEDTEXIMAGE1DPROC glCompressedTexImage1D_Impl; + PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D_Impl; + PFNGLCOMPRESSEDTEXIMAGE3DPROC glCompressedTexImage3D_Impl; + PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D_Impl; + PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D_Impl; + PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D_Impl; + PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage_Impl; + PFNGLLOADTRANSPOSEMATRIXDPROC glLoadTransposeMatrixd_Impl; + PFNGLLOADTRANSPOSEMATRIXFPROC glLoadTransposeMatrixf_Impl; + PFNGLMULTTRANSPOSEMATRIXDPROC glMultTransposeMatrixd_Impl; + PFNGLMULTTRANSPOSEMATRIXFPROC glMultTransposeMatrixf_Impl; + PFNGLMULTITEXCOORD1DPROC glMultiTexCoord1d_Impl; + PFNGLMULTITEXCOORD1DVPROC glMultiTexCoord1dv_Impl; + PFNGLMULTITEXCOORD1FPROC glMultiTexCoord1f_Impl; + PFNGLMULTITEXCOORD1FVPROC glMultiTexCoord1fv_Impl; + PFNGLMULTITEXCOORD1IPROC glMultiTexCoord1i_Impl; + PFNGLMULTITEXCOORD1IVPROC glMultiTexCoord1iv_Impl; + PFNGLMULTITEXCOORD1SPROC glMultiTexCoord1s_Impl; + PFNGLMULTITEXCOORD1SVPROC glMultiTexCoord1sv_Impl; + PFNGLMULTITEXCOORD2DPROC glMultiTexCoord2d_Impl; + PFNGLMULTITEXCOORD2DVPROC glMultiTexCoord2dv_Impl; + PFNGLMULTITEXCOORD2FPROC glMultiTexCoord2f_Impl; + PFNGLMULTITEXCOORD2FVPROC glMultiTexCoord2fv_Impl; + PFNGLMULTITEXCOORD2IPROC glMultiTexCoord2i_Impl; + PFNGLMULTITEXCOORD2IVPROC glMultiTexCoord2iv_Impl; + PFNGLMULTITEXCOORD2SPROC glMultiTexCoord2s_Impl; + PFNGLMULTITEXCOORD2SVPROC glMultiTexCoord2sv_Impl; + PFNGLMULTITEXCOORD3DPROC glMultiTexCoord3d_Impl; + PFNGLMULTITEXCOORD3DVPROC glMultiTexCoord3dv_Impl; + PFNGLMULTITEXCOORD3FPROC glMultiTexCoord3f_Impl; + PFNGLMULTITEXCOORD3FVPROC glMultiTexCoord3fv_Impl; + PFNGLMULTITEXCOORD3IPROC glMultiTexCoord3i_Impl; + PFNGLMULTITEXCOORD3IVPROC glMultiTexCoord3iv_Impl; + PFNGLMULTITEXCOORD3SPROC glMultiTexCoord3s_Impl; + PFNGLMULTITEXCOORD3SVPROC glMultiTexCoord3sv_Impl; + PFNGLMULTITEXCOORD4DPROC glMultiTexCoord4d_Impl; + PFNGLMULTITEXCOORD4DVPROC glMultiTexCoord4dv_Impl; + PFNGLMULTITEXCOORD4FPROC glMultiTexCoord4f_Impl; + PFNGLMULTITEXCOORD4FVPROC glMultiTexCoord4fv_Impl; + PFNGLMULTITEXCOORD4IPROC glMultiTexCoord4i_Impl; + PFNGLMULTITEXCOORD4IVPROC glMultiTexCoord4iv_Impl; + PFNGLMULTITEXCOORD4SPROC glMultiTexCoord4s_Impl; + PFNGLMULTITEXCOORD4SVPROC glMultiTexCoord4sv_Impl; + PFNGLSAMPLECOVERAGEPROC glSampleCoverage_Impl; + + // GL_VERSION_1_4 + PFNGLBLENDCOLORPROC glBlendColor_Impl; + PFNGLBLENDEQUATIONPROC glBlendEquation_Impl; + PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate_Impl; + PFNGLFOGCOORDPOINTERPROC glFogCoordPointer_Impl; + PFNGLFOGCOORDDPROC glFogCoordd_Impl; + PFNGLFOGCOORDDVPROC glFogCoorddv_Impl; + PFNGLFOGCOORDFPROC glFogCoordf_Impl; + PFNGLFOGCOORDFVPROC glFogCoordfv_Impl; + PFNGLMULTIDRAWARRAYSPROC glMultiDrawArrays_Impl; + PFNGLMULTIDRAWELEMENTSPROC glMultiDrawElements_Impl; + PFNGLPOINTPARAMETERFPROC glPointParameterf_Impl; + PFNGLPOINTPARAMETERFVPROC glPointParameterfv_Impl; + PFNGLPOINTPARAMETERIPROC glPointParameteri_Impl; + PFNGLPOINTPARAMETERIVPROC glPointParameteriv_Impl; + PFNGLSECONDARYCOLOR3BPROC glSecondaryColor3b_Impl; + PFNGLSECONDARYCOLOR3BVPROC glSecondaryColor3bv_Impl; + PFNGLSECONDARYCOLOR3DPROC glSecondaryColor3d_Impl; + PFNGLSECONDARYCOLOR3DVPROC glSecondaryColor3dv_Impl; + PFNGLSECONDARYCOLOR3FPROC glSecondaryColor3f_Impl; + PFNGLSECONDARYCOLOR3FVPROC glSecondaryColor3fv_Impl; + PFNGLSECONDARYCOLOR3IPROC glSecondaryColor3i_Impl; + PFNGLSECONDARYCOLOR3IVPROC glSecondaryColor3iv_Impl; + PFNGLSECONDARYCOLOR3SPROC glSecondaryColor3s_Impl; + PFNGLSECONDARYCOLOR3SVPROC glSecondaryColor3sv_Impl; + PFNGLSECONDARYCOLOR3UBPROC glSecondaryColor3ub_Impl; + PFNGLSECONDARYCOLOR3UBVPROC glSecondaryColor3ubv_Impl; + PFNGLSECONDARYCOLOR3UIPROC glSecondaryColor3ui_Impl; + PFNGLSECONDARYCOLOR3UIVPROC glSecondaryColor3uiv_Impl; + PFNGLSECONDARYCOLOR3USPROC glSecondaryColor3us_Impl; + PFNGLSECONDARYCOLOR3USVPROC glSecondaryColor3usv_Impl; + PFNGLSECONDARYCOLORPOINTERPROC glSecondaryColorPointer_Impl; + PFNGLWINDOWPOS2DPROC glWindowPos2d_Impl; + PFNGLWINDOWPOS2DVPROC glWindowPos2dv_Impl; + PFNGLWINDOWPOS2FPROC glWindowPos2f_Impl; + PFNGLWINDOWPOS2FVPROC glWindowPos2fv_Impl; + PFNGLWINDOWPOS2IPROC glWindowPos2i_Impl; + PFNGLWINDOWPOS2IVPROC glWindowPos2iv_Impl; + PFNGLWINDOWPOS2SPROC glWindowPos2s_Impl; + PFNGLWINDOWPOS2SVPROC glWindowPos2sv_Impl; + PFNGLWINDOWPOS3DPROC glWindowPos3d_Impl; + PFNGLWINDOWPOS3DVPROC glWindowPos3dv_Impl; + PFNGLWINDOWPOS3FPROC glWindowPos3f_Impl; + PFNGLWINDOWPOS3FVPROC glWindowPos3fv_Impl; + PFNGLWINDOWPOS3IPROC glWindowPos3i_Impl; + PFNGLWINDOWPOS3IVPROC glWindowPos3iv_Impl; + PFNGLWINDOWPOS3SPROC glWindowPos3s_Impl; + PFNGLWINDOWPOS3SVPROC glWindowPos3sv_Impl; + + // GL_VERSION_1_5 + PFNGLBEGINQUERYPROC glBeginQuery_Impl; + PFNGLBINDBUFFERPROC glBindBuffer_Impl; + PFNGLBUFFERDATAPROC glBufferData_Impl; + PFNGLBUFFERSUBDATAPROC glBufferSubData_Impl; + PFNGLDELETEBUFFERSPROC glDeleteBuffers_Impl; + PFNGLDELETEQUERIESPROC glDeleteQueries_Impl; + PFNGLENDQUERYPROC glEndQuery_Impl; + PFNGLGENBUFFERSPROC glGenBuffers_Impl; + PFNGLGENQUERIESPROC glGenQueries_Impl; + PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv_Impl; + PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv_Impl; + PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData_Impl; + PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv_Impl; + PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv_Impl; + PFNGLGETQUERYIVPROC glGetQueryiv_Impl; + PFNGLISBUFFERPROC glIsBuffer_Impl; + PFNGLISQUERYPROC glIsQuery_Impl; + PFNGLMAPBUFFERPROC glMapBuffer_Impl; + PFNGLUNMAPBUFFERPROC glUnmapBuffer_Impl; + + // GL_VERSION_2_0 + PFNGLATTACHSHADERPROC glAttachShader_Impl; + PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation_Impl; + PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate_Impl; + PFNGLCOMPILESHADERPROC glCompileShader_Impl; + PFNGLCREATEPROGRAMPROC glCreateProgram_Impl; + PFNGLCREATESHADERPROC glCreateShader_Impl; + PFNGLDELETEPROGRAMPROC glDeleteProgram_Impl; + PFNGLDELETESHADERPROC glDeleteShader_Impl; + PFNGLDETACHSHADERPROC glDetachShader_Impl; + PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray_Impl; + PFNGLDRAWBUFFERSPROC glDrawBuffers_Impl; + PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray_Impl; + PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib_Impl; + PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform_Impl; + PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders_Impl; + PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation_Impl; + PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog_Impl; + PFNGLGETPROGRAMIVPROC glGetProgramiv_Impl; + PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog_Impl; + PFNGLGETSHADERSOURCEPROC glGetShaderSource_Impl; + PFNGLGETSHADERIVPROC glGetShaderiv_Impl; + PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation_Impl; + PFNGLGETUNIFORMFVPROC glGetUniformfv_Impl; + PFNGLGETUNIFORMIVPROC glGetUniformiv_Impl; + PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv_Impl; + PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv_Impl; + PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv_Impl; + PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv_Impl; + PFNGLISPROGRAMPROC glIsProgram_Impl; + PFNGLISSHADERPROC glIsShader_Impl; + PFNGLLINKPROGRAMPROC glLinkProgram_Impl; + PFNGLSHADERSOURCEPROC glShaderSource_Impl; + PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate_Impl; + PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate_Impl; + PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate_Impl; + PFNGLUNIFORM1FPROC glUniform1f_Impl; + PFNGLUNIFORM1FVPROC glUniform1fv_Impl; + PFNGLUNIFORM1IPROC glUniform1i_Impl; + PFNGLUNIFORM1IVPROC glUniform1iv_Impl; + PFNGLUNIFORM2FPROC glUniform2f_Impl; + PFNGLUNIFORM2FVPROC glUniform2fv_Impl; + PFNGLUNIFORM2IPROC glUniform2i_Impl; + PFNGLUNIFORM2IVPROC glUniform2iv_Impl; + PFNGLUNIFORM3FPROC glUniform3f_Impl; + PFNGLUNIFORM3FVPROC glUniform3fv_Impl; + PFNGLUNIFORM3IPROC glUniform3i_Impl; + PFNGLUNIFORM3IVPROC glUniform3iv_Impl; + PFNGLUNIFORM4FPROC glUniform4f_Impl; + PFNGLUNIFORM4FVPROC glUniform4fv_Impl; + PFNGLUNIFORM4IPROC glUniform4i_Impl; + PFNGLUNIFORM4IVPROC glUniform4iv_Impl; + PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv_Impl; + PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv_Impl; + PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv_Impl; + PFNGLUSEPROGRAMPROC glUseProgram_Impl; + PFNGLVALIDATEPROGRAMPROC glValidateProgram_Impl; + PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d_Impl; + PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv_Impl; + PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f_Impl; + PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv_Impl; + PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s_Impl; + PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv_Impl; + PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d_Impl; + PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv_Impl; + PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f_Impl; + PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv_Impl; + PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s_Impl; + PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv_Impl; + PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d_Impl; + PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv_Impl; + PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f_Impl; + PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv_Impl; + PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s_Impl; + PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv_Impl; + PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4Nbv_Impl; + PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4Niv_Impl; + PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4Nsv_Impl; + PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4Nub_Impl; + PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4Nubv_Impl; + PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4Nuiv_Impl; + PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4Nusv_Impl; + PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv_Impl; + PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d_Impl; + PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv_Impl; + PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f_Impl; + PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv_Impl; + PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv_Impl; + PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s_Impl; + PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv_Impl; + PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv_Impl; + PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv_Impl; + PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv_Impl; + PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer_Impl; + + // GL_VERSION_2_1 + PFNGLUNIFORMMATRIX2X3FVPROC glUniformMatrix2x3fv_Impl; + PFNGLUNIFORMMATRIX2X4FVPROC glUniformMatrix2x4fv_Impl; + PFNGLUNIFORMMATRIX3X2FVPROC glUniformMatrix3x2fv_Impl; + PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv_Impl; + PFNGLUNIFORMMATRIX4X2FVPROC glUniformMatrix4x2fv_Impl; + PFNGLUNIFORMMATRIX4X3FVPROC glUniformMatrix4x3fv_Impl; + + // GL_VERSION_3_0 + PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender_Impl; + PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback_Impl; + PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation_Impl; + PFNGLCLAMPCOLORPROC glClampColor_Impl; + PFNGLCLEARBUFFERFIPROC glClearBufferfi_Impl; + PFNGLCLEARBUFFERFVPROC glClearBufferfv_Impl; + PFNGLCLEARBUFFERIVPROC glClearBufferiv_Impl; + PFNGLCLEARBUFFERUIVPROC glClearBufferuiv_Impl; + PFNGLCOLORMASKIPROC glColorMaski_Impl; + PFNGLDISABLEIPROC glDisablei_Impl; + PFNGLENABLEIPROC glEnablei_Impl; + PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender_Impl; + PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback_Impl; + PFNGLBINDBUFFERRANGEPROC glBindBufferRange_Impl; + PFNGLBINDBUFFERBASEPROC glBindBufferBase_Impl; + PFNGLGETBOOLEANI_VPROC glGetBooleani_v_Impl; + PFNGLGETINTEGERI_VPROC glGetIntegeri_v_Impl; + PFNGLGETFRAGDATALOCATIONPROC glGetFragDataLocation_Impl; + PFNGLGETSTRINGIPROC glGetStringi_Impl; + PFNGLGETTEXPARAMETERIIVPROC glGetTexParameterIiv_Impl; + PFNGLGETTEXPARAMETERIUIVPROC glGetTexParameterIuiv_Impl; + PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glGetTransformFeedbackVarying_Impl; + PFNGLGETUNIFORMUIVPROC glGetUniformuiv_Impl; + PFNGLGETVERTEXATTRIBIIVPROC glGetVertexAttribIiv_Impl; + PFNGLGETVERTEXATTRIBIUIVPROC glGetVertexAttribIuiv_Impl; + PFNGLISENABLEDIPROC glIsEnabledi_Impl; + PFNGLTEXPARAMETERIIVPROC glTexParameterIiv_Impl; + PFNGLTEXPARAMETERIUIVPROC glTexParameterIuiv_Impl; + PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings_Impl; + PFNGLUNIFORM1UIPROC glUniform1ui_Impl; + PFNGLUNIFORM1UIVPROC glUniform1uiv_Impl; + PFNGLUNIFORM2UIPROC glUniform2ui_Impl; + PFNGLUNIFORM2UIVPROC glUniform2uiv_Impl; + PFNGLUNIFORM3UIPROC glUniform3ui_Impl; + PFNGLUNIFORM3UIVPROC glUniform3uiv_Impl; + PFNGLUNIFORM4UIPROC glUniform4ui_Impl; + PFNGLUNIFORM4UIVPROC glUniform4uiv_Impl; + PFNGLVERTEXATTRIBI1IPROC glVertexAttribI1i_Impl; + PFNGLVERTEXATTRIBI1IVPROC glVertexAttribI1iv_Impl; + PFNGLVERTEXATTRIBI1UIPROC glVertexAttribI1ui_Impl; + PFNGLVERTEXATTRIBI1UIVPROC glVertexAttribI1uiv_Impl; + PFNGLVERTEXATTRIBI2IPROC glVertexAttribI2i_Impl; + PFNGLVERTEXATTRIBI2IVPROC glVertexAttribI2iv_Impl; + PFNGLVERTEXATTRIBI2UIPROC glVertexAttribI2ui_Impl; + PFNGLVERTEXATTRIBI2UIVPROC glVertexAttribI2uiv_Impl; + PFNGLVERTEXATTRIBI3IPROC glVertexAttribI3i_Impl; + PFNGLVERTEXATTRIBI3IVPROC glVertexAttribI3iv_Impl; + PFNGLVERTEXATTRIBI3UIPROC glVertexAttribI3ui_Impl; + PFNGLVERTEXATTRIBI3UIVPROC glVertexAttribI3uiv_Impl; + PFNGLVERTEXATTRIBI4BVPROC glVertexAttribI4bv_Impl; + PFNGLVERTEXATTRIBI4IPROC glVertexAttribI4i_Impl; + PFNGLVERTEXATTRIBI4IVPROC glVertexAttribI4iv_Impl; + PFNGLVERTEXATTRIBI4SVPROC glVertexAttribI4sv_Impl; + PFNGLVERTEXATTRIBI4UBVPROC glVertexAttribI4ubv_Impl; + PFNGLVERTEXATTRIBI4UIPROC glVertexAttribI4ui_Impl; + PFNGLVERTEXATTRIBI4UIVPROC glVertexAttribI4uiv_Impl; + PFNGLVERTEXATTRIBI4USVPROC glVertexAttribI4usv_Impl; + PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer_Impl; + + // GL_VERSION_3_1 + PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced_Impl; + PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced_Impl; + PFNGLPRIMITIVERESTARTINDEXPROC glPrimitiveRestartIndex_Impl; + PFNGLTEXBUFFERPROC glTexBuffer_Impl; + + // GL_VERSION_3_2 + PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture_Impl; + PFNGLGETBUFFERPARAMETERI64VPROC glGetBufferParameteri64v_Impl; + PFNGLGETINTEGER64I_VPROC glGetInteger64i_v_Impl; + + // GL_VERSION_3_3 + PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor_Impl; + + // GL_VERSION_4_0 + PFNGLBLENDEQUATIONSEPARATEIPROC glBlendEquationSeparatei_Impl; + PFNGLBLENDEQUATIONIPROC glBlendEquationi_Impl; + PFNGLBLENDFUNCSEPARATEIPROC glBlendFuncSeparatei_Impl; + PFNGLBLENDFUNCIPROC glBlendFunci_Impl; + PFNGLMINSAMPLESHADINGPROC glMinSampleShading_Impl; + + // GL_AMD_debug_output + PFNGLDEBUGMESSAGECALLBACKAMDPROC glDebugMessageCallbackAMD_Impl; + PFNGLDEBUGMESSAGEENABLEAMDPROC glDebugMessageEnableAMD_Impl; + PFNGLDEBUGMESSAGEINSERTAMDPROC glDebugMessageInsertAMD_Impl; + PFNGLGETDEBUGMESSAGELOGAMDPROC glGetDebugMessageLogAMD_Impl; + + #if defined(GLE_CGL_ENABLED) + // GL_APPLE_aux_depth_stencil + // (no functions) + + // GL_APPLE_client_storage + // (no functions) + + // GL_APPLE_element_array + PFNGLDRAWELEMENTARRAYAPPLEPROC glDrawElementArrayAPPLE_Impl; + PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC glDrawRangeElementArrayAPPLE_Impl; + PFNGLELEMENTPOINTERAPPLEPROC glElementPointerAPPLE_Impl; + PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC glMultiDrawElementArrayAPPLE_Impl; + PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC glMultiDrawRangeElementArrayAPPLE_Impl; + + // GL_APPLE_fence + PFNGLDELETEFENCESAPPLEPROC glDeleteFencesAPPLE_Impl; + PFNGLFINISHFENCEAPPLEPROC glFinishFenceAPPLE_Impl; + PFNGLFINISHOBJECTAPPLEPROC glFinishObjectAPPLE_Impl; + PFNGLGENFENCESAPPLEPROC glGenFencesAPPLE_Impl; + PFNGLISFENCEAPPLEPROC glIsFenceAPPLE_Impl; + PFNGLSETFENCEAPPLEPROC glSetFenceAPPLE_Impl; + PFNGLTESTFENCEAPPLEPROC glTestFenceAPPLE_Impl; + PFNGLTESTOBJECTAPPLEPROC glTestObjectAPPLE_Impl; + + // GL_APPLE_float_pixels + // (no functions) + + // GL_APPLE_flush_buffer_range + PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE_Impl; + PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE_Impl; + + // GL_APPLE_object_purgeable + PFNGLGETOBJECTPARAMETERIVAPPLEPROC glGetObjectParameterivAPPLE_Impl; + PFNGLOBJECTPURGEABLEAPPLEPROC glObjectPurgeableAPPLE_Impl; + PFNGLOBJECTUNPURGEABLEAPPLEPROC glObjectUnpurgeableAPPLE_Impl; + + // GL_APPLE_pixel_buffer + // (no functions) + + // GL_APPLE_rgb_422 + // (no functions) + + // GL_APPLE_row_bytes + // (no functions) + + // GL_APPLE_specular_vector + // (no functions) + + // GL_APPLE_texture_range + PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC glGetTexParameterPointervAPPLE_Impl; + PFNGLTEXTURERANGEAPPLEPROC glTextureRangeAPPLE_Impl; + + // GL_APPLE_transform_hint + // (no functions) + + // GL_APPLE_vertex_array_object + PFNGLBINDVERTEXARRAYAPPLEPROC glBindVertexArrayAPPLE_Impl; + PFNGLDELETEVERTEXARRAYSAPPLEPROC glDeleteVertexArraysAPPLE_Impl; + PFNGLGENVERTEXARRAYSAPPLEPROC glGenVertexArraysAPPLE_Impl; + PFNGLISVERTEXARRAYAPPLEPROC glIsVertexArrayAPPLE_Impl; + + // GL_APPLE_vertex_array_range + PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC glFlushVertexArrayRangeAPPLE_Impl; + PFNGLVERTEXARRAYPARAMETERIAPPLEPROC glVertexArrayParameteriAPPLE_Impl; + PFNGLVERTEXARRAYRANGEAPPLEPROC glVertexArrayRangeAPPLE_Impl; + + // GL_APPLE_vertex_program_evaluators + PFNGLDISABLEVERTEXATTRIBAPPLEPROC glDisableVertexAttribAPPLE_Impl; + PFNGLENABLEVERTEXATTRIBAPPLEPROC glEnableVertexAttribAPPLE_Impl; + PFNGLISVERTEXATTRIBENABLEDAPPLEPROC glIsVertexAttribEnabledAPPLE_Impl; + PFNGLMAPVERTEXATTRIB1DAPPLEPROC glMapVertexAttrib1dAPPLE_Impl; + PFNGLMAPVERTEXATTRIB1FAPPLEPROC glMapVertexAttrib1fAPPLE_Impl; + PFNGLMAPVERTEXATTRIB2DAPPLEPROC glMapVertexAttrib2dAPPLE_Impl; + PFNGLMAPVERTEXATTRIB2FAPPLEPROC glMapVertexAttrib2fAPPLE_Impl; + #endif // GLE_CGL_ENABLED + + // GL_ARB_copy_buffer + PFNGLCOPYBUFFERSUBDATAPROC glCopyBufferSubData_Impl; + + // GL_ARB_debug_output + PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallbackARB_Impl; + PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControlARB_Impl; + PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsertARB_Impl; + PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLogARB_Impl; + + // GL_ARB_ES2_compatibility + PFNGLCLEARDEPTHFPROC glClearDepthf_Impl; + PFNGLDEPTHRANGEFPROC glDepthRangef_Impl; + PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat_Impl; + PFNGLRELEASESHADERCOMPILERPROC glReleaseShaderCompiler_Impl; + PFNGLSHADERBINARYPROC glShaderBinary_Impl; + + // GL_ARB_framebuffer_object + PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer_Impl; + PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer_Impl; + PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer_Impl; + PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus_Impl; + PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers_Impl; + PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers_Impl; + PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer_Impl; + PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D_Impl; + PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D_Impl; + PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D_Impl; + PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer_Impl; + PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers_Impl; + PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers_Impl; + PFNGLGENERATEMIPMAPPROC glGenerateMipmap_Impl; + PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv_Impl; + PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv_Impl; + PFNGLISFRAMEBUFFERPROC glIsFramebuffer_Impl; + PFNGLISRENDERBUFFERPROC glIsRenderbuffer_Impl; + PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage_Impl; + PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample_Impl; + + // GL_ARB_framebuffer_sRGB + // (no functions) + + // GL_ARB_texture_multisample + PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv_Impl; + PFNGLSAMPLEMASKIPROC glSampleMaski_Impl; + PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample_Impl; + PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample_Impl; + + // GL_ARB_texture_non_power_of_two + // (no functions) + + // GL_ARB_texture_rectangle + // (no functions) + + // GL_ARB_timer_query + PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v_Impl; + PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v_Impl; + PFNGLQUERYCOUNTERPROC glQueryCounter_Impl; + + // GL_ARB_vertex_array_object + PFNGLBINDVERTEXARRAYPROC glBindVertexArray_Impl; + PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays_Impl; + PFNGLGENVERTEXARRAYSPROC glGenVertexArrays_Impl; + PFNGLISVERTEXARRAYPROC glIsVertexArray_Impl; + + // GL_EXT_draw_buffers2 + PFNGLCOLORMASKINDEXEDEXTPROC glColorMaskIndexedEXT_Impl; + PFNGLDISABLEINDEXEDEXTPROC glDisableIndexedEXT_Impl; + PFNGLENABLEINDEXEDEXTPROC glEnableIndexedEXT_Impl; + PFNGLGETBOOLEANINDEXEDVEXTPROC glGetBooleanIndexedvEXT_Impl; + PFNGLGETINTEGERINDEXEDVEXTPROC glGetIntegerIndexedvEXT_Impl; + PFNGLISENABLEDINDEXEDEXTPROC glIsEnabledIndexedEXT_Impl; + + // GL_EXT_texture_filter_anisotropic + // (no functions) + + // GL_KHR_debug + PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback_Impl; + PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl_Impl; + PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert_Impl; + PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog_Impl; + PFNGLGETOBJECTLABELPROC glGetObjectLabel_Impl; + PFNGLGETOBJECTPTRLABELPROC glGetObjectPtrLabel_Impl; + PFNGLOBJECTLABELPROC glObjectLabel_Impl; + PFNGLOBJECTPTRLABELPROC glObjectPtrLabel_Impl; + PFNGLPOPDEBUGGROUPPROC glPopDebugGroup_Impl; + PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup_Impl; + + // GL_KHR_robust_buffer_access_behavior + + // GL_WIN_swap_hint + PFNGLADDSWAPHINTRECTWINPROC glAddSwapHintRectWIN_Impl; + + #if defined(GLE_WGL_ENABLED) + // WGL + // We don't declare pointers for these because we statically link to the implementations, same as with the OpenGL 1.1 functions. + // BOOL wglCopyContext_Hook(HGLRC, HGLRC, UINT); + // HGLRC wglCreateContext_Hook(HDC); + // HGLRC wglCreateLayerContext_Hook(HDC, int); + // BOOL wglDeleteContext_Hook(HGLRC); + // HGLRC wglGetCurrentContext_Hook(VOID); + // HDC wglGetCurrentDC_Hook(VOID); + // PROC wglGetProcAddress_Hook(LPCSTR); + // BOOL wglMakeCurrent_Hook(HDC, HGLRC); + // BOOL wglShareLists_Hook(HGLRC, HGLRC); + // BOOL wglUseFontBitmapsA_Hook(HDC, DWORD, DWORD, DWORD); + // BOOL wglUseFontBitmapsW_Hook(HDC, DWORD, DWORD, DWORD); + // BOOL wglUseFontOutlinesA_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); + // BOOL wglUseFontOutlinesW_Hook(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); + // BOOL wglDescribeLayerPlane_Hook(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); + // int wglSetLayerPaletteEntries_Hook(HDC, int, int, int, CONST COLORREF *); + // int wglGetLayerPaletteEntries_Hook(HDC, int, int, int, COLORREF *); + // BOOL wglRealizeLayerPalette_Hook(HDC, int, BOOL); + // BOOL wglSwapLayerBuffers_Hook(HDC, UINT); + // DWORD wglSwapMultipleBuffers_Hook(UINT, CONST WGLSWAP *); + + #if 0 + PFNWGLCOPYCONTEXTPROC wglCopyContext_Impl; + PFNWGLCREATECONTEXTPROC wglCreateContext_Impl; + PFNWGLCREATELAYERCONTEXTPROC wglCreateLayerContext_Impl; + PFNWGLDELETECONTEXTPROC wglDeleteContext_Impl; + PFNWGLGETCURRENTCONTEXTPROC wglGetCurrentContext_Impl; + PFNWGLGETCURRENTDCPROC wglGetCurrentDC_Impl; + PFNWGLGETPROCADDRESSPROC wglGetProcAddress_Impl; + PFNWGLMAKECURRENTPROC wglMakeCurrent_Impl; + PFNWGLSHARELISTSPROC wglShareLists_Impl; + PFNWGLUSEFONTBITMAPSAPROC wglUseFontBitmapsA_Impl; + PFNWGLUSEFONTBITMAPSWPROC wglUseFontBitmapsW_Impl; + PFNWGLUSEFONTOUTLINESAPROC wglUseFontOutlinesA_Impl; + PFNWGLUSEFONTOUTLINESWPROC wglUseFontOutlinesW_Impl; + PFNWGLDESCRIBELAYERPLANEPROC wglDescribeLayerPlane_Impl; + PFNWGLSETLAYERPALETTEENTRIESPROC wglSetLayerPaletteEntries_Impl; + PFNWGLGETLAYERPALETTEENTRIESPROC wglGetLayerPaletteEntries_Impl; + PFNWGLREALIZELAYERPALETTEPROC wglRealizeLayerPalette_Impl; + PFNWGLSWAPLAYERBUFFERSPROC wglSwapLayerBuffers_Impl; + PFNWGLSWAPMULTIPLEBUFFERSPROC wglSwapMultipleBuffers_Impl; + #endif + + // WGL_ARB_buffer_region + PFNWGLCREATEBUFFERREGIONARBPROC wglCreateBufferRegionARB_Impl; + PFNWGLDELETEBUFFERREGIONARBPROC wglDeleteBufferRegionARB_Impl; + PFNWGLSAVEBUFFERREGIONARBPROC wglSaveBufferRegionARB_Impl; + PFNWGLRESTOREBUFFERREGIONARBPROC wglRestoreBufferRegionARB_Impl; + + // WGL_ARB_extensions_string + PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB_Impl; + + // WGL_ARB_pixel_format + PFNWGLGETPIXELFORMATATTRIBIVARBPROC wglGetPixelFormatAttribivARB_Impl; + PFNWGLGETPIXELFORMATATTRIBFVARBPROC wglGetPixelFormatAttribfvARB_Impl; + PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB_Impl; + + // WGL_ARB_make_current_read + PFNWGLMAKECONTEXTCURRENTARBPROC wglMakeContextCurrentARB_Impl; + PFNWGLGETCURRENTREADDCARBPROC wglGetCurrentReadDCARB_Impl; + + // WGL_ARB_pbuffer + PFNWGLCREATEPBUFFERARBPROC wglCreatePbufferARB_Impl; + PFNWGLGETPBUFFERDCARBPROC wglGetPbufferDCARB_Impl; + PFNWGLRELEASEPBUFFERDCARBPROC wglReleasePbufferDCARB_Impl; + PFNWGLDESTROYPBUFFERARBPROC wglDestroyPbufferARB_Impl; + PFNWGLQUERYPBUFFERARBPROC wglQueryPbufferARB_Impl; + + // WGL_ARB_render_texture + PFNWGLBINDTEXIMAGEARBPROC wglBindTexImageARB_Impl; + PFNWGLRELEASETEXIMAGEARBPROC wglReleaseTexImageARB_Impl; + PFNWGLSETPBUFFERATTRIBARBPROC wglSetPbufferAttribARB_Impl; + + // WGL_ARB_pixel_format_float + // (no functions) + + // WGL_ARB_framebuffer_sRGB + // (no functions) + + // WGL_NV_present_video + PFNWGLENUMERATEVIDEODEVICESNVPROC wglEnumerateVideoDevicesNV_Impl; + PFNWGLBINDVIDEODEVICENVPROC wglBindVideoDeviceNV_Impl; + PFNWGLQUERYCURRENTCONTEXTNVPROC wglQueryCurrentContextNV_Impl; + + // WGL_ARB_create_context + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB_Impl; + + // WGL_ARB_create_context_profile + // (no functions) + + // WGL_ARB_create_context_robustness + // (no functions) + + // WGL_EXT_extensions_string + PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT_Impl; + + // WGL_EXT_swap_control + PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT_Impl; + PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT_Impl; + + // WGL_OML_sync_control + PFNWGLGETSYNCVALUESOMLPROC wglGetSyncValuesOML_Impl; + PFNWGLGETMSCRATEOMLPROC wglGetMscRateOML_Impl; + PFNWGLSWAPBUFFERSMSCOMLPROC wglSwapBuffersMscOML_Impl; + PFNWGLSWAPLAYERBUFFERSMSCOMLPROC wglSwapLayerBuffersMscOML_Impl; + PFNWGLWAITFORMSCOMLPROC wglWaitForMscOML_Impl; + PFNWGLWAITFORSBCOMLPROC wglWaitForSbcOML_Impl; + + // WGL_NV_video_output + PFNWGLGETVIDEODEVICENVPROC wglGetVideoDeviceNV_Impl; + PFNWGLRELEASEVIDEODEVICENVPROC wglReleaseVideoDeviceNV_Impl; + PFNWGLBINDVIDEOIMAGENVPROC wglBindVideoImageNV_Impl; + PFNWGLRELEASEVIDEOIMAGENVPROC wglReleaseVideoImageNV_Impl; + PFNWGLSENDPBUFFERTOVIDEONVPROC wglSendPbufferToVideoNV_Impl; + PFNWGLGETVIDEOINFONVPROC wglGetVideoInfoNV_Impl; + + // WGL_NV_swap_group + PFNWGLJOINSWAPGROUPNVPROC wglJoinSwapGroupNV_Impl; + PFNWGLBINDSWAPBARRIERNVPROC wglBindSwapBarrierNV_Impl; + PFNWGLQUERYSWAPGROUPNVPROC wglQuerySwapGroupNV_Impl; + PFNWGLQUERYMAXSWAPGROUPSNVPROC wglQueryMaxSwapGroupsNV_Impl; + PFNWGLQUERYFRAMECOUNTNVPROC wglQueryFrameCountNV_Impl; + PFNWGLRESETFRAMECOUNTNVPROC wglResetFrameCountNV_Impl; + + // WGL_NV_video_capture + PFNWGLBINDVIDEOCAPTUREDEVICENVPROC wglBindVideoCaptureDeviceNV_Impl; + PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC wglEnumerateVideoCaptureDevicesNV_Impl; + PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC wglLockVideoCaptureDeviceNV_Impl; + PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC wglQueryVideoCaptureDeviceNV_Impl; + PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC wglReleaseVideoCaptureDeviceNV_Impl; + + // WGL_NV_copy_image + PFNWGLCOPYIMAGESUBDATANVPROC wglCopyImageSubDataNV_Impl; + + // WGL_NV_DX_interop + PFNWGLDXCLOSEDEVICENVPROC wglDXCloseDeviceNV_Impl; + PFNWGLDXLOCKOBJECTSNVPROC wglDXLockObjectsNV_Impl; + PFNWGLDXOBJECTACCESSNVPROC wglDXObjectAccessNV_Impl; + PFNWGLDXOPENDEVICENVPROC wglDXOpenDeviceNV_Impl; + PFNWGLDXREGISTEROBJECTNVPROC wglDXRegisterObjectNV_Impl; + PFNWGLDXSETRESOURCESHAREHANDLENVPROC wglDXSetResourceShareHandleNV_Impl; + PFNWGLDXUNLOCKOBJECTSNVPROC wglDXUnlockObjectsNV_Impl; + PFNWGLDXUNREGISTEROBJECTNVPROC wglDXUnregisterObjectNV_Impl; + + #endif // GLE_WGL_ENABLED + + #if defined(GLE_GLX_ENABLED) + // GLX_VERSION_1_1 + // We don't create any pointers, because we assume these functions are always present. + + // GLX_VERSION_1_2 + PFNGLXGETCURRENTDISPLAYPROC glXGetCurrentDisplay_Impl; + + // GLX_VERSION_1_3 + PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig_Impl; + PFNGLXCREATENEWCONTEXTPROC glXCreateNewContext_Impl; + PFNGLXCREATEPBUFFERPROC glXCreatePbuffer_Impl; + PFNGLXCREATEPIXMAPPROC glXCreatePixmap_Impl; + PFNGLXCREATEWINDOWPROC glXCreateWindow_Impl; + PFNGLXDESTROYPBUFFERPROC glXDestroyPbuffer_Impl; + PFNGLXDESTROYPIXMAPPROC glXDestroyPixmap_Impl; + PFNGLXDESTROYWINDOWPROC glXDestroyWindow_Impl; + PFNGLXGETCURRENTREADDRAWABLEPROC glXGetCurrentReadDrawable_Impl; + PFNGLXGETFBCONFIGATTRIBPROC glXGetFBConfigAttrib_Impl; + PFNGLXGETFBCONFIGSPROC glXGetFBConfigs_Impl; + PFNGLXGETSELECTEDEVENTPROC glXGetSelectedEvent_Impl; + PFNGLXGETVISUALFROMFBCONFIGPROC glXGetVisualFromFBConfig_Impl; + PFNGLXMAKECONTEXTCURRENTPROC glXMakeContextCurrent_Impl; + PFNGLXQUERYCONTEXTPROC glXQueryContext_Impl; + PFNGLXQUERYDRAWABLEPROC glXQueryDrawable_Impl; + PFNGLXSELECTEVENTPROC glXSelectEvent_Impl; + + // GLX_VERSION_1_4 + // Nothing to declare + + // GLX_ARB_create_context + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB_Impl; + + // GLX_EXT_swap_control + PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT_Impl; + + // GLX_OML_sync_control + PFNGLXGETMSCRATEOMLPROC glXGetMscRateOML_Impl; + PFNGLXGETSYNCVALUESOMLPROC glXGetSyncValuesOML_Impl; + PFNGLXSWAPBUFFERSMSCOMLPROC glXSwapBuffersMscOML_Impl; + PFNGLXWAITFORMSCOMLPROC glXWaitForMscOML_Impl; + PFNGLXWAITFORSBCOMLPROC glXWaitForSbcOML_Impl; + + // GLX_MESA_swap_control + PFNGLXGETSWAPINTERVALMESAPROC glXGetSwapIntervalMESA_Impl; + PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA_Impl; + + #endif // GLE_GLX_ENABLED + + + // Boolean extension support indicators. Each of these identifies the + // presence or absence of the given extension. A better solution here + // might be to use an STL map. + bool gle_AMD_debug_output; + //bool gle_AMD_performance_monitor; + bool gle_APPLE_aux_depth_stencil; + bool gle_APPLE_client_storage; + bool gle_APPLE_element_array; + bool gle_APPLE_fence; + bool gle_APPLE_float_pixels; + bool gle_APPLE_flush_buffer_range; + bool gle_APPLE_object_purgeable; + bool gle_APPLE_pixel_buffer; + bool gle_APPLE_rgb_422; + bool gle_APPLE_row_bytes; + bool gle_APPLE_specular_vector; + bool gle_APPLE_texture_range; + bool gle_APPLE_transform_hint; + bool gle_APPLE_vertex_array_object; + bool gle_APPLE_vertex_array_range; + bool gle_APPLE_vertex_program_evaluators; + bool gle_APPLE_ycbcr_422; + bool gle_ARB_copy_buffer; + bool gle_ARB_debug_output; + bool gle_ARB_depth_buffer_float; + //bool gle_ARB_direct_state_access; + bool gle_ARB_ES2_compatibility; + bool gle_ARB_framebuffer_object; + bool gle_ARB_framebuffer_sRGB; + bool gle_ARB_texture_multisample; + bool gle_ARB_texture_non_power_of_two; + bool gle_ARB_texture_rectangle; + bool gle_ARB_timer_query; + bool gle_ARB_vertex_array_object; + //bool gle_ARB_vertex_attrib_binding; + bool gle_EXT_draw_buffers2; + bool gle_EXT_texture_compression_s3tc; + bool gle_EXT_texture_filter_anisotropic; + //bool gle_KHR_context_flush_control; + bool gle_KHR_debug; + //bool gle_KHR_robust_buffer_access_behavior; + //bool gle_KHR_robustness; + bool gle_WIN_swap_hint; + + #if defined(GLE_WGL_ENABLED) + bool gle_WGL_ARB_buffer_region; + bool gle_WGL_ARB_create_context; + bool gle_WGL_ARB_create_context_profile; + bool gle_WGL_ARB_create_context_robustness; + bool gle_WGL_ARB_extensions_string; + bool gle_WGL_ARB_framebuffer_sRGB; + bool gle_WGL_ARB_make_current_read; + bool gle_WGL_ARB_pbuffer; + bool gle_WGL_ARB_pixel_format; + bool gle_WGL_ARB_pixel_format_float; + bool gle_WGL_ARB_render_texture; + bool gle_WGL_ATI_render_texture_rectangle; + bool gle_WGL_EXT_extensions_string; + bool gle_WGL_EXT_swap_control; + bool gle_WGL_NV_copy_image; + bool gle_WGL_NV_DX_interop; + bool gle_WGL_NV_DX_interop2; + bool gle_WGL_NV_present_video; + bool gle_WGL_NV_render_texture_rectangle; + bool gle_WGL_NV_swap_group; + bool gle_WGL_NV_video_capture; + bool gle_WGL_NV_video_output; + bool gle_WGL_OML_sync_control; + #elif defined(GLE_GLX_ENABLED) + bool gle_GLX_ARB_create_context; + bool gle_GLX_ARB_create_context_profile; + bool gle_GLX_ARB_create_context_robustness; + bool gle_GLX_EXT_swap_control; + bool gle_GLX_OML_sync_control; + bool gle_MESA_swap_control; + #endif + + }; // class GLEContext + + +} // namespace OVR + + +#endif // OVR_CAPI_GLE_h diff --git a/LibOVRKernel/Src/GL/CAPI_GLE_GL.h b/LibOVRKernel/Src/GL/CAPI_GLE_GL.h new file mode 100644 index 0000000..cff7f79 --- /dev/null +++ b/LibOVRKernel/Src/GL/CAPI_GLE_GL.h @@ -0,0 +1,4765 @@ +/************************************************************************************ + +Filename : CAPI_GLE_GL.h +Content : GL extensions declarations. +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + + +#ifndef OVR_CAPI_GLE_GL_h +#define OVR_CAPI_GLE_GL_h + + +#include + + +// Windows headers +// Windows-specific OpenGL 1.1 interfaces. Long ago this was . +// OpenGL 1.1 interface. +// OpenGL 1.2+ compatibility profile and extension interfaces. Not provided by Microsoft. +// Windows-specific extension interfaces. Not provided by Microsoft. +// OpenGL core profile and ARB extension interfaces. Doesn't include interfaces found only in the compatibility profile. Overlaps with gl.h and glext.h. +// +// Mac headers +// OpenGL 1.1 interface. +// OpenGL 1.2+ compatibility profile and extension interfaces. +// Includes only interfaces supported in a core OpenGL 3.1 implementations plus a few related extensions. +// Includes extensions supported in a core OpenGL 3.1 implementation. +// Apple-specific OpenGL interfaces. +// Apple-specific OpenGL interfaces. +// +// Linux headers +// OpenGL 1.1 interface. +// OpenGL 1.2+ compatibility profile and extension interfaces. +// X Windows-specific OpenGL interfaces. +// X Windows 1.3+ API and GLX extension interfaces. +// OpenGL core profile and ARB extension interfaces. Doesn't include interfaces found only in the compatibility profile. Overlaps with gl.h and glext.h. + +#if defined(__gl_h_) || defined(__GL_H__) || defined(__X_GL_H) + #error gl.h should be included after this, not before. +#endif +#if defined(__gl2_h_) + #error gl2.h should be included after this, not before. +#endif +#if defined(__gltypes_h_) + #error gltypes.h should be included after this, not before. +#endif +#if defined(__glext_h_) || defined(__GLEXT_H_) + #error glext.h should be included after this, not before. +#endif + +// Prevent other GL versions from being included in the future. +// We do not disable Microsoft's wingdi.h and redeclare its functions. That's a big header that includes many other things. +// We do not currently disable Apple's OpenGL/OpenGL.h, though we could if we replicated its declarations in this header file. +#define __gl_h_ // Disable future #includes of Apple's +#define __GL_H__ // Disable future #includes of Microsoft's +#define __X_GL_H // etc. +#define __gl2_h_ +#define __gltypes_h_ +#define __glext_h_ +#define __GLEXT_H_ + + +// GLE platform identification +#if defined(_WIN32) + #define GLE_WGL_ENABLED 1 // WGL interface +#elif defined(__ANDROID__) + #define GLE_EGL_ENABLED 1 // EGL interface +#elif defined(__IPHONE__) + #define GLE_EAGL_ENABLED 1 // EAGL interface +#elif defined(__APPLE__) + #define GLE_CGL_ENABLED 1 // CGL interface +#else + #define GLE_GLX_ENABLED 1 // GLX interface +#endif + + +// GLAPI / GLAPIENTRY +// +// GLAPI is a wrapper for Microsoft __declspec(dllimport). +// GLAPIENTRY is the calling convention (__stdcall under Microsoft). +// +#if defined(GLE_WGL_ENABLED) + #include + + #ifndef WINGDIAPI // Normally defined via windows.h + #define WINGDIAPI __declspec(dllimport) + #define GLE_WINGDIAPI_DEFINED // We define this so that we can know to undefine WINGDIAPI at the end of this file. + #endif + + #if !defined(GLAPI) + #if defined(__MINGW32__) || defined(__CYGWIN__) + #define GLAPI extern + #else + #define GLAPI WINGDIAPI + #endif + #endif + #if !defined(GLAPIENTRY) + #define GLAPIENTRY __stdcall + #endif +#else + #include + + #define GLAPI extern + #define GLAPIENTRY /* empty */ +#endif + + +// GLE_CLASS_EXPORT +// Possibly maps to Microsoft __declspec(dllexport) or nothing on other platforms. +#define GLE_CLASS_EXPORT // Currently defined to nothing. Could be defined to a dll export type. + + + +// GLE_HOOKING_ENABLED +// When enabled, we intercept all OpenGL calls and do any useful internal processing before or after the call. +// An example use case for this is to intercept OpenGL errors on platforms that don't support the OpenGL +// debug functionality (e.g. KHR_Debug). +#if !defined(GLE_WGL_ENABLED) && !defined(GLE_GLX_ENABLED) && defined(OVR_BUILD_DEBUG) // Windows and Unix don't need it because they have OpenGL debug extension support (e.g. KHR_Debug). + #define GLE_HOOKING_ENABLED 1 +#endif + +// When using hooking, we map all OpenGL function usage to our member functions that end with _Hook. +// These member hook functions will internally call the actual OpenGL functions after doing some internal processing. +#if defined(GLE_HOOKING_ENABLED) + #define GLEGetCurrentFunction(x) GLEContext::GetCurrentContext()->x##_Hook + #define GLEGetCurrentVariable(x) GLEContext::GetCurrentContext()->x +#else + #define GLEGetCurrentFunction(x) GLEContext::GetCurrentContext()->x##_Impl + #define GLEGetCurrentVariable(x) GLEContext::GetCurrentContext()->x +#endif + +// GLE_CURRENT_FUNCTION +// Used by hooking in debug builds. +#if defined(OVR_BUILD_DEBUG) + #define GLE_CURRENT_FUNCTION __FUNCTION__ +#else + #define GLE_CURRENT_FUNCTION NULL +#endif + + +// GLE_WHOLE_VERSION +// Returns the major+minor version of the current GLEContext. +// Example usage: +// if(GLE_WHOLE_VERSION() >= 302) // If OpenGL 3.2 or later... +// ... +#define GLE_WHOLE_VERSION() GLEContext::GetCurrentContext()->WholeVersion() + + + +#ifdef __cplusplus +extern "C" { +#endif + + +// OpenGL 1.1 declarations are present in all versions of gl.h, including Microsoft's. +// You don't need to dynamically link to these functions on any platform and can just assume +// they are present. A number of these functions have been deprecated by OpenGL v3+, and +// if an OpenGL v3+ core profile is enabled then usage of the deprecated functions is an error. + +#ifndef GL_VERSION_1_1 + #define GL_VERSION_1_1 1 + + typedef unsigned int GLenum; + typedef unsigned int GLbitfield; + typedef unsigned int GLuint; + typedef int GLint; + typedef int GLsizei; + typedef unsigned char GLboolean; + typedef signed char GLbyte; + typedef short GLshort; + typedef unsigned char GLubyte; + typedef unsigned short GLushort; + typedef unsigned long GLulong; + typedef float GLfloat; + typedef float GLclampf; + typedef double GLdouble; + typedef double GLclampd; + typedef void GLvoid; + typedef int64_t GLint64EXT; + typedef uint64_t GLuint64EXT; + typedef GLint64EXT GLint64; + typedef GLuint64EXT GLuint64; + typedef struct __GLsync *GLsync; + typedef char GLchar; + + #define GL_ZERO 0 + #define GL_FALSE 0 + #define GL_LOGIC_OP 0x0BF1 + #define GL_NONE 0 + #define GL_TEXTURE_COMPONENTS 0x1003 + #define GL_NO_ERROR 0 + #define GL_POINTS 0x0000 + #define GL_CURRENT_BIT 0x00000001 + #define GL_TRUE 1 + #define GL_ONE 1 + #define GL_CLIENT_PIXEL_STORE_BIT 0x00000001 + #define GL_LINES 0x0001 + #define GL_LINE_LOOP 0x0002 + #define GL_POINT_BIT 0x00000002 + #define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 + #define GL_LINE_STRIP 0x0003 + #define GL_LINE_BIT 0x00000004 + #define GL_TRIANGLES 0x0004 + #define GL_TRIANGLE_STRIP 0x0005 + #define GL_TRIANGLE_FAN 0x0006 + #define GL_QUADS 0x0007 + #define GL_QUAD_STRIP 0x0008 + #define GL_POLYGON_BIT 0x00000008 + #define GL_POLYGON 0x0009 + #define GL_POLYGON_STIPPLE_BIT 0x00000010 + #define GL_PIXEL_MODE_BIT 0x00000020 + #define GL_LIGHTING_BIT 0x00000040 + #define GL_FOG_BIT 0x00000080 + #define GL_DEPTH_BUFFER_BIT 0x00000100 + #define GL_ACCUM 0x0100 + #define GL_LOAD 0x0101 + #define GL_RETURN 0x0102 + #define GL_MULT 0x0103 + #define GL_ADD 0x0104 + #define GL_NEVER 0x0200 + #define GL_ACCUM_BUFFER_BIT 0x00000200 + #define GL_LESS 0x0201 + #define GL_EQUAL 0x0202 + #define GL_LEQUAL 0x0203 + #define GL_GREATER 0x0204 + #define GL_NOTEQUAL 0x0205 + #define GL_GEQUAL 0x0206 + #define GL_ALWAYS 0x0207 + #define GL_SRC_COLOR 0x0300 + #define GL_ONE_MINUS_SRC_COLOR 0x0301 + #define GL_SRC_ALPHA 0x0302 + #define GL_ONE_MINUS_SRC_ALPHA 0x0303 + #define GL_DST_ALPHA 0x0304 + #define GL_ONE_MINUS_DST_ALPHA 0x0305 + #define GL_DST_COLOR 0x0306 + #define GL_ONE_MINUS_DST_COLOR 0x0307 + #define GL_SRC_ALPHA_SATURATE 0x0308 + #define GL_STENCIL_BUFFER_BIT 0x00000400 + #define GL_FRONT_LEFT 0x0400 + #define GL_FRONT_RIGHT 0x0401 + #define GL_BACK_LEFT 0x0402 + #define GL_BACK_RIGHT 0x0403 + #define GL_FRONT 0x0404 + #define GL_BACK 0x0405 + #define GL_LEFT 0x0406 + #define GL_RIGHT 0x0407 + #define GL_FRONT_AND_BACK 0x0408 + #define GL_AUX0 0x0409 + #define GL_AUX1 0x040A + #define GL_AUX2 0x040B + #define GL_AUX3 0x040C + #define GL_INVALID_ENUM 0x0500 + #define GL_INVALID_VALUE 0x0501 + #define GL_INVALID_OPERATION 0x0502 + #define GL_STACK_OVERFLOW 0x0503 + #define GL_STACK_UNDERFLOW 0x0504 + #define GL_OUT_OF_MEMORY 0x0505 + #define GL_2D 0x0600 + #define GL_3D 0x0601 + #define GL_3D_COLOR 0x0602 + #define GL_3D_COLOR_TEXTURE 0x0603 + #define GL_4D_COLOR_TEXTURE 0x0604 + #define GL_PASS_THROUGH_TOKEN 0x0700 + #define GL_POINT_TOKEN 0x0701 + #define GL_LINE_TOKEN 0x0702 + #define GL_POLYGON_TOKEN 0x0703 + #define GL_BITMAP_TOKEN 0x0704 + #define GL_DRAW_PIXEL_TOKEN 0x0705 + #define GL_COPY_PIXEL_TOKEN 0x0706 + #define GL_LINE_RESET_TOKEN 0x0707 + #define GL_EXP 0x0800 + #define GL_VIEWPORT_BIT 0x00000800 + #define GL_EXP2 0x0801 + #define GL_CW 0x0900 + #define GL_CCW 0x0901 + #define GL_COEFF 0x0A00 + #define GL_ORDER 0x0A01 + #define GL_DOMAIN 0x0A02 + #define GL_CURRENT_COLOR 0x0B00 + #define GL_CURRENT_INDEX 0x0B01 + #define GL_CURRENT_NORMAL 0x0B02 + #define GL_CURRENT_TEXTURE_COORDS 0x0B03 + #define GL_CURRENT_RASTER_COLOR 0x0B04 + #define GL_CURRENT_RASTER_INDEX 0x0B05 + #define GL_CURRENT_RASTER_TEXTURE_COORDS 0x0B06 + #define GL_CURRENT_RASTER_POSITION 0x0B07 + #define GL_CURRENT_RASTER_POSITION_VALID 0x0B08 + #define GL_CURRENT_RASTER_DISTANCE 0x0B09 + #define GL_POINT_SMOOTH 0x0B10 + #define GL_POINT_SIZE 0x0B11 + #define GL_POINT_SIZE_RANGE 0x0B12 + #define GL_POINT_SIZE_GRANULARITY 0x0B13 + #define GL_LINE_SMOOTH 0x0B20 + #define GL_LINE_WIDTH 0x0B21 + #define GL_LINE_WIDTH_RANGE 0x0B22 + #define GL_LINE_WIDTH_GRANULARITY 0x0B23 + #define GL_LINE_STIPPLE 0x0B24 + #define GL_LINE_STIPPLE_PATTERN 0x0B25 + #define GL_LINE_STIPPLE_REPEAT 0x0B26 + #define GL_LIST_MODE 0x0B30 + #define GL_MAX_LIST_NESTING 0x0B31 + #define GL_LIST_BASE 0x0B32 + #define GL_LIST_INDEX 0x0B33 + #define GL_POLYGON_MODE 0x0B40 + #define GL_POLYGON_SMOOTH 0x0B41 + #define GL_POLYGON_STIPPLE 0x0B42 + #define GL_EDGE_FLAG 0x0B43 + #define GL_CULL_FACE 0x0B44 + #define GL_CULL_FACE_MODE 0x0B45 + #define GL_FRONT_FACE 0x0B46 + #define GL_LIGHTING 0x0B50 + #define GL_LIGHT_MODEL_LOCAL_VIEWER 0x0B51 + #define GL_LIGHT_MODEL_TWO_SIDE 0x0B52 + #define GL_LIGHT_MODEL_AMBIENT 0x0B53 + #define GL_SHADE_MODEL 0x0B54 + #define GL_COLOR_MATERIAL_FACE 0x0B55 + #define GL_COLOR_MATERIAL_PARAMETER 0x0B56 + #define GL_COLOR_MATERIAL 0x0B57 + #define GL_FOG 0x0B60 + #define GL_FOG_INDEX 0x0B61 + #define GL_FOG_DENSITY 0x0B62 + #define GL_FOG_START 0x0B63 + #define GL_FOG_END 0x0B64 + #define GL_FOG_MODE 0x0B65 + #define GL_FOG_COLOR 0x0B66 + #define GL_DEPTH_RANGE 0x0B70 + #define GL_DEPTH_TEST 0x0B71 + #define GL_DEPTH_WRITEMASK 0x0B72 + #define GL_DEPTH_CLEAR_VALUE 0x0B73 + #define GL_DEPTH_FUNC 0x0B74 + #define GL_ACCUM_CLEAR_VALUE 0x0B80 + #define GL_STENCIL_TEST 0x0B90 + #define GL_STENCIL_CLEAR_VALUE 0x0B91 + #define GL_STENCIL_FUNC 0x0B92 + #define GL_STENCIL_VALUE_MASK 0x0B93 + #define GL_STENCIL_FAIL 0x0B94 + #define GL_STENCIL_PASS_DEPTH_FAIL 0x0B95 + #define GL_STENCIL_PASS_DEPTH_PASS 0x0B96 + #define GL_STENCIL_REF 0x0B97 + #define GL_STENCIL_WRITEMASK 0x0B98 + #define GL_MATRIX_MODE 0x0BA0 + #define GL_NORMALIZE 0x0BA1 + #define GL_VIEWPORT 0x0BA2 + #define GL_MODELVIEW_STACK_DEPTH 0x0BA3 + #define GL_PROJECTION_STACK_DEPTH 0x0BA4 + #define GL_TEXTURE_STACK_DEPTH 0x0BA5 + #define GL_MODELVIEW_MATRIX 0x0BA6 + #define GL_PROJECTION_MATRIX 0x0BA7 + #define GL_TEXTURE_MATRIX 0x0BA8 + #define GL_ATTRIB_STACK_DEPTH 0x0BB0 + #define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1 + #define GL_ALPHA_TEST 0x0BC0 + #define GL_ALPHA_TEST_FUNC 0x0BC1 + #define GL_ALPHA_TEST_REF 0x0BC2 + #define GL_DITHER 0x0BD0 + #define GL_BLEND_DST 0x0BE0 + #define GL_BLEND_SRC 0x0BE1 + #define GL_BLEND 0x0BE2 + #define GL_LOGIC_OP_MODE 0x0BF0 + #define GL_INDEX_LOGIC_OP 0x0BF1 + #define GL_COLOR_LOGIC_OP 0x0BF2 + #define GL_AUX_BUFFERS 0x0C00 + #define GL_DRAW_BUFFER 0x0C01 + #define GL_READ_BUFFER 0x0C02 + #define GL_SCISSOR_BOX 0x0C10 + #define GL_SCISSOR_TEST 0x0C11 + #define GL_INDEX_CLEAR_VALUE 0x0C20 + #define GL_INDEX_WRITEMASK 0x0C21 + #define GL_COLOR_CLEAR_VALUE 0x0C22 + #define GL_COLOR_WRITEMASK 0x0C23 + #define GL_INDEX_MODE 0x0C30 + #define GL_RGBA_MODE 0x0C31 + #define GL_DOUBLEBUFFER 0x0C32 + #define GL_STEREO 0x0C33 + #define GL_RENDER_MODE 0x0C40 + #define GL_PERSPECTIVE_CORRECTION_HINT 0x0C50 + #define GL_POINT_SMOOTH_HINT 0x0C51 + #define GL_LINE_SMOOTH_HINT 0x0C52 + #define GL_POLYGON_SMOOTH_HINT 0x0C53 + #define GL_FOG_HINT 0x0C54 + #define GL_TEXTURE_GEN_S 0x0C60 + #define GL_TEXTURE_GEN_T 0x0C61 + #define GL_TEXTURE_GEN_R 0x0C62 + #define GL_TEXTURE_GEN_Q 0x0C63 + #define GL_PIXEL_MAP_I_TO_I 0x0C70 + #define GL_PIXEL_MAP_S_TO_S 0x0C71 + #define GL_PIXEL_MAP_I_TO_R 0x0C72 + #define GL_PIXEL_MAP_I_TO_G 0x0C73 + #define GL_PIXEL_MAP_I_TO_B 0x0C74 + #define GL_PIXEL_MAP_I_TO_A 0x0C75 + #define GL_PIXEL_MAP_R_TO_R 0x0C76 + #define GL_PIXEL_MAP_G_TO_G 0x0C77 + #define GL_PIXEL_MAP_B_TO_B 0x0C78 + #define GL_PIXEL_MAP_A_TO_A 0x0C79 + #define GL_PIXEL_MAP_I_TO_I_SIZE 0x0CB0 + #define GL_PIXEL_MAP_S_TO_S_SIZE 0x0CB1 + #define GL_PIXEL_MAP_I_TO_R_SIZE 0x0CB2 + #define GL_PIXEL_MAP_I_TO_G_SIZE 0x0CB3 + #define GL_PIXEL_MAP_I_TO_B_SIZE 0x0CB4 + #define GL_PIXEL_MAP_I_TO_A_SIZE 0x0CB5 + #define GL_PIXEL_MAP_R_TO_R_SIZE 0x0CB6 + #define GL_PIXEL_MAP_G_TO_G_SIZE 0x0CB7 + #define GL_PIXEL_MAP_B_TO_B_SIZE 0x0CB8 + #define GL_PIXEL_MAP_A_TO_A_SIZE 0x0CB9 + #define GL_UNPACK_SWAP_BYTES 0x0CF0 + #define GL_UNPACK_LSB_FIRST 0x0CF1 + #define GL_UNPACK_ROW_LENGTH 0x0CF2 + #define GL_UNPACK_SKIP_ROWS 0x0CF3 + #define GL_UNPACK_SKIP_PIXELS 0x0CF4 + #define GL_UNPACK_ALIGNMENT 0x0CF5 + #define GL_PACK_SWAP_BYTES 0x0D00 + #define GL_PACK_LSB_FIRST 0x0D01 + #define GL_PACK_ROW_LENGTH 0x0D02 + #define GL_PACK_SKIP_ROWS 0x0D03 + #define GL_PACK_SKIP_PIXELS 0x0D04 + #define GL_PACK_ALIGNMENT 0x0D05 + #define GL_MAP_COLOR 0x0D10 + #define GL_MAP_STENCIL 0x0D11 + #define GL_INDEX_SHIFT 0x0D12 + #define GL_INDEX_OFFSET 0x0D13 + #define GL_RED_SCALE 0x0D14 + #define GL_RED_BIAS 0x0D15 + #define GL_ZOOM_X 0x0D16 + #define GL_ZOOM_Y 0x0D17 + #define GL_GREEN_SCALE 0x0D18 + #define GL_GREEN_BIAS 0x0D19 + #define GL_BLUE_SCALE 0x0D1A + #define GL_BLUE_BIAS 0x0D1B + #define GL_ALPHA_SCALE 0x0D1C + #define GL_ALPHA_BIAS 0x0D1D + #define GL_DEPTH_SCALE 0x0D1E + #define GL_DEPTH_BIAS 0x0D1F + #define GL_MAX_EVAL_ORDER 0x0D30 + #define GL_MAX_LIGHTS 0x0D31 + #define GL_MAX_CLIP_PLANES 0x0D32 + #define GL_MAX_TEXTURE_SIZE 0x0D33 + #define GL_MAX_PIXEL_MAP_TABLE 0x0D34 + #define GL_MAX_ATTRIB_STACK_DEPTH 0x0D35 + #define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 + #define GL_MAX_NAME_STACK_DEPTH 0x0D37 + #define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 + #define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 + #define GL_MAX_VIEWPORT_DIMS 0x0D3A + #define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B + #define GL_SUBPIXEL_BITS 0x0D50 + #define GL_INDEX_BITS 0x0D51 + #define GL_RED_BITS 0x0D52 + #define GL_GREEN_BITS 0x0D53 + #define GL_BLUE_BITS 0x0D54 + #define GL_ALPHA_BITS 0x0D55 + #define GL_DEPTH_BITS 0x0D56 + #define GL_STENCIL_BITS 0x0D57 + #define GL_ACCUM_RED_BITS 0x0D58 + #define GL_ACCUM_GREEN_BITS 0x0D59 + #define GL_ACCUM_BLUE_BITS 0x0D5A + #define GL_ACCUM_ALPHA_BITS 0x0D5B + #define GL_NAME_STACK_DEPTH 0x0D70 + #define GL_AUTO_NORMAL 0x0D80 + #define GL_MAP1_COLOR_4 0x0D90 + #define GL_MAP1_INDEX 0x0D91 + #define GL_MAP1_NORMAL 0x0D92 + #define GL_MAP1_TEXTURE_COORD_1 0x0D93 + #define GL_MAP1_TEXTURE_COORD_2 0x0D94 + #define GL_MAP1_TEXTURE_COORD_3 0x0D95 + #define GL_MAP1_TEXTURE_COORD_4 0x0D96 + #define GL_MAP1_VERTEX_3 0x0D97 + #define GL_MAP1_VERTEX_4 0x0D98 + #define GL_MAP2_COLOR_4 0x0DB0 + #define GL_MAP2_INDEX 0x0DB1 + #define GL_MAP2_NORMAL 0x0DB2 + #define GL_MAP2_TEXTURE_COORD_1 0x0DB3 + #define GL_MAP2_TEXTURE_COORD_2 0x0DB4 + #define GL_MAP2_TEXTURE_COORD_3 0x0DB5 + #define GL_MAP2_TEXTURE_COORD_4 0x0DB6 + #define GL_MAP2_VERTEX_3 0x0DB7 + #define GL_MAP2_VERTEX_4 0x0DB8 + #define GL_MAP1_GRID_DOMAIN 0x0DD0 + #define GL_MAP1_GRID_SEGMENTS 0x0DD1 + #define GL_MAP2_GRID_DOMAIN 0x0DD2 + #define GL_MAP2_GRID_SEGMENTS 0x0DD3 + #define GL_TEXTURE_1D 0x0DE0 + #define GL_TEXTURE_2D 0x0DE1 + #define GL_FEEDBACK_BUFFER_POINTER 0x0DF0 + #define GL_FEEDBACK_BUFFER_SIZE 0x0DF1 + #define GL_FEEDBACK_BUFFER_TYPE 0x0DF2 + #define GL_SELECTION_BUFFER_POINTER 0x0DF3 + #define GL_SELECTION_BUFFER_SIZE 0x0DF4 + #define GL_TEXTURE_WIDTH 0x1000 + #define GL_TRANSFORM_BIT 0x00001000 + #define GL_TEXTURE_HEIGHT 0x1001 + #define GL_TEXTURE_INTERNAL_FORMAT 0x1003 + #define GL_TEXTURE_BORDER_COLOR 0x1004 + #define GL_TEXTURE_BORDER 0x1005 + #define GL_DONT_CARE 0x1100 + #define GL_FASTEST 0x1101 + #define GL_NICEST 0x1102 + #define GL_AMBIENT 0x1200 + #define GL_DIFFUSE 0x1201 + #define GL_SPECULAR 0x1202 + #define GL_POSITION 0x1203 + #define GL_SPOT_DIRECTION 0x1204 + #define GL_SPOT_EXPONENT 0x1205 + #define GL_SPOT_CUTOFF 0x1206 + #define GL_CONSTANT_ATTENUATION 0x1207 + #define GL_LINEAR_ATTENUATION 0x1208 + #define GL_QUADRATIC_ATTENUATION 0x1209 + #define GL_COMPILE 0x1300 + #define GL_COMPILE_AND_EXECUTE 0x1301 + #define GL_BYTE 0x1400 + #define GL_UNSIGNED_BYTE 0x1401 + #define GL_SHORT 0x1402 + #define GL_UNSIGNED_SHORT 0x1403 + #define GL_INT 0x1404 + #define GL_UNSIGNED_INT 0x1405 + #define GL_FLOAT 0x1406 + #define GL_2_BYTES 0x1407 + #define GL_3_BYTES 0x1408 + #define GL_4_BYTES 0x1409 + #define GL_DOUBLE 0x140A + #define GL_CLEAR 0x1500 + #define GL_AND 0x1501 + #define GL_AND_REVERSE 0x1502 + #define GL_COPY 0x1503 + #define GL_AND_INVERTED 0x1504 + #define GL_NOOP 0x1505 + #define GL_XOR 0x1506 + #define GL_OR 0x1507 + #define GL_NOR 0x1508 + #define GL_EQUIV 0x1509 + #define GL_INVERT 0x150A + #define GL_OR_REVERSE 0x150B + #define GL_COPY_INVERTED 0x150C + #define GL_OR_INVERTED 0x150D + #define GL_NAND 0x150E + #define GL_SET 0x150F + #define GL_EMISSION 0x1600 + #define GL_SHININESS 0x1601 + #define GL_AMBIENT_AND_DIFFUSE 0x1602 + #define GL_COLOR_INDEXES 0x1603 + #define GL_MODELVIEW 0x1700 + #define GL_PROJECTION 0x1701 + #define GL_TEXTURE 0x1702 + #define GL_COLOR 0x1800 + #define GL_DEPTH 0x1801 + #define GL_STENCIL 0x1802 + #define GL_COLOR_INDEX 0x1900 + #define GL_STENCIL_INDEX 0x1901 + #define GL_DEPTH_COMPONENT 0x1902 + #define GL_RED 0x1903 + #define GL_GREEN 0x1904 + #define GL_BLUE 0x1905 + #define GL_ALPHA 0x1906 + #define GL_RGB 0x1907 + #define GL_RGBA 0x1908 + #define GL_LUMINANCE 0x1909 + #define GL_LUMINANCE_ALPHA 0x190A + #define GL_BITMAP 0x1A00 + #define GL_POINT 0x1B00 + #define GL_LINE 0x1B01 + #define GL_FILL 0x1B02 + #define GL_RENDER 0x1C00 + #define GL_FEEDBACK 0x1C01 + #define GL_SELECT 0x1C02 + #define GL_FLAT 0x1D00 + #define GL_SMOOTH 0x1D01 + #define GL_KEEP 0x1E00 + #define GL_REPLACE 0x1E01 + #define GL_INCR 0x1E02 + #define GL_DECR 0x1E03 + #define GL_VENDOR 0x1F00 + #define GL_RENDERER 0x1F01 + #define GL_VERSION 0x1F02 + #define GL_EXTENSIONS 0x1F03 + #define GL_S 0x2000 + #define GL_ENABLE_BIT 0x00002000 + #define GL_T 0x2001 + #define GL_R 0x2002 + #define GL_Q 0x2003 + #define GL_MODULATE 0x2100 + #define GL_DECAL 0x2101 + #define GL_TEXTURE_ENV_MODE 0x2200 + #define GL_TEXTURE_ENV_COLOR 0x2201 + #define GL_TEXTURE_ENV 0x2300 + #define GL_EYE_LINEAR 0x2400 + #define GL_OBJECT_LINEAR 0x2401 + #define GL_SPHERE_MAP 0x2402 + #define GL_TEXTURE_GEN_MODE 0x2500 + #define GL_OBJECT_PLANE 0x2501 + #define GL_EYE_PLANE 0x2502 + #define GL_NEAREST 0x2600 + #define GL_LINEAR 0x2601 + #define GL_NEAREST_MIPMAP_NEAREST 0x2700 + #define GL_LINEAR_MIPMAP_NEAREST 0x2701 + #define GL_NEAREST_MIPMAP_LINEAR 0x2702 + #define GL_LINEAR_MIPMAP_LINEAR 0x2703 + #define GL_TEXTURE_MAG_FILTER 0x2800 + #define GL_TEXTURE_MIN_FILTER 0x2801 + #define GL_TEXTURE_WRAP_S 0x2802 + #define GL_TEXTURE_WRAP_T 0x2803 + #define GL_CLAMP 0x2900 + #define GL_REPEAT 0x2901 + #define GL_POLYGON_OFFSET_UNITS 0x2A00 + #define GL_POLYGON_OFFSET_POINT 0x2A01 + #define GL_POLYGON_OFFSET_LINE 0x2A02 + #define GL_R3_G3_B2 0x2A10 + #define GL_V2F 0x2A20 + #define GL_V3F 0x2A21 + #define GL_C4UB_V2F 0x2A22 + #define GL_C4UB_V3F 0x2A23 + #define GL_C3F_V3F 0x2A24 + #define GL_N3F_V3F 0x2A25 + #define GL_C4F_N3F_V3F 0x2A26 + #define GL_T2F_V3F 0x2A27 + #define GL_T4F_V4F 0x2A28 + #define GL_T2F_C4UB_V3F 0x2A29 + #define GL_T2F_C3F_V3F 0x2A2A + #define GL_T2F_N3F_V3F 0x2A2B + #define GL_T2F_C4F_N3F_V3F 0x2A2C + #define GL_T4F_C4F_N3F_V4F 0x2A2D + #define GL_CLIP_PLANE0 0x3000 + #define GL_CLIP_PLANE1 0x3001 + #define GL_CLIP_PLANE2 0x3002 + #define GL_CLIP_PLANE3 0x3003 + #define GL_CLIP_PLANE4 0x3004 + #define GL_CLIP_PLANE5 0x3005 + #define GL_LIGHT0 0x4000 + #define GL_COLOR_BUFFER_BIT 0x00004000 + #define GL_LIGHT1 0x4001 + #define GL_LIGHT2 0x4002 + #define GL_LIGHT3 0x4003 + #define GL_LIGHT4 0x4004 + #define GL_LIGHT5 0x4005 + #define GL_LIGHT6 0x4006 + #define GL_LIGHT7 0x4007 + #define GL_HINT_BIT 0x00008000 + #define GL_POLYGON_OFFSET_FILL 0x8037 + #define GL_POLYGON_OFFSET_FACTOR 0x8038 + #define GL_ALPHA4 0x803B + #define GL_ALPHA8 0x803C + #define GL_ALPHA12 0x803D + #define GL_ALPHA16 0x803E + #define GL_LUMINANCE4 0x803F + #define GL_LUMINANCE8 0x8040 + #define GL_LUMINANCE12 0x8041 + #define GL_LUMINANCE16 0x8042 + #define GL_LUMINANCE4_ALPHA4 0x8043 + #define GL_LUMINANCE6_ALPHA2 0x8044 + #define GL_LUMINANCE8_ALPHA8 0x8045 + #define GL_LUMINANCE12_ALPHA4 0x8046 + #define GL_LUMINANCE12_ALPHA12 0x8047 + #define GL_LUMINANCE16_ALPHA16 0x8048 + #define GL_INTENSITY 0x8049 + #define GL_INTENSITY4 0x804A + #define GL_INTENSITY8 0x804B + #define GL_INTENSITY12 0x804C + #define GL_INTENSITY16 0x804D + #define GL_RGB4 0x804F + #define GL_RGB5 0x8050 + #define GL_RGB8 0x8051 + #define GL_RGB10 0x8052 + #define GL_RGB12 0x8053 + #define GL_RGB16 0x8054 + #define GL_RGBA2 0x8055 + #define GL_RGBA4 0x8056 + #define GL_RGB5_A1 0x8057 + #define GL_RGBA8 0x8058 + #define GL_RGB10_A2 0x8059 + #define GL_RGBA12 0x805A + #define GL_RGBA16 0x805B + #define GL_TEXTURE_RED_SIZE 0x805C + #define GL_TEXTURE_GREEN_SIZE 0x805D + #define GL_TEXTURE_BLUE_SIZE 0x805E + #define GL_TEXTURE_ALPHA_SIZE 0x805F + #define GL_TEXTURE_LUMINANCE_SIZE 0x8060 + #define GL_TEXTURE_INTENSITY_SIZE 0x8061 + #define GL_PROXY_TEXTURE_1D 0x8063 + #define GL_PROXY_TEXTURE_2D 0x8064 + #define GL_TEXTURE_PRIORITY 0x8066 + #define GL_TEXTURE_RESIDENT 0x8067 + #define GL_TEXTURE_BINDING_1D 0x8068 + #define GL_TEXTURE_BINDING_2D 0x8069 + #define GL_VERTEX_ARRAY 0x8074 + #define GL_NORMAL_ARRAY 0x8075 + #define GL_COLOR_ARRAY 0x8076 + #define GL_INDEX_ARRAY 0x8077 + #define GL_TEXTURE_COORD_ARRAY 0x8078 + #define GL_EDGE_FLAG_ARRAY 0x8079 + #define GL_VERTEX_ARRAY_SIZE 0x807A + #define GL_VERTEX_ARRAY_TYPE 0x807B + #define GL_VERTEX_ARRAY_STRIDE 0x807C + #define GL_NORMAL_ARRAY_TYPE 0x807E + #define GL_NORMAL_ARRAY_STRIDE 0x807F + #define GL_COLOR_ARRAY_SIZE 0x8081 + #define GL_COLOR_ARRAY_TYPE 0x8082 + #define GL_COLOR_ARRAY_STRIDE 0x8083 + #define GL_INDEX_ARRAY_TYPE 0x8085 + #define GL_INDEX_ARRAY_STRIDE 0x8086 + #define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088 + #define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089 + #define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A + #define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C + #define GL_VERTEX_ARRAY_POINTER 0x808E + #define GL_NORMAL_ARRAY_POINTER 0x808F + #define GL_COLOR_ARRAY_POINTER 0x8090 + #define GL_INDEX_ARRAY_POINTER 0x8091 + #define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092 + #define GL_EDGE_FLAG_ARRAY_POINTER 0x8093 + #define GL_COLOR_INDEX1_EXT 0x80E2 + #define GL_COLOR_INDEX2_EXT 0x80E3 + #define GL_COLOR_INDEX4_EXT 0x80E4 + #define GL_COLOR_INDEX8_EXT 0x80E5 + #define GL_COLOR_INDEX12_EXT 0x80E6 + #define GL_COLOR_INDEX16_EXT 0x80E7 + #define GL_EVAL_BIT 0x00010000 + #define GL_LIST_BIT 0x00020000 + #define GL_TEXTURE_BIT 0x00040000 + #define GL_SCISSOR_BIT 0x00080000 + #define GL_ALL_ATTRIB_BITS 0x000fffff + #define GL_CLIENT_ALL_ATTRIB_BITS 0xffffffff + + #if defined(GLE_HOOKING_ENABLED) + // In this case we map these functions to internal versions instead of the standard versions. + #define glAccum(...) GLEGetCurrentFunction(glAccum)(__VA_ARGS__) + #define glAlphaFunc(...) GLEGetCurrentFunction(glAlphaFunc)(__VA_ARGS__) + #define glAreTexturesResident(...) GLEGetCurrentFunction(glAreTexturesResident)(__VA_ARGS__) + #define glArrayElement(...) GLEGetCurrentFunction(glArrayElement)(__VA_ARGS__) + #define glBegin(...) GLEGetCurrentFunction(glBegin)(__VA_ARGS__) + #define glBindTexture(...) GLEGetCurrentFunction(glBindTexture)(__VA_ARGS__) + #define glBitmap(...) GLEGetCurrentFunction(glBitmap)(__VA_ARGS__) + #define glBlendFunc(...) GLEGetCurrentFunction(glBlendFunc)(__VA_ARGS__) + #define glCallList(...) GLEGetCurrentFunction(glCallList)(__VA_ARGS__) + #define glCallLists(...) GLEGetCurrentFunction(glCallLists)(__VA_ARGS__) + #define glClear(...) GLEGetCurrentFunction(glClear)(__VA_ARGS__) + #define glClearAccum(...) GLEGetCurrentFunction(glClearAccum)(__VA_ARGS__) + #define glClearColor(...) GLEGetCurrentFunction(glClearColor)(__VA_ARGS__) + #define glClearDepth(...) GLEGetCurrentFunction(glClearDepth)(__VA_ARGS__) + #define glClearIndex(...) GLEGetCurrentFunction(glClearIndex)(__VA_ARGS__) + #define glClearStencil(...) GLEGetCurrentFunction(glClearStencil)(__VA_ARGS__) + #define glClipPlane(...) GLEGetCurrentFunction(glClipPlane)(__VA_ARGS__) + #define glColor3b(...) GLEGetCurrentFunction(glColor3b)(__VA_ARGS__) + #define glColor3bv(...) GLEGetCurrentFunction(glColor3bv)(__VA_ARGS__) + #define glColor3d(...) GLEGetCurrentFunction(glColor3d)(__VA_ARGS__) + #define glColor3dv(...) GLEGetCurrentFunction(glColor3dv)(__VA_ARGS__) + #define glColor3f(...) GLEGetCurrentFunction(glColor3f)(__VA_ARGS__) + #define glColor3fv(...) GLEGetCurrentFunction(glColor3fv)(__VA_ARGS__) + #define glColor3i(...) GLEGetCurrentFunction(glColor3i)(__VA_ARGS__) + #define glColor3iv(...) GLEGetCurrentFunction(glColor3iv)(__VA_ARGS__) + #define glColor3s(...) GLEGetCurrentFunction(glColor3s)(__VA_ARGS__) + #define glColor3sv(...) GLEGetCurrentFunction(glColor3sv)(__VA_ARGS__) + #define glColor3ub(...) GLEGetCurrentFunction(glColor3ub)(__VA_ARGS__) + #define glColor3ubv(...) GLEGetCurrentFunction(glColor3ubv)(__VA_ARGS__) + #define glColor3ui(...) GLEGetCurrentFunction(glColor3ui)(__VA_ARGS__) + #define glColor3uiv(...) GLEGetCurrentFunction(glColor3uiv)(__VA_ARGS__) + #define glColor3us(...) GLEGetCurrentFunction(glColor3us)(__VA_ARGS__) + #define glColor3usv(...) GLEGetCurrentFunction(glColor3usv)(__VA_ARGS__) + #define glColor4b(...) GLEGetCurrentFunction(glColor4b)(__VA_ARGS__) + #define glColor4bv(...) GLEGetCurrentFunction(glColor4bv)(__VA_ARGS__) + #define glColor4d(...) GLEGetCurrentFunction(glColor4d)(__VA_ARGS__) + #define glColor4dv(...) GLEGetCurrentFunction(glColor4dv)(__VA_ARGS__) + #define glColor4f(...) GLEGetCurrentFunction(glColor4f)(__VA_ARGS__) + #define glColor4fv(...) GLEGetCurrentFunction(glColor4fv)(__VA_ARGS__) + #define glColor4i(...) GLEGetCurrentFunction(glColor4i)(__VA_ARGS__) + #define glColor4iv(...) GLEGetCurrentFunction(glColor4iv)(__VA_ARGS__) + #define glColor4s(...) GLEGetCurrentFunction(glColor4s)(__VA_ARGS__) + #define glColor4sv(...) GLEGetCurrentFunction(glColor4sv)(__VA_ARGS__) + #define glColor4ub(...) GLEGetCurrentFunction(glColor4ub)(__VA_ARGS__) + #define glColor4ubv(...) GLEGetCurrentFunction(glColor4ubv)(__VA_ARGS__) + #define glColor4ui(...) GLEGetCurrentFunction(glColor4ui)(__VA_ARGS__) + #define glColor4uiv(...) GLEGetCurrentFunction(glColor4uiv)(__VA_ARGS__) + #define glColor4us(...) GLEGetCurrentFunction(glColor4us)(__VA_ARGS__) + #define glColor4usv(...) GLEGetCurrentFunction(glColor4usv)(__VA_ARGS__) + #define glColorMask(...) GLEGetCurrentFunction(glColorMask)(__VA_ARGS__) + #define glColorMaterial(...) GLEGetCurrentFunction(glColorMaterial)(__VA_ARGS__) + #define glColorPointer(...) GLEGetCurrentFunction(glColorPointer)(__VA_ARGS__) + #define glCopyPixels(...) GLEGetCurrentFunction(glCopyPixels)(__VA_ARGS__) + #define glCopyTexImage1D(...) GLEGetCurrentFunction(glCopyTexImage1D)(__VA_ARGS__) + #define glCopyTexImage2D(...) GLEGetCurrentFunction(glCopyTexImage2D)(__VA_ARGS__) + #define glCopyTexSubImage1D(...) GLEGetCurrentFunction(glCopyTexSubImage1D)(__VA_ARGS__) + #define glCopyTexSubImage2D(...) GLEGetCurrentFunction(glCopyTexSubImage2D)(__VA_ARGS__) + #define glCullFace(...) GLEGetCurrentFunction(glCullFace)(__VA_ARGS__) + #define glDeleteLists(...) GLEGetCurrentFunction(glDeleteLists)(__VA_ARGS__) + #define glDeleteTextures(...) GLEGetCurrentFunction(glDeleteTextures)(__VA_ARGS__) + #define glDepthFunc(...) GLEGetCurrentFunction(glDepthFunc)(__VA_ARGS__) + #define glDepthMask(...) GLEGetCurrentFunction(glDepthMask)(__VA_ARGS__) + #define glDepthRange(...) GLEGetCurrentFunction(glDepthRange)(__VA_ARGS__) + #define glDisable(...) GLEGetCurrentFunction(glDisable)(__VA_ARGS__) + #define glDisableClientState(...) GLEGetCurrentFunction(glDisableClientState)(__VA_ARGS__) + #define glDrawArrays(...) GLEGetCurrentFunction(glDrawArrays)(__VA_ARGS__) + #define glDrawBuffer(...) GLEGetCurrentFunction(glDrawBuffer)(__VA_ARGS__) + #define glDrawElements(...) GLEGetCurrentFunction(glDrawElements)(__VA_ARGS__) + #define glDrawPixels(...) GLEGetCurrentFunction(glDrawPixels)(__VA_ARGS__) + #define glEdgeFlag(...) GLEGetCurrentFunction(glEdgeFlag)(__VA_ARGS__) + #define glEdgeFlagPointer(...) GLEGetCurrentFunction(glEdgeFlagPointer)(__VA_ARGS__) + #define glEdgeFlagv(...) GLEGetCurrentFunction(glEdgeFlagv)(__VA_ARGS__) + #define glEnable(...) GLEGetCurrentFunction(glEnable)(__VA_ARGS__) + #define glEnableClientState(...) GLEGetCurrentFunction(glEnableClientState)(__VA_ARGS__) + #define glEnd() GLEGetCurrentFunction(glEnd)() + #define glEndList() GLEGetCurrentFunction(glEndList)(_) + #define glEvalCoord1d(...) GLEGetCurrentFunction(glEvalCoord1d)(__VA_ARGS__) + #define glEvalCoord1dv(...) GLEGetCurrentFunction(glEvalCoord1dv)(__VA_ARGS__) + #define glEvalCoord1f(...) GLEGetCurrentFunction(glEvalCoord1f)(__VA_ARGS__) + #define glEvalCoord1fv(...) GLEGetCurrentFunction(glEvalCoord1fv)(__VA_ARGS__) + #define glEvalCoord2d(...) GLEGetCurrentFunction(glEvalCoord2d)(__VA_ARGS__) + #define glEvalCoord2dv(...) GLEGetCurrentFunction(glEvalCoord2dv)(__VA_ARGS__) + #define glEvalCoord2f(...) GLEGetCurrentFunction(glEvalCoord2f)(__VA_ARGS__) + #define glEvalCoord2fv(...) GLEGetCurrentFunction(glEvalCoord2fv)(__VA_ARGS__) + #define glEvalMesh1(...) GLEGetCurrentFunction(glEvalMesh1)(__VA_ARGS__) + #define glEvalMesh2(...) GLEGetCurrentFunction(glEvalMesh2)(__VA_ARGS__) + #define glEvalPoint1(...) GLEGetCurrentFunction(glEvalPoint1)(__VA_ARGS__) + #define glEvalPoint2(...) GLEGetCurrentFunction(glEvalPoint2)(__VA_ARGS__) + #define glFeedbackBuffer(...) GLEGetCurrentFunction(glFeedbackBuffer)(__VA_ARGS__) + #define glFinish() GLEGetCurrentFunction(glFinish)() + #define glFlush() GLEGetCurrentFunction(glFlush)() + #define glFogf(...) GLEGetCurrentFunction(glFogf)(__VA_ARGS__) + #define glFogfv(...) GLEGetCurrentFunction(glFogfv)(__VA_ARGS__) + #define glFogi(...) GLEGetCurrentFunction(glFogi)(__VA_ARGS__) + #define glFogiv(...) GLEGetCurrentFunction(glFogiv)(__VA_ARGS__) + #define glFrontFace(...) GLEGetCurrentFunction(glFrontFace)(__VA_ARGS__) + #define glFrustum(...) GLEGetCurrentFunction(glFrustum)(__VA_ARGS__) + #define glGenLists(...) GLEGetCurrentFunction(glGenLists)(__VA_ARGS__) + #define glGenTextures(...) GLEGetCurrentFunction(glGenTextures)(__VA_ARGS__) + #define glGetBooleanv(...) GLEGetCurrentFunction(glGetBooleanv)(__VA_ARGS__) + #define glGetClipPlane(...) GLEGetCurrentFunction(glGetClipPlane)(__VA_ARGS__) + #define glGetDoublev(...) GLEGetCurrentFunction(glGetDoublev)(__VA_ARGS__) + #define glGetError() GLEGetCurrentFunction(glGetError)() + #define glGetFloatv(...) GLEGetCurrentFunction(glGetFloatv)(__VA_ARGS__) + #define glGetIntegerv(...) GLEGetCurrentFunction(glGetIntegerv)(__VA_ARGS__) + #define glGetLightfv(...) GLEGetCurrentFunction(glGetLightfv)(__VA_ARGS__) + #define glGetLightiv(...) GLEGetCurrentFunction(glGetLightiv)(__VA_ARGS__) + #define glGetMapdv(...) GLEGetCurrentFunction(glGetMapdv)(__VA_ARGS__) + #define glGetMapfv(...) GLEGetCurrentFunction(glGetMapfv)(__VA_ARGS__) + #define glGetMapiv(...) GLEGetCurrentFunction(glGetMapiv)(__VA_ARGS__) + #define glGetMaterialfv(...) GLEGetCurrentFunction(glGetMaterialfv)(__VA_ARGS__) + #define glGetMaterialiv(...) GLEGetCurrentFunction(glGetMaterialiv)(__VA_ARGS__) + #define glGetPixelMapfv(...) GLEGetCurrentFunction(glGetPixelMapfv)(__VA_ARGS__) + #define glGetPixelMapuiv(...) GLEGetCurrentFunction(glGetPixelMapuiv)(__VA_ARGS__) + #define glGetPixelMapusv(...) GLEGetCurrentFunction(glGetPixelMapusv)(__VA_ARGS__) + #define glGetPointerv(...) GLEGetCurrentFunction(glGetPointerv)(__VA_ARGS__) + #define glGetPolygonStipple(...) GLEGetCurrentFunction(glGetPolygonStipple)(__VA_ARGS__) + #define glGetString(...) GLEGetCurrentFunction(glGetString)(__VA_ARGS__) + #define glGetTexEnvfv(...) GLEGetCurrentFunction(glGetTexEnvfv)(__VA_ARGS__) + #define glGetTexEnviv(...) GLEGetCurrentFunction(glGetTexEnviv)(__VA_ARGS__) + #define glGetTexGendv(...) GLEGetCurrentFunction(glGetTexGendv)(__VA_ARGS__) + #define glGetTexGenfv(...) GLEGetCurrentFunction(glGetTexGenfv)(__VA_ARGS__) + #define glGetTexGeniv(...) GLEGetCurrentFunction(glGetTexGeniv)(__VA_ARGS__) + #define glGetTexImage(...) GLEGetCurrentFunction(glGetTexImage)(__VA_ARGS__) + #define glGetTexLevelParameterfv(...) GLEGetCurrentFunction(glGetTexLevelParameterfv)(__VA_ARGS__) + #define glGetTexLevelParameteriv(...) GLEGetCurrentFunction(glGetTexLevelParameteriv)(__VA_ARGS__) + #define glGetTexParameterfv(...) GLEGetCurrentFunction(glGetTexParameterfv)(__VA_ARGS__) + #define glGetTexParameteriv(...) GLEGetCurrentFunction(glGetTexParameteriv)(__VA_ARGS__) + #define glHint(...) GLEGetCurrentFunction(glHint)(__VA_ARGS__) + #define glIndexMask(...) GLEGetCurrentFunction(glIndexMask)(__VA_ARGS__) + #define glIndexPointer(...) GLEGetCurrentFunction(glIndexPointer)(__VA_ARGS__) + #define glIndexd(...) GLEGetCurrentFunction(glIndexd)(__VA_ARGS__) + #define glIndexdv(...) GLEGetCurrentFunction(glIndexdv)(__VA_ARGS__) + #define glIndexf(...) GLEGetCurrentFunction(glIndexf)(__VA_ARGS__) + #define glIndexfv(...) GLEGetCurrentFunction(glIndexfv)(__VA_ARGS__) + #define glIndexi(...) GLEGetCurrentFunction(glIndexi)(__VA_ARGS__) + #define glIndexiv(...) GLEGetCurrentFunction(glIndexiv)(__VA_ARGS__) + #define glIndexs(...) GLEGetCurrentFunction(glIndexs)(__VA_ARGS__) + #define glIndexsv(...) GLEGetCurrentFunction(glIndexsv)(__VA_ARGS__) + #define glIndexub(...) GLEGetCurrentFunction(glIndexub)(__VA_ARGS__) + #define glIndexubv(...) GLEGetCurrentFunction(glIndexubv)(__VA_ARGS__) + #define glInitNames() GLEGetCurrentFunction(glInitNames)() + #define glInterleavedArrays(...) GLEGetCurrentFunction(glInterleavedArrays)(__VA_ARGS__) + #define glIsEnabled(...) GLEGetCurrentFunction(glIsEnabled)(__VA_ARGS__) + #define glIsList(...) GLEGetCurrentFunction(glIsList)(__VA_ARGS__) + #define glIsTexture(...) GLEGetCurrentFunction(glIsTexture)(__VA_ARGS__) + #define glLightModelf(...) GLEGetCurrentFunction(glLightModelf)(__VA_ARGS__) + #define glLightModelfv(...) GLEGetCurrentFunction(glLightModelfv)(__VA_ARGS__) + #define glLightModeli(...) GLEGetCurrentFunction(glLightModeli)(__VA_ARGS__) + #define glLightModeliv(...) GLEGetCurrentFunction(glLightModeliv)(__VA_ARGS__) + #define glLightf(...) GLEGetCurrentFunction(glLightf)(__VA_ARGS__) + #define glLightfv(...) GLEGetCurrentFunction(glLightfv)(__VA_ARGS__) + #define glLighti(...) GLEGetCurrentFunction(glLighti)(__VA_ARGS__) + #define glLightiv(...) GLEGetCurrentFunction(glLightiv)(__VA_ARGS__) + #define glLineStipple(...) GLEGetCurrentFunction(glLineStipple)(__VA_ARGS__) + #define glLineWidth(...) GLEGetCurrentFunction(glLineWidth)(__VA_ARGS__) + #define glListBase(...) GLEGetCurrentFunction(glListBase)(__VA_ARGS__) + #define glLoadIdentity() GLEGetCurrentFunction(glLoadIdentity)() + #define glLoadMatrixd(...) GLEGetCurrentFunction(glLoadMatrixd)(__VA_ARGS__) + #define glLoadMatrixf(...) GLEGetCurrentFunction(glLoadMatrixf)(__VA_ARGS__) + #define glLoadName(...) GLEGetCurrentFunction(glLoadName)(__VA_ARGS__) + #define glLogicOp(...) GLEGetCurrentFunction(glLogicOp)(__VA_ARGS__) + #define glMap1d(...) GLEGetCurrentFunction(glMap1d)(__VA_ARGS__) + #define glMap1f(...) GLEGetCurrentFunction(glMap1f)(__VA_ARGS__) + #define glMap2d(...) GLEGetCurrentFunction(glMap2d)(__VA_ARGS__) + #define glMap2f(...) GLEGetCurrentFunction(glMap2f)(__VA_ARGS__) + #define glMapGrid1d(...) GLEGetCurrentFunction(glMapGrid1d)(__VA_ARGS__) + #define glMapGrid1f(...) GLEGetCurrentFunction(glMapGrid1f)(__VA_ARGS__) + #define glMapGrid2d(...) GLEGetCurrentFunction(glMapGrid2d)(__VA_ARGS__) + #define glMapGrid2f(...) GLEGetCurrentFunction(glMapGrid2f)(__VA_ARGS__) + #define glMaterialf(...) GLEGetCurrentFunction(glMaterialf)(__VA_ARGS__) + #define glMaterialfv(...) GLEGetCurrentFunction(glMaterialfv)(__VA_ARGS__) + #define glMateriali(...) GLEGetCurrentFunction(glMateriali)(__VA_ARGS__) + #define glMaterialiv(...) GLEGetCurrentFunction(glMaterialiv)(__VA_ARGS__) + #define glMatrixMode(...) GLEGetCurrentFunction(glMatrixMode)(__VA_ARGS__) + #define glMultMatrixd(...) GLEGetCurrentFunction(glMultMatrixd)(__VA_ARGS__) + #define glMultMatrixf(...) GLEGetCurrentFunction(glMultMatrixf)(__VA_ARGS__) + #define glNewList(...) GLEGetCurrentFunction(glNewList)(__VA_ARGS__) + #define glNormal3b(...) GLEGetCurrentFunction(glNormal3b)(__VA_ARGS__) + #define glNormal3bv(...) GLEGetCurrentFunction(glNormal3bv)(__VA_ARGS__) + #define glNormal3d(...) GLEGetCurrentFunction(glNormal3d)(__VA_ARGS__) + #define glNormal3dv(...) GLEGetCurrentFunction(glNormal3dv)(__VA_ARGS__) + #define glNormal3f(...) GLEGetCurrentFunction(glNormal3f)(__VA_ARGS__) + #define glNormal3fv(...) GLEGetCurrentFunction(glNormal3fv)(__VA_ARGS__) + #define glNormal3i(...) GLEGetCurrentFunction(glNormal3i)(__VA_ARGS__) + #define glNormal3iv(...) GLEGetCurrentFunction(glNormal3iv)(__VA_ARGS__) + #define glNormal3s(...) GLEGetCurrentFunction(glNormal3s)(__VA_ARGS__) + #define glNormal3sv(...) GLEGetCurrentFunction(glNormal3sv)(__VA_ARGS__) + #define glNormalPointer(...) GLEGetCurrentFunction(glNormalPointer)(__VA_ARGS__) + #define glOrtho(...) GLEGetCurrentFunction(glOrtho)(__VA_ARGS__) + #define glPassThrough(...) GLEGetCurrentFunction(glPassThrough)(__VA_ARGS__) + #define glPixelMapfv(...) GLEGetCurrentFunction(glPixelMapfv)(__VA_ARGS__) + #define glPixelMapuiv(...) GLEGetCurrentFunction(glPixelMapuiv)(__VA_ARGS__) + #define glPixelMapusv(...) GLEGetCurrentFunction(glPixelMapusv)(__VA_ARGS__) + #define glPixelStoref(...) GLEGetCurrentFunction(glPixelStoref)(__VA_ARGS__) + #define glPixelStorei(...) GLEGetCurrentFunction(glPixelStorei)(__VA_ARGS__) + #define glPixelTransferf(...) GLEGetCurrentFunction(glPixelTransferf)(__VA_ARGS__) + #define glPixelTransferi(...) GLEGetCurrentFunction(glPixelTransferi)(__VA_ARGS__) + #define glPixelZoom(...) GLEGetCurrentFunction(glPixelZoom)(__VA_ARGS__) + #define glPointSize(...) GLEGetCurrentFunction(glPointSize)(__VA_ARGS__) + #define glPolygonMode(...) GLEGetCurrentFunction(glPolygonMode)(__VA_ARGS__) + #define glPolygonOffset(...) GLEGetCurrentFunction(glPolygonOffset)(__VA_ARGS__) + #define glPolygonStipple(...) GLEGetCurrentFunction(glPolygonStipple)(__VA_ARGS__) + #define glPopAttrib() GLEGetCurrentFunction(glPopAttrib)() + #define glPopClientAttrib() GLEGetCurrentFunction(glPopClientAttrib)() + #define glPopMatrix() GLEGetCurrentFunction(glPopMatrix)() + #define glPopName() GLEGetCurrentFunction(glPopName)() + #define glPrioritizeTextures(...) GLEGetCurrentFunction(glPrioritizeTextures)(__VA_ARGS__) + #define glPushAttrib(...) GLEGetCurrentFunction(glPushAttrib)(__VA_ARGS__) + #define glPushClientAttrib(...) GLEGetCurrentFunction(glPushClientAttrib)(__VA_ARGS__) + #define glPushMatrix() GLEGetCurrentFunction(glPushMatrix)() + #define glPushName(...) GLEGetCurrentFunction(glPushName)(__VA_ARGS__) + #define glRasterPos2d(...) GLEGetCurrentFunction(glRasterPos2d)(__VA_ARGS__) + #define glRasterPos2dv(...) GLEGetCurrentFunction(glRasterPos2dv)(__VA_ARGS__) + #define glRasterPos2f(...) GLEGetCurrentFunction(glRasterPos2f)(__VA_ARGS__) + #define glRasterPos2fv(...) GLEGetCurrentFunction(glRasterPos2fv)(__VA_ARGS__) + #define glRasterPos2i(...) GLEGetCurrentFunction(glRasterPos2i)(__VA_ARGS__) + #define glRasterPos2iv(...) GLEGetCurrentFunction(glRasterPos2iv)(__VA_ARGS__) + #define glRasterPos2s(...) GLEGetCurrentFunction(glRasterPos2s)(__VA_ARGS__) + #define glRasterPos2sv(...) GLEGetCurrentFunction(glRasterPos2sv)(__VA_ARGS__) + #define glRasterPos3d(...) GLEGetCurrentFunction(glRasterPos3d)(__VA_ARGS__) + #define glRasterPos3dv(...) GLEGetCurrentFunction(glRasterPos3dv)(__VA_ARGS__) + #define glRasterPos3f(...) GLEGetCurrentFunction(glRasterPos3f)(__VA_ARGS__) + #define glRasterPos3fv(...) GLEGetCurrentFunction(glRasterPos3fv)(__VA_ARGS__) + #define glRasterPos3i(...) GLEGetCurrentFunction(glRasterPos3i)(__VA_ARGS__) + #define glRasterPos3iv(...) GLEGetCurrentFunction(glRasterPos3iv)(__VA_ARGS__) + #define glRasterPos3s(...) GLEGetCurrentFunction(glRasterPos3s)(__VA_ARGS__) + #define glRasterPos3sv(...) GLEGetCurrentFunction(glRasterPos3sv)(__VA_ARGS__) + #define glRasterPos4d(...) GLEGetCurrentFunction(glRasterPos4d)(__VA_ARGS__) + #define glRasterPos4dv(...) GLEGetCurrentFunction(glRasterPos4dv)(__VA_ARGS__) + #define glRasterPos4f(...) GLEGetCurrentFunction(glRasterPos4f)(__VA_ARGS__) + #define glRasterPos4fv(...) GLEGetCurrentFunction(glRasterPos4fv)(__VA_ARGS__) + #define glRasterPos4i(...) GLEGetCurrentFunction(glRasterPos4i)(__VA_ARGS__) + #define glRasterPos4iv(...) GLEGetCurrentFunction(glRasterPos4iv)(__VA_ARGS__) + #define glRasterPos4s(...) GLEGetCurrentFunction(glRasterPos4s)(__VA_ARGS__) + #define glRasterPos4sv(...) GLEGetCurrentFunction(glRasterPos4sv)(__VA_ARGS__) + #define glReadBuffer(...) GLEGetCurrentFunction(glReadBuffer)(__VA_ARGS__) + #define glReadPixels(...) GLEGetCurrentFunction(glReadPixels)(__VA_ARGS__) + #define glRectd(...) GLEGetCurrentFunction(glRectd)(__VA_ARGS__) + #define glRectdv(...) GLEGetCurrentFunction(glRectdv)(__VA_ARGS__) + #define glRectf(...) GLEGetCurrentFunction(glRectf)(__VA_ARGS__) + #define glRectfv(...) GLEGetCurrentFunction(glRectfv)(__VA_ARGS__) + #define glRecti(...) GLEGetCurrentFunction(glRecti)(__VA_ARGS__) + #define glRectiv(...) GLEGetCurrentFunction(glRectiv)(__VA_ARGS__) + #define glRects(...) GLEGetCurrentFunction(glRects)(__VA_ARGS__) + #define glRectsv(...) GLEGetCurrentFunction(glRectsv)(__VA_ARGS__) + #define glRenderMode(...) GLEGetCurrentFunction(glRenderMode)(__VA_ARGS__) + #define glRotated(...) GLEGetCurrentFunction(glRotated)(__VA_ARGS__) + #define glRotatef(...) GLEGetCurrentFunction(glRotatef)(__VA_ARGS__) + #define glScaled(...) GLEGetCurrentFunction(glScaled)(__VA_ARGS__) + #define glScalef(...) GLEGetCurrentFunction(glScalef)(__VA_ARGS__) + #define glScissor(...) GLEGetCurrentFunction(glScissor)(__VA_ARGS__) + #define glSelectBuffer(...) GLEGetCurrentFunction(glSelectBuffer)(__VA_ARGS__) + #define glShadeModel(...) GLEGetCurrentFunction(glShadeModel)(__VA_ARGS__) + #define glStencilFunc(...) GLEGetCurrentFunction(glStencilFunc)(__VA_ARGS__) + #define glStencilMask(...) GLEGetCurrentFunction(glStencilMask)(__VA_ARGS__) + #define glStencilOp(...) GLEGetCurrentFunction(glStencilOp)(__VA_ARGS__) + #define glTexCoord1d(...) GLEGetCurrentFunction(glTexCoord1d)(__VA_ARGS__) + #define glTexCoord1dv(...) GLEGetCurrentFunction(glTexCoord1dv)(__VA_ARGS__) + #define glTexCoord1f(...) GLEGetCurrentFunction(glTexCoord1f)(__VA_ARGS__) + #define glTexCoord1fv(...) GLEGetCurrentFunction(glTexCoord1fv)(__VA_ARGS__) + #define glTexCoord1i(...) GLEGetCurrentFunction(glTexCoord1i)(__VA_ARGS__) + #define glTexCoord1iv(...) GLEGetCurrentFunction(glTexCoord1iv)(__VA_ARGS__) + #define glTexCoord1s(...) GLEGetCurrentFunction(glTexCoord1s)(__VA_ARGS__) + #define glTexCoord1sv(...) GLEGetCurrentFunction(glTexCoord1sv)(__VA_ARGS__) + #define glTexCoord2d(...) GLEGetCurrentFunction(glTexCoord2d)(__VA_ARGS__) + #define glTexCoord2dv(...) GLEGetCurrentFunction(glTexCoord2dv)(__VA_ARGS__) + #define glTexCoord2f(...) GLEGetCurrentFunction(glTexCoord2f)(__VA_ARGS__) + #define glTexCoord2fv(...) GLEGetCurrentFunction(glTexCoord2fv)(__VA_ARGS__) + #define glTexCoord2i(...) GLEGetCurrentFunction(glTexCoord2i)(__VA_ARGS__) + #define glTexCoord2iv(...) GLEGetCurrentFunction(glTexCoord2iv)(__VA_ARGS__) + #define glTexCoord2s(...) GLEGetCurrentFunction(glTexCoord2s)(__VA_ARGS__) + #define glTexCoord2sv(...) GLEGetCurrentFunction(glTexCoord2sv)(__VA_ARGS__) + #define glTexCoord3d(...) GLEGetCurrentFunction(glTexCoord3d)(__VA_ARGS__) + #define glTexCoord3dv(...) GLEGetCurrentFunction(glTexCoord3dv)(__VA_ARGS__) + #define glTexCoord3f(...) GLEGetCurrentFunction(glTexCoord3f)(__VA_ARGS__) + #define glTexCoord3fv(...) GLEGetCurrentFunction(glTexCoord3fv)(__VA_ARGS__) + #define glTexCoord3i(...) GLEGetCurrentFunction(glTexCoord3i)(__VA_ARGS__) + #define glTexCoord3iv(...) GLEGetCurrentFunction(glTexCoord3iv)(__VA_ARGS__) + #define glTexCoord3s(...) GLEGetCurrentFunction(glTexCoord3s)(__VA_ARGS__) + #define glTexCoord3sv(...) GLEGetCurrentFunction(glTexCoord3sv)(__VA_ARGS__) + #define glTexCoord4d(...) GLEGetCurrentFunction(glTexCoord4d)(__VA_ARGS__) + #define glTexCoord4dv(...) GLEGetCurrentFunction(glTexCoord4dv)(__VA_ARGS__) + #define glTexCoord4f(...) GLEGetCurrentFunction(glTexCoord4f)(__VA_ARGS__) + #define glTexCoord4fv(...) GLEGetCurrentFunction(glTexCoord4fv)(__VA_ARGS__) + #define glTexCoord4i(...) GLEGetCurrentFunction(glTexCoord4i)(__VA_ARGS__) + #define glTexCoord4iv(...) GLEGetCurrentFunction(glTexCoord4iv)(__VA_ARGS__) + #define glTexCoord4s(...) GLEGetCurrentFunction(glTexCoord4s)(__VA_ARGS__) + #define glTexCoord4sv(...) GLEGetCurrentFunction(glTexCoord4sv)(__VA_ARGS__) + #define glTexCoordPointer(...) GLEGetCurrentFunction(glTexCoordPointer)(__VA_ARGS__) + #define glTexEnvf(...) GLEGetCurrentFunction(glTexEnvf)(__VA_ARGS__) + #define glTexEnvfv(...) GLEGetCurrentFunction(glTexEnvfv)(__VA_ARGS__) + #define glTexEnvi(...) GLEGetCurrentFunction(glTexEnvi)(__VA_ARGS__) + #define glTexEnviv(...) GLEGetCurrentFunction(glTexEnviv)(__VA_ARGS__) + #define glTexGend(...) GLEGetCurrentFunction(glTexGend)(__VA_ARGS__) + #define glTexGendv(...) GLEGetCurrentFunction(glTexGendv)(__VA_ARGS__) + #define glTexGenf(...) GLEGetCurrentFunction(glTexGenf)(__VA_ARGS__) + #define glTexGenfv(...) GLEGetCurrentFunction(glTexGenfv)(__VA_ARGS__) + #define glTexGeni(...) GLEGetCurrentFunction(glTexGeni)(__VA_ARGS__) + #define glTexGeniv(...) GLEGetCurrentFunction(glTexGeniv)(__VA_ARGS__) + #define glTexImage1D(...) GLEGetCurrentFunction(glTexImage1D)(__VA_ARGS__) + #define glTexImage2D(...) GLEGetCurrentFunction(glTexImage2D)(__VA_ARGS__) + #define glTexParameterf(...) GLEGetCurrentFunction(glTexParameterf)(__VA_ARGS__) + #define glTexParameterfv(...) GLEGetCurrentFunction(glTexParameterfv)(__VA_ARGS__) + #define glTexParameteri(...) GLEGetCurrentFunction(glTexParameteri)(__VA_ARGS__) + #define glTexParameteriv(...) GLEGetCurrentFunction(glTexParameteriv)(__VA_ARGS__) + #define glTexSubImage1D(...) GLEGetCurrentFunction(glTexSubImage1D)(__VA_ARGS__) + #define glTexSubImage2D(...) GLEGetCurrentFunction(glTexSubImage2D)(__VA_ARGS__) + #define glTranslated(...) GLEGetCurrentFunction(glTranslated)(__VA_ARGS__) + #define glTranslatef(...) GLEGetCurrentFunction(glTranslatef)(__VA_ARGS__) + #define glVertex2d(...) GLEGetCurrentFunction(glVertex2d)(__VA_ARGS__) + #define glVertex2dv(...) GLEGetCurrentFunction(glVertex2dv)(__VA_ARGS__) + #define glVertex2f(...) GLEGetCurrentFunction(glVertex2f)(__VA_ARGS__) + #define glVertex2fv(...) GLEGetCurrentFunction(glVertex2fv)(__VA_ARGS__) + #define glVertex2i(...) GLEGetCurrentFunction(glVertex2i)(__VA_ARGS__) + #define glVertex2iv(...) GLEGetCurrentFunction(glVertex2iv)(__VA_ARGS__) + #define glVertex2s(...) GLEGetCurrentFunction(glVertex2s)(__VA_ARGS__) + #define glVertex2sv(...) GLEGetCurrentFunction(glVertex2sv)(__VA_ARGS__) + #define glVertex3d(...) GLEGetCurrentFunction(glVertex3d)(__VA_ARGS__) + #define glVertex3dv(...) GLEGetCurrentFunction(glVertex3dv)(__VA_ARGS__) + #define glVertex3f(...) GLEGetCurrentFunction(glVertex3f)(__VA_ARGS__) + #define glVertex3fv(...) GLEGetCurrentFunction(glVertex3fv)(__VA_ARGS__) + #define glVertex3i(...) GLEGetCurrentFunction(glVertex3i)(__VA_ARGS__) + #define glVertex3iv(...) GLEGetCurrentFunction(glVertex3iv)(__VA_ARGS__) + #define glVertex3s(...) GLEGetCurrentFunction(glVertex3s)(__VA_ARGS__) + #define glVertex3sv(...) GLEGetCurrentFunction(glVertex3sv)(__VA_ARGS__) + #define glVertex4d(...) GLEGetCurrentFunction(glVertex4d)(__VA_ARGS__) + #define glVertex4dv(...) GLEGetCurrentFunction(glVertex4dv)(__VA_ARGS__) + #define glVertex4f(...) GLEGetCurrentFunction(glVertex4f)(__VA_ARGS__) + #define glVertex4fv(...) GLEGetCurrentFunction(glVertex4fv)(__VA_ARGS__) + #define glVertex4i(...) GLEGetCurrentFunction(glVertex4i)(__VA_ARGS__) + #define glVertex4iv(...) GLEGetCurrentFunction(glVertex4iv)(__VA_ARGS__) + #define glVertex4s(...) GLEGetCurrentFunction(glVertex4s)(__VA_ARGS__) + #define glVertex4sv(...) GLEGetCurrentFunction(glVertex4sv)(__VA_ARGS__) + #define glVertexPointer(...) GLEGetCurrentFunction(glVertexPointer)(__VA_ARGS__) + #define glViewport(...) GLEGetCurrentFunction(glViewport)(__VA_ARGS__) + #else + // There is no need to typedef OpenGL 1.1 function types because they are present in all + // OpenGL implementations and don't need to be treated dynamically like extensions. + GLAPI void GLAPIENTRY glAccum (GLenum op, GLfloat value); + GLAPI void GLAPIENTRY glAlphaFunc (GLenum func, GLclampf ref); + GLAPI GLboolean GLAPIENTRY glAreTexturesResident (GLsizei n, const GLuint *textures, GLboolean *residences); + GLAPI void GLAPIENTRY glArrayElement (GLint i); + GLAPI void GLAPIENTRY glBegin (GLenum mode); + GLAPI void GLAPIENTRY glBindTexture (GLenum target, GLuint texture); + GLAPI void GLAPIENTRY glBitmap (GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); + GLAPI void GLAPIENTRY glBlendFunc (GLenum sfactor, GLenum dfactor); + GLAPI void GLAPIENTRY glCallList (GLuint list); + GLAPI void GLAPIENTRY glCallLists (GLsizei n, GLenum type, const void *lists); + GLAPI void GLAPIENTRY glClear (GLbitfield mask); + GLAPI void GLAPIENTRY glClearAccum (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + GLAPI void GLAPIENTRY glClearColor (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + GLAPI void GLAPIENTRY glClearDepth (GLclampd depth); + GLAPI void GLAPIENTRY glClearIndex (GLfloat c); + GLAPI void GLAPIENTRY glClearStencil (GLint s); + GLAPI void GLAPIENTRY glClipPlane (GLenum plane, const GLdouble *equation); + GLAPI void GLAPIENTRY glColor3b (GLbyte red, GLbyte green, GLbyte blue); + GLAPI void GLAPIENTRY glColor3bv (const GLbyte *v); + GLAPI void GLAPIENTRY glColor3d (GLdouble red, GLdouble green, GLdouble blue); + GLAPI void GLAPIENTRY glColor3dv (const GLdouble *v); + GLAPI void GLAPIENTRY glColor3f (GLfloat red, GLfloat green, GLfloat blue); + GLAPI void GLAPIENTRY glColor3fv (const GLfloat *v); + GLAPI void GLAPIENTRY glColor3i (GLint red, GLint green, GLint blue); + GLAPI void GLAPIENTRY glColor3iv (const GLint *v); + GLAPI void GLAPIENTRY glColor3s (GLshort red, GLshort green, GLshort blue); + GLAPI void GLAPIENTRY glColor3sv (const GLshort *v); + GLAPI void GLAPIENTRY glColor3ub (GLubyte red, GLubyte green, GLubyte blue); + GLAPI void GLAPIENTRY glColor3ubv (const GLubyte *v); + GLAPI void GLAPIENTRY glColor3ui (GLuint red, GLuint green, GLuint blue); + GLAPI void GLAPIENTRY glColor3uiv (const GLuint *v); + GLAPI void GLAPIENTRY glColor3us (GLushort red, GLushort green, GLushort blue); + GLAPI void GLAPIENTRY glColor3usv (const GLushort *v); + GLAPI void GLAPIENTRY glColor4b (GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); + GLAPI void GLAPIENTRY glColor4bv (const GLbyte *v); + GLAPI void GLAPIENTRY glColor4d (GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); + GLAPI void GLAPIENTRY glColor4dv (const GLdouble *v); + GLAPI void GLAPIENTRY glColor4f (GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + GLAPI void GLAPIENTRY glColor4fv (const GLfloat *v); + GLAPI void GLAPIENTRY glColor4i (GLint red, GLint green, GLint blue, GLint alpha); + GLAPI void GLAPIENTRY glColor4iv (const GLint *v); + GLAPI void GLAPIENTRY glColor4s (GLshort red, GLshort green, GLshort blue, GLshort alpha); + GLAPI void GLAPIENTRY glColor4sv (const GLshort *v); + GLAPI void GLAPIENTRY glColor4ub (GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); + GLAPI void GLAPIENTRY glColor4ubv (const GLubyte *v); + GLAPI void GLAPIENTRY glColor4ui (GLuint red, GLuint green, GLuint blue, GLuint alpha); + GLAPI void GLAPIENTRY glColor4uiv (const GLuint *v); + GLAPI void GLAPIENTRY glColor4us (GLushort red, GLushort green, GLushort blue, GLushort alpha); + GLAPI void GLAPIENTRY glColor4usv (const GLushort *v); + GLAPI void GLAPIENTRY glColorMask (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + GLAPI void GLAPIENTRY glColorMaterial (GLenum face, GLenum mode); + GLAPI void GLAPIENTRY glColorPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); + GLAPI void GLAPIENTRY glCopyPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); + GLAPI void GLAPIENTRY glCopyTexImage1D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border); + GLAPI void GLAPIENTRY glCopyTexImage2D (GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + GLAPI void GLAPIENTRY glCopyTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + GLAPI void GLAPIENTRY glCopyTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + GLAPI void GLAPIENTRY glCullFace (GLenum mode); + GLAPI void GLAPIENTRY glDeleteLists (GLuint list, GLsizei range); + GLAPI void GLAPIENTRY glDeleteTextures (GLsizei n, const GLuint *textures); + GLAPI void GLAPIENTRY glDepthFunc (GLenum func); + GLAPI void GLAPIENTRY glDepthMask (GLboolean flag); + GLAPI void GLAPIENTRY glDepthRange (GLclampd zNear, GLclampd zFar); + GLAPI void GLAPIENTRY glDisable (GLenum cap); + GLAPI void GLAPIENTRY glDisableClientState (GLenum array); + GLAPI void GLAPIENTRY glDrawArrays (GLenum mode, GLint first, GLsizei count); + GLAPI void GLAPIENTRY glDrawBuffer (GLenum mode); + GLAPI void GLAPIENTRY glDrawElements (GLenum mode, GLsizei count, GLenum type, const void *indices); + GLAPI void GLAPIENTRY glDrawPixels (GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); + GLAPI void GLAPIENTRY glEdgeFlag (GLboolean flag); + GLAPI void GLAPIENTRY glEdgeFlagPointer (GLsizei stride, const void *pointer); + GLAPI void GLAPIENTRY glEdgeFlagv (const GLboolean *flag); + GLAPI void GLAPIENTRY glEnable (GLenum cap); + GLAPI void GLAPIENTRY glEnableClientState (GLenum array); + GLAPI void GLAPIENTRY glEnd (void); + GLAPI void GLAPIENTRY glEndList (void); + GLAPI void GLAPIENTRY glEvalCoord1d (GLdouble u); + GLAPI void GLAPIENTRY glEvalCoord1dv (const GLdouble *u); + GLAPI void GLAPIENTRY glEvalCoord1f (GLfloat u); + GLAPI void GLAPIENTRY glEvalCoord1fv (const GLfloat *u); + GLAPI void GLAPIENTRY glEvalCoord2d (GLdouble u, GLdouble v); + GLAPI void GLAPIENTRY glEvalCoord2dv (const GLdouble *u); + GLAPI void GLAPIENTRY glEvalCoord2f (GLfloat u, GLfloat v); + GLAPI void GLAPIENTRY glEvalCoord2fv (const GLfloat *u); + GLAPI void GLAPIENTRY glEvalMesh1 (GLenum mode, GLint i1, GLint i2); + GLAPI void GLAPIENTRY glEvalMesh2 (GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); + GLAPI void GLAPIENTRY glEvalPoint1 (GLint i); + GLAPI void GLAPIENTRY glEvalPoint2 (GLint i, GLint j); + GLAPI void GLAPIENTRY glFeedbackBuffer (GLsizei size, GLenum type, GLfloat *buffer); + GLAPI void GLAPIENTRY glFinish (void); + GLAPI void GLAPIENTRY glFlush (void); + GLAPI void GLAPIENTRY glFogf (GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glFogfv (GLenum pname, const GLfloat *params); + GLAPI void GLAPIENTRY glFogi (GLenum pname, GLint param); + GLAPI void GLAPIENTRY glFogiv (GLenum pname, const GLint *params); + GLAPI void GLAPIENTRY glFrontFace (GLenum mode); + GLAPI void GLAPIENTRY glFrustum (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + GLAPI GLuint GLAPIENTRY glGenLists (GLsizei range); + GLAPI void GLAPIENTRY glGenTextures (GLsizei n, GLuint *textures); + GLAPI void GLAPIENTRY glGetBooleanv (GLenum pname, GLboolean *params); + GLAPI void GLAPIENTRY glGetClipPlane (GLenum plane, GLdouble *equation); + GLAPI void GLAPIENTRY glGetDoublev (GLenum pname, GLdouble *params); + GLAPI GLenum GLAPIENTRY glGetError (void); + GLAPI void GLAPIENTRY glGetFloatv (GLenum pname, GLfloat *params); + GLAPI void GLAPIENTRY glGetIntegerv (GLenum pname, GLint *params); + GLAPI void GLAPIENTRY glGetLightfv (GLenum light, GLenum pname, GLfloat *params); + GLAPI void GLAPIENTRY glGetLightiv (GLenum light, GLenum pname, GLint *params); + GLAPI void GLAPIENTRY glGetMapdv (GLenum target, GLenum query, GLdouble *v); + GLAPI void GLAPIENTRY glGetMapfv (GLenum target, GLenum query, GLfloat *v); + GLAPI void GLAPIENTRY glGetMapiv (GLenum target, GLenum query, GLint *v); + GLAPI void GLAPIENTRY glGetMaterialfv (GLenum face, GLenum pname, GLfloat *params); + GLAPI void GLAPIENTRY glGetMaterialiv (GLenum face, GLenum pname, GLint *params); + GLAPI void GLAPIENTRY glGetPixelMapfv (GLenum map, GLfloat *values); + GLAPI void GLAPIENTRY glGetPixelMapuiv (GLenum map, GLuint *values); + GLAPI void GLAPIENTRY glGetPixelMapusv (GLenum map, GLushort *values); + GLAPI void GLAPIENTRY glGetPointerv (GLenum pname, void* *params); + GLAPI void GLAPIENTRY glGetPolygonStipple (GLubyte *mask); + GLAPI const GLubyte * GLAPIENTRY glGetString (GLenum name); + GLAPI void GLAPIENTRY glGetTexEnvfv (GLenum target, GLenum pname, GLfloat *params); + GLAPI void GLAPIENTRY glGetTexEnviv (GLenum target, GLenum pname, GLint *params); + GLAPI void GLAPIENTRY glGetTexGendv (GLenum coord, GLenum pname, GLdouble *params); + GLAPI void GLAPIENTRY glGetTexGenfv (GLenum coord, GLenum pname, GLfloat *params); + GLAPI void GLAPIENTRY glGetTexGeniv (GLenum coord, GLenum pname, GLint *params); + GLAPI void GLAPIENTRY glGetTexImage (GLenum target, GLint level, GLenum format, GLenum type, void *pixels); + GLAPI void GLAPIENTRY glGetTexLevelParameterfv (GLenum target, GLint level, GLenum pname, GLfloat *params); + GLAPI void GLAPIENTRY glGetTexLevelParameteriv (GLenum target, GLint level, GLenum pname, GLint *params); + GLAPI void GLAPIENTRY glGetTexParameterfv (GLenum target, GLenum pname, GLfloat *params); + GLAPI void GLAPIENTRY glGetTexParameteriv (GLenum target, GLenum pname, GLint *params); + GLAPI void GLAPIENTRY glHint (GLenum target, GLenum mode); + GLAPI void GLAPIENTRY glIndexMask (GLuint mask); + GLAPI void GLAPIENTRY glIndexPointer (GLenum type, GLsizei stride, const void *pointer); + GLAPI void GLAPIENTRY glIndexd (GLdouble c); + GLAPI void GLAPIENTRY glIndexdv (const GLdouble *c); + GLAPI void GLAPIENTRY glIndexf (GLfloat c); + GLAPI void GLAPIENTRY glIndexfv (const GLfloat *c); + GLAPI void GLAPIENTRY glIndexi (GLint c); + GLAPI void GLAPIENTRY glIndexiv (const GLint *c); + GLAPI void GLAPIENTRY glIndexs (GLshort c); + GLAPI void GLAPIENTRY glIndexsv (const GLshort *c); + GLAPI void GLAPIENTRY glIndexub (GLubyte c); + GLAPI void GLAPIENTRY glIndexubv (const GLubyte *c); + GLAPI void GLAPIENTRY glInitNames (void); + GLAPI void GLAPIENTRY glInterleavedArrays (GLenum format, GLsizei stride, const void *pointer); + GLAPI GLboolean GLAPIENTRY glIsEnabled (GLenum cap); + GLAPI GLboolean GLAPIENTRY glIsList (GLuint list); + GLAPI GLboolean GLAPIENTRY glIsTexture (GLuint texture); + GLAPI void GLAPIENTRY glLightModelf (GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glLightModelfv (GLenum pname, const GLfloat *params); + GLAPI void GLAPIENTRY glLightModeli (GLenum pname, GLint param); + GLAPI void GLAPIENTRY glLightModeliv (GLenum pname, const GLint *params); + GLAPI void GLAPIENTRY glLightf (GLenum light, GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glLightfv (GLenum light, GLenum pname, const GLfloat *params); + GLAPI void GLAPIENTRY glLighti (GLenum light, GLenum pname, GLint param); + GLAPI void GLAPIENTRY glLightiv (GLenum light, GLenum pname, const GLint *params); + GLAPI void GLAPIENTRY glLineStipple (GLint factor, GLushort pattern); + GLAPI void GLAPIENTRY glLineWidth (GLfloat width); + GLAPI void GLAPIENTRY glListBase (GLuint base); + GLAPI void GLAPIENTRY glLoadIdentity (void); + GLAPI void GLAPIENTRY glLoadMatrixd (const GLdouble *m); + GLAPI void GLAPIENTRY glLoadMatrixf (const GLfloat *m); + GLAPI void GLAPIENTRY glLoadName (GLuint name); + GLAPI void GLAPIENTRY glLogicOp (GLenum opcode); + GLAPI void GLAPIENTRY glMap1d (GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); + GLAPI void GLAPIENTRY glMap1f (GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); + GLAPI void GLAPIENTRY glMap2d (GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); + GLAPI void GLAPIENTRY glMap2f (GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); + GLAPI void GLAPIENTRY glMapGrid1d (GLint un, GLdouble u1, GLdouble u2); + GLAPI void GLAPIENTRY glMapGrid1f (GLint un, GLfloat u1, GLfloat u2); + GLAPI void GLAPIENTRY glMapGrid2d (GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); + GLAPI void GLAPIENTRY glMapGrid2f (GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); + GLAPI void GLAPIENTRY glMaterialf (GLenum face, GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glMaterialfv (GLenum face, GLenum pname, const GLfloat *params); + GLAPI void GLAPIENTRY glMateriali (GLenum face, GLenum pname, GLint param); + GLAPI void GLAPIENTRY glMaterialiv (GLenum face, GLenum pname, const GLint *params); + GLAPI void GLAPIENTRY glMatrixMode (GLenum mode); + GLAPI void GLAPIENTRY glMultMatrixd (const GLdouble *m); + GLAPI void GLAPIENTRY glMultMatrixf (const GLfloat *m); + GLAPI void GLAPIENTRY glNewList (GLuint list, GLenum mode); + GLAPI void GLAPIENTRY glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz); + GLAPI void GLAPIENTRY glNormal3bv (const GLbyte *v); + GLAPI void GLAPIENTRY glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz); + GLAPI void GLAPIENTRY glNormal3dv (const GLdouble *v); + GLAPI void GLAPIENTRY glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz); + GLAPI void GLAPIENTRY glNormal3fv (const GLfloat *v); + GLAPI void GLAPIENTRY glNormal3i (GLint nx, GLint ny, GLint nz); + GLAPI void GLAPIENTRY glNormal3iv (const GLint *v); + GLAPI void GLAPIENTRY glNormal3s (GLshort nx, GLshort ny, GLshort nz); + GLAPI void GLAPIENTRY glNormal3sv (const GLshort *v); + GLAPI void GLAPIENTRY glNormalPointer (GLenum type, GLsizei stride, const void *pointer); + GLAPI void GLAPIENTRY glOrtho (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + GLAPI void GLAPIENTRY glPassThrough (GLfloat token); + GLAPI void GLAPIENTRY glPixelMapfv (GLenum map, GLsizei mapsize, const GLfloat *values); + GLAPI void GLAPIENTRY glPixelMapuiv (GLenum map, GLsizei mapsize, const GLuint *values); + GLAPI void GLAPIENTRY glPixelMapusv (GLenum map, GLsizei mapsize, const GLushort *values); + GLAPI void GLAPIENTRY glPixelStoref (GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glPixelStorei (GLenum pname, GLint param); + GLAPI void GLAPIENTRY glPixelTransferf (GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glPixelTransferi (GLenum pname, GLint param); + GLAPI void GLAPIENTRY glPixelZoom (GLfloat xfactor, GLfloat yfactor); + GLAPI void GLAPIENTRY glPointSize (GLfloat size); + GLAPI void GLAPIENTRY glPolygonMode (GLenum face, GLenum mode); + GLAPI void GLAPIENTRY glPolygonOffset (GLfloat factor, GLfloat units); + GLAPI void GLAPIENTRY glPolygonStipple (const GLubyte *mask); + GLAPI void GLAPIENTRY glPopAttrib (void); + GLAPI void GLAPIENTRY glPopClientAttrib (void); + GLAPI void GLAPIENTRY glPopMatrix (void); + GLAPI void GLAPIENTRY glPopName (void); + GLAPI void GLAPIENTRY glPrioritizeTextures (GLsizei n, const GLuint *textures, const GLclampf *priorities); + GLAPI void GLAPIENTRY glPushAttrib (GLbitfield mask); + GLAPI void GLAPIENTRY glPushClientAttrib (GLbitfield mask); + GLAPI void GLAPIENTRY glPushMatrix (void); + GLAPI void GLAPIENTRY glPushName (GLuint name); + GLAPI void GLAPIENTRY glRasterPos2d (GLdouble x, GLdouble y); + GLAPI void GLAPIENTRY glRasterPos2dv (const GLdouble *v); + GLAPI void GLAPIENTRY glRasterPos2f (GLfloat x, GLfloat y); + GLAPI void GLAPIENTRY glRasterPos2fv (const GLfloat *v); + GLAPI void GLAPIENTRY glRasterPos2i (GLint x, GLint y); + GLAPI void GLAPIENTRY glRasterPos2iv (const GLint *v); + GLAPI void GLAPIENTRY glRasterPos2s (GLshort x, GLshort y); + GLAPI void GLAPIENTRY glRasterPos2sv (const GLshort *v); + GLAPI void GLAPIENTRY glRasterPos3d (GLdouble x, GLdouble y, GLdouble z); + GLAPI void GLAPIENTRY glRasterPos3dv (const GLdouble *v); + GLAPI void GLAPIENTRY glRasterPos3f (GLfloat x, GLfloat y, GLfloat z); + GLAPI void GLAPIENTRY glRasterPos3fv (const GLfloat *v); + GLAPI void GLAPIENTRY glRasterPos3i (GLint x, GLint y, GLint z); + GLAPI void GLAPIENTRY glRasterPos3iv (const GLint *v); + GLAPI void GLAPIENTRY glRasterPos3s (GLshort x, GLshort y, GLshort z); + GLAPI void GLAPIENTRY glRasterPos3sv (const GLshort *v); + GLAPI void GLAPIENTRY glRasterPos4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLAPI void GLAPIENTRY glRasterPos4dv (const GLdouble *v); + GLAPI void GLAPIENTRY glRasterPos4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLAPI void GLAPIENTRY glRasterPos4fv (const GLfloat *v); + GLAPI void GLAPIENTRY glRasterPos4i (GLint x, GLint y, GLint z, GLint w); + GLAPI void GLAPIENTRY glRasterPos4iv (const GLint *v); + GLAPI void GLAPIENTRY glRasterPos4s (GLshort x, GLshort y, GLshort z, GLshort w); + GLAPI void GLAPIENTRY glRasterPos4sv (const GLshort *v); + GLAPI void GLAPIENTRY glReadBuffer (GLenum mode); + GLAPI void GLAPIENTRY glReadPixels (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); + GLAPI void GLAPIENTRY glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); + GLAPI void GLAPIENTRY glRectdv (const GLdouble *v1, const GLdouble *v2); + GLAPI void GLAPIENTRY glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); + GLAPI void GLAPIENTRY glRectfv (const GLfloat *v1, const GLfloat *v2); + GLAPI void GLAPIENTRY glRecti (GLint x1, GLint y1, GLint x2, GLint y2); + GLAPI void GLAPIENTRY glRectiv (const GLint *v1, const GLint *v2); + GLAPI void GLAPIENTRY glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2); + GLAPI void GLAPIENTRY glRectsv (const GLshort *v1, const GLshort *v2); + GLAPI GLint GLAPIENTRY glRenderMode (GLenum mode); + GLAPI void GLAPIENTRY glRotated (GLdouble angle, GLdouble x, GLdouble y, GLdouble z); + GLAPI void GLAPIENTRY glRotatef (GLfloat angle, GLfloat x, GLfloat y, GLfloat z); + GLAPI void GLAPIENTRY glScaled (GLdouble x, GLdouble y, GLdouble z); + GLAPI void GLAPIENTRY glScalef (GLfloat x, GLfloat y, GLfloat z); + GLAPI void GLAPIENTRY glScissor (GLint x, GLint y, GLsizei width, GLsizei height); + GLAPI void GLAPIENTRY glSelectBuffer (GLsizei size, GLuint *buffer); + GLAPI void GLAPIENTRY glShadeModel (GLenum mode); + GLAPI void GLAPIENTRY glStencilFunc (GLenum func, GLint ref, GLuint mask); + GLAPI void GLAPIENTRY glStencilMask (GLuint mask); + GLAPI void GLAPIENTRY glStencilOp (GLenum fail, GLenum zfail, GLenum zpass); + GLAPI void GLAPIENTRY glTexCoord1d (GLdouble s); + GLAPI void GLAPIENTRY glTexCoord1dv (const GLdouble *v); + GLAPI void GLAPIENTRY glTexCoord1f (GLfloat s); + GLAPI void GLAPIENTRY glTexCoord1fv (const GLfloat *v); + GLAPI void GLAPIENTRY glTexCoord1i (GLint s); + GLAPI void GLAPIENTRY glTexCoord1iv (const GLint *v); + GLAPI void GLAPIENTRY glTexCoord1s (GLshort s); + GLAPI void GLAPIENTRY glTexCoord1sv (const GLshort *v); + GLAPI void GLAPIENTRY glTexCoord2d (GLdouble s, GLdouble t); + GLAPI void GLAPIENTRY glTexCoord2dv (const GLdouble *v); + GLAPI void GLAPIENTRY glTexCoord2f (GLfloat s, GLfloat t); + GLAPI void GLAPIENTRY glTexCoord2fv (const GLfloat *v); + GLAPI void GLAPIENTRY glTexCoord2i (GLint s, GLint t); + GLAPI void GLAPIENTRY glTexCoord2iv (const GLint *v); + GLAPI void GLAPIENTRY glTexCoord2s (GLshort s, GLshort t); + GLAPI void GLAPIENTRY glTexCoord2sv (const GLshort *v); + GLAPI void GLAPIENTRY glTexCoord3d (GLdouble s, GLdouble t, GLdouble r); + GLAPI void GLAPIENTRY glTexCoord3dv (const GLdouble *v); + GLAPI void GLAPIENTRY glTexCoord3f (GLfloat s, GLfloat t, GLfloat r); + GLAPI void GLAPIENTRY glTexCoord3fv (const GLfloat *v); + GLAPI void GLAPIENTRY glTexCoord3i (GLint s, GLint t, GLint r); + GLAPI void GLAPIENTRY glTexCoord3iv (const GLint *v); + GLAPI void GLAPIENTRY glTexCoord3s (GLshort s, GLshort t, GLshort r); + GLAPI void GLAPIENTRY glTexCoord3sv (const GLshort *v); + GLAPI void GLAPIENTRY glTexCoord4d (GLdouble s, GLdouble t, GLdouble r, GLdouble q); + GLAPI void GLAPIENTRY glTexCoord4dv (const GLdouble *v); + GLAPI void GLAPIENTRY glTexCoord4f (GLfloat s, GLfloat t, GLfloat r, GLfloat q); + GLAPI void GLAPIENTRY glTexCoord4fv (const GLfloat *v); + GLAPI void GLAPIENTRY glTexCoord4i (GLint s, GLint t, GLint r, GLint q); + GLAPI void GLAPIENTRY glTexCoord4iv (const GLint *v); + GLAPI void GLAPIENTRY glTexCoord4s (GLshort s, GLshort t, GLshort r, GLshort q); + GLAPI void GLAPIENTRY glTexCoord4sv (const GLshort *v); + GLAPI void GLAPIENTRY glTexCoordPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); + GLAPI void GLAPIENTRY glTexEnvf (GLenum target, GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glTexEnvfv (GLenum target, GLenum pname, const GLfloat *params); + GLAPI void GLAPIENTRY glTexEnvi (GLenum target, GLenum pname, GLint param); + GLAPI void GLAPIENTRY glTexEnviv (GLenum target, GLenum pname, const GLint *params); + GLAPI void GLAPIENTRY glTexGend (GLenum coord, GLenum pname, GLdouble param); + GLAPI void GLAPIENTRY glTexGendv (GLenum coord, GLenum pname, const GLdouble *params); + GLAPI void GLAPIENTRY glTexGenf (GLenum coord, GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glTexGenfv (GLenum coord, GLenum pname, const GLfloat *params); + GLAPI void GLAPIENTRY glTexGeni (GLenum coord, GLenum pname, GLint param); + GLAPI void GLAPIENTRY glTexGeniv (GLenum coord, GLenum pname, const GLint *params); + GLAPI void GLAPIENTRY glTexImage1D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); + GLAPI void GLAPIENTRY glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); + GLAPI void GLAPIENTRY glTexParameterf (GLenum target, GLenum pname, GLfloat param); + GLAPI void GLAPIENTRY glTexParameterfv (GLenum target, GLenum pname, const GLfloat *params); + GLAPI void GLAPIENTRY glTexParameteri (GLenum target, GLenum pname, GLint param); + GLAPI void GLAPIENTRY glTexParameteriv (GLenum target, GLenum pname, const GLint *params); + GLAPI void GLAPIENTRY glTexSubImage1D (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); + GLAPI void GLAPIENTRY glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); + GLAPI void GLAPIENTRY glTranslated (GLdouble x, GLdouble y, GLdouble z); + GLAPI void GLAPIENTRY glTranslatef (GLfloat x, GLfloat y, GLfloat z); + GLAPI void GLAPIENTRY glVertex2d (GLdouble x, GLdouble y); + GLAPI void GLAPIENTRY glVertex2dv (const GLdouble *v); + GLAPI void GLAPIENTRY glVertex2f (GLfloat x, GLfloat y); + GLAPI void GLAPIENTRY glVertex2fv (const GLfloat *v); + GLAPI void GLAPIENTRY glVertex2i (GLint x, GLint y); + GLAPI void GLAPIENTRY glVertex2iv (const GLint *v); + GLAPI void GLAPIENTRY glVertex2s (GLshort x, GLshort y); + GLAPI void GLAPIENTRY glVertex2sv (const GLshort *v); + GLAPI void GLAPIENTRY glVertex3d (GLdouble x, GLdouble y, GLdouble z); + GLAPI void GLAPIENTRY glVertex3dv (const GLdouble *v); + GLAPI void GLAPIENTRY glVertex3f (GLfloat x, GLfloat y, GLfloat z); + GLAPI void GLAPIENTRY glVertex3fv (const GLfloat *v); + GLAPI void GLAPIENTRY glVertex3i (GLint x, GLint y, GLint z); + GLAPI void GLAPIENTRY glVertex3iv (const GLint *v); + GLAPI void GLAPIENTRY glVertex3s (GLshort x, GLshort y, GLshort z); + GLAPI void GLAPIENTRY glVertex3sv (const GLshort *v); + GLAPI void GLAPIENTRY glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w); + GLAPI void GLAPIENTRY glVertex4dv (const GLdouble *v); + GLAPI void GLAPIENTRY glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w); + GLAPI void GLAPIENTRY glVertex4fv (const GLfloat *v); + GLAPI void GLAPIENTRY glVertex4i (GLint x, GLint y, GLint z, GLint w); + GLAPI void GLAPIENTRY glVertex4iv (const GLint *v); + GLAPI void GLAPIENTRY glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w); + GLAPI void GLAPIENTRY glVertex4sv (const GLshort *v); + GLAPI void GLAPIENTRY glVertexPointer (GLint size, GLenum type, GLsizei stride, const void *pointer); + GLAPI void GLAPIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height); + + #endif // GLE_HOOKING_ENABLED + +#endif // GL_VERSION_1_1 + + + + +// OpenGL 1.2+ functions are not declared in Microsoft's gl.h + +#ifndef GL_VERSION_1_2 + #define GL_VERSION_1_2 1 + + #define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 + #define GL_SMOOTH_POINT_SIZE_GRANULARITY 0x0B13 + #define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 + #define GL_SMOOTH_LINE_WIDTH_GRANULARITY 0x0B23 + #define GL_UNSIGNED_BYTE_3_3_2 0x8032 + #define GL_UNSIGNED_SHORT_4_4_4_4 0x8033 + #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 + #define GL_UNSIGNED_INT_8_8_8_8 0x8035 + #define GL_UNSIGNED_INT_10_10_10_2 0x8036 + #define GL_RESCALE_NORMAL 0x803A + #define GL_TEXTURE_BINDING_3D 0x806A + #define GL_PACK_SKIP_IMAGES 0x806B + #define GL_PACK_IMAGE_HEIGHT 0x806C + #define GL_UNPACK_SKIP_IMAGES 0x806D + #define GL_UNPACK_IMAGE_HEIGHT 0x806E + #define GL_TEXTURE_3D 0x806F + #define GL_PROXY_TEXTURE_3D 0x8070 + #define GL_TEXTURE_DEPTH 0x8071 + #define GL_TEXTURE_WRAP_R 0x8072 + #define GL_MAX_3D_TEXTURE_SIZE 0x8073 + #define GL_BGR 0x80E0 + #define GL_BGRA 0x80E1 + #define GL_MAX_ELEMENTS_VERTICES 0x80E8 + #define GL_MAX_ELEMENTS_INDICES 0x80E9 + #define GL_CLAMP_TO_EDGE 0x812F + #define GL_TEXTURE_MIN_LOD 0x813A + #define GL_TEXTURE_MAX_LOD 0x813B + #define GL_TEXTURE_BASE_LEVEL 0x813C + #define GL_TEXTURE_MAX_LEVEL 0x813D + #define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 + #define GL_SINGLE_COLOR 0x81F9 + #define GL_SEPARATE_SPECULAR_COLOR 0x81FA + #define GL_UNSIGNED_BYTE_2_3_3_REV 0x8362 + #define GL_UNSIGNED_SHORT_5_6_5 0x8363 + #define GL_UNSIGNED_SHORT_5_6_5_REV 0x8364 + #define GL_UNSIGNED_SHORT_4_4_4_4_REV 0x8365 + #define GL_UNSIGNED_SHORT_1_5_5_5_REV 0x8366 + #define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367 + #define GL_ALIASED_POINT_SIZE_RANGE 0x846D + #define GL_ALIASED_LINE_WIDTH_RANGE 0x846E + + typedef void (GLAPIENTRY * PFNGLCOPYTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTSPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DPROC) (GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + typedef void (GLAPIENTRY * PFNGLTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + + #define glCopyTexSubImage3D GLEGetCurrentFunction(glCopyTexSubImage3D) + #define glDrawRangeElements GLEGetCurrentFunction(glDrawRangeElements) + #define glTexImage3D GLEGetCurrentFunction(glTexImage3D) + #define glTexSubImage3D GLEGetCurrentFunction(glTexSubImage3D) + + // OpenGL 2.1 deprecated functions + /* + typedef void (GLAPIENTRY PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + typedef void (GLAPIENTRY PFNGLBLENDEQUATIONPROC) (GLenum mode); + typedef void (GLAPIENTRY PFNGLCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *table); + typedef void (GLAPIENTRY PFNGLCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); + typedef void (GLAPIENTRY PFNGLCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); + typedef void (GLAPIENTRY PFNGLCOPYCOLORTABLEPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPROC) (GLenum target, GLenum format, GLenum type, GLvoid *table); + typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); + typedef void (GLAPIENTRY PFNGLGETCOLORTABLEPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); + typedef void (GLAPIENTRY PFNGLCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data); + typedef void (GLAPIENTRY PFNGLCOPYCOLORSUBTABLEPROC) (GLenum target, GLsizei start, GLint x, GLint y, GLsizei width); + typedef void (GLAPIENTRY PFNGLCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLenum format, GLenum type, const GLvoid *image); + typedef void (GLAPIENTRY PFNGLCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image); + typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERFPROC) (GLenum target, GLenum pname, GLfloat params); + typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, const GLfloat *params); + typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERIPROC) (GLenum target, GLenum pname, GLint params); + typedef void (GLAPIENTRY PFNGLCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, const GLint *params); + typedef void (GLAPIENTRY PFNGLCOPYCONVOLUTIONFILTER1DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width); + typedef void (GLAPIENTRY PFNGLCOPYCONVOLUTIONFILTER2DPROC) (GLenum target, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *image); + typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); + typedef void (GLAPIENTRY PFNGLGETCONVOLUTIONPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); + typedef void (GLAPIENTRY PFNGLGETSEPARABLEFILTERPROC) (GLenum target, GLenum format, GLenum type, GLvoid *row, GLvoid *column, GLvoid *span); + typedef void (GLAPIENTRY PFNGLSEPARABLEFILTER2DPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column); + typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); + typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); + typedef void (GLAPIENTRY PFNGLGETHISTOGRAMPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); + typedef void (GLAPIENTRY PFNGLGETMINMAXPROC) (GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values); + typedef void (GLAPIENTRY PFNGLGETMINMAXPARAMETERFVPROC) (GLenum target, GLenum pname, GLfloat *params); + typedef void (GLAPIENTRY PFNGLGETMINMAXPARAMETERIVPROC) (GLenum target, GLenum pname, GLint *params); + typedef void (GLAPIENTRY PFNGLHISTOGRAMPROC) (GLenum target, GLsizei width, GLenum internalformat, GLboolean sink); + typedef void (GLAPIENTRY PFNGLMINMAXPROC) (GLenum target, GLenum internalformat, GLboolean sink); + typedef void (GLAPIENTRY PFNGLRESETHISTOGRAMPROC) (GLenum target); + typedef void (GLAPIENTRY PFNGLRESETMINMAXPROC) (GLenum target); + */ +#endif // GL_VERSION_1_2 + + + +#ifndef GL_VERSION_1_3 + #define GL_VERSION_1_3 1 + + #define GL_MULTISAMPLE 0x809D + #define GL_SAMPLE_ALPHA_TO_COVERAGE 0x809E + #define GL_SAMPLE_ALPHA_TO_ONE 0x809F + #define GL_SAMPLE_COVERAGE 0x80A0 + #define GL_SAMPLE_BUFFERS 0x80A8 + #define GL_SAMPLES 0x80A9 + #define GL_SAMPLE_COVERAGE_VALUE 0x80AA + #define GL_SAMPLE_COVERAGE_INVERT 0x80AB + #define GL_CLAMP_TO_BORDER 0x812D + #define GL_TEXTURE0 0x84C0 + #define GL_TEXTURE1 0x84C1 + #define GL_TEXTURE2 0x84C2 + #define GL_TEXTURE3 0x84C3 + #define GL_TEXTURE4 0x84C4 + #define GL_TEXTURE5 0x84C5 + #define GL_TEXTURE6 0x84C6 + #define GL_TEXTURE7 0x84C7 + #define GL_TEXTURE8 0x84C8 + #define GL_TEXTURE9 0x84C9 + #define GL_TEXTURE10 0x84CA + #define GL_TEXTURE11 0x84CB + #define GL_TEXTURE12 0x84CC + #define GL_TEXTURE13 0x84CD + #define GL_TEXTURE14 0x84CE + #define GL_TEXTURE15 0x84CF + #define GL_TEXTURE16 0x84D0 + #define GL_TEXTURE17 0x84D1 + #define GL_TEXTURE18 0x84D2 + #define GL_TEXTURE19 0x84D3 + #define GL_TEXTURE20 0x84D4 + #define GL_TEXTURE21 0x84D5 + #define GL_TEXTURE22 0x84D6 + #define GL_TEXTURE23 0x84D7 + #define GL_TEXTURE24 0x84D8 + #define GL_TEXTURE25 0x84D9 + #define GL_TEXTURE26 0x84DA + #define GL_TEXTURE27 0x84DB + #define GL_TEXTURE28 0x84DC + #define GL_TEXTURE29 0x84DD + #define GL_TEXTURE30 0x84DE + #define GL_TEXTURE31 0x84DF + #define GL_ACTIVE_TEXTURE 0x84E0 + #define GL_CLIENT_ACTIVE_TEXTURE 0x84E1 + #define GL_MAX_TEXTURE_UNITS 0x84E2 + #define GL_TRANSPOSE_MODELVIEW_MATRIX 0x84E3 + #define GL_TRANSPOSE_PROJECTION_MATRIX 0x84E4 + #define GL_TRANSPOSE_TEXTURE_MATRIX 0x84E5 + #define GL_TRANSPOSE_COLOR_MATRIX 0x84E6 + #define GL_SUBTRACT 0x84E7 + #define GL_COMPRESSED_ALPHA 0x84E9 + #define GL_COMPRESSED_LUMINANCE 0x84EA + #define GL_COMPRESSED_LUMINANCE_ALPHA 0x84EB + #define GL_COMPRESSED_INTENSITY 0x84EC + #define GL_COMPRESSED_RGB 0x84ED + #define GL_COMPRESSED_RGBA 0x84EE + #define GL_TEXTURE_COMPRESSION_HINT 0x84EF + #define GL_NORMAL_MAP 0x8511 + #define GL_REFLECTION_MAP 0x8512 + #define GL_TEXTURE_CUBE_MAP 0x8513 + #define GL_TEXTURE_BINDING_CUBE_MAP 0x8514 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x8515 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_X 0x8516 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_Y 0x8517 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x8518 + #define GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x8519 + #define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z 0x851A + #define GL_PROXY_TEXTURE_CUBE_MAP 0x851B + #define GL_MAX_CUBE_MAP_TEXTURE_SIZE 0x851C + #define GL_COMBINE 0x8570 + #define GL_COMBINE_RGB 0x8571 + #define GL_COMBINE_ALPHA 0x8572 + #define GL_RGB_SCALE 0x8573 + #define GL_ADD_SIGNED 0x8574 + #define GL_INTERPOLATE 0x8575 + #define GL_CONSTANT 0x8576 + #define GL_PRIMARY_COLOR 0x8577 + #define GL_PREVIOUS 0x8578 + #define GL_SOURCE0_RGB 0x8580 + #define GL_SOURCE1_RGB 0x8581 + #define GL_SOURCE2_RGB 0x8582 + #define GL_SOURCE0_ALPHA 0x8588 + #define GL_SOURCE1_ALPHA 0x8589 + #define GL_SOURCE2_ALPHA 0x858A + #define GL_OPERAND0_RGB 0x8590 + #define GL_OPERAND1_RGB 0x8591 + #define GL_OPERAND2_RGB 0x8592 + #define GL_OPERAND0_ALPHA 0x8598 + #define GL_OPERAND1_ALPHA 0x8599 + #define GL_OPERAND2_ALPHA 0x859A + #define GL_TEXTURE_COMPRESSED_IMAGE_SIZE 0x86A0 + #define GL_TEXTURE_COMPRESSED 0x86A1 + #define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 + #define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 + #define GL_DOT3_RGB 0x86AE + #define GL_DOT3_RGBA 0x86AF + #define GL_MULTISAMPLE_BIT 0x20000000 + + typedef void (GLAPIENTRY * PFNGLACTIVETEXTUREPROC) (GLenum texture); + typedef void (GLAPIENTRY * PFNGLCLIENTACTIVETEXTUREPROC) (GLenum texture); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint lod, void *img); + typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); + typedef void (GLAPIENTRY * PFNGLLOADTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); + typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXDPROC) (const GLdouble m[16]); + typedef void (GLAPIENTRY * PFNGLMULTTRANSPOSEMATRIXFPROC) (const GLfloat m[16]); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DPROC) (GLenum target, GLdouble s); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1DVPROC) (GLenum target, const GLdouble *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FPROC) (GLenum target, GLfloat s); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1FVPROC) (GLenum target, const GLfloat *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IPROC) (GLenum target, GLint s); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1IVPROC) (GLenum target, const GLint *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SPROC) (GLenum target, GLshort s); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD1SVPROC) (GLenum target, const GLshort *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DPROC) (GLenum target, GLdouble s, GLdouble t); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2DVPROC) (GLenum target, const GLdouble *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FPROC) (GLenum target, GLfloat s, GLfloat t); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2FVPROC) (GLenum target, const GLfloat *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IPROC) (GLenum target, GLint s, GLint t); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2IVPROC) (GLenum target, const GLint *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SPROC) (GLenum target, GLshort s, GLshort t); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD2SVPROC) (GLenum target, const GLshort *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3DVPROC) (GLenum target, const GLdouble *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3FVPROC) (GLenum target, const GLfloat *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IPROC) (GLenum target, GLint s, GLint t, GLint r); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3IVPROC) (GLenum target, const GLint *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SPROC) (GLenum target, GLshort s, GLshort t, GLshort r); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD3SVPROC) (GLenum target, const GLshort *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DPROC) (GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4DVPROC) (GLenum target, const GLdouble *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FPROC) (GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4FVPROC) (GLenum target, const GLfloat *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IPROC) (GLenum target, GLint s, GLint t, GLint r, GLint q); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4IVPROC) (GLenum target, const GLint *v); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SPROC) (GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); + typedef void (GLAPIENTRY * PFNGLMULTITEXCOORD4SVPROC) (GLenum target, const GLshort *v); + typedef void (GLAPIENTRY * PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert); + + #define glActiveTexture GLEGetCurrentFunction(glActiveTexture) + #define glClientActiveTexture GLEGetCurrentFunction(glClientActiveTexture) + #define glCompressedTexImage1D GLEGetCurrentFunction(glCompressedTexImage1D) + #define glCompressedTexImage2D GLEGetCurrentFunction(glCompressedTexImage2D) + #define glCompressedTexImage3D GLEGetCurrentFunction(glCompressedTexImage3D) + #define glCompressedTexSubImage1D GLEGetCurrentFunction(glCompressedTexSubImage1D) + #define glCompressedTexSubImage2D GLEGetCurrentFunction(glCompressedTexSubImage2D) + #define glCompressedTexSubImage3D GLEGetCurrentFunction(glCompressedTexSubImage3D) + #define glGetCompressedTexImage GLEGetCurrentFunction(glGetCompressedTexImage) + #define glLoadTransposeMatrixd GLEGetCurrentFunction(glLoadTransposeMatrixd) + #define glLoadTransposeMatrixf GLEGetCurrentFunction(glLoadTransposeMatrixf) + #define glMultTransposeMatrixd GLEGetCurrentFunction(glMultTransposeMatrixd) + #define glMultTransposeMatrixf GLEGetCurrentFunction(glMultTransposeMatrixf) + #define glMultiTexCoord1d GLEGetCurrentFunction(glMultiTexCoord1d) + #define glMultiTexCoord1dv GLEGetCurrentFunction(glMultiTexCoord1dv) + #define glMultiTexCoord1f GLEGetCurrentFunction(glMultiTexCoord1f) + #define glMultiTexCoord1fv GLEGetCurrentFunction(glMultiTexCoord1fv) + #define glMultiTexCoord1i GLEGetCurrentFunction(glMultiTexCoord1i) + #define glMultiTexCoord1iv GLEGetCurrentFunction(glMultiTexCoord1iv) + #define glMultiTexCoord1s GLEGetCurrentFunction(glMultiTexCoord1s) + #define glMultiTexCoord1sv GLEGetCurrentFunction(glMultiTexCoord1sv) + #define glMultiTexCoord2d GLEGetCurrentFunction(glMultiTexCoord2d) + #define glMultiTexCoord2dv GLEGetCurrentFunction(glMultiTexCoord2dv) + #define glMultiTexCoord2f GLEGetCurrentFunction(glMultiTexCoord2f) + #define glMultiTexCoord2fv GLEGetCurrentFunction(glMultiTexCoord2fv) + #define glMultiTexCoord2i GLEGetCurrentFunction(glMultiTexCoord2i) + #define glMultiTexCoord2iv GLEGetCurrentFunction(glMultiTexCoord2iv) + #define glMultiTexCoord2s GLEGetCurrentFunction(glMultiTexCoord2s) + #define glMultiTexCoord2sv GLEGetCurrentFunction(glMultiTexCoord2sv) + #define glMultiTexCoord3d GLEGetCurrentFunction(glMultiTexCoord3d) + #define glMultiTexCoord3dv GLEGetCurrentFunction(glMultiTexCoord3dv) + #define glMultiTexCoord3f GLEGetCurrentFunction(glMultiTexCoord3f) + #define glMultiTexCoord3fv GLEGetCurrentFunction(glMultiTexCoord3fv) + #define glMultiTexCoord3i GLEGetCurrentFunction(glMultiTexCoord3i) + #define glMultiTexCoord3iv GLEGetCurrentFunction(glMultiTexCoord3iv) + #define glMultiTexCoord3s GLEGetCurrentFunction(glMultiTexCoord3s) + #define glMultiTexCoord3sv GLEGetCurrentFunction(glMultiTexCoord3sv) + #define glMultiTexCoord4d GLEGetCurrentFunction(glMultiTexCoord4d) + #define glMultiTexCoord4dv GLEGetCurrentFunction(glMultiTexCoord4dv) + #define glMultiTexCoord4f GLEGetCurrentFunction(glMultiTexCoord4f) + #define glMultiTexCoord4fv GLEGetCurrentFunction(glMultiTexCoord4fv) + #define glMultiTexCoord4i GLEGetCurrentFunction(glMultiTexCoord4i) + #define glMultiTexCoord4iv GLEGetCurrentFunction(glMultiTexCoord4iv) + #define glMultiTexCoord4s GLEGetCurrentFunction(glMultiTexCoord4s) + #define glMultiTexCoord4sv GLEGetCurrentFunction(glMultiTexCoord4sv) + #define glSampleCoverage GLEGetCurrentFunction(glSampleCoverage) + +#endif // GL_VERSION_1_3 + + + +#ifndef GL_VERSION_1_4 + #define GL_VERSION_1_4 1 + + #define GL_BLEND_DST_RGB 0x80C8 + #define GL_BLEND_SRC_RGB 0x80C9 + #define GL_BLEND_DST_ALPHA 0x80CA + #define GL_BLEND_SRC_ALPHA 0x80CB + #define GL_POINT_SIZE_MIN 0x8126 + #define GL_POINT_SIZE_MAX 0x8127 + #define GL_POINT_FADE_THRESHOLD_SIZE 0x8128 + #define GL_POINT_DISTANCE_ATTENUATION 0x8129 + #define GL_GENERATE_MIPMAP 0x8191 + #define GL_GENERATE_MIPMAP_HINT 0x8192 + #define GL_DEPTH_COMPONENT16 0x81A5 + #define GL_DEPTH_COMPONENT24 0x81A6 + #define GL_DEPTH_COMPONENT32 0x81A7 + #define GL_MIRRORED_REPEAT 0x8370 + #define GL_FOG_COORDINATE_SOURCE 0x8450 + #define GL_FOG_COORDINATE 0x8451 + #define GL_FRAGMENT_DEPTH 0x8452 + #define GL_CURRENT_FOG_COORDINATE 0x8453 + #define GL_FOG_COORDINATE_ARRAY_TYPE 0x8454 + #define GL_FOG_COORDINATE_ARRAY_STRIDE 0x8455 + #define GL_FOG_COORDINATE_ARRAY_POINTER 0x8456 + #define GL_FOG_COORDINATE_ARRAY 0x8457 + #define GL_COLOR_SUM 0x8458 + #define GL_CURRENT_SECONDARY_COLOR 0x8459 + #define GL_SECONDARY_COLOR_ARRAY_SIZE 0x845A + #define GL_SECONDARY_COLOR_ARRAY_TYPE 0x845B + #define GL_SECONDARY_COLOR_ARRAY_STRIDE 0x845C + #define GL_SECONDARY_COLOR_ARRAY_POINTER 0x845D + #define GL_SECONDARY_COLOR_ARRAY 0x845E + #define GL_MAX_TEXTURE_LOD_BIAS 0x84FD + #define GL_TEXTURE_FILTER_CONTROL 0x8500 + #define GL_TEXTURE_LOD_BIAS 0x8501 + #define GL_INCR_WRAP 0x8507 + #define GL_DECR_WRAP 0x8508 + #define GL_TEXTURE_DEPTH_SIZE 0x884A + #define GL_DEPTH_TEXTURE_MODE 0x884B + #define GL_TEXTURE_COMPARE_MODE 0x884C + #define GL_TEXTURE_COMPARE_FUNC 0x884D + #define GL_COMPARE_R_TO_TEXTURE 0x884E + + typedef void (GLAPIENTRY * PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); + typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONPROC) (GLenum mode); + typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEPROC) (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + typedef void (GLAPIENTRY * PFNGLFOGCOORDPOINTERPROC) (GLenum type, GLsizei stride, const void *pointer); + typedef void (GLAPIENTRY * PFNGLFOGCOORDDPROC) (GLdouble coord); + typedef void (GLAPIENTRY * PFNGLFOGCOORDDVPROC) (const GLdouble *coord); + typedef void (GLAPIENTRY * PFNGLFOGCOORDFPROC) (GLfloat coord); + typedef void (GLAPIENTRY * PFNGLFOGCOORDFVPROC) (const GLfloat *coord); + typedef void (GLAPIENTRY * PFNGLMULTIDRAWARRAYSPROC) (GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); + typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTSPROC) (GLenum mode, const GLsizei *count, GLenum type, const void *const* indices, GLsizei drawcount); + typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFPROC) (GLenum pname, GLfloat param); + typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERFVPROC) (GLenum pname, const GLfloat *params); + typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIPROC) (GLenum pname, GLint param); + typedef void (GLAPIENTRY * PFNGLPOINTPARAMETERIVPROC) (GLenum pname, const GLint *params); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BPROC) (GLbyte red, GLbyte green, GLbyte blue); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3BVPROC) (const GLbyte *v); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DPROC) (GLdouble red, GLdouble green, GLdouble blue); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3DVPROC) (const GLdouble *v); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FPROC) (GLfloat red, GLfloat green, GLfloat blue); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3FVPROC) (const GLfloat *v); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IPROC) (GLint red, GLint green, GLint blue); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3IVPROC) (const GLint *v); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SPROC) (GLshort red, GLshort green, GLshort blue); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3SVPROC) (const GLshort *v); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBPROC) (GLubyte red, GLubyte green, GLubyte blue); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UBVPROC) (const GLubyte *v); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIPROC) (GLuint red, GLuint green, GLuint blue); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3UIVPROC) (const GLuint *v); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USPROC) (GLushort red, GLushort green, GLushort blue); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLOR3USVPROC) (const GLushort *v); + typedef void (GLAPIENTRY * PFNGLSECONDARYCOLORPOINTERPROC) (GLint size, GLenum type, GLsizei stride, const void *pointer); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DPROC) (GLdouble x, GLdouble y); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS2DVPROC) (const GLdouble *p); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FPROC) (GLfloat x, GLfloat y); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS2FVPROC) (const GLfloat *p); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IPROC) (GLint x, GLint y); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS2IVPROC) (const GLint *p); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SPROC) (GLshort x, GLshort y); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS2SVPROC) (const GLshort *p); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DPROC) (GLdouble x, GLdouble y, GLdouble z); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS3DVPROC) (const GLdouble *p); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FPROC) (GLfloat x, GLfloat y, GLfloat z); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS3FVPROC) (const GLfloat *p); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IPROC) (GLint x, GLint y, GLint z); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS3IVPROC) (const GLint *p); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SPROC) (GLshort x, GLshort y, GLshort z); + typedef void (GLAPIENTRY * PFNGLWINDOWPOS3SVPROC) (const GLshort *p); + + #define glBlendColor GLEGetCurrentFunction(glBlendColor) + #define glBlendEquation GLEGetCurrentFunction(glBlendEquation) + #define glBlendFuncSeparate GLEGetCurrentFunction(glBlendFuncSeparate) + #define glFogCoordPointer GLEGetCurrentFunction(glFogCoordPointer) + #define glFogCoordd GLEGetCurrentFunction(glFogCoordd) + #define glFogCoorddv GLEGetCurrentFunction(glFogCoorddv) + #define glFogCoordf GLEGetCurrentFunction(glFogCoordf) + #define glFogCoordfv GLEGetCurrentFunction(glFogCoordfv) + #define glMultiDrawArrays GLEGetCurrentFunction(glMultiDrawArrays) + #define glMultiDrawElements GLEGetCurrentFunction(glMultiDrawElements) + #define glPointParameterf GLEGetCurrentFunction(glPointParameterf) + #define glPointParameterfv GLEGetCurrentFunction(glPointParameterfv) + #define glPointParameteri GLEGetCurrentFunction(glPointParameteri) + #define glPointParameteriv GLEGetCurrentFunction(glPointParameteriv) + #define glSecondaryColor3b GLEGetCurrentFunction(glSecondaryColor3b) + #define glSecondaryColor3bv GLEGetCurrentFunction(glSecondaryColor3bv) + #define glSecondaryColor3d GLEGetCurrentFunction(glSecondaryColor3d) + #define glSecondaryColor3dv GLEGetCurrentFunction(glSecondaryColor3dv) + #define glSecondaryColor3f GLEGetCurrentFunction(glSecondaryColor3f) + #define glSecondaryColor3fv GLEGetCurrentFunction(glSecondaryColor3fv) + #define glSecondaryColor3i GLEGetCurrentFunction(glSecondaryColor3i) + #define glSecondaryColor3iv GLEGetCurrentFunction(glSecondaryColor3iv) + #define glSecondaryColor3s GLEGetCurrentFunction(glSecondaryColor3s) + #define glSecondaryColor3sv GLEGetCurrentFunction(glSecondaryColor3sv) + #define glSecondaryColor3ub GLEGetCurrentFunction(glSecondaryColor3ub) + #define glSecondaryColor3ubv GLEGetCurrentFunction(glSecondaryColor3ubv) + #define glSecondaryColor3ui GLEGetCurrentFunction(glSecondaryColor3ui) + #define glSecondaryColor3uiv GLEGetCurrentFunction(glSecondaryColor3uiv) + #define glSecondaryColor3us GLEGetCurrentFunction(glSecondaryColor3us) + #define glSecondaryColor3usv GLEGetCurrentFunction(glSecondaryColor3usv) + #define glSecondaryColorPointer GLEGetCurrentFunction(glSecondaryColorPointer) + #define glWindowPos2d GLEGetCurrentFunction(glWindowPos2d) + #define glWindowPos2dv GLEGetCurrentFunction(glWindowPos2dv) + #define glWindowPos2f GLEGetCurrentFunction(glWindowPos2f) + #define glWindowPos2fv GLEGetCurrentFunction(glWindowPos2fv) + #define glWindowPos2i GLEGetCurrentFunction(glWindowPos2i) + #define glWindowPos2iv GLEGetCurrentFunction(glWindowPos2iv) + #define glWindowPos2s GLEGetCurrentFunction(glWindowPos2s) + #define glWindowPos2sv GLEGetCurrentFunction(glWindowPos2sv) + #define glWindowPos3d GLEGetCurrentFunction(glWindowPos3d) + #define glWindowPos3dv GLEGetCurrentFunction(glWindowPos3dv) + #define glWindowPos3f GLEGetCurrentFunction(glWindowPos3f) + #define glWindowPos3fv GLEGetCurrentFunction(glWindowPos3fv) + #define glWindowPos3i GLEGetCurrentFunction(glWindowPos3i) + #define glWindowPos3iv GLEGetCurrentFunction(glWindowPos3iv) + #define glWindowPos3s GLEGetCurrentFunction(glWindowPos3s) + #define glWindowPos3sv GLEGetCurrentFunction(glWindowPos3sv) + +#endif // GL_VERSION_1_4 + + + +#ifndef GL_VERSION_1_5 + #define GL_VERSION_1_5 1 + + #define GL_CURRENT_FOG_COORD GL_CURRENT_FOG_COORDINATE + #define GL_FOG_COORD GL_FOG_COORDINATE + #define GL_FOG_COORD_ARRAY GL_FOG_COORDINATE_ARRAY + #define GL_FOG_COORD_ARRAY_BUFFER_BINDING GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING + #define GL_FOG_COORD_ARRAY_POINTER GL_FOG_COORDINATE_ARRAY_POINTER + #define GL_FOG_COORD_ARRAY_STRIDE GL_FOG_COORDINATE_ARRAY_STRIDE + #define GL_FOG_COORD_ARRAY_TYPE GL_FOG_COORDINATE_ARRAY_TYPE + #define GL_FOG_COORD_SRC GL_FOG_COORDINATE_SOURCE + #define GL_SRC0_ALPHA GL_SOURCE0_ALPHA + #define GL_SRC0_RGB GL_SOURCE0_RGB + #define GL_SRC1_ALPHA GL_SOURCE1_ALPHA + #define GL_SRC1_RGB GL_SOURCE1_RGB + #define GL_SRC2_ALPHA GL_SOURCE2_ALPHA + #define GL_SRC2_RGB GL_SOURCE2_RGB + #define GL_BUFFER_SIZE 0x8764 + #define GL_BUFFER_USAGE 0x8765 + #define GL_QUERY_COUNTER_BITS 0x8864 + #define GL_CURRENT_QUERY 0x8865 + #define GL_QUERY_RESULT 0x8866 + #define GL_QUERY_RESULT_AVAILABLE 0x8867 + #define GL_ARRAY_BUFFER 0x8892 + #define GL_ELEMENT_ARRAY_BUFFER 0x8893 + #define GL_ARRAY_BUFFER_BINDING 0x8894 + #define GL_ELEMENT_ARRAY_BUFFER_BINDING 0x8895 + #define GL_VERTEX_ARRAY_BUFFER_BINDING 0x8896 + #define GL_NORMAL_ARRAY_BUFFER_BINDING 0x8897 + #define GL_COLOR_ARRAY_BUFFER_BINDING 0x8898 + #define GL_INDEX_ARRAY_BUFFER_BINDING 0x8899 + #define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING 0x889A + #define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING 0x889B + #define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING 0x889C + #define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING 0x889D + #define GL_WEIGHT_ARRAY_BUFFER_BINDING 0x889E + #define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING 0x889F + #define GL_READ_ONLY 0x88B8 + #define GL_WRITE_ONLY 0x88B9 + #define GL_READ_WRITE 0x88BA + #define GL_BUFFER_ACCESS 0x88BB + #define GL_BUFFER_MAPPED 0x88BC + #define GL_BUFFER_MAP_POINTER 0x88BD + #define GL_STREAM_DRAW 0x88E0 + #define GL_STREAM_READ 0x88E1 + #define GL_STREAM_COPY 0x88E2 + #define GL_STATIC_DRAW 0x88E4 + #define GL_STATIC_READ 0x88E5 + #define GL_STATIC_COPY 0x88E6 + #define GL_DYNAMIC_DRAW 0x88E8 + #define GL_DYNAMIC_READ 0x88E9 + #define GL_DYNAMIC_COPY 0x88EA + #define GL_SAMPLES_PASSED 0x8914 + + typedef ptrdiff_t GLintptr; + typedef ptrdiff_t GLsizeiptr; + + typedef void (GLAPIENTRY * PFNGLBEGINQUERYPROC) (GLenum target, GLuint id); + typedef void (GLAPIENTRY * PFNGLBINDBUFFERPROC) (GLenum target, GLuint buffer); + typedef void (GLAPIENTRY * PFNGLBUFFERDATAPROC) (GLenum target, GLsizeiptr size, const void* data, GLenum usage); + typedef void (GLAPIENTRY * PFNGLBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, const void* data); + typedef void (GLAPIENTRY * PFNGLDELETEBUFFERSPROC) (GLsizei n, const GLuint* buffers); + typedef void (GLAPIENTRY * PFNGLDELETEQUERIESPROC) (GLsizei n, const GLuint* ids); + typedef void (GLAPIENTRY * PFNGLENDQUERYPROC) (GLenum target); + typedef void (GLAPIENTRY * PFNGLGENBUFFERSPROC) (GLsizei n, GLuint* buffers); + typedef void (GLAPIENTRY * PFNGLGENQUERIESPROC) (GLsizei n, GLuint* ids); + typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETBUFFERPOINTERVPROC) (GLenum target, GLenum pname, void** params); + typedef void (GLAPIENTRY * PFNGLGETBUFFERSUBDATAPROC) (GLenum target, GLintptr offset, GLsizeiptr size, void* data); + typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTIVPROC) (GLuint id, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUIVPROC) (GLuint id, GLenum pname, GLuint* params); + typedef void (GLAPIENTRY * PFNGLGETQUERYIVPROC) (GLenum target, GLenum pname, GLint* params); + typedef GLboolean (GLAPIENTRY * PFNGLISBUFFERPROC) (GLuint buffer); + typedef GLboolean (GLAPIENTRY * PFNGLISQUERYPROC) (GLuint id); + typedef void* (GLAPIENTRY * PFNGLMAPBUFFERPROC) (GLenum target, GLenum access); + typedef GLboolean (GLAPIENTRY * PFNGLUNMAPBUFFERPROC) (GLenum target); + + #define glBeginQuery GLEGetCurrentFunction(glBeginQuery) + #define glBindBuffer GLEGetCurrentFunction(glBindBuffer) + #define glBufferData GLEGetCurrentFunction(glBufferData) + #define glBufferSubData GLEGetCurrentFunction(glBufferSubData) + #define glDeleteBuffers GLEGetCurrentFunction(glDeleteBuffers) + #define glDeleteQueries GLEGetCurrentFunction(glDeleteQueries) + #define glEndQuery GLEGetCurrentFunction(glEndQuery) + #define glGenBuffers GLEGetCurrentFunction(glGenBuffers) + #define glGenQueries GLEGetCurrentFunction(glGenQueries) + #define glGetBufferParameteriv GLEGetCurrentFunction(glGetBufferParameteriv) + #define glGetBufferPointerv GLEGetCurrentFunction(glGetBufferPointerv) + #define glGetBufferSubData GLEGetCurrentFunction(glGetBufferSubData) + #define glGetQueryObjectiv GLEGetCurrentFunction(glGetQueryObjectiv) + #define glGetQueryObjectuiv GLEGetCurrentFunction(glGetQueryObjectuiv) + #define glGetQueryiv GLEGetCurrentFunction(glGetQueryiv) + #define glIsBuffer GLEGetCurrentFunction(glIsBuffer) + #define glIsQuery GLEGetCurrentFunction(glIsQuery) + #define glMapBuffer GLEGetCurrentFunction(glMapBuffer) + #define glUnmapBuffer GLEGetCurrentFunction(glUnmapBuffer) + +#endif // GL_VERSION_1_5 + + + + +#ifndef GL_VERSION_2_0 + #define GL_VERSION_2_0 1 + + #define GL_BLEND_EQUATION_RGB GL_BLEND_EQUATION + #define GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622 + #define GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623 + #define GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624 + #define GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625 + #define GL_CURRENT_VERTEX_ATTRIB 0x8626 + #define GL_VERTEX_PROGRAM_POINT_SIZE 0x8642 + #define GL_VERTEX_PROGRAM_TWO_SIDE 0x8643 + #define GL_VERTEX_ATTRIB_ARRAY_POINTER 0x8645 + #define GL_STENCIL_BACK_FUNC 0x8800 + #define GL_STENCIL_BACK_FAIL 0x8801 + #define GL_STENCIL_BACK_PASS_DEPTH_FAIL 0x8802 + #define GL_STENCIL_BACK_PASS_DEPTH_PASS 0x8803 + #define GL_MAX_DRAW_BUFFERS 0x8824 + #define GL_DRAW_BUFFER0 0x8825 + #define GL_DRAW_BUFFER1 0x8826 + #define GL_DRAW_BUFFER2 0x8827 + #define GL_DRAW_BUFFER3 0x8828 + #define GL_DRAW_BUFFER4 0x8829 + #define GL_DRAW_BUFFER5 0x882A + #define GL_DRAW_BUFFER6 0x882B + #define GL_DRAW_BUFFER7 0x882C + #define GL_DRAW_BUFFER8 0x882D + #define GL_DRAW_BUFFER9 0x882E + #define GL_DRAW_BUFFER10 0x882F + #define GL_DRAW_BUFFER11 0x8830 + #define GL_DRAW_BUFFER12 0x8831 + #define GL_DRAW_BUFFER13 0x8832 + #define GL_DRAW_BUFFER14 0x8833 + #define GL_DRAW_BUFFER15 0x8834 + #define GL_BLEND_EQUATION_ALPHA 0x883D + #define GL_POINT_SPRITE 0x8861 + #define GL_COORD_REPLACE 0x8862 + #define GL_MAX_VERTEX_ATTRIBS 0x8869 + #define GL_VERTEX_ATTRIB_ARRAY_NORMALIZED 0x886A + #define GL_MAX_TEXTURE_COORDS 0x8871 + #define GL_MAX_TEXTURE_IMAGE_UNITS 0x8872 + #define GL_FRAGMENT_SHADER 0x8B30 + #define GL_VERTEX_SHADER 0x8B31 + #define GL_MAX_FRAGMENT_UNIFORM_COMPONENTS 0x8B49 + #define GL_MAX_VERTEX_UNIFORM_COMPONENTS 0x8B4A + #define GL_MAX_VARYING_FLOATS 0x8B4B + #define GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS 0x8B4C + #define GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS 0x8B4D + #define GL_SHADER_TYPE 0x8B4F + #define GL_FLOAT_VEC2 0x8B50 + #define GL_FLOAT_VEC3 0x8B51 + #define GL_FLOAT_VEC4 0x8B52 + #define GL_INT_VEC2 0x8B53 + #define GL_INT_VEC3 0x8B54 + #define GL_INT_VEC4 0x8B55 + #define GL_BOOL 0x8B56 + #define GL_BOOL_VEC2 0x8B57 + #define GL_BOOL_VEC3 0x8B58 + #define GL_BOOL_VEC4 0x8B59 + #define GL_FLOAT_MAT2 0x8B5A + #define GL_FLOAT_MAT3 0x8B5B + #define GL_FLOAT_MAT4 0x8B5C + #define GL_SAMPLER_1D 0x8B5D + #define GL_SAMPLER_2D 0x8B5E + #define GL_SAMPLER_3D 0x8B5F + #define GL_SAMPLER_CUBE 0x8B60 + #define GL_SAMPLER_1D_SHADOW 0x8B61 + #define GL_SAMPLER_2D_SHADOW 0x8B62 + #define GL_DELETE_STATUS 0x8B80 + #define GL_COMPILE_STATUS 0x8B81 + #define GL_LINK_STATUS 0x8B82 + #define GL_VALIDATE_STATUS 0x8B83 + #define GL_INFO_LOG_LENGTH 0x8B84 + #define GL_ATTACHED_SHADERS 0x8B85 + #define GL_ACTIVE_UNIFORMS 0x8B86 + #define GL_ACTIVE_UNIFORM_MAX_LENGTH 0x8B87 + #define GL_SHADER_SOURCE_LENGTH 0x8B88 + #define GL_ACTIVE_ATTRIBUTES 0x8B89 + #define GL_ACTIVE_ATTRIBUTE_MAX_LENGTH 0x8B8A + #define GL_FRAGMENT_SHADER_DERIVATIVE_HINT 0x8B8B + #define GL_SHADING_LANGUAGE_VERSION 0x8B8C + #define GL_CURRENT_PROGRAM 0x8B8D + #define GL_POINT_SPRITE_COORD_ORIGIN 0x8CA0 + #define GL_LOWER_LEFT 0x8CA1 + #define GL_UPPER_LEFT 0x8CA2 + #define GL_STENCIL_BACK_REF 0x8CA3 + #define GL_STENCIL_BACK_VALUE_MASK 0x8CA4 + #define GL_STENCIL_BACK_WRITEMASK 0x8CA5 + + typedef void (GLAPIENTRY * PFNGLATTACHSHADERPROC) (GLuint program, GLuint shader); + typedef void (GLAPIENTRY * PFNGLBINDATTRIBLOCATIONPROC) (GLuint program, GLuint index, const GLchar* name); + typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEPROC) (GLenum modeRGB, GLenum modeAlpha); + typedef void (GLAPIENTRY * PFNGLCOMPILESHADERPROC) (GLuint shader); + typedef GLuint (GLAPIENTRY * PFNGLCREATEPROGRAMPROC) (void); + typedef GLuint (GLAPIENTRY * PFNGLCREATESHADERPROC) (GLenum type); + typedef void (GLAPIENTRY * PFNGLDELETEPROGRAMPROC) (GLuint program); + typedef void (GLAPIENTRY * PFNGLDELETESHADERPROC) (GLuint shader); + typedef void (GLAPIENTRY * PFNGLDETACHSHADERPROC) (GLuint program, GLuint shader); + typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBARRAYPROC) (GLuint index); + typedef void (GLAPIENTRY * PFNGLDRAWBUFFERSPROC) (GLsizei n, const GLenum* bufs); + typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBARRAYPROC) (GLuint index); + typedef void (GLAPIENTRY * PFNGLGETACTIVEATTRIBPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); + typedef void (GLAPIENTRY * PFNGLGETACTIVEUNIFORMPROC) (GLuint program, GLuint index, GLsizei maxLength, GLsizei* length, GLint* size, GLenum* type, GLchar* name); + typedef void (GLAPIENTRY * PFNGLGETATTACHEDSHADERSPROC) (GLuint program, GLsizei maxCount, GLsizei* count, GLuint* shaders); + typedef GLint (GLAPIENTRY * PFNGLGETATTRIBLOCATIONPROC) (GLuint program, const GLchar* name); + typedef void (GLAPIENTRY * PFNGLGETPROGRAMINFOLOGPROC) (GLuint program, GLsizei bufSize, GLsizei* length, GLchar* infoLog); + typedef void (GLAPIENTRY * PFNGLGETPROGRAMIVPROC) (GLuint program, GLenum pname, GLint* param); + typedef void (GLAPIENTRY * PFNGLGETSHADERINFOLOGPROC) (GLuint shader, GLsizei bufSize, GLsizei* length, GLchar* infoLog); + typedef void (GLAPIENTRY * PFNGLGETSHADERSOURCEPROC) (GLuint obj, GLsizei maxLength, GLsizei* length, GLchar* source); + typedef void (GLAPIENTRY * PFNGLGETSHADERIVPROC) (GLuint shader, GLenum pname, GLint* param); + typedef GLint (GLAPIENTRY * PFNGLGETUNIFORMLOCATIONPROC) (GLuint program, const GLchar* name); + typedef void (GLAPIENTRY * PFNGLGETUNIFORMFVPROC) (GLuint program, GLint location, GLfloat* params); + typedef void (GLAPIENTRY * PFNGLGETUNIFORMIVPROC) (GLuint program, GLint location, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBPOINTERVPROC) (GLuint index, GLenum pname, void** pointer); + typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBDVPROC) (GLuint index, GLenum pname, GLdouble* params); + typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBFVPROC) (GLuint index, GLenum pname, GLfloat* params); + typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIVPROC) (GLuint index, GLenum pname, GLint* params); + typedef GLboolean (GLAPIENTRY * PFNGLISPROGRAMPROC) (GLuint program); + typedef GLboolean (GLAPIENTRY * PFNGLISSHADERPROC) (GLuint shader); + typedef void (GLAPIENTRY * PFNGLLINKPROGRAMPROC) (GLuint program); + typedef void (GLAPIENTRY * PFNGLSHADERSOURCEPROC) (GLuint shader, GLsizei count, const GLchar *const* string, const GLint* length); + typedef void (GLAPIENTRY * PFNGLSTENCILFUNCSEPARATEPROC) (GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); + typedef void (GLAPIENTRY * PFNGLSTENCILMASKSEPARATEPROC) (GLenum face, GLuint mask); + typedef void (GLAPIENTRY * PFNGLSTENCILOPSEPARATEPROC) (GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + typedef void (GLAPIENTRY * PFNGLUNIFORM1FPROC) (GLint location, GLfloat v0); + typedef void (GLAPIENTRY * PFNGLUNIFORM1FVPROC) (GLint location, GLsizei count, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM1IPROC) (GLint location, GLint v0); + typedef void (GLAPIENTRY * PFNGLUNIFORM1IVPROC) (GLint location, GLsizei count, const GLint* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM2FPROC) (GLint location, GLfloat v0, GLfloat v1); + typedef void (GLAPIENTRY * PFNGLUNIFORM2FVPROC) (GLint location, GLsizei count, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM2IPROC) (GLint location, GLint v0, GLint v1); + typedef void (GLAPIENTRY * PFNGLUNIFORM2IVPROC) (GLint location, GLsizei count, const GLint* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM3FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + typedef void (GLAPIENTRY * PFNGLUNIFORM3FVPROC) (GLint location, GLsizei count, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM3IPROC) (GLint location, GLint v0, GLint v1, GLint v2); + typedef void (GLAPIENTRY * PFNGLUNIFORM3IVPROC) (GLint location, GLsizei count, const GLint* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM4FPROC) (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + typedef void (GLAPIENTRY * PFNGLUNIFORM4FVPROC) (GLint location, GLsizei count, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM4IPROC) (GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + typedef void (GLAPIENTRY * PFNGLUNIFORM4IVPROC) (GLint location, GLsizei count, const GLint* value); + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLUSEPROGRAMPROC) (GLuint program); + typedef void (GLAPIENTRY * PFNGLVALIDATEPROGRAMPROC) (GLuint program); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DPROC) (GLuint index, GLdouble x); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1DVPROC) (GLuint index, const GLdouble* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FPROC) (GLuint index, GLfloat x); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1FVPROC) (GLuint index, const GLfloat* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SPROC) (GLuint index, GLshort x); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB1SVPROC) (GLuint index, const GLshort* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DPROC) (GLuint index, GLdouble x, GLdouble y); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2DVPROC) (GLuint index, const GLdouble* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FPROC) (GLuint index, GLfloat x, GLfloat y); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2FVPROC) (GLuint index, const GLfloat* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SPROC) (GLuint index, GLshort x, GLshort y); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB2SVPROC) (GLuint index, const GLshort* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3DVPROC) (GLuint index, const GLdouble* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3FVPROC) (GLuint index, const GLfloat* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SPROC) (GLuint index, GLshort x, GLshort y, GLshort z); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB3SVPROC) (GLuint index, const GLshort* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NBVPROC) (GLuint index, const GLbyte* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NIVPROC) (GLuint index, const GLint* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NSVPROC) (GLuint index, const GLshort* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBPROC) (GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUBVPROC) (GLuint index, const GLubyte* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUIVPROC) (GLuint index, const GLuint* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4NUSVPROC) (GLuint index, const GLushort* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4BVPROC) (GLuint index, const GLbyte* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DPROC) (GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4DVPROC) (GLuint index, const GLdouble* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FPROC) (GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4FVPROC) (GLuint index, const GLfloat* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4IVPROC) (GLuint index, const GLint* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SPROC) (GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4SVPROC) (GLuint index, const GLshort* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UBVPROC) (GLuint index, const GLubyte* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4UIVPROC) (GLuint index, const GLuint* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIB4USVPROC) (GLuint index, const GLushort* v); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBPOINTERPROC) (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void* pointer); + + #define glAttachShader GLEGetCurrentFunction(glAttachShader) + #define glBindAttribLocation GLEGetCurrentFunction(glBindAttribLocation) + #define glBlendEquationSeparate GLEGetCurrentFunction(glBlendEquationSeparate) + #define glCompileShader GLEGetCurrentFunction(glCompileShader) + #define glCreateProgram GLEGetCurrentFunction(glCreateProgram) + #define glCreateShader GLEGetCurrentFunction(glCreateShader) + #define glDeleteProgram GLEGetCurrentFunction(glDeleteProgram) + #define glDeleteShader GLEGetCurrentFunction(glDeleteShader) + #define glDetachShader GLEGetCurrentFunction(glDetachShader) + #define glDisableVertexAttribArray GLEGetCurrentFunction(glDisableVertexAttribArray) + #define glDrawBuffers GLEGetCurrentFunction(glDrawBuffers) + #define glEnableVertexAttribArray GLEGetCurrentFunction(glEnableVertexAttribArray) + #define glGetActiveAttrib GLEGetCurrentFunction(glGetActiveAttrib) + #define glGetActiveUniform GLEGetCurrentFunction(glGetActiveUniform) + #define glGetAttachedShaders GLEGetCurrentFunction(glGetAttachedShaders) + #define glGetAttribLocation GLEGetCurrentFunction(glGetAttribLocation) + #define glGetProgramInfoLog GLEGetCurrentFunction(glGetProgramInfoLog) + #define glGetProgramiv GLEGetCurrentFunction(glGetProgramiv) + #define glGetShaderInfoLog GLEGetCurrentFunction(glGetShaderInfoLog) + #define glGetShaderSource GLEGetCurrentFunction(glGetShaderSource) + #define glGetShaderiv GLEGetCurrentFunction(glGetShaderiv) + #define glGetUniformLocation GLEGetCurrentFunction(glGetUniformLocation) + #define glGetUniformfv GLEGetCurrentFunction(glGetUniformfv) + #define glGetUniformiv GLEGetCurrentFunction(glGetUniformiv) + #define glGetVertexAttribPointerv GLEGetCurrentFunction(glGetVertexAttribPointerv) + #define glGetVertexAttribdv GLEGetCurrentFunction(glGetVertexAttribdv) + #define glGetVertexAttribfv GLEGetCurrentFunction(glGetVertexAttribfv) + #define glGetVertexAttribiv GLEGetCurrentFunction(glGetVertexAttribiv) + #define glIsProgram GLEGetCurrentFunction(glIsProgram) + #define glIsShader GLEGetCurrentFunction(glIsShader) + #define glLinkProgram GLEGetCurrentFunction(glLinkProgram) + #define glShaderSource GLEGetCurrentFunction(glShaderSource) + #define glStencilFuncSeparate GLEGetCurrentFunction(glStencilFuncSeparate) + #define glStencilMaskSeparate GLEGetCurrentFunction(glStencilMaskSeparate) + #define glStencilOpSeparate GLEGetCurrentFunction(glStencilOpSeparate) + #define glUniform1f GLEGetCurrentFunction(glUniform1f) + #define glUniform1fv GLEGetCurrentFunction(glUniform1fv) + #define glUniform1i GLEGetCurrentFunction(glUniform1i) + #define glUniform1iv GLEGetCurrentFunction(glUniform1iv) + #define glUniform2f GLEGetCurrentFunction(glUniform2f) + #define glUniform2fv GLEGetCurrentFunction(glUniform2fv) + #define glUniform2i GLEGetCurrentFunction(glUniform2i) + #define glUniform2iv GLEGetCurrentFunction(glUniform2iv) + #define glUniform3f GLEGetCurrentFunction(glUniform3f) + #define glUniform3fv GLEGetCurrentFunction(glUniform3fv) + #define glUniform3i GLEGetCurrentFunction(glUniform3i) + #define glUniform3iv GLEGetCurrentFunction(glUniform3iv) + #define glUniform4f GLEGetCurrentFunction(glUniform4f) + #define glUniform4fv GLEGetCurrentFunction(glUniform4fv) + #define glUniform4i GLEGetCurrentFunction(glUniform4i) + #define glUniform4iv GLEGetCurrentFunction(glUniform4iv) + #define glUniformMatrix2fv GLEGetCurrentFunction(glUniformMatrix2fv) + #define glUniformMatrix3fv GLEGetCurrentFunction(glUniformMatrix3fv) + #define glUniformMatrix4fv GLEGetCurrentFunction(glUniformMatrix4fv) + #define glUseProgram GLEGetCurrentFunction(glUseProgram) + #define glValidateProgram GLEGetCurrentFunction(glValidateProgram) + #define glVertexAttrib1d GLEGetCurrentFunction(glVertexAttrib1d) + #define glVertexAttrib1dv GLEGetCurrentFunction(glVertexAttrib1dv) + #define glVertexAttrib1f GLEGetCurrentFunction(glVertexAttrib1f) + #define glVertexAttrib1fv GLEGetCurrentFunction(glVertexAttrib1fv) + #define glVertexAttrib1s GLEGetCurrentFunction(glVertexAttrib1s) + #define glVertexAttrib1sv GLEGetCurrentFunction(glVertexAttrib1sv) + #define glVertexAttrib2d GLEGetCurrentFunction(glVertexAttrib2d) + #define glVertexAttrib2dv GLEGetCurrentFunction(glVertexAttrib2dv) + #define glVertexAttrib2f GLEGetCurrentFunction(glVertexAttrib2f) + #define glVertexAttrib2fv GLEGetCurrentFunction(glVertexAttrib2fv) + #define glVertexAttrib2s GLEGetCurrentFunction(glVertexAttrib2s) + #define glVertexAttrib2sv GLEGetCurrentFunction(glVertexAttrib2sv) + #define glVertexAttrib3d GLEGetCurrentFunction(glVertexAttrib3d) + #define glVertexAttrib3dv GLEGetCurrentFunction(glVertexAttrib3dv) + #define glVertexAttrib3f GLEGetCurrentFunction(glVertexAttrib3f) + #define glVertexAttrib3fv GLEGetCurrentFunction(glVertexAttrib3fv) + #define glVertexAttrib3s GLEGetCurrentFunction(glVertexAttrib3s) + #define glVertexAttrib3sv GLEGetCurrentFunction(glVertexAttrib3sv) + #define glVertexAttrib4Nbv GLEGetCurrentFunction(glVertexAttrib4Nbv) + #define glVertexAttrib4Niv GLEGetCurrentFunction(glVertexAttrib4Niv) + #define glVertexAttrib4Nsv GLEGetCurrentFunction(glVertexAttrib4Nsv) + #define glVertexAttrib4Nub GLEGetCurrentFunction(glVertexAttrib4Nub) + #define glVertexAttrib4Nubv GLEGetCurrentFunction(glVertexAttrib4Nubv) + #define glVertexAttrib4Nuiv GLEGetCurrentFunction(glVertexAttrib4Nuiv) + #define glVertexAttrib4Nusv GLEGetCurrentFunction(glVertexAttrib4Nusv) + #define glVertexAttrib4bv GLEGetCurrentFunction(glVertexAttrib4bv) + #define glVertexAttrib4d GLEGetCurrentFunction(glVertexAttrib4d) + #define glVertexAttrib4dv GLEGetCurrentFunction(glVertexAttrib4dv) + #define glVertexAttrib4f GLEGetCurrentFunction(glVertexAttrib4f) + #define glVertexAttrib4fv GLEGetCurrentFunction(glVertexAttrib4fv) + #define glVertexAttrib4iv GLEGetCurrentFunction(glVertexAttrib4iv) + #define glVertexAttrib4s GLEGetCurrentFunction(glVertexAttrib4s) + #define glVertexAttrib4sv GLEGetCurrentFunction(glVertexAttrib4sv) + #define glVertexAttrib4ubv GLEGetCurrentFunction(glVertexAttrib4ubv) + #define glVertexAttrib4uiv GLEGetCurrentFunction(glVertexAttrib4uiv) + #define glVertexAttrib4usv GLEGetCurrentFunction(glVertexAttrib4usv) + #define glVertexAttribPointer GLEGetCurrentFunction(glVertexAttribPointer) + +#endif // GL_VERSION_2_0 + + + +#ifndef GL_VERSION_2_1 + #define GL_VERSION_2_1 1 + + #define GL_CURRENT_RASTER_SECONDARY_COLOR 0x845F + #define GL_PIXEL_PACK_BUFFER 0x88EB + #define GL_PIXEL_UNPACK_BUFFER 0x88EC + #define GL_PIXEL_PACK_BUFFER_BINDING 0x88ED + #define GL_PIXEL_UNPACK_BUFFER_BINDING 0x88EF + #define GL_FLOAT_MAT2x3 0x8B65 + #define GL_FLOAT_MAT2x4 0x8B66 + #define GL_FLOAT_MAT3x2 0x8B67 + #define GL_FLOAT_MAT3x4 0x8B68 + #define GL_FLOAT_MAT4x2 0x8B69 + #define GL_FLOAT_MAT4x3 0x8B6A + #define GL_SRGB 0x8C40 + #define GL_SRGB8 0x8C41 + #define GL_SRGB_ALPHA 0x8C42 + #define GL_SRGB8_ALPHA8 0x8C43 + #define GL_SLUMINANCE_ALPHA 0x8C44 + #define GL_SLUMINANCE8_ALPHA8 0x8C45 + #define GL_SLUMINANCE 0x8C46 + #define GL_SLUMINANCE8 0x8C47 + #define GL_COMPRESSED_SRGB 0x8C48 + #define GL_COMPRESSED_SRGB_ALPHA 0x8C49 + #define GL_COMPRESSED_SLUMINANCE 0x8C4A + #define GL_COMPRESSED_SLUMINANCE_ALPHA 0x8C4B + + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX2X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX3X4FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X2FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void (GLAPIENTRY * PFNGLUNIFORMMATRIX4X3FVPROC) (GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + + #define glUniformMatrix2x3fv GLEGetCurrentFunction(glUniformMatrix2x3fv) + #define glUniformMatrix2x4fv GLEGetCurrentFunction(glUniformMatrix2x4fv) + #define glUniformMatrix3x2fv GLEGetCurrentFunction(glUniformMatrix3x2fv) + #define glUniformMatrix3x4fv GLEGetCurrentFunction(glUniformMatrix3x4fv) + #define glUniformMatrix4x2fv GLEGetCurrentFunction(glUniformMatrix4x2fv) + #define glUniformMatrix4x3fv GLEGetCurrentFunction(glUniformMatrix4x3fv) + +#endif // GL_VERSION_2_1 + + + + +#ifndef GL_VERSION_3_0 + #define GL_VERSION_3_0 1 + + #define GL_CLIP_DISTANCE0 GL_CLIP_PLANE0 + #define GL_CLIP_DISTANCE1 GL_CLIP_PLANE1 + #define GL_CLIP_DISTANCE2 GL_CLIP_PLANE2 + #define GL_CLIP_DISTANCE3 GL_CLIP_PLANE3 + #define GL_CLIP_DISTANCE4 GL_CLIP_PLANE4 + #define GL_CLIP_DISTANCE5 GL_CLIP_PLANE5 + #define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_R_TO_TEXTURE_ARB + #define GL_MAX_CLIP_DISTANCES GL_MAX_CLIP_PLANES + #define GL_MAX_VARYING_COMPONENTS GL_MAX_VARYING_FLOATS + #define GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT 0x0001 + #define GL_MAJOR_VERSION 0x821B + #define GL_MINOR_VERSION 0x821C + #define GL_NUM_EXTENSIONS 0x821D + #define GL_CONTEXT_FLAGS 0x821E + #define GL_DEPTH_BUFFER 0x8223 + #define GL_STENCIL_BUFFER 0x8224 + #define GL_RGBA32F 0x8814 + #define GL_RGB32F 0x8815 + #define GL_RGBA16F 0x881A + #define GL_RGB16F 0x881B + #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD + #define GL_MAX_ARRAY_TEXTURE_LAYERS 0x88FF + #define GL_MIN_PROGRAM_TEXEL_OFFSET 0x8904 + #define GL_MAX_PROGRAM_TEXEL_OFFSET 0x8905 + #define GL_CLAMP_VERTEX_COLOR 0x891A + #define GL_CLAMP_FRAGMENT_COLOR 0x891B + #define GL_CLAMP_READ_COLOR 0x891C + #define GL_FIXED_ONLY 0x891D + #define GL_TEXTURE_RED_TYPE 0x8C10 + #define GL_TEXTURE_GREEN_TYPE 0x8C11 + #define GL_TEXTURE_BLUE_TYPE 0x8C12 + #define GL_TEXTURE_ALPHA_TYPE 0x8C13 + #define GL_TEXTURE_LUMINANCE_TYPE 0x8C14 + #define GL_TEXTURE_INTENSITY_TYPE 0x8C15 + #define GL_TEXTURE_DEPTH_TYPE 0x8C16 + #define GL_TEXTURE_1D_ARRAY 0x8C18 + #define GL_PROXY_TEXTURE_1D_ARRAY 0x8C19 + #define GL_TEXTURE_2D_ARRAY 0x8C1A + #define GL_PROXY_TEXTURE_2D_ARRAY 0x8C1B + #define GL_TEXTURE_BINDING_1D_ARRAY 0x8C1C + #define GL_TEXTURE_BINDING_2D_ARRAY 0x8C1D + #define GL_R11F_G11F_B10F 0x8C3A + #define GL_UNSIGNED_INT_10F_11F_11F_REV 0x8C3B + #define GL_RGB9_E5 0x8C3D + #define GL_UNSIGNED_INT_5_9_9_9_REV 0x8C3E + #define GL_TEXTURE_SHARED_SIZE 0x8C3F + #define GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH 0x8C76 + #define GL_TRANSFORM_FEEDBACK_BUFFER_MODE 0x8C7F + #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS 0x8C80 + #define GL_TRANSFORM_FEEDBACK_VARYINGS 0x8C83 + #define GL_TRANSFORM_FEEDBACK_BUFFER_START 0x8C84 + #define GL_TRANSFORM_FEEDBACK_BUFFER_SIZE 0x8C85 + #define GL_PRIMITIVES_GENERATED 0x8C87 + #define GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN 0x8C88 + #define GL_RASTERIZER_DISCARD 0x8C89 + #define GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS 0x8C8A + #define GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS 0x8C8B + #define GL_INTERLEAVED_ATTRIBS 0x8C8C + #define GL_SEPARATE_ATTRIBS 0x8C8D + #define GL_TRANSFORM_FEEDBACK_BUFFER 0x8C8E + #define GL_TRANSFORM_FEEDBACK_BUFFER_BINDING 0x8C8F + #define GL_RGBA32UI 0x8D70 + #define GL_RGB32UI 0x8D71 + #define GL_RGBA16UI 0x8D76 + #define GL_RGB16UI 0x8D77 + #define GL_RGBA8UI 0x8D7C + #define GL_RGB8UI 0x8D7D + #define GL_RGBA32I 0x8D82 + #define GL_RGB32I 0x8D83 + #define GL_RGBA16I 0x8D88 + #define GL_RGB16I 0x8D89 + #define GL_RGBA8I 0x8D8E + #define GL_RGB8I 0x8D8F + #define GL_RED_INTEGER 0x8D94 + #define GL_GREEN_INTEGER 0x8D95 + #define GL_BLUE_INTEGER 0x8D96 + #define GL_ALPHA_INTEGER 0x8D97 + #define GL_RGB_INTEGER 0x8D98 + #define GL_RGBA_INTEGER 0x8D99 + #define GL_BGR_INTEGER 0x8D9A + #define GL_BGRA_INTEGER 0x8D9B + #define GL_SAMPLER_1D_ARRAY 0x8DC0 + #define GL_SAMPLER_2D_ARRAY 0x8DC1 + #define GL_SAMPLER_1D_ARRAY_SHADOW 0x8DC3 + #define GL_SAMPLER_2D_ARRAY_SHADOW 0x8DC4 + #define GL_SAMPLER_CUBE_SHADOW 0x8DC5 + #define GL_UNSIGNED_INT_VEC2 0x8DC6 + #define GL_UNSIGNED_INT_VEC3 0x8DC7 + #define GL_UNSIGNED_INT_VEC4 0x8DC8 + #define GL_INT_SAMPLER_1D 0x8DC9 + #define GL_INT_SAMPLER_2D 0x8DCA + #define GL_INT_SAMPLER_3D 0x8DCB + #define GL_INT_SAMPLER_CUBE 0x8DCC + #define GL_INT_SAMPLER_1D_ARRAY 0x8DCE + #define GL_INT_SAMPLER_2D_ARRAY 0x8DCF + #define GL_UNSIGNED_INT_SAMPLER_1D 0x8DD1 + #define GL_UNSIGNED_INT_SAMPLER_2D 0x8DD2 + #define GL_UNSIGNED_INT_SAMPLER_3D 0x8DD3 + #define GL_UNSIGNED_INT_SAMPLER_CUBE 0x8DD4 + #define GL_UNSIGNED_INT_SAMPLER_1D_ARRAY 0x8DD6 + #define GL_UNSIGNED_INT_SAMPLER_2D_ARRAY 0x8DD7 + #define GL_QUERY_WAIT 0x8E13 + #define GL_QUERY_NO_WAIT 0x8E14 + #define GL_QUERY_BY_REGION_WAIT 0x8E15 + #define GL_QUERY_BY_REGION_NO_WAIT 0x8E16 + + typedef void (GLAPIENTRY * PFNGLBEGINCONDITIONALRENDERPROC) (GLuint id, GLenum mode); + typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACKPROC) (GLenum primitiveMode); + typedef void (GLAPIENTRY * PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint colorNumber, const GLchar* name); + typedef void (GLAPIENTRY * PFNGLCLAMPCOLORPROC) (GLenum target, GLenum clamp); + typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawBuffer, GLfloat depth, GLint stencil); + typedef void (GLAPIENTRY * PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawBuffer, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawBuffer, const GLint* value); + typedef void (GLAPIENTRY * PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawBuffer, const GLuint* value); + typedef void (GLAPIENTRY * PFNGLCOLORMASKIPROC) (GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + typedef void (GLAPIENTRY * PFNGLDISABLEIPROC) (GLenum cap, GLuint index); + typedef void (GLAPIENTRY * PFNGLENABLEIPROC) (GLenum cap, GLuint index); + typedef void (GLAPIENTRY * PFNGLENDCONDITIONALRENDERPROC) (void); + typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACKPROC) (void); + typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGEPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASEPROC) (GLenum target, GLuint index, GLuint buffer); + typedef void (GLAPIENTRY * PFNGLGETBOOLEANI_VPROC) (GLenum pname, GLuint index, GLboolean* data); + typedef void (GLAPIENTRY * PFNGLGETINTEGERI_VPROC) (GLenum target, GLuint index, GLint* data); + typedef GLint (GLAPIENTRY * PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar* name); + typedef const GLubyte* (GLAPIENTRY * PFNGLGETSTRINGIPROC) (GLenum name, GLuint index); + typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint* params); + typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); + typedef void (GLAPIENTRY * PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint* params); + typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint* params); + typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDIPROC) (GLenum cap, GLuint index); + typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint* params); + typedef void (GLAPIENTRY * PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint* params); + typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGSPROC) (GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); + typedef void (GLAPIENTRY * PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0); + typedef void (GLAPIENTRY * PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1); + typedef void (GLAPIENTRY * PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2); + typedef void (GLAPIENTRY * PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint* value); + typedef void (GLAPIENTRY * PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + typedef void (GLAPIENTRY * PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint* value); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1IVPROC) (GLuint index, const GLint* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIPROC) (GLuint index, GLuint v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI1UIVPROC) (GLuint index, const GLuint* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint v0, GLint v1); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2IVPROC) (GLuint index, const GLint* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIPROC) (GLuint index, GLuint v0, GLuint v1); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI2UIVPROC) (GLuint index, const GLuint* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint v0, GLint v1, GLint v2); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3IVPROC) (GLuint index, const GLint* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI3UIVPROC) (GLuint index, const GLuint* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IPROC) (GLuint index, GLint v0, GLint v1, GLint v2, GLint v3); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4IVPROC) (GLuint index, const GLint* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIPROC) (GLuint index, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4UIVPROC) (GLuint index, const GLuint* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort* v0); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const void*pointer); + + #define glBeginConditionalRender GLEGetCurrentFunction(glBeginConditionalRender) + #define glBeginTransformFeedback GLEGetCurrentFunction(glBeginTransformFeedback) + #define glBindFragDataLocation GLEGetCurrentFunction(glBindFragDataLocation) + #define glClampColor GLEGetCurrentFunction(glClampColor) + #define glClearBufferfi GLEGetCurrentFunction(glClearBufferfi) + #define glClearBufferfv GLEGetCurrentFunction(glClearBufferfv) + #define glClearBufferiv GLEGetCurrentFunction(glClearBufferiv) + #define glClearBufferuiv GLEGetCurrentFunction(glClearBufferuiv) + #define glColorMaski GLEGetCurrentFunction(glColorMaski) + #define glDisablei GLEGetCurrentFunction(glDisablei) + #define glEnablei GLEGetCurrentFunction(glEnablei) + #define glEndConditionalRender GLEGetCurrentFunction(glEndConditionalRender) + #define glEndTransformFeedback GLEGetCurrentFunction(glEndTransformFeedback) + #define glGetBooleani_v GLEGetCurrentFunction(glGetBooleani_v) + #define glGetIntegeri_v GLEGetCurrentFunction(glGetIntegeri_v) + #define glGetFragDataLocation GLEGetCurrentFunction(glGetFragDataLocation) + #define glGetStringi GLEGetCurrentFunction(glGetStringi) + #define glGetTexParameterIiv GLEGetCurrentFunction(glGetTexParameterIiv) + #define glGetTexParameterIuiv GLEGetCurrentFunction(glGetTexParameterIuiv) + #define glGetTransformFeedbackVarying GLEGetCurrentFunction(glGetTransformFeedbackVarying) + #define glGetUniformuiv GLEGetCurrentFunction(glGetUniformuiv) + #define glGetVertexAttribIiv GLEGetCurrentFunction(glGetVertexAttribIiv) + #define glGetVertexAttribIuiv GLEGetCurrentFunction(glGetVertexAttribIuiv) + #define glIsEnabledi GLEGetCurrentFunction(glIsEnabledi) + #define glTexParameterIiv GLEGetCurrentFunction(glTexParameterIiv) + #define glTexParameterIuiv GLEGetCurrentFunction(glTexParameterIuiv) + #define glTransformFeedbackVaryings GLEGetCurrentFunction(glTransformFeedbackVaryings) + #define glUniform1ui GLEGetCurrentFunction(glUniform1ui) + #define glUniform1uiv GLEGetCurrentFunction(glUniform1uiv) + #define glUniform2ui GLEGetCurrentFunction(glUniform2ui) + #define glUniform2uiv GLEGetCurrentFunction(glUniform2uiv) + #define glUniform3ui GLEGetCurrentFunction(glUniform3ui) + #define glUniform3uiv GLEGetCurrentFunction(glUniform3uiv) + #define glUniform4ui GLEGetCurrentFunction(glUniform4ui) + #define glUniform4uiv GLEGetCurrentFunction(glUniform4uiv) + #define glVertexAttribI1i GLEGetCurrentFunction(glVertexAttribI1i) + #define glVertexAttribI1iv GLEGetCurrentFunction(glVertexAttribI1iv) + #define glVertexAttribI1ui GLEGetCurrentFunction(glVertexAttribI1ui) + #define glVertexAttribI1uiv GLEGetCurrentFunction(glVertexAttribI1uiv) + #define glVertexAttribI2i GLEGetCurrentFunction(glVertexAttribI2i) + #define glVertexAttribI2iv GLEGetCurrentFunction(glVertexAttribI2iv) + #define glVertexAttribI2ui GLEGetCurrentFunction(glVertexAttribI2ui) + #define glVertexAttribI2uiv GLEGetCurrentFunction(glVertexAttribI2uiv) + #define glVertexAttribI3i GLEGetCurrentFunction(glVertexAttribI3i) + #define glVertexAttribI3iv GLEGetCurrentFunction(glVertexAttribI3iv) + #define glVertexAttribI3ui GLEGetCurrentFunction(glVertexAttribI3ui) + #define glVertexAttribI3uiv GLEGetCurrentFunction(glVertexAttribI3uiv) + #define glVertexAttribI4bv GLEGetCurrentFunction(glVertexAttribI4bv) + #define glVertexAttribI4i GLEGetCurrentFunction(glVertexAttribI4i) + #define glVertexAttribI4iv GLEGetCurrentFunction(glVertexAttribI4iv) + #define glVertexAttribI4sv GLEGetCurrentFunction(glVertexAttribI4sv) + #define glVertexAttribI4ubv GLEGetCurrentFunction(glVertexAttribI4ubv) + #define glVertexAttribI4ui GLEGetCurrentFunction(glVertexAttribI4ui) + #define glVertexAttribI4uiv GLEGetCurrentFunction(glVertexAttribI4uiv) + #define glVertexAttribI4usv GLEGetCurrentFunction(glVertexAttribI4usv) + #define glVertexAttribIPointer GLEGetCurrentFunction(glVertexAttribIPointer) + +#endif // GL_VERSION_3_0 + + + + +#ifndef GL_VERSION_3_1 + #define GL_VERSION_3_1 1 + + #define GL_TEXTURE_RECTANGLE 0x84F5 + #define GL_TEXTURE_BINDING_RECTANGLE 0x84F6 + #define GL_PROXY_TEXTURE_RECTANGLE 0x84F7 + #define GL_MAX_RECTANGLE_TEXTURE_SIZE 0x84F8 + #define GL_SAMPLER_2D_RECT 0x8B63 + #define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 + #define GL_TEXTURE_BUFFER 0x8C2A + #define GL_MAX_TEXTURE_BUFFER_SIZE 0x8C2B + #define GL_TEXTURE_BINDING_BUFFER 0x8C2C + #define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0x8C2D + #define GL_TEXTURE_BUFFER_FORMAT 0x8C2E + #define GL_SAMPLER_BUFFER 0x8DC2 + #define GL_INT_SAMPLER_2D_RECT 0x8DCD + #define GL_INT_SAMPLER_BUFFER 0x8DD0 + #define GL_UNSIGNED_INT_SAMPLER_2D_RECT 0x8DD5 + #define GL_UNSIGNED_INT_SAMPLER_BUFFER 0x8DD8 + #define GL_RED_SNORM 0x8F90 + #define GL_RG_SNORM 0x8F91 + #define GL_RGB_SNORM 0x8F92 + #define GL_RGBA_SNORM 0x8F93 + #define GL_R8_SNORM 0x8F94 + #define GL_RG8_SNORM 0x8F95 + #define GL_RGB8_SNORM 0x8F96 + #define GL_RGBA8_SNORM 0x8F97 + #define GL_R16_SNORM 0x8F98 + #define GL_RG16_SNORM 0x8F99 + #define GL_RGB16_SNORM 0x8F9A + #define GL_RGBA16_SNORM 0x8F9B + #define GL_SIGNED_NORMALIZED 0x8F9C + #define GL_PRIMITIVE_RESTART 0x8F9D + #define GL_PRIMITIVE_RESTART_INDEX 0x8F9E + #define GL_BUFFER_ACCESS_FLAGS 0x911F + #define GL_BUFFER_MAP_LENGTH 0x9120 + #define GL_BUFFER_MAP_OFFSET 0x9121 + + typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCEDPROC) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); + typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCEDPROC) (GLenum mode, GLsizei count, GLenum type, const void* indices, GLsizei primcount); + typedef void (GLAPIENTRY * PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint buffer); + typedef void (GLAPIENTRY * PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalFormat, GLuint buffer); + + #define glDrawArraysInstanced GLEGetCurrentFunction(glDrawArraysInstanced) + #define glDrawElementsInstanced GLEGetCurrentFunction(glDrawElementsInstanced) + #define glPrimitiveRestartIndex GLEGetCurrentFunction(glPrimitiveRestartIndex) + #define glTexBuffer GLEGetCurrentFunction(glTexBuffer) + +#endif // GL_VERSION_3_1 + + + +#ifndef GL_VERSION_3_2 + #define GL_VERSION_3_2 1 + + #define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001 + #define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002 + #define GL_LINES_ADJACENCY 0x000A + #define GL_LINE_STRIP_ADJACENCY 0x000B + #define GL_TRIANGLES_ADJACENCY 0x000C + #define GL_TRIANGLE_STRIP_ADJACENCY 0x000D + #define GL_PROGRAM_POINT_SIZE 0x8642 + #define GL_GEOMETRY_VERTICES_OUT 0x8916 + #define GL_GEOMETRY_INPUT_TYPE 0x8917 + #define GL_GEOMETRY_OUTPUT_TYPE 0x8918 + #define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29 + #define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7 + #define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8 + #define GL_GEOMETRY_SHADER 0x8DD9 + #define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF + #define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0 + #define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1 + #define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122 + #define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123 + #define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124 + #define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125 + #define GL_CONTEXT_PROFILE_MASK 0x9126 + + typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level); + typedef void (GLAPIENTRY * PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum value, GLint64 * data); + typedef void (GLAPIENTRY * PFNGLGETINTEGER64I_VPROC) (GLenum pname, GLuint index, GLint64 * data); + + #define glFramebufferTexture GLEGetCurrentFunction(glFramebufferTexture) + #define glGetBufferParameteri64v GLEGetCurrentFunction(glGetBufferParameteri64v) + #define glGetInteger64i_v GLEGetCurrentFunction(glGetInteger64i_v) + +#endif // GL_VERSION_3_2 + + + +#ifndef GL_VERSION_3_3 + #define GL_VERSION_3_3 1 + + #define GL_VERTEX_ATTRIB_ARRAY_DIVISOR 0x88FE + #define GL_RGB10_A2UI 0x906F + + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISORPROC) (GLuint index, GLuint divisor); + + #define glVertexAttribDivisor GLEGetCurrentFunction(glVertexAttribDivisor) +#endif + + + +#ifndef GL_VERSION_4_0 + #define GL_VERSION_4_0 1 + + #define GL_SAMPLE_SHADING 0x8C36 + #define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37 + #define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E + #define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F + #define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F + #define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009 + #define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A + #define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B + #define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C + #define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D + #define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E + #define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F + + typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha); + typedef void (GLAPIENTRY * PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode); + typedef void (GLAPIENTRY * PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + typedef void (GLAPIENTRY * PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst); + typedef void (GLAPIENTRY * PFNGLMINSAMPLESHADINGPROC) (GLclampf value); + + #define glBlendEquationSeparatei GLEGetCurrentFunction(glBlendEquationSeparatei) + #define glBlendEquationi GLEGetCurrentFunction(glBlendEquationi) + #define glBlendFuncSeparatei GLEGetCurrentFunction(glBlendFuncSeparatei) + #define glBlendFunci GLEGetCurrentFunction(glBlendFunci) + #define glMinSampleShading GLEGetCurrentFunction(glMinSampleShading) + +#endif // GL_VERSION_4_0 + + + + +#ifndef GL_VERSION_4_1 + #define GL_VERSION_4_1 1 + // Empty +#endif + + + +#ifndef GL_VERSION_4_2 + #define GL_VERSION_4_2 1 + + #define GL_COMPRESSED_RGBA_BPTC_UNORM 0x8E8C + #define GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM 0x8E8D + #define GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT 0x8E8E + #define GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT 0x8E8F +#endif + + + +#ifndef GL_VERSION_4_3 + #define GL_VERSION_4_3 1 + + #define GL_NUM_SHADING_LANGUAGE_VERSIONS 0x82E9 + #define GL_VERTEX_ATTRIB_ARRAY_LONG 0x874E +#endif + + + +#ifndef GL_VERSION_4_4 + #define GL_VERSION_4_4 1 + + #define GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED 0x8221 + #define GL_MAX_VERTEX_ATTRIB_STRIDE 0x82E5 + #define GL_TEXTURE_BUFFER_BINDING 0x8C2A +#endif + + + +#ifndef GL_VERSION_4_5 + #define GL_VERSION_4_5 1 + // Empty +#endif + + + +#ifndef GL_AMD_debug_output + #define GL_AMD_debug_output 1 + + #define GL_MAX_DEBUG_MESSAGE_LENGTH_AMD 0x9143 + #define GL_MAX_DEBUG_LOGGED_MESSAGES_AMD 0x9144 + #define GL_DEBUG_LOGGED_MESSAGES_AMD 0x9145 + #define GL_DEBUG_SEVERITY_HIGH_AMD 0x9146 + #define GL_DEBUG_SEVERITY_MEDIUM_AMD 0x9147 + #define GL_DEBUG_SEVERITY_LOW_AMD 0x9148 + #define GL_DEBUG_CATEGORY_API_ERROR_AMD 0x9149 + #define GL_DEBUG_CATEGORY_WINDOW_SYSTEM_AMD 0x914A + #define GL_DEBUG_CATEGORY_DEPRECATION_AMD 0x914B + #define GL_DEBUG_CATEGORY_UNDEFINED_BEHAVIOR_AMD 0x914C + #define GL_DEBUG_CATEGORY_PERFORMANCE_AMD 0x914D + #define GL_DEBUG_CATEGORY_SHADER_COMPILER_AMD 0x914E + #define GL_DEBUG_CATEGORY_APPLICATION_AMD 0x914F + #define GL_DEBUG_CATEGORY_OTHER_AMD 0x9150 + + typedef void (GLAPIENTRY *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar* message, void* userParam); + + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKAMDPROC) (GLDEBUGPROCAMD callback, void *userParam); + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEENABLEAMDPROC) (GLenum category, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTAMDPROC) (GLenum category, GLenum severity, GLuint id, GLsizei length, const GLchar* buf); + typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGAMDPROC) (GLuint count, GLsizei bufsize, GLenum* categories, GLuint* severities, GLuint* ids, GLsizei* lengths, GLchar* message); + + #define glDebugMessageCallbackAMD GLEGetCurrentFunction(glDebugMessageCallbackAMD) + #define glDebugMessageEnableAMD GLEGetCurrentFunction(glDebugMessageEnableAMD) + #define glDebugMessageInsertAMD GLEGetCurrentFunction(glDebugMessageInsertAMD) + #define glGetDebugMessageLogAMD GLEGetCurrentFunction(glGetDebugMessageLogAMD) + + #define GLE_AMD_debug_output GLEGetCurrentVariable(gle_AMD_debug_output) + +#endif // GL_AMD_debug_output + + + +/* Disabled until needed +#ifndef GL_AMD_performance_monitor + #define GL_AMD_performance_monitor 1 + + #define GL_COUNTER_TYPE_AMD 0x8BC0 + #define GL_COUNTER_RANGE_AMD 0x8BC1 + #define GL_UNSIGNED_INT64_AMD 0x8BC2 + #define GL_PERCENTAGE_AMD 0x8BC3 + #define GL_PERFMON_RESULT_AVAILABLE_AMD 0x8BC4 + #define GL_PERFMON_RESULT_SIZE_AMD 0x8BC5 + #define GL_PERFMON_RESULT_AMD 0x8BC6 + + typedef void (GLAPIENTRY * PFNGLBEGINPERFMONITORAMDPROC) (GLuint monitor); + typedef void (GLAPIENTRY * PFNGLDELETEPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); + typedef void (GLAPIENTRY * PFNGLENDPERFMONITORAMDPROC) (GLuint monitor); + typedef void (GLAPIENTRY * PFNGLGENPERFMONITORSAMDPROC) (GLsizei n, GLuint* monitors); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERDATAAMDPROC) (GLuint monitor, GLenum pname, GLsizei dataSize, GLuint* data, GLint *bytesWritten); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERINFOAMDPROC) (GLuint group, GLuint counter, GLenum pname, void *data); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSTRINGAMDPROC) (GLuint group, GLuint counter, GLsizei bufSize, GLsizei* length, GLchar *counterString); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORCOUNTERSAMDPROC) (GLuint group, GLint* numCounters, GLint *maxActiveCounters, GLsizei countersSize, GLuint *counters); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSTRINGAMDPROC) (GLuint group, GLsizei bufSize, GLsizei* length, GLchar *groupString); + typedef void (GLAPIENTRY * PFNGLGETPERFMONITORGROUPSAMDPROC) (GLint* numGroups, GLsizei groupsSize, GLuint *groups); + typedef void (GLAPIENTRY * PFNGLSELECTPERFMONITORCOUNTERSAMDPROC) (GLuint monitor, GLboolean enable, GLuint group, GLint numCounters, GLuint* counterList); + + #define glBeginPerfMonitorAMD GLEGetCurrentFunction(glBeginPerfMonitorAMD) + #define glDeletePerfMonitorsAMD GLEGetCurrentFunction(glDeletePerfMonitorsAMD) + #define glEndPerfMonitorAMD GLEGetCurrentFunction(glEndPerfMonitorAMD) + #define glGenPerfMonitorsAMD GLEGetCurrentFunction(glGenPerfMonitorsAMD) + #define glGetPerfMonitorCounterDataAMD GLEGetCurrentFunction(glGetPerfMonitorCounterDataAMD) + #define glGetPerfMonitorCounterInfoAMD GLEGetCurrentFunction(glGetPerfMonitorCounterInfoAMD) + #define glGetPerfMonitorCounterStringAMD GLEGetCurrentFunction(glGetPerfMonitorCounterStringAMD) + #define glGetPerfMonitorCountersAMD GLEGetCurrentFunction(glGetPerfMonitorCountersAMD) + #define glGetPerfMonitorGroupStringAMD GLEGetCurrentFunction(glGetPerfMonitorGroupStringAMD) + #define glGetPerfMonitorGroupsAMD GLEGetCurrentFunction(glGetPerfMonitorGroupsAMD) + #define glSelectPerfMonitorCountersAMD GLEGetCurrentFunction(glSelectPerfMonitorCountersAMD) + + #define GLE_AMD_performance_monitor GLEGetCurrentVariable(gle_AMD_performance_monitor) + +#endif // GL_AMD_performance_monitor +*/ + + +#if defined(GLE_CGL_ENABLED) + #ifndef GL_APPLE_aux_depth_stencil + #define GL_APPLE_aux_depth_stencil 1 + + #define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14g + + #define GLE_APPLE_aux_depth_stencil GLEGetCurrentVariable(gle_APPLE_aux_depth_stencil) + #endif + + + + #ifndef GL_APPLE_client_storage + #define GL_APPLE_client_storage 1 + + #define GL_UNPACK_CLIENT_STORAGE_APPLE 0x85B2 + + #define GLE_APPLE_client_storage GLEGetCurrentVariable(gle_APPLE_client_storage) + #endif + + + + #ifndef GL_APPLE_element_array + #define GL_APPLE_element_array 1 + + #define GL_ELEMENT_ARRAY_APPLE 0x8A0C + #define GL_ELEMENT_ARRAY_TYPE_APPLE 0x8A0D + #define GL_ELEMENT_ARRAY_POINTER_APPLE 0x8A0E + + typedef void (GLAPIENTRY * PFNGLDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, GLint first, GLsizei count); + typedef void (GLAPIENTRY * PFNGLDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, GLint first, GLsizei count); + typedef void (GLAPIENTRY * PFNGLELEMENTPOINTERAPPLEPROC) (GLenum type, const void *pointer); + typedef void (GLAPIENTRY * PFNGLMULTIDRAWELEMENTARRAYAPPLEPROC) (GLenum mode, const GLint* first, const GLsizei *count, GLsizei primcount); + typedef void (GLAPIENTRY * PFNGLMULTIDRAWRANGEELEMENTARRAYAPPLEPROC) (GLenum mode, GLuint start, GLuint end, const GLint* first, const GLsizei *count, GLsizei primcount); + + #define glDrawElementArrayAPPLE GLEGetCurrentFunction(glDrawElementArrayAPPLE) + #define glDrawRangeElementArrayAPPLE GLEGetCurrentFunction(glDrawRangeElementArrayAPPLE) + #define glElementPointerAPPLE GLEGetCurrentFunction(glElementPointerAPPLE) + #define glMultiDrawElementArrayAPPLE GLEGetCurrentFunction(glMultiDrawElementArrayAPPLE) + #define glMultiDrawRangeElementArrayAPPLE GLEGetCurrentFunction(glMultiDrawRangeElementArrayAPPLE) + + #define GLE_APPLE_element_array GLEGetCurrentVariable(gle_APPLE_element_array) + #endif + + + + #ifndef GL_APPLE_fence + #define GL_APPLE_fence 1 + + #define GL_DRAW_PIXELS_APPLE 0x8A0A + #define GL_FENCE_APPLE 0x8A0B + + typedef void (GLAPIENTRY * PFNGLDELETEFENCESAPPLEPROC) (GLsizei n, const GLuint* fences); + typedef void (GLAPIENTRY * PFNGLFINISHFENCEAPPLEPROC) (GLuint fence); + typedef void (GLAPIENTRY * PFNGLFINISHOBJECTAPPLEPROC) (GLenum object, GLint name); + typedef void (GLAPIENTRY * PFNGLGENFENCESAPPLEPROC) (GLsizei n, GLuint* fences); + typedef GLboolean (GLAPIENTRY * PFNGLISFENCEAPPLEPROC) (GLuint fence); + typedef void (GLAPIENTRY * PFNGLSETFENCEAPPLEPROC) (GLuint fence); + typedef GLboolean (GLAPIENTRY * PFNGLTESTFENCEAPPLEPROC) (GLuint fence); + typedef GLboolean (GLAPIENTRY * PFNGLTESTOBJECTAPPLEPROC) (GLenum object, GLuint name); + + #define glDeleteFencesAPPLE GLEGetCurrentFunction(glDeleteFencesAPPLE) + #define glFinishFenceAPPLE GLEGetCurrentFunction(glFinishFenceAPPLE) + #define glFinishObjectAPPLE GLEGetCurrentFunction(glFinishObjectAPPLE) + #define glGenFencesAPPLE GLEGetCurrentFunction(glGenFencesAPPLE) + #define glIsFenceAPPLE GLEGetCurrentFunction(glIsFenceAPPLE) + #define glSetFenceAPPLE GLEGetCurrentFunction(glSetFenceAPPLE) + #define glTestFenceAPPLE GLEGetCurrentFunction(glTestFenceAPPLE) + #define glTestObjectAPPLE GLEGetCurrentFunction(glTestObjectAPPLE) + + #define GLE_APPLE_fence GLEGetCurrentVariable(gle_APPLE_fence) + + #endif + + + + #ifndef GL_APPLE_float_pixels + #define GL_APPLE_float_pixels 1 + + #define GL_HALF_APPLE 0x140B + #define GL_RGBA_FLOAT32_APPLE 0x8814 + #define GL_RGB_FLOAT32_APPLE 0x8815 + #define GL_ALPHA_FLOAT32_APPLE 0x8816 + #define GL_INTENSITY_FLOAT32_APPLE 0x8817 + #define GL_LUMINANCE_FLOAT32_APPLE 0x8818 + #define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819 + #define GL_RGBA_FLOAT16_APPLE 0x881A + #define GL_RGB_FLOAT16_APPLE 0x881B + #define GL_ALPHA_FLOAT16_APPLE 0x881C + #define GL_INTENSITY_FLOAT16_APPLE 0x881D + #define GL_LUMINANCE_FLOAT16_APPLE 0x881E + #define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F + #define GL_COLOR_FLOAT_APPLE 0x8A0F + + #define GLE_APPLE_float_pixels GLEGetCurrentVariable(gle_APPLE_float_pixels) + #endif + + + + #ifndef GL_APPLE_flush_buffer_range + #define GL_APPLE_flush_buffer_range 1 + + #define GL_BUFFER_SERIALIZED_MODIFY_APPLE 0x8A12 + #define GL_BUFFER_FLUSHING_UNMAP_APPLE 0x8A13 + + typedef void (GLAPIENTRY * PFNGLBUFFERPARAMETERIAPPLEPROC) (GLenum target, GLenum pname, GLint param); + typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC) (GLenum target, GLintptr offset, GLsizeiptr size); + + #define glBufferParameteriAPPLE GLEGetCurrentFunction(glBufferParameteriAPPLE) + #define glFlushMappedBufferRangeAPPLE GLEGetCurrentFunction(glFlushMappedBufferRangeAPPLE) + + #define GLE_APPLE_flush_buffer_range GLEGetCurrentVariable(gle_APPLE_flush_buffer_range) + #endif + + + + #ifndef GL_APPLE_object_purgeable + #define GL_APPLE_object_purgeable 1 + + #define GL_BUFFER_OBJECT_APPLE 0x85B3 + #define GL_RELEASED_APPLE 0x8A19 + #define GL_VOLATILE_APPLE 0x8A1A + #define GL_RETAINED_APPLE 0x8A1B + #define GL_UNDEFINED_APPLE 0x8A1C + #define GL_PURGEABLE_APPLE 0x8A1D + + typedef void (GLAPIENTRY * PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint* params); + typedef GLenum (GLAPIENTRY * PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); + typedef GLenum (GLAPIENTRY * PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option); + + #define glGetObjectParameterivAPPLE GLEGetCurrentFunction(glGetObjectParameterivAPPLE) + #define glObjectPurgeableAPPLE GLEGetCurrentFunction(glObjectPurgeableAPPLE) + #define glObjectUnpurgeableAPPLE GLEGetCurrentFunction(glObjectUnpurgeableAPPLE) + + #define GLE_APPLE_object_purgeable GLEGetCurrentVariable(gle_APPLE_object_purgeable) + #endif + + + + #ifndef GL_APPLE_pixel_buffer + #define GL_APPLE_pixel_buffer 1 + + #define GL_MIN_PBUFFER_VIEWPORT_DIMS_APPLE 0x8A10 + + #define GLE_APPLE_pixel_buffer GLEGetCurrentVariable(gle_APPLE_pixel_buffer) + #endif + + + + #ifndef GL_APPLE_rgb_422 + #define GL_APPLE_rgb_422 1 + + #define GL_UNSIGNED_SHORT_8_8_APPLE 0x85BA + #define GL_UNSIGNED_SHORT_8_8_REV_APPLE 0x85BB + #define GL_RGB_422_APPLE 0x8A1F + #define GL_RGB_RAW_422_APPLE 0x8A51 + + #define GLE_APPLE_rgb_422 GLEGetCurrentVariable(gle_APPLE_rgb_422) + #endif + + + + #ifndef GL_APPLE_row_bytes + #define GL_APPLE_row_bytes 1 + + #define GL_PACK_ROW_BYTES_APPLE 0x8A15 + #define GL_UNPACK_ROW_BYTES_APPLE 0x8A16 + + #define GLE_APPLE_row_bytes GLEGetCurrentVariable(gle_APPLE_row_bytes) + #endif + + + + #ifndef GL_APPLE_specular_vector + #define GL_APPLE_specular_vector 1 + + #define GL_LIGHT_MODEL_SPECULAR_VECTOR_APPLE 0x85B0 + + #define GLE_APPLE_specular_vector GLEGetCurrentVariable(gle_APPLE_specular_vector) + #endif + + + + #ifndef GL_APPLE_texture_range + #define GL_APPLE_texture_range 1 + + #define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7 + #define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8 + #define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC + #define GL_STORAGE_PRIVATE_APPLE 0x85BD + #define GL_STORAGE_CACHED_APPLE 0x85BE + #define GL_STORAGE_SHARED_APPLE 0x85BF + + typedef void (GLAPIENTRY * PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, void **params); + typedef void (GLAPIENTRY * PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const void *pointer); + + #define glGetTexParameterPointervAPPLE GLEGetCurrentFunction(glGetTexParameterPointervAPPLE) + #define glTextureRangeAPPLE GLEGetCurrentFunction(glTextureRangeAPPLE) + + #define GLE_APPLE_texture_range GLEGetCurrentVariable(gle_APPLE_texture_range) + #endif + + + #ifndef GL_APPLE_transform_hint + #define GL_APPLE_transform_hint 1 + + #define GL_TRANSFORM_HINT_APPLE 0x85B1 + + #define GLE_APPLE_transform_hint GLEGetCurrentVariable(gle_APPLE_transform_hint) + #endif + + + + #ifndef GL_APPLE_vertex_array_object + #define GL_APPLE_vertex_array_object 1 + + // This has been superceded by GL_ARB_vertex_array_object, though if you are using Apple + // OpenGL prior to 3.x then only this interface will be available. However, we have made + // it so that glBindVertexArray maps to glBindVertexArrayApple when only the latter is present, + // thus allowing you to write cleaner code. You can always just call glBindVertexArray instead + // of glBindVertexArrayAPPLE, etc. + #define GL_VERTEX_ARRAY_BINDING_APPLE 0x85B5 + + typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYAPPLEPROC) (GLuint array); + typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); + typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSAPPLEPROC) (GLsizei n, const GLuint* arrays); // It's not clear whether arrays needs to be const or not. + typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYAPPLEPROC) (GLuint array); + + #define glBindVertexArrayAPPLE GLEGetCurrentFunction(glBindVertexArrayAPPLE) + #define glDeleteVertexArraysAPPLE GLEGetCurrentFunction(glDeleteVertexArraysAPPLE) + #define glGenVertexArraysAPPLE GLEGetCurrentFunction(glGenVertexArraysAPPLE) + #define glIsVertexArrayAPPLE GLEGetCurrentFunction(glIsVertexArrayAPPLE) + + #define GLE_APPLE_vertex_array_object GLEGetCurrentVariable(gle_APPLE_vertex_array_object) + #endif + + + + #ifndef GL_APPLE_vertex_array_range + #define GL_APPLE_vertex_array_range 1 + + #define GL_VERTEX_ARRAY_RANGE_APPLE 0x851D + #define GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE 0x851E + #define GL_VERTEX_ARRAY_STORAGE_HINT_APPLE 0x851F + #define GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE 0x8520 + #define GL_VERTEX_ARRAY_RANGE_POINTER_APPLE 0x8521 + #define GL_STORAGE_CLIENT_APPLE 0x85B4 + #define GL_STORAGE_CACHED_APPLE 0x85BE + #define GL_STORAGE_SHARED_APPLE 0x85BF + + typedef void (GLAPIENTRY * PFNGLFLUSHVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYPARAMETERIAPPLEPROC) (GLenum pname, GLint param); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYRANGEAPPLEPROC) (GLsizei length, void *pointer); + + #define glFlushVertexArrayRangeAPPLE GLEGetCurrentFunction(glFlushVertexArrayRangeAPPLE) + #define glVertexArrayParameteriAPPLE GLEGetCurrentFunction(glVertexArrayParameteriAPPLE) + #define glVertexArrayRangeAPPLE GLEGetCurrentFunction(glVertexArrayRangeAPPLE) + + #define GLE_APPLE_vertex_array_range GLEGetCurrentVariable(gle_APPLE_vertex_array_range) + #endif + + + + #ifndef GL_APPLE_vertex_program_evaluators + #define GL_APPLE_vertex_program_evaluators 1 + + #define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00 + #define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01 + #define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02 + #define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03 + #define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04 + #define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05 + #define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06 + #define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07 + #define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08 + #define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09 + + typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); + typedef void (GLAPIENTRY * PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname); + typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname); + typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble* points); + typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat* points); + typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble* points); + typedef void (GLAPIENTRY * PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat* points); + + #define glDisableVertexAttribAPPLE GLEGetCurrentFunction(glDisableVertexAttribAPPLE) + #define glEnableVertexAttribAPPLE GLEGetCurrentFunction(glEnableVertexAttribAPPLE) + #define glIsVertexAttribEnabledAPPLE GLEGetCurrentFunction(glIsVertexAttribEnabledAPPLE) + #define glMapVertexAttrib1dAPPLE GLEGetCurrentFunction(glMapVertexAttrib1dAPPLE) + #define glMapVertexAttrib1fAPPLE GLEGetCurrentFunction(glMapVertexAttrib1fAPPLE) + #define glMapVertexAttrib2dAPPLE GLEGetCurrentFunction(glMapVertexAttrib2dAPPLE) + #define glMapVertexAttrib2fAPPLE GLEGetCurrentFunction(glMapVertexAttrib2fAPPLE) + + #define GLE_APPLE_vertex_program_evaluators GLEGetCurrentVariable(gle_APPLE_vertex_program_evaluators) + #endif + +#endif // GLE_CGL_ENABLED + + + +#ifndef GL_ARB_copy_buffer + #define GL_ARB_copy_buffer 1 + + #define GL_COPY_READ_BUFFER 0x8F36 + #define GL_COPY_WRITE_BUFFER 0x8F37 + + typedef void (GLAPIENTRY * PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size); + + #define glCopyBufferSubData GLEGetCurrentFunction(glCopyBufferSubData) + + #define GLE_ARB_copy_buffer GLEGetCurrentVariable(gle_ARB_copy_buffer) +#endif + + +#ifndef GL_ARB_debug_output + #define GL_ARB_debug_output 1 + + #define GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB 0x8242 + #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH_ARB 0x8243 + #define GL_DEBUG_CALLBACK_FUNCTION_ARB 0x8244 + #define GL_DEBUG_CALLBACK_USER_PARAM_ARB 0x8245 + #define GL_DEBUG_SOURCE_API_ARB 0x8246 + #define GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB 0x8247 + #define GL_DEBUG_SOURCE_SHADER_COMPILER_ARB 0x8248 + #define GL_DEBUG_SOURCE_THIRD_PARTY_ARB 0x8249 + #define GL_DEBUG_SOURCE_APPLICATION_ARB 0x824A + #define GL_DEBUG_SOURCE_OTHER_ARB 0x824B + #define GL_DEBUG_TYPE_ERROR_ARB 0x824C + #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB 0x824D + #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB 0x824E + #define GL_DEBUG_TYPE_PORTABILITY_ARB 0x824F + #define GL_DEBUG_TYPE_PERFORMANCE_ARB 0x8250 + #define GL_DEBUG_TYPE_OTHER_ARB 0x8251 + #define GL_MAX_DEBUG_MESSAGE_LENGTH_ARB 0x9143 + #define GL_MAX_DEBUG_LOGGED_MESSAGES_ARB 0x9144 + #define GL_DEBUG_LOGGED_MESSAGES_ARB 0x9145 + #define GL_DEBUG_SEVERITY_HIGH_ARB 0x9146 + #define GL_DEBUG_SEVERITY_MEDIUM_ARB 0x9147 + #define GL_DEBUG_SEVERITY_LOW_ARB 0x9148 + + typedef void (GLAPIENTRY *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); + + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKARBPROC) (GLDEBUGPROCARB callback, const void *userParam); + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLARBPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTARBPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); + typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGARBPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); + + #define glDebugMessageCallbackARB GLEGetCurrentFunction(glDebugMessageCallbackARB) + #define glDebugMessageControlARB GLEGetCurrentFunction(glDebugMessageControlARB) + #define glDebugMessageInsertARB GLEGetCurrentFunction(glDebugMessageInsertARB) + #define glGetDebugMessageLogARB GLEGetCurrentFunction(glGetDebugMessageLogARB) + + #define GLE_ARB_debug_output GLEGetCurrentVariable(gle_ARB_debug_output) + +#endif // GL_ARB_debug_output + + + +#ifndef GL_ARB_depth_buffer_float + #define GL_ARB_depth_buffer_float 1 + + // Supercededs GL_NV_depth_buffer_float + #define GL_DEPTH_COMPONENT32F 0x8CAC + #define GL_DEPTH32F_STENCIL8 0x8CAD + #define GL_FLOAT_32_UNSIGNED_INT_24_8_REV 0x8DAD + + #define GLE_ARB_depth_buffer_float GLEGetCurrentVariable(gle_ARB_depth_buffer_float) +#endif + + +/* Disabled until needed +#ifndef GL_ARB_direct_state_access + #define GL_ARB_direct_state_access 1 + + #define GL_TEXTURE_TARGET 0x1006 + #define GL_QUERY_TARGET 0x82EA + #define GL_TEXTURE_BINDING 0x82EB + + typedef void (GLAPIENTRY * PFNGLBINDTEXTUREUNITPROC) (GLuint unit, GLuint texture); + typedef void (GLAPIENTRY * PFNGLBLITNAMEDFRAMEBUFFERPROC) (GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + typedef GLenum (GLAPIENTRY * PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) (GLuint framebuffer, GLenum target); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERDATAPROC) (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) (GLuint framebuffer, GLenum buffer, GLfloat depth, GLint stencil); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat* value); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint* value); + typedef void (GLAPIENTRY * PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) (GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint* value); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + typedef void (GLAPIENTRY * PFNGLCOPYNAMEDBUFFERSUBDATAPROC) (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLCOPYTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLCREATEBUFFERSPROC) (GLsizei n, GLuint* buffers); + typedef void (GLAPIENTRY * PFNGLCREATEFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); + typedef void (GLAPIENTRY * PFNGLCREATEPROGRAMPIPELINESPROC) (GLsizei n, GLuint* pipelines); + typedef void (GLAPIENTRY * PFNGLCREATEQUERIESPROC) (GLenum target, GLsizei n, GLuint* ids); + typedef void (GLAPIENTRY * PFNGLCREATERENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); + typedef void (GLAPIENTRY * PFNGLCREATESAMPLERSPROC) (GLsizei n, GLuint* samplers); + typedef void (GLAPIENTRY * PFNGLCREATETEXTURESPROC) (GLenum target, GLsizei n, GLuint* textures); + typedef void (GLAPIENTRY * PFNGLCREATETRANSFORMFEEDBACKSPROC) (GLsizei n, GLuint* ids); + typedef void (GLAPIENTRY * PFNGLCREATEVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); + typedef void (GLAPIENTRY * PFNGLDISABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); + typedef void (GLAPIENTRY * PFNGLENABLEVERTEXARRAYATTRIBPROC) (GLuint vaobj, GLuint index); + typedef void (GLAPIENTRY * PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length); + typedef void (GLAPIENTRY * PFNGLGENERATETEXTUREMIPMAPPROC) (GLuint texture); + typedef void (GLAPIENTRY * PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLsizei bufSize, void *pixels); + typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) (GLuint buffer, GLenum pname, GLint64* params); + typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPARAMETERIVPROC) (GLuint buffer, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERPOINTERVPROC) (GLuint buffer, GLenum pname, void** params); + typedef void (GLAPIENTRY * PFNGLGETNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); + typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLuint framebuffer, GLenum attachment, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) (GLuint framebuffer, GLenum pname, GLint* param); + typedef void (GLAPIENTRY * PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) (GLuint renderbuffer, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREIMAGEPROC) (GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); + typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERFVPROC) (GLuint texture, GLint level, GLenum pname, GLfloat* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTURELEVELPARAMETERIVPROC) (GLuint texture, GLint level, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, GLuint* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, GLfloat* params); + typedef void (GLAPIENTRY * PFNGLGETTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI64_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint64* param); + typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKI_VPROC) (GLuint xfb, GLenum pname, GLuint index, GLint* param); + typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKIVPROC) (GLuint xfb, GLenum pname, GLint* param); + typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXED64IVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint64* param); + typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYINDEXEDIVPROC) (GLuint vaobj, GLuint index, GLenum pname, GLint* param); + typedef void (GLAPIENTRY * PFNGLGETVERTEXARRAYIVPROC) (GLuint vaobj, GLenum pname, GLint* param); + typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments); + typedef void (GLAPIENTRY * PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) (GLuint framebuffer, GLsizei numAttachments, const GLenum* attachments, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERPROC) (GLuint buffer, GLenum access); + typedef void * (GLAPIENTRY * PFNGLMAPNAMEDBUFFERRANGEPROC) (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); + typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERDATAPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); + typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSTORAGEPROC) (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); + typedef void (GLAPIENTRY * PFNGLNAMEDBUFFERSUBDATAPROC) (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) (GLuint framebuffer, GLenum mode); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) (GLuint framebuffer, GLsizei n, const GLenum* bufs); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) (GLuint framebuffer, GLenum pname, GLint param); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) (GLuint framebuffer, GLenum mode); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); + typedef void (GLAPIENTRY * PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) (GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); + typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEPROC) (GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERPROC) (GLuint texture, GLenum internalformat, GLuint buffer); + typedef void (GLAPIENTRY * PFNGLTEXTUREBUFFERRANGEPROC) (GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIIVPROC) (GLuint texture, GLenum pname, const GLint* params); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIUIVPROC) (GLuint texture, GLenum pname, const GLuint* params); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFPROC) (GLuint texture, GLenum pname, GLfloat param); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERFVPROC) (GLuint texture, GLenum pname, const GLfloat* param); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIPROC) (GLuint texture, GLenum pname, GLint param); + typedef void (GLAPIENTRY * PFNGLTEXTUREPARAMETERIVPROC) (GLuint texture, GLenum pname, const GLint* param); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE1DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DPROC) (GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + typedef void (GLAPIENTRY * PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) (GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE1DPROC) (GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); + typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE2DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); + typedef void (GLAPIENTRY * PFNGLTEXTURESUBIMAGE3DPROC) (GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) (GLuint xfb, GLuint index, GLuint buffer); + typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef GLboolean (GLAPIENTRY * PFNGLUNMAPNAMEDBUFFERPROC) (GLuint buffer); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBBINDINGPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBIFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYATTRIBLFORMATPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDINGDIVISORPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYELEMENTBUFFERPROC) (GLuint vaobj, GLuint buffer); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBUFFERSPROC) (GLuint vaobj, GLuint first, GLsizei count, const GLuint* buffers, const GLintptr *offsets, const GLsizei *strides); + + #define glBindTextureUnit GLEGetCurrentFunction(glBindTextureUnit) + #define glBlitNamedFramebuffer GLEGetCurrentFunction(glBlitNamedFramebuffer) + #define glCheckNamedFramebufferStatus GLEGetCurrentFunction(glCheckNamedFramebufferStatus) + #define glClearNamedBufferData GLEGetCurrentFunction(glClearNamedBufferData) + #define glClearNamedBufferSubData GLEGetCurrentFunction(glClearNamedBufferSubData) + #define glClearNamedFramebufferfi GLEGetCurrentFunction(glClearNamedFramebufferfi) + #define glClearNamedFramebufferfv GLEGetCurrentFunction(glClearNamedFramebufferfv) + #define glClearNamedFramebufferiv GLEGetCurrentFunction(glClearNamedFramebufferiv) + #define glClearNamedFramebufferuiv GLEGetCurrentFunction(glClearNamedFramebufferuiv) + #define glCompressedTextureSubImage1D GLEGetCurrentFunction(glCompressedTextureSubImage1D) + #define glCompressedTextureSubImage2D GLEGetCurrentFunction(glCompressedTextureSubImage2D) + #define glCompressedTextureSubImage3D GLEGetCurrentFunction(glCompressedTextureSubImage3D) + #define glCopyNamedBufferSubData GLEGetCurrentFunction(glCopyNamedBufferSubData) + #define glCopyTextureSubImage1D GLEGetCurrentFunction(glCopyTextureSubImage1D) + #define glCopyTextureSubImage2D GLEGetCurrentFunction(glCopyTextureSubImage2D) + #define glCopyTextureSubImage3D GLEGetCurrentFunction(glCopyTextureSubImage3D) + #define glCreateBuffers GLEGetCurrentFunction(glCreateBuffers) + #define glCreateFramebuffers GLEGetCurrentFunction(glCreateFramebuffers) + #define glCreateProgramPipelines GLEGetCurrentFunction(glCreateProgramPipelines) + #define glCreateQueries GLEGetCurrentFunction(glCreateQueries) + #define glCreateRenderbuffers GLEGetCurrentFunction(glCreateRenderbuffers) + #define glCreateSamplers GLEGetCurrentFunction(glCreateSamplers) + #define glCreateTextures GLEGetCurrentFunction(glCreateTextures) + #define glCreateTransformFeedbacks GLEGetCurrentFunction(glCreateTransformFeedbacks) + #define glCreateVertexArrays GLEGetCurrentFunction(glCreateVertexArrays) + #define glDisableVertexArrayAttrib GLEGetCurrentFunction(glDisableVertexArrayAttrib) + #define glEnableVertexArrayAttrib GLEGetCurrentFunction(glEnableVertexArrayAttrib) + #define glFlushMappedNamedBufferRange GLEGetCurrentFunction(glFlushMappedNamedBufferRange) + #define glGenerateTextureMipmap GLEGetCurrentFunction(glGenerateTextureMipmap) + #define glGetCompressedTextureImage GLEGetCurrentFunction(glGetCompressedTextureImage) + #define glGetNamedBufferParameteri64v GLEGetCurrentFunction(glGetNamedBufferParameteri64v) + #define glGetNamedBufferParameteriv GLEGetCurrentFunction(glGetNamedBufferParameteriv) + #define glGetNamedBufferPointerv GLEGetCurrentFunction(glGetNamedBufferPointerv) + #define glGetNamedBufferSubData GLEGetCurrentFunction(glGetNamedBufferSubData) + #define glGetNamedFramebufferAttachmentParameteriv GLEGetCurrentFunction(glGetNamedFramebufferAttachmentParameteriv) + #define glGetNamedFramebufferParameteriv GLEGetCurrentFunction(glGetNamedFramebufferParameteriv) + #define glGetNamedRenderbufferParameteriv GLEGetCurrentFunction(glGetNamedRenderbufferParameteriv) + #define glGetTextureImage GLEGetCurrentFunction(glGetTextureImage) + #define glGetTextureLevelParameterfv GLEGetCurrentFunction(glGetTextureLevelParameterfv) + #define glGetTextureLevelParameteriv GLEGetCurrentFunction(glGetTextureLevelParameteriv) + #define glGetTextureParameterIiv GLEGetCurrentFunction(glGetTextureParameterIiv) + #define glGetTextureParameterIuiv GLEGetCurrentFunction(glGetTextureParameterIuiv) + #define glGetTextureParameterfv GLEGetCurrentFunction(glGetTextureParameterfv) + #define glGetTextureParameteriv GLEGetCurrentFunction(glGetTextureParameteriv) + #define glGetTransformFeedbacki64_v GLEGetCurrentFunction(glGetTransformFeedbacki64_v) + #define glGetTransformFeedbacki_v GLEGetCurrentFunction(glGetTransformFeedbacki_v) + #define glGetTransformFeedbackiv GLEGetCurrentFunction(glGetTransformFeedbackiv) + #define glGetVertexArrayIndexed64iv GLEGetCurrentFunction(glGetVertexArrayIndexed64iv) + #define glGetVertexArrayIndexediv GLEGetCurrentFunction(glGetVertexArrayIndexediv) + #define glGetVertexArrayiv GLEGetCurrentFunction(glGetVertexArrayiv) + #define glInvalidateNamedFramebufferData GLEGetCurrentFunction(glInvalidateNamedFramebufferData) + #define glInvalidateNamedFramebufferSubData GLEGetCurrentFunction(glInvalidateNamedFramebufferSubData) + #define glMapNamedBuffer GLEGetCurrentFunction(glMapNamedBuffer) + #define glMapNamedBufferRange GLEGetCurrentFunction(glMapNamedBufferRange) + #define glNamedBufferData GLEGetCurrentFunction(glNamedBufferData) + #define glNamedBufferStorage GLEGetCurrentFunction(glNamedBufferStorage) + #define glNamedBufferSubData GLEGetCurrentFunction(glNamedBufferSubData) + #define glNamedFramebufferDrawBuffer GLEGetCurrentFunction(glNamedFramebufferDrawBuffer) + #define glNamedFramebufferDrawBuffers GLEGetCurrentFunction(glNamedFramebufferDrawBuffers) + #define glNamedFramebufferParameteri GLEGetCurrentFunction(glNamedFramebufferParameteri) + #define glNamedFramebufferReadBuffer GLEGetCurrentFunction(glNamedFramebufferReadBuffer) + #define glNamedFramebufferRenderbuffer GLEGetCurrentFunction(glNamedFramebufferRenderbuffer) + #define glNamedFramebufferTexture GLEGetCurrentFunction(glNamedFramebufferTexture) + #define glNamedFramebufferTextureLayer GLEGetCurrentFunction(glNamedFramebufferTextureLayer) + #define glNamedRenderbufferStorage GLEGetCurrentFunction(glNamedRenderbufferStorage) + #define glNamedRenderbufferStorageMultisample GLEGetCurrentFunction(glNamedRenderbufferStorageMultisample) + #define glTextureBuffer GLEGetCurrentFunction(glTextureBuffer) + #define glTextureBufferRange GLEGetCurrentFunction(glTextureBufferRange) + #define glTextureParameterIiv GLEGetCurrentFunction(glTextureParameterIiv) + #define glTextureParameterIuiv GLEGetCurrentFunction(glTextureParameterIuiv) + #define glTextureParameterf GLEGetCurrentFunction(glTextureParameterf) + #define glTextureParameterfv GLEGetCurrentFunction(glTextureParameterfv) + #define glTextureParameteri GLEGetCurrentFunction(glTextureParameteri) + #define glTextureParameteriv GLEGetCurrentFunction(glTextureParameteriv) + #define glTextureStorage1D GLEGetCurrentFunction(glTextureStorage1D) + #define glTextureStorage2D GLEGetCurrentFunction(glTextureStorage2D) + #define glTextureStorage2DMultisample GLEGetCurrentFunction(glTextureStorage2DMultisample) + #define glTextureStorage3D GLEGetCurrentFunction(glTextureStorage3D) + #define glTextureStorage3DMultisample GLEGetCurrentFunction(glTextureStorage3DMultisample) + #define glTextureSubImage1D GLEGetCurrentFunction(glTextureSubImage1D) + #define glTextureSubImage2D GLEGetCurrentFunction(glTextureSubImage2D) + #define glTextureSubImage3D GLEGetCurrentFunction(glTextureSubImage3D) + #define glTransformFeedbackBufferBase GLEGetCurrentFunction(glTransformFeedbackBufferBase) + #define glTransformFeedbackBufferRange GLEGetCurrentFunction(glTransformFeedbackBufferRange) + #define glUnmapNamedBuffer GLEGetCurrentFunction(glUnmapNamedBuffer) + #define glVertexArrayAttribBinding GLEGetCurrentFunction(glVertexArrayAttribBinding) + #define glVertexArrayAttribFormat GLEGetCurrentFunction(glVertexArrayAttribFormat) + #define glVertexArrayAttribIFormat GLEGetCurrentFunction(glVertexArrayAttribIFormat) + #define glVertexArrayAttribLFormat GLEGetCurrentFunction(glVertexArrayAttribLFormat) + #define glVertexArrayBindingDivisor GLEGetCurrentFunction(glVertexArrayBindingDivisor) + #define glVertexArrayElementBuffer GLEGetCurrentFunction(glVertexArrayElementBuffer) + #define glVertexArrayVertexBuffer GLEGetCurrentFunction(glVertexArrayVertexBuffer) + #define glVertexArrayVertexBuffers GLEGetCurrentFunction(glVertexArrayVertexBuffers) + + #define GLE_ARB_direct_state_access GLEGetCurrentVariable(gle_ARB_direct_state_access) +#endif // GL_ARB_direct_state_access */ + + + +#ifndef GL_ARB_ES2_compatibility + #define GL_ARB_ES2_compatibility 1 + + // This is for OpenGL ES compatibility. + #define GL_FIXED 0x140C + #define GL_IMPLEMENTATION_COLOR_READ_TYPE 0x8B9A + #define GL_IMPLEMENTATION_COLOR_READ_FORMAT 0x8B9B + #define GL_RGB565 0x8D62 + #define GL_LOW_FLOAT 0x8DF0 + #define GL_MEDIUM_FLOAT 0x8DF1 + #define GL_HIGH_FLOAT 0x8DF2 + #define GL_LOW_INT 0x8DF3 + #define GL_MEDIUM_INT 0x8DF4 + #define GL_HIGH_INT 0x8DF5 + #define GL_SHADER_BINARY_FORMATS 0x8DF8 + #define GL_NUM_SHADER_BINARY_FORMATS 0x8DF9 + #define GL_SHADER_COMPILER 0x8DFA + #define GL_MAX_VERTEX_UNIFORM_VECTORS 0x8DFB + #define GL_MAX_VARYING_VECTORS 0x8DFC + #define GL_MAX_FRAGMENT_UNIFORM_VECTORS 0x8DFD + + typedef int GLfixed; + + typedef void (GLAPIENTRY * PFNGLCLEARDEPTHFPROC) (GLclampf d); + typedef void (GLAPIENTRY * PFNGLDEPTHRANGEFPROC) (GLclampf n, GLclampf f); + typedef void (GLAPIENTRY * PFNGLGETSHADERPRECISIONFORMATPROC) (GLenum shadertype, GLenum precisiontype, GLint* range, GLint *precision); + typedef void (GLAPIENTRY * PFNGLRELEASESHADERCOMPILERPROC) (void); + typedef void (GLAPIENTRY * PFNGLSHADERBINARYPROC) (GLsizei count, const GLuint* shaders, GLenum binaryformat, const void*binary, GLsizei length); + + #define glClearDepthf GLEGetCurrentFunction(glClearDepthf) + #define glDepthRangef GLEGetCurrentFunction(glDepthRangef) + #define glGetShaderPrecisionFormat GLEGetCurrentFunction(glGetShaderPrecisionFormat) + #define glReleaseShaderCompiler GLEGetCurrentFunction(glReleaseShaderCompiler) + #define glShaderBinary GLEGetCurrentFunction(glShaderBinary) + + #define GLE_ARB_ES2_compatibility GLEGetCurrentVariable(gle_ARB_ES2_compatibility) +#endif + + + +#ifndef GL_ARB_framebuffer_object + #define GL_ARB_framebuffer_object 1 + + // GL_ARB_framebuffer_object is part of the OpenGL 4.4 core profile. + #define GL_INVALID_FRAMEBUFFER_OPERATION 0x0506 + #define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 + #define GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE 0x8211 + #define GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE 0x8212 + #define GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE 0x8213 + #define GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE 0x8214 + #define GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE 0x8215 + #define GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE 0x8216 + #define GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE 0x8217 + #define GL_FRAMEBUFFER_DEFAULT 0x8218 + #define GL_FRAMEBUFFER_UNDEFINED 0x8219 + #define GL_DEPTH_STENCIL_ATTACHMENT 0x821A + #define GL_INDEX 0x8222 + #define GL_MAX_RENDERBUFFER_SIZE 0x84E8 + #define GL_DEPTH_STENCIL 0x84F9 + #define GL_UNSIGNED_INT_24_8 0x84FA + #define GL_DEPTH24_STENCIL8 0x88F0 + #define GL_TEXTURE_STENCIL_SIZE 0x88F1 + #define GL_UNSIGNED_NORMALIZED 0x8C17 + #define GL_SRGB 0x8C40 + #define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6 + #define GL_FRAMEBUFFER_BINDING 0x8CA6 + #define GL_RENDERBUFFER_BINDING 0x8CA7 + #define GL_READ_FRAMEBUFFER 0x8CA8 + #define GL_DRAW_FRAMEBUFFER 0x8CA9 + #define GL_READ_FRAMEBUFFER_BINDING 0x8CAA + #define GL_RENDERBUFFER_SAMPLES 0x8CAB + #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE 0x8CD0 + #define GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME 0x8CD1 + #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL 0x8CD2 + #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE 0x8CD3 + #define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER 0x8CD4 + #define GL_FRAMEBUFFER_COMPLETE 0x8CD5 + #define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 + #define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 + #define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB + #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC + #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + #define GL_MAX_COLOR_ATTACHMENTS 0x8CDF + #define GL_COLOR_ATTACHMENT0 0x8CE0 + #define GL_COLOR_ATTACHMENT1 0x8CE1 + #define GL_COLOR_ATTACHMENT2 0x8CE2 + #define GL_COLOR_ATTACHMENT3 0x8CE3 + #define GL_COLOR_ATTACHMENT4 0x8CE4 + #define GL_COLOR_ATTACHMENT5 0x8CE5 + #define GL_COLOR_ATTACHMENT6 0x8CE6 + #define GL_COLOR_ATTACHMENT7 0x8CE7 + #define GL_COLOR_ATTACHMENT8 0x8CE8 + #define GL_COLOR_ATTACHMENT9 0x8CE9 + #define GL_COLOR_ATTACHMENT10 0x8CEA + #define GL_COLOR_ATTACHMENT11 0x8CEB + #define GL_COLOR_ATTACHMENT12 0x8CEC + #define GL_COLOR_ATTACHMENT13 0x8CED + #define GL_COLOR_ATTACHMENT14 0x8CEE + #define GL_COLOR_ATTACHMENT15 0x8CEF + #define GL_DEPTH_ATTACHMENT 0x8D00 + #define GL_STENCIL_ATTACHMENT 0x8D20 + #define GL_FRAMEBUFFER 0x8D40 + #define GL_RENDERBUFFER 0x8D41 + #define GL_RENDERBUFFER_WIDTH 0x8D42 + #define GL_RENDERBUFFER_HEIGHT 0x8D43 + #define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 + #define GL_STENCIL_INDEX1 0x8D46 + #define GL_STENCIL_INDEX4 0x8D47 + #define GL_STENCIL_INDEX8 0x8D48 + #define GL_STENCIL_INDEX16 0x8D49 + #define GL_RENDERBUFFER_RED_SIZE 0x8D50 + #define GL_RENDERBUFFER_GREEN_SIZE 0x8D51 + #define GL_RENDERBUFFER_BLUE_SIZE 0x8D52 + #define GL_RENDERBUFFER_ALPHA_SIZE 0x8D53 + #define GL_RENDERBUFFER_DEPTH_SIZE 0x8D54 + #define GL_RENDERBUFFER_STENCIL_SIZE 0x8D55 + #define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56 + #define GL_MAX_SAMPLES 0x8D57 + + typedef void (GLAPIENTRY * PFNGLBINDFRAMEBUFFERPROC) (GLenum target, GLuint framebuffer); + typedef void (GLAPIENTRY * PFNGLBINDRENDERBUFFERPROC) (GLenum target, GLuint renderbuffer); + typedef void (GLAPIENTRY * PFNGLBLITFRAMEBUFFERPROC) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + typedef GLenum (GLAPIENTRY * PFNGLCHECKFRAMEBUFFERSTATUSPROC) (GLenum target); + typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERSPROC) (GLsizei n, const GLuint* framebuffers); + typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERSPROC) (GLsizei n, const GLuint* renderbuffers); + typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERRENDERBUFFERPROC) (GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE1DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE2DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURE3DPROC) (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); + typedef void (GLAPIENTRY * PFNGLFRAMEBUFFERTEXTURELAYERPROC) (GLenum target,GLenum attachment, GLuint texture,GLint level,GLint layer); + typedef void (GLAPIENTRY * PFNGLGENFRAMEBUFFERSPROC) (GLsizei n, GLuint* framebuffers); + typedef void (GLAPIENTRY * PFNGLGENRENDERBUFFERSPROC) (GLsizei n, GLuint* renderbuffers); + typedef void (GLAPIENTRY * PFNGLGENERATEMIPMAPPROC) (GLenum target); + typedef void (GLAPIENTRY * PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) (GLenum target, GLenum attachment, GLenum pname, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETRENDERBUFFERPARAMETERIVPROC) (GLenum target, GLenum pname, GLint* params); + typedef GLboolean (GLAPIENTRY * PFNGLISFRAMEBUFFERPROC) (GLuint framebuffer); + typedef GLboolean (GLAPIENTRY * PFNGLISRENDERBUFFERPROC) (GLuint renderbuffer); + typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEPROC) (GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + typedef void (GLAPIENTRY * PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + + #define glBindFramebuffer GLEGetCurrentFunction(glBindFramebuffer) + #define glBindRenderbuffer GLEGetCurrentFunction(glBindRenderbuffer) + #define glBlitFramebuffer GLEGetCurrentFunction(glBlitFramebuffer) + #define glCheckFramebufferStatus GLEGetCurrentFunction(glCheckFramebufferStatus) + #define glDeleteFramebuffers GLEGetCurrentFunction(glDeleteFramebuffers) + #define glDeleteRenderbuffers GLEGetCurrentFunction(glDeleteRenderbuffers) + #define glFramebufferRenderbuffer GLEGetCurrentFunction(glFramebufferRenderbuffer) + #define glFramebufferTexture1D GLEGetCurrentFunction(glFramebufferTexture1D) + #define glFramebufferTexture2D GLEGetCurrentFunction(glFramebufferTexture2D) + #define glFramebufferTexture3D GLEGetCurrentFunction(glFramebufferTexture3D) + #define glFramebufferTextureLayer GLEGetCurrentFunction(glFramebufferTextureLayer) + #define glGenFramebuffers GLEGetCurrentFunction(glGenFramebuffers) + #define glGenRenderbuffers GLEGetCurrentFunction(glGenRenderbuffers) + #define glGenerateMipmap GLEGetCurrentFunction(glGenerateMipmap) + #define glGetFramebufferAttachmentParameteriv GLEGetCurrentFunction(glGetFramebufferAttachmentParameteriv) + #define glGetRenderbufferParameteriv GLEGetCurrentFunction(glGetRenderbufferParameteriv) + #define glIsFramebuffer GLEGetCurrentFunction(glIsFramebuffer) + #define glIsRenderbuffer GLEGetCurrentFunction(glIsRenderbuffer) + #define glRenderbufferStorage GLEGetCurrentFunction(glRenderbufferStorage) + #define glRenderbufferStorageMultisample GLEGetCurrentFunction(glRenderbufferStorageMultisample) + + #define GLE_ARB_framebuffer_object GLEGetCurrentVariable(gle_ARB_framebuffer_object) + +#endif // GL_ARB_framebuffer_object + + + +#ifndef GL_ARB_framebuffer_sRGB + #define GL_ARB_framebuffer_sRGB 1 + + // GL_ARB_framebuffer_sRGB is part of the OpenGL 4.4 core profile. + #define GL_FRAMEBUFFER_SRGB 0x8DB9 + + #define GLE_ARB_framebuffer_sRGB GLEGetCurrentVariable(gle_ARB_framebuffer_sRGB) +#endif + + + +#ifndef GL_ARB_texture_multisample + #define GL_ARB_texture_multisample 1 + + #define GL_SAMPLE_POSITION 0x8E50 + #define GL_SAMPLE_MASK 0x8E51 + #define GL_SAMPLE_MASK_VALUE 0x8E52 + #define GL_MAX_SAMPLE_MASK_WORDS 0x8E59 + #define GL_TEXTURE_2D_MULTISAMPLE 0x9100 + #define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101 + #define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102 + #define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103 + #define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104 + #define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105 + #define GL_TEXTURE_SAMPLES 0x9106 + #define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107 + #define GL_SAMPLER_2D_MULTISAMPLE 0x9108 + #define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109 + #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A + #define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B + #define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C + #define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D + #define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E + #define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F + #define GL_MAX_INTEGER_SAMPLES 0x9110 + + typedef void (GLAPIENTRY * PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat* val); + typedef void (GLAPIENTRY * PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask); + typedef void (GLAPIENTRY * PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + typedef void (GLAPIENTRY * PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + + #define glGetMultisamplefv GLEGetCurrentFunction(glGetMultisamplefv) + #define glSampleMaski GLEGetCurrentFunction(glSampleMaski) + #define glTexImage2DMultisample GLEGetCurrentFunction(glTexImage2DMultisample) + #define glTexImage3DMultisample GLEGetCurrentFunction(glTexImage3DMultisample) + + #define GLE_ARB_texture_multisample GLEGetCurrentVariable(gle_ARB_texture_multisample) + +#endif // GL_ARB_texture_multisample + + + +#ifndef GL_ARB_texture_non_power_of_two + #define GL_ARB_texture_non_power_of_two 1 + + #define GLE_ARB_texture_non_power_of_two GLEGetCurrentVariable(gle_ARB_texture_non_power_of_two) +#endif + + + +#ifndef GL_ARB_texture_rectangle + #define GL_ARB_texture_rectangle 1 + + // texture_rectangle was added to the OpenGL 3.1 core profile and so this extension is not needed + // unless using an earlier version of OpenGL. + // There are also the GL_EXT_texture_rectangle and GL_NV_texture_rectangle extensions. Apple reports + // the preseence of GL_EXT_texture_rectangle but not GL_ARB_texture_rectangle or GL_NV_texture_rectangle. + // You should check for GL_ARB_texture_rectangle instead of these other two. + #define GL_TEXTURE_RECTANGLE_ARB 0x84F5 + #define GL_TEXTURE_BINDING_RECTANGLE_ARB 0x84F6 + #define GL_PROXY_TEXTURE_RECTANGLE_ARB 0x84F7 + #define GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB 0x84F8 + #define GL_SAMPLER_2D_RECT_ARB 0x8B63 + #define GL_SAMPLER_2D_RECT_SHADOW_ARB 0x8B64 + + #define GLE_ARB_texture_rectangle GLEGetCurrentVariable(gle_ARB_texture_rectangle) +#endif + + + +#ifndef GL_ARB_timer_query + #define GL_ARB_timer_query 1 + + #define GL_TIME_ELAPSED 0x88BF + #define GL_TIMESTAMP 0x8E28 + + typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTI64VPROC) (GLuint id, GLenum pname, GLint64* params); + typedef void (GLAPIENTRY * PFNGLGETQUERYOBJECTUI64VPROC) (GLuint id, GLenum pname, GLuint64* params); + typedef void (GLAPIENTRY * PFNGLQUERYCOUNTERPROC) (GLuint id, GLenum target); + + #define glGetQueryObjecti64v GLEGetCurrentFunction(glGetQueryObjecti64v) + #define glGetQueryObjectui64v GLEGetCurrentFunction(glGetQueryObjectui64v) + #define glQueryCounter GLEGetCurrentFunction(glQueryCounter) + + #define GLE_ARB_timer_query GLEGetCurrentVariable(gle_ARB_timer_query) +#endif + + + +#ifndef GL_ARB_vertex_array_object + #define GL_ARB_vertex_array_object 1 + + #define GL_VERTEX_ARRAY_BINDING 0x85B5 + + typedef void (GLAPIENTRY * PFNGLBINDVERTEXARRAYPROC) (GLuint array); + typedef void (GLAPIENTRY * PFNGLDELETEVERTEXARRAYSPROC) (GLsizei n, const GLuint* arrays); + typedef void (GLAPIENTRY * PFNGLGENVERTEXARRAYSPROC) (GLsizei n, GLuint* arrays); + typedef GLboolean (GLAPIENTRY * PFNGLISVERTEXARRAYPROC) (GLuint array); + + #define glBindVertexArray GLEGetCurrentFunction(glBindVertexArray) + #define glDeleteVertexArrays GLEGetCurrentFunction(glDeleteVertexArrays) + #define glGenVertexArrays GLEGetCurrentFunction(glGenVertexArrays) + #define glIsVertexArray GLEGetCurrentFunction(glIsVertexArray) + + #define GLE_ARB_vertex_array_object GLEGetCurrentVariable(gle_ARB_vertex_array_object) +#endif + + + +/* Disabled until needed +#ifndef GL_ARB_vertex_attrib_binding + #define GL_ARB_vertex_attrib_binding 1 + + #define GL_VERTEX_ATTRIB_BINDING 0x82D4 + #define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5 + #define GL_VERTEX_BINDING_DIVISOR 0x82D6 + #define GL_VERTEX_BINDING_OFFSET 0x82D7 + #define GL_VERTEX_BINDING_STRIDE 0x82D8 + #define GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D9 + #define GL_MAX_VERTEX_ATTRIB_BINDINGS 0x82DA + #define GL_VERTEX_BINDING_BUFFER 0x8F4F + + typedef void (GLAPIENTRY * PFNGLBINDVERTEXBUFFERPROC) (GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYBINDVERTEXBUFFEREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBBINDINGEXTPROC) (GLuint vaobj, GLuint attribindex, GLuint bindingindex); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBIFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXATTRIBLFORMATEXTPROC) (GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXARRAYVERTEXBINDINGDIVISOREXTPROC) (GLuint vaobj, GLuint bindingindex, GLuint divisor); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBBINDINGPROC) (GLuint attribindex, GLuint bindingindex); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBIFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBLFORMATPROC) (GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void (GLAPIENTRY * PFNGLVERTEXBINDINGDIVISORPROC) (GLuint bindingindex, GLuint divisor); + + #define glBindVertexBuffer GLEGetCurrentFunction(glBindVertexBuffer) + #define glVertexArrayBindVertexBufferEXT GLEGetCurrentFunction(glVertexArrayBindVertexBufferEXT) + #define glVertexArrayVertexAttribBindingEXT GLEGetCurrentFunction(glVertexArrayVertexAttribBindingEXT) + #define glVertexArrayVertexAttribFormatEXT GLEGetCurrentFunction(glVertexArrayVertexAttribFormatEXT) + #define glVertexArrayVertexAttribIFormatEXT GLEGetCurrentFunction(glVertexArrayVertexAttribIFormatEXT) + #define glVertexArrayVertexAttribLFormatEXT GLEGetCurrentFunction(glVertexArrayVertexAttribLFormatEXT) + #define glVertexArrayVertexBindingDivisorEXT GLEGetCurrentFunction(glVertexArrayVertexBindingDivisorEXT) + #define glVertexAttribBinding GLEGetCurrentFunction(glVertexAttribBinding) + #define glVertexAttribFormat GLEGetCurrentFunction(glVertexAttribFormat) + #define glVertexAttribIFormat GLEGetCurrentFunction(glVertexAttribIFormat) + #define glVertexAttribLFormat GLEGetCurrentFunction(glVertexAttribLFormat) + #define glVertexBindingDivisor GLEGetCurrentFunction(glVertexBindingDivisor) + + #define GLE_ARB_vertex_attrib_binding GLEGetCurrentVariable(gle_ARB_vertex_attrib_binding) +#endif +*/ + + +#ifndef GL_EXT_draw_buffers2 + #define GL_EXT_draw_buffers2 1 + + typedef void (GLAPIENTRY * PFNGLCOLORMASKINDEXEDEXTPROC) (GLuint buf, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + typedef void (GLAPIENTRY * PFNGLDISABLEINDEXEDEXTPROC) (GLenum target, GLuint index); + typedef void (GLAPIENTRY * PFNGLENABLEINDEXEDEXTPROC) (GLenum target, GLuint index); + typedef void (GLAPIENTRY * PFNGLGETBOOLEANINDEXEDVEXTPROC) (GLenum value, GLuint index, GLboolean* data); + typedef void (GLAPIENTRY * PFNGLGETINTEGERINDEXEDVEXTPROC) (GLenum value, GLuint index, GLint* data); + typedef GLboolean (GLAPIENTRY * PFNGLISENABLEDINDEXEDEXTPROC) (GLenum target, GLuint index); + + #define glColorMaskIndexedEXT GLEGetCurrentFunction(glColorMaskIndexedEXT) + #define glDisableIndexedEXT GLEGetCurrentFunction(glDisableIndexedEXT) + #define glEnableIndexedEXT GLEGetCurrentFunction(glEnableIndexedEXT) + #define glGetBooleanIndexedvEXT GLEGetCurrentFunction(glGetBooleanIndexedvEXT) + #define glGetIntegerIndexedvEXT GLEGetCurrentFunction(glGetIntegerIndexedvEXT) + #define glIsEnabledIndexedEXT GLEGetCurrentFunction(glIsEnabledIndexedEXT) + + #define GLE_EXT_draw_buffers2 GLEGetCurrentVariable(gle_EXT_draw_buffers2) +#endif + + + +#ifndef GL_EXT_texture_compression_s3tc + #define GL_EXT_texture_compression_s3tc 1 + + #define GL_COMPRESSED_RGB_S3TC_DXT1_EXT 0x83F0 + #define GL_COMPRESSED_RGBA_S3TC_DXT1_EXT 0x83F1 + #define GL_COMPRESSED_RGBA_S3TC_DXT3_EXT 0x83F2 + #define GL_COMPRESSED_RGBA_S3TC_DXT5_EXT 0x83F3 + + #define GLE_EXT_texture_compression_s3tc GLEGetCurrentVariable(gle_EXT_texture_compression_s3tc) +#endif + + + +#ifndef GL_EXT_texture_filter_anisotropic + #define GL_EXT_texture_filter_anisotropic 1 + + #define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE + #define GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT 0x84FF + + #define GLE_EXT_texture_filter_anisotropic GLEGetCurrentVariable(gle_EXT_texture_filter_anisotropic) +#endif + + + +/* Disabled until needed +#ifndef GL_KHR_context_flush_control + #define GL_KHR_context_flush_control 1 + + #define GLE_KHR_context_flush_control GLEGetCurrentVariable(gle_KHR_context_flush_control) +#endif +*/ + + + +#ifndef GL_KHR_debug + #define GL_KHR_debug 1 + + #define GL_CONTEXT_FLAG_DEBUG_BIT 0x00000002 + #define GL_STACK_OVERFLOW 0x0503 + #define GL_STACK_UNDERFLOW 0x0504 + #define GL_DEBUG_OUTPUT_SYNCHRONOUS 0x8242 + #define GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH 0x8243 + #define GL_DEBUG_CALLBACK_FUNCTION 0x8244 + #define GL_DEBUG_CALLBACK_USER_PARAM 0x8245 + #define GL_DEBUG_SOURCE_API 0x8246 + #define GL_DEBUG_SOURCE_WINDOW_SYSTEM 0x8247 + #define GL_DEBUG_SOURCE_SHADER_COMPILER 0x8248 + #define GL_DEBUG_SOURCE_THIRD_PARTY 0x8249 + #define GL_DEBUG_SOURCE_APPLICATION 0x824A + #define GL_DEBUG_SOURCE_OTHER 0x824B + #define GL_DEBUG_TYPE_ERROR 0x824C + #define GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR 0x824D + #define GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR 0x824E + #define GL_DEBUG_TYPE_PORTABILITY 0x824F + #define GL_DEBUG_TYPE_PERFORMANCE 0x8250 + #define GL_DEBUG_TYPE_OTHER 0x8251 + #define GL_DEBUG_TYPE_MARKER 0x8268 + #define GL_DEBUG_TYPE_PUSH_GROUP 0x8269 + #define GL_DEBUG_TYPE_POP_GROUP 0x826A + #define GL_DEBUG_SEVERITY_NOTIFICATION 0x826B + #define GL_MAX_DEBUG_GROUP_STACK_DEPTH 0x826C + #define GL_DEBUG_GROUP_STACK_DEPTH 0x826D + #define GL_BUFFER 0x82E0 + #define GL_SHADER 0x82E1 + #define GL_PROGRAM 0x82E2 + #define GL_QUERY 0x82E3 + #define GL_PROGRAM_PIPELINE 0x82E4 + #define GL_SAMPLER 0x82E6 + #define GL_DISPLAY_LIST 0x82E7 + #define GL_MAX_LABEL_LENGTH 0x82E8 + #define GL_MAX_DEBUG_MESSAGE_LENGTH 0x9143 + #define GL_MAX_DEBUG_LOGGED_MESSAGES 0x9144 + #define GL_DEBUG_LOGGED_MESSAGES 0x9145 + #define GL_DEBUG_SEVERITY_HIGH 0x9146 + #define GL_DEBUG_SEVERITY_MEDIUM 0x9147 + #define GL_DEBUG_SEVERITY_LOW 0x9148 + #define GL_DEBUG_OUTPUT 0x92E0 + + typedef void (GLAPIENTRY *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* userParam); + + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECALLBACKPROC) (GLDEBUGPROC callback, const void *userParam); + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGECONTROLPROC) (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint* ids, GLboolean enabled); + typedef void (GLAPIENTRY * PFNGLDEBUGMESSAGEINSERTPROC) (GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* buf); + typedef GLuint (GLAPIENTRY * PFNGLGETDEBUGMESSAGELOGPROC) (GLuint count, GLsizei bufSize, GLenum* sources, GLenum* types, GLuint* ids, GLenum* severities, GLsizei* lengths, GLchar* messageLog); + typedef void (GLAPIENTRY * PFNGLGETOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei bufSize, GLsizei* length, GLchar *label); + typedef void (GLAPIENTRY * PFNGLGETOBJECTPTRLABELPROC) (const void *ptr, GLsizei bufSize, GLsizei* length, GLchar *label); + typedef void (GLAPIENTRY * PFNGLOBJECTLABELPROC) (GLenum identifier, GLuint name, GLsizei length, const GLchar* label); + typedef void (GLAPIENTRY * PFNGLOBJECTPTRLABELPROC) (const void *ptr, GLsizei length, const GLchar* label); + typedef void (GLAPIENTRY * PFNGLPOPDEBUGGROUPPROC) (void); + typedef void (GLAPIENTRY * PFNGLPUSHDEBUGGROUPPROC) (GLenum source, GLuint id, GLsizei length, const GLchar * message); + + #define glDebugMessageCallback GLEGetCurrentFunction(glDebugMessageCallback) + #define glDebugMessageControl GLEGetCurrentFunction(glDebugMessageControl) + #define glDebugMessageInsert GLEGetCurrentFunction(glDebugMessageInsert) + #define glGetDebugMessageLog GLEGetCurrentFunction(glGetDebugMessageLog) + #define glGetObjectLabel GLEGetCurrentFunction(glGetObjectLabel) + #define glGetObjectPtrLabel GLEGetCurrentFunction(glGetObjectPtrLabel) + #define glObjectLabel GLEGetCurrentFunction(glObjectLabel) + #define glObjectPtrLabel GLEGetCurrentFunction(glObjectPtrLabel) + #define glPopDebugGroup GLEGetCurrentFunction(glPopDebugGroup) + #define glPushDebugGroup GLEGetCurrentFunction(glPushDebugGroup) + + #define GLE_KHR_debug GLEGetCurrentVariable(gle_KHR_debug) +#endif // GL_KHR_debug + + + +#ifndef GL_KHR_robust_buffer_access_behavior + #define GL_KHR_robust_buffer_access_behavior 1 + + #define GLE_KHR_robust_buffer_access_behavior GLEGetCurrentVariable(gle_KHR_robust_buffer_access_behavior) +#endif + + + +/* Disabled until needed +#ifndef GL_KHR_robustness + #define GL_KHR_robustness 1 + + #define GL_CONTEXT_LOST 0x0507 + #define GL_LOSE_CONTEXT_ON_RESET 0x8252 + #define GL_GUILTY_CONTEXT_RESET 0x8253 + #define GL_INNOCENT_CONTEXT_RESET 0x8254 + #define GL_UNKNOWN_CONTEXT_RESET 0x8255 + #define GL_RESET_NOTIFICATION_STRATEGY 0x8256 + #define GL_NO_RESET_NOTIFICATION 0x8261 + #define GL_CONTEXT_ROBUST_ACCESS 0x90F3 + + typedef void (GLAPIENTRY * PFNGLGETNUNIFORMFVPROC) (GLuint program, GLint location, GLsizei bufSize, GLfloat* params); + typedef void (GLAPIENTRY * PFNGLGETNUNIFORMIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLint* params); + typedef void (GLAPIENTRY * PFNGLGETNUNIFORMUIVPROC) (GLuint program, GLint location, GLsizei bufSize, GLuint* params); + typedef void (GLAPIENTRY * PFNGLREADNPIXELSPROC) (GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); + + #define glGetnUniformfv GLEGetCurrentFunction(glGetnUniformfv) + #define glGetnUniformiv GLEGetCurrentFunction(glGetnUniformiv) + #define glGetnUniformuiv GLEGetCurrentFunction(glGetnUniformuiv) + #define glReadnPixels GLEGetCurrentFunction(glReadnPixels) + + #define GLE_KHR_robustness GLEGetCurrentVariable(gle_KHR_robustness) + +#endif // GL_KHR_robustness +*/ + + + +#ifndef GL_WIN_swap_hint + #define GL_WIN_swap_hint 1 + + typedef void (GLAPIENTRY * PFNGLADDSWAPHINTRECTWINPROC) (GLint x, GLint y, GLsizei width, GLsizei height); + + #define glAddSwapHintRectWIN GLEGetCurrentFunction(glAddSwapHintRectWIN) + + #define GLE_WIN_swap_hint GLEGetCurrentVariable(gle_WIN_swap_hint) +#endif + + + +/************************************************************************************ + Windows-specific (WGL) functionality +************************************************************************************/ + +#if defined(GLE_WGL_ENABLED) + #ifdef __wglext_h_ + #error wglext.h was included before this header. This header needs to be inlcuded instead of or at least before wglext.h + #endif + #define __wglext_h_ // Prevent wglext.h from having any future effect if it's #included. + + // Declare shared types and structs from wglext.h + DECLARE_HANDLE(HPBUFFERARB); // This type is used by a couple extensions. + + // WGL functions from + #if 0 // defined(GLE_HOOKING_ENABLED) We currently don't hook these. + #define wglCopyContext(...) GLEGetCurrentFunction(wglCopyContext)(__VA_ARGS__) + #define wglCreateContext(...) GLEGetCurrentFunction(wglCreateContext)(__VA_ARGS__) + #define wglCreateLayerContext(...) GLEGetCurrentFunction(wglCreateLayerContext)(__VA_ARGS__) + #define wglDeleteContext(...) GLEGetCurrentFunction(wglDeleteContext)(__VA_ARGS__) + #define wglGetCurrentContext(...) GLEGetCurrentFunction(wglGetCurrentContext)(__VA_ARGS__) + #define wglGetCurrentDC(...) GLEGetCurrentFunction(wglGetCurrentDC)(__VA_ARGS__) + #define wglGetProcAddress(...) GLEGetCurrentFunction(wglGetProcAddress)(__VA_ARGS__) + #define wglMakeCurrent(...) GLEGetCurrentFunction(wglMakeCurrent)(__VA_ARGS__) + #define wglShareLists(...) GLEGetCurrentFunction(wglShareLists)(__VA_ARGS__) + #define wglUseFontBitmapsA(...) GLEGetCurrentFunction(wglUseFontBitmapsA)(__VA_ARGS__) + #define wglUseFontBitmapsW(...) GLEGetCurrentFunction(wglUseFontBitmapsW)(__VA_ARGS__) + #define wglUseFontOutlinesA(...) GLEGetCurrentFunction(wglUseFontOutlinesA)(__VA_ARGS__) + #define wglUseFontOutlinesW(...) GLEGetCurrentFunction(wglUseFontOutlinesW)(__VA_ARGS__) + #define wglDescribeLayerPlane(...) GLEGetCurrentFunction(wglDescribeLayerPlane)(__VA_ARGS__) + #define wglSetLayerPaletteEntries(...) GLEGetCurrentFunction(wglSetLayerPaletteEntries)(__VA_ARGS__) + #define wglGetLayerPaletteEntries(...) GLEGetCurrentFunction(wglGetLayerPaletteEntries)(__VA_ARGS__) + #define wglRealizeLayerPalette(...) GLEGetCurrentFunction(wglRealizeLayerPalette)(__VA_ARGS__) + #define wglSwapLayerBuffers(...) GLEGetCurrentFunction(wglSwapLayerBuffers)(__VA_ARGS__) + #define wglSwapMultipleBuffers(...) GLEGetCurrentFunction(wglSwapMultipleBuffers)(__VA_ARGS__) + #else + // The following functions are directly declared in Microsoft's without associated typedefs, and are exported from Opengl32.dll. + // We can link to them directly through Opengl32.lib/dll (same as OpenGL 1.1 functions) or we can dynamically link them from OpenGL32.dll at runtime. + typedef BOOL (WINAPI * PFNWGLCOPYCONTEXTPROC)(HGLRC, HGLRC, UINT); + typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTPROC)(HDC); + typedef HGLRC (WINAPI * PFNWGLCREATELAYERCONTEXTPROC)(HDC, int); + typedef BOOL (WINAPI * PFNWGLDELETECONTEXTPROC)(HGLRC); + typedef HGLRC (WINAPI * PFNWGLGETCURRENTCONTEXTPROC)(VOID); + typedef HDC (WINAPI * PFNWGLGETCURRENTDCPROC)(VOID); + typedef PROC (WINAPI * PFNWGLGETPROCADDRESSPROC)(LPCSTR); + typedef BOOL (WINAPI * PFNWGLMAKECURRENTPROC)(HDC, HGLRC); + typedef BOOL (WINAPI * PFNWGLSHARELISTSPROC)(HGLRC, HGLRC); + typedef BOOL (WINAPI * PFNWGLUSEFONTBITMAPSAPROC)(HDC, DWORD, DWORD, DWORD); + typedef BOOL (WINAPI * PFNWGLUSEFONTBITMAPSWPROC)(HDC, DWORD, DWORD, DWORD); + typedef BOOL (WINAPI * PFNWGLUSEFONTOUTLINESAPROC)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); + typedef BOOL (WINAPI * PFNWGLUSEFONTOUTLINESWPROC)(HDC, DWORD, DWORD, DWORD, FLOAT, FLOAT, int, LPGLYPHMETRICSFLOAT); + typedef BOOL (WINAPI * PFNWGLDESCRIBELAYERPLANEPROC)(HDC, int, int, UINT, LPLAYERPLANEDESCRIPTOR); + typedef int (WINAPI * PFNWGLSETLAYERPALETTEENTRIESPROC)(HDC, int, int, int, CONST COLORREF *); + typedef int (WINAPI * PFNWGLGETLAYERPALETTEENTRIESPROC)(HDC, int, int, int, COLORREF *); + typedef BOOL (WINAPI * PFNWGLREALIZELAYERPALETTEPROC)(HDC, int, BOOL); + typedef BOOL (WINAPI * PFNWGLSWAPLAYERBUFFERSPROC)(HDC, UINT); + typedef DWORD (WINAPI * PFNWGLSWAPMULTIPLEBUFFERSPROC)(UINT, CONST WGLSWAP *); + + #if 0 + #define wglCopyContext GLEContext::GetCurrentContext()->wglCopyContext_Impl + #define wglCreateContext GLEContext::GetCurrentContext()->wglCreateContext_Impl + #define wglCreateLayerContext GLEContext::GetCurrentContext()->wglCreateLayerContext_Impl + #define wglDeleteContext GLEContext::GetCurrentContext()->wglDeleteContext_Impl + #define wglGetCurrentContext GLEContext::GetCurrentContext()->wglGetCurrentContext_Impl + #define wglGetCurrentDC GLEContext::GetCurrentContext()->wglGetCurrentDC_Impl + #define wglGetProcAddress GLEContext::GetCurrentContext()->wglGetProcAddress_Impl + #define wglMakeCurrent GLEContext::GetCurrentContext()->wglMakeCurrent_Impl + #define wglShareLists GLEContext::GetCurrentContext()->wglShareLists_Impl + #define wglUseFontBitmapsA GLEContext::GetCurrentContext()->wglUseFontBitmapsA_Impl + #define wglUseFontBitmapsW GLEContext::GetCurrentContext()->wglUseFontBitmapsW_Impl + #define wglUseFontOutlinesA GLEContext::GetCurrentContext()->wglUseFontOutlinesA_Impl + #define wglUseFontOutlinesW GLEContext::GetCurrentContext()->wglUseFontOutlinesW_Impl + #define wglDescribeLayerPlane GLEContext::GetCurrentContext()->wglDescribeLayerPlane_Impl + #define wglSetLayerPaletteEntries GLEContext::GetCurrentContext()->wglSetLayerPaletteEntries_Impl + #define wglGetLayerPaletteEntries GLEContext::GetCurrentContext()->wglGetLayerPaletteEntries_Impl + #define wglRealizeLayerPalette GLEContext::GetCurrentContext()->wglRealizeLayerPalette_Impl + #define wglSwapLayerBuffers GLEContext::GetCurrentContext()->wglSwapLayerBuffers_Impl + #define wglSwapMultipleBuffers GLEContext::GetCurrentContext()->wglSwapMultipleBuffers_Impl + #endif + #endif + + // Note: In order to detect the WGL extensions' availability, we need to call wglGetExtensionsStringARB or + // wglGetExtensionsStringEXT instead of glGetString(GL_EXTENSIONS). + #ifndef WGL_ARB_buffer_region + #define WGL_ARB_buffer_region 1 + + #define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 + #define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 + #define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 + #define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 + + typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); + typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); + typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); + typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); + + #define wglCreateBufferRegionARB GLEGetCurrentFunction(wglCreateBufferRegionARB) + #define wglDeleteBufferRegionARB GLEGetCurrentFunction(wglDeleteBufferRegionARB) + #define wglSaveBufferRegionARB GLEGetCurrentFunction(wglSaveBufferRegionARB) + #define wglRestoreBufferRegionARB GLEGetCurrentFunction(wglRestoreBufferRegionARB) + + #define GLE_WGL_ARB_buffer_region GLEGetCurrentVariable(gle_WGL_ARB_buffer_region) + #endif + + + #ifndef WGL_ARB_extensions_string + #define WGL_ARB_extensions_string 1 + + typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); + + #define wglGetExtensionsStringARB GLEGetCurrentFunction(wglGetExtensionsStringARB) + + #define GLE_WGL_ARB_extensions_string GLEGetCurrentVariable(gle_WGL_ARB_extensions_string) + #endif + + + #ifndef WGL_ARB_pixel_format + #define WGL_ARB_pixel_format 1 + + #define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 + #define WGL_DRAW_TO_WINDOW_ARB 0x2001 + #define WGL_DRAW_TO_BITMAP_ARB 0x2002 + #define WGL_ACCELERATION_ARB 0x2003 + #define WGL_NEED_PALETTE_ARB 0x2004 + #define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 + #define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 + #define WGL_SWAP_METHOD_ARB 0x2007 + #define WGL_NUMBER_OVERLAYS_ARB 0x2008 + #define WGL_NUMBER_UNDERLAYS_ARB 0x2009 + #define WGL_TRANSPARENT_ARB 0x200A + #define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 + #define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 + #define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 + #define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A + #define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B + #define WGL_SHARE_DEPTH_ARB 0x200C + #define WGL_SHARE_STENCIL_ARB 0x200D + #define WGL_SHARE_ACCUM_ARB 0x200E + #define WGL_SUPPORT_GDI_ARB 0x200F + #define WGL_SUPPORT_OPENGL_ARB 0x2010 + #define WGL_DOUBLE_BUFFER_ARB 0x2011 + #define WGL_STEREO_ARB 0x2012 + #define WGL_PIXEL_TYPE_ARB 0x2013 + #define WGL_COLOR_BITS_ARB 0x2014 + #define WGL_RED_BITS_ARB 0x2015 + #define WGL_RED_SHIFT_ARB 0x2016 + #define WGL_GREEN_BITS_ARB 0x2017 + #define WGL_GREEN_SHIFT_ARB 0x2018 + #define WGL_BLUE_BITS_ARB 0x2019 + #define WGL_BLUE_SHIFT_ARB 0x201A + #define WGL_ALPHA_BITS_ARB 0x201B + #define WGL_ALPHA_SHIFT_ARB 0x201C + #define WGL_ACCUM_BITS_ARB 0x201D + #define WGL_ACCUM_RED_BITS_ARB 0x201E + #define WGL_ACCUM_GREEN_BITS_ARB 0x201F + #define WGL_ACCUM_BLUE_BITS_ARB 0x2020 + #define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 + #define WGL_DEPTH_BITS_ARB 0x2022 + #define WGL_STENCIL_BITS_ARB 0x2023 + #define WGL_AUX_BUFFERS_ARB 0x2024 + #define WGL_NO_ACCELERATION_ARB 0x2025 + #define WGL_GENERIC_ACCELERATION_ARB 0x2026 + #define WGL_FULL_ACCELERATION_ARB 0x2027 + #define WGL_SWAP_EXCHANGE_ARB 0x2028 + #define WGL_SWAP_COPY_ARB 0x2029 + #define WGL_SWAP_UNDEFINED_ARB 0x202A + #define WGL_TYPE_RGBA_ARB 0x202B + #define WGL_TYPE_COLORINDEX_ARB 0x202C + + typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); + typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); + typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); + + #define wglGetPixelFormatAttribivARB GLEGetCurrentFunction(wglGetPixelFormatAttribivARB) + #define wglGetPixelFormatAttribfvARB GLEGetCurrentFunction(wglGetPixelFormatAttribfvARB) + #define wglChoosePixelFormatARB GLEGetCurrentFunction(wglChoosePixelFormatARB) + + #define GLE_WGL_ARB_pixel_format GLEGetCurrentVariable(gle_WGL_ARB_pixel_format) + #endif + + + #ifndef WGL_ARB_make_current_read + #define WGL_ARB_make_current_read 1 + + #define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 + #define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 + + typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); + typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); + + #define wglMakeContextCurrentARB GLEGetCurrentFunction(wglMakeContextCurrentARB) + #define wglGetCurrentReadDCARB GLEGetCurrentFunction(wglGetCurrentReadDCARB) + + #define GLE_WGL_ARB_make_current_read GLEGetCurrentVariable(gle_WGL_ARB_make_current_read) + #endif + + + #ifndef WGL_ARB_pbuffer + #define WGL_ARB_pbuffer 1 + + #define WGL_DRAW_TO_PBUFFER_ARB 0x202D + #define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E + #define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F + #define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 + #define WGL_PBUFFER_LARGEST_ARB 0x2033 + #define WGL_PBUFFER_WIDTH_ARB 0x2034 + #define WGL_PBUFFER_HEIGHT_ARB 0x2035 + + typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); + typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); + typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); + typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); + typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); + + #define wglCreatePbufferARB GLEGetCurrentFunction(wglCreatePbufferARB) + #define wglGetPbufferDCARB GLEGetCurrentFunction(wglGetPbufferDCARB) + #define wglReleasePbufferDCARB GLEGetCurrentFunction(wglReleasePbufferDCARB) + #define wglDestroyPbufferARB GLEGetCurrentFunction(wglDestroyPbufferARB) + #define wglQueryPbufferARB GLEGetCurrentFunction(wglQueryPbufferARB) + + #define GLE_WGL_ARB_pbuffer GLEGetCurrentVariable(gle_WGL_ARB_pbuffer) + #endif + + + #ifndef WGL_ARB_render_texture + #define WGL_ARB_render_texture 1 + + #define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 + #define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 + #define WGL_TEXTURE_FORMAT_ARB 0x2072 + #define WGL_TEXTURE_TARGET_ARB 0x2073 + #define WGL_MIPMAP_TEXTURE_ARB 0x2074 + #define WGL_TEXTURE_RGB_ARB 0x2075 + #define WGL_TEXTURE_RGBA_ARB 0x2076 + #define WGL_NO_TEXTURE_ARB 0x2077 + #define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 + #define WGL_TEXTURE_1D_ARB 0x2079 + #define WGL_TEXTURE_2D_ARB 0x207A + #define WGL_MIPMAP_LEVEL_ARB 0x207B + #define WGL_CUBE_MAP_FACE_ARB 0x207C + #define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D + #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E + #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F + #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 + #define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 + #define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 + #define WGL_FRONT_LEFT_ARB 0x2083 + #define WGL_FRONT_RIGHT_ARB 0x2084 + #define WGL_BACK_LEFT_ARB 0x2085 + #define WGL_BACK_RIGHT_ARB 0x2086 + #define WGL_AUX0_ARB 0x2087 + #define WGL_AUX1_ARB 0x2088 + #define WGL_AUX2_ARB 0x2089 + #define WGL_AUX3_ARB 0x208A + #define WGL_AUX4_ARB 0x208B + #define WGL_AUX5_ARB 0x208C + #define WGL_AUX6_ARB 0x208D + #define WGL_AUX7_ARB 0x208E + #define WGL_AUX8_ARB 0x208F + #define WGL_AUX9_ARB 0x2090 + + typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); + typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); + typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); + + #define wglBindTexImageARB GLEGetCurrentFunction(wglBindTexImageARB) + #define wglReleaseTexImageARB GLEGetCurrentFunction(wglReleaseTexImageARB) + #define wglSetPbufferAttribARB GLEGetCurrentFunction(wglSetPbufferAttribARB) + + #define GLE_WGL_ARB_render_texture GLEGetCurrentVariable(gle_WGL_ARB_render_texture) + #endif + + + #ifndef WGL_ARB_pixel_format_float + #define WGL_ARB_pixel_format_float 1 + + #define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 + + #define GLE_WGL_ARB_pixel_format_float GLEGetCurrentVariable(gle_WGL_ARB_pixel_format_float) + #endif + + + #ifndef WGL_ARB_framebuffer_sRGB + #define WGL_ARB_framebuffer_sRGB 1 + + // There is also the WGL_EXT_framebuffer_sRGB extension, which is the + // same as this. So use this one instead of that for checking. + #define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9 + + #define GLE_WGL_ARB_framebuffer_sRGB GLEGetCurrentVariable(gle_WGL_ARB_framebuffer_sRGB) + #endif + + + #ifndef WGL_NV_present_video + #define WGL_NV_present_video 1 + + DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); + + typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); + typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); + typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); + + #define wglEnumerateVideoDevicesNV GLEGetCurrentFunction(wglEnumerateVideoDevicesNV) + #define wglBindVideoDeviceNV GLEGetCurrentFunction(wglBindVideoDeviceNV) + #define wglQueryCurrentContextNV GLEGetCurrentFunction(wglQueryCurrentContextNV) + + #define GLE_WGL_NV_present_video GLEGetCurrentVariable(gle_WGL_NV_present_video) + #endif + + + #ifndef WGL_ARB_create_context + #define WGL_ARB_create_context 1 + + #define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 + #define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 + #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 + #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 + #define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 + #define WGL_CONTEXT_FLAGS_ARB 0x2094 + #define ERROR_INVALID_VERSION_ARB 0x2095 + + typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); + + #define wglCreateContextAttribsARB GLEGetCurrentFunction(wglCreateContextAttribsARB) + + #define GLE_WGL_ARB_create_context GLEGetCurrentVariable(gle_WGL_ARB_create_context) + #endif + + + #ifndef WGL_ARB_create_context_profile + #define WGL_ARB_create_context_profile 1 + + #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 + #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 + #define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 + #define ERROR_INVALID_PROFILE_ARB 0x2096 + + #define GLE_WGL_ARB_create_context_profile GLEGetCurrentVariable(gle_WGL_ARB_create_context_profile) + #endif + + + #ifndef WGL_ARB_create_context_robustness + #define WGL_ARB_create_context_robustness 1 + + #define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 + #define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 + #define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 + #define WGL_NO_RESET_NOTIFICATION_ARB 0x8261 + + #define GLE_WGL_ARB_create_context_robustness GLEGetCurrentVariable(gle_WGL_ARB_create_context_robustness) + #endif + + + + #ifndef WGL_ATI_render_texture_rectangle + #define WGL_ATI_render_texture_rectangle 1 + + #define WGL_TEXTURE_RECTANGLE_ATI 0x21A5 + + #define GLE_WGL_ATI_render_texture_rectangle GLEGetCurrentVariable(gle_WGL_ATI_render_texture_rectangle) + #endif + + + #ifndef WGL_EXT_extensions_string + #define WGL_EXT_extensions_string 1 + + typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); + + #define wglGetExtensionsStringEXT GLEGetCurrentFunction(wglGetExtensionsStringEXT) + + #define GLE_WGL_EXT_extensions_string GLEGetCurrentVariable(gle_WGL_EXT_extensions_string) + #endif + + + #ifndef WGL_NV_render_texture_rectangle + #define WGL_NV_render_texture_rectangle 1 + + #define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 + #define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 + #define WGL_TEXTURE_RECTANGLE_NV 0x20A2 + + #define GLE_WGL_NV_render_texture_rectangle GLEGetCurrentVariable(gle_WGL_NV_render_texture_rectangle) + #endif + + + #ifndef WGL_EXT_swap_control + #define WGL_EXT_swap_control 1 + + typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); + typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + + #define wglGetSwapIntervalEXT GLEGetCurrentFunction(wglGetSwapIntervalEXT) + #define wglSwapIntervalEXT GLEGetCurrentFunction(wglSwapIntervalEXT) + + #define GLE_WGL_EXT_swap_control GLEGetCurrentVariable(gle_WGL_EXT_swap_control) + #endif + + + #ifndef WGL_OML_sync_control + #define WGL_OML_sync_control 1 + + typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); + typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); + typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); + typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); + typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); + typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); + + #define wglGetSyncValuesOML GLEGetCurrentFunction(wglGetSyncValuesOML) + #define wglGetMscRateOML GLEGetCurrentFunction(wglGetMscRateOML) + #define wglSwapBuffersMscOML GLEGetCurrentFunction(wglSwapBuffersMscOML) + #define wglSwapLayerBuffersMscOML GLEGetCurrentFunction(wglSwapLayerBuffersMscOML) + #define wglWaitForMscOML GLEGetCurrentFunction(wglWaitForMscOML) + #define wglWaitForSbcOML GLEGetCurrentFunction(wglWaitForSbcOML) + + #define GLE_WGL_OML_sync_control GLEGetCurrentVariable(gle_WGL_OML_sync_control) + #endif + + + #ifndef WGL_NV_video_output + #define WGL_NV_video_output 1 + + DECLARE_HANDLE(HPVIDEODEV); + + typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); + typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); + typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); + typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); + typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); + typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); + + #define wglGetVideoDeviceNV GLEGetCurrentFunction(wglGetVideoDeviceNV) + #define wglReleaseVideoDeviceNV GLEGetCurrentFunction(wglReleaseVideoDeviceNV) + #define wglBindVideoImageNV GLEGetCurrentFunction(wglBindVideoImageNV) + #define wglReleaseVideoImageNV GLEGetCurrentFunction(wglReleaseVideoImageNV) + #define wglSendPbufferToVideoNV GLEGetCurrentFunction(wglSendPbufferToVideoNV) + #define wglGetVideoInfoNV GLEGetCurrentFunction(wglGetVideoInfoNV) + + #define GLE_WGL_NV_video_output GLEGetCurrentVariable(gle_WGL_NV_video_output) + #endif + + + #ifndef WGL_NV_swap_group + #define WGL_NV_swap_group 1 + + typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); + typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); + typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); + typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); + typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); + typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); + + #define wglJoinSwapGroupNV GLEGetCurrentFunction(wglJoinSwapGroupNV) + #define wglBindSwapBarrierNV GLEGetCurrentFunction(wglBindSwapBarrierNV) + #define wglQuerySwapGroupNV GLEGetCurrentFunction(wglQuerySwapGroupNV) + #define wglQueryMaxSwapGroupsNV GLEGetCurrentFunction(wglQueryMaxSwapGroupsNV) + #define wglQueryFrameCountNV GLEGetCurrentFunction(wglQueryFrameCountNV) + #define wglResetFrameCountNV GLEGetCurrentFunction(wglResetFrameCountNV) + + #define GLE_WGL_NV_swap_group GLEGetCurrentVariable(gle_WGL_NV_swap_group) + #endif + + + #ifndef WGL_NV_video_capture + #define WGL_NV_video_capture 1 + + #define WGL_UNIQUE_ID_NV 0x20CE + #define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF + + typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; + } GPU_DEVICE, *PGPU_DEVICE; + DECLARE_HANDLE(HVIDEOINPUTDEVICENV); + + typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); + typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); + typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); + typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); + typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); + + #define wglBindVideoCaptureDeviceNV GLEGetCurrentFunction(wglBindVideoCaptureDeviceNV) + #define wglEnumerateVideoCaptureDevicesNV GLEGetCurrentFunction(wglEnumerateVideoCaptureDevicesNV) + #define wglLockVideoCaptureDeviceNV GLEGetCurrentFunction(wglLockVideoCaptureDeviceNV) + #define wglQueryVideoCaptureDeviceNV GLEGetCurrentFunction(wglQueryVideoCaptureDeviceNV) + #define wglReleaseVideoCaptureDeviceNV GLEGetCurrentFunction(wglReleaseVideoCaptureDeviceNV) + + #define GLE_WGL_NV_video_capture GLEGetCurrentVariable(gle_WGL_NV_video_capture) + #endif + + + #ifndef WGL_NV_copy_image + #define WGL_NV_copy_image 1 + + typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + + #define wglCopyImageSubDataNV GLEGetCurrentFunction(wglCopyImageSubDataNV) + + #define GLE_WGL_NV_copy_image GLEGetCurrentVariable(gle_WGL_NV_copy_image) + #endif + + + #ifndef WGL_NV_DX_interop + #define WGL_NV_DX_interop 1 + + // Note that modern AMD drivers support this NVidia extension. + #define WGL_ACCESS_READ_ONLY_NV 0x0000 + #define WGL_ACCESS_READ_WRITE_NV 0x0001 + #define WGL_ACCESS_WRITE_DISCARD_NV 0x0002 + + typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice); + typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); + typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access); + typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void* dxDevice); + typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void* dxObject, GLuint name, GLenum type, GLenum access); + typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void* dxObject, HANDLE shareHandle); + typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE* hObjects); + typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject); + + #define wglDXCloseDeviceNV GLEGetCurrentFunction(wglDXCloseDeviceNV) + #define wglDXLockObjectsNV GLEGetCurrentFunction(wglDXLockObjectsNV) + #define wglDXObjectAccessNV GLEGetCurrentFunction(wglDXObjectAccessNV) + #define wglDXOpenDeviceNV GLEGetCurrentFunction(wglDXOpenDeviceNV) + #define wglDXRegisterObjectNV GLEGetCurrentFunction(wglDXRegisterObjectNV) + #define wglDXSetResourceShareHandleNV GLEGetCurrentFunction(wglDXSetResourceShareHandleNV) + #define wglDXUnlockObjectsNV GLEGetCurrentFunction(wglDXUnlockObjectsNV) + #define wglDXUnregisterObjectNV GLEGetCurrentFunction(wglDXUnregisterObjectNV) + + #define GLE_WGL_NV_DX_interop GLEGetCurrentVariable(gle_WGL_NV_DX_interop) + #endif + + + #ifndef WGL_NV_DX_interop2 + #define WGL_NV_DX_interop2 1 + + // This is an update to WGL_NV_DX_interop to support DX10/DX11. + // https://www.opengl.org/registry/specs/NV/DX_interop2.txt + #define GLE_WGL_NV_DX_interop2 GLEGetCurrentVariable(gle_WGL_NV_DX_interop2) + + #endif + +#endif // GLE_WGL_ENABLED + + + +/************************************************************************************ + Apple-specific (CGL) functionality +************************************************************************************/ + +#if defined(GLE_CGL_ENABLED) + // We don't currently disable Apple's OpenGL/OpenGL.h and replicate its declarations here. + // We might want to do that if we intended to support hooking its functions here like we do for wgl functions. + #include +#endif + + + +/************************************************************************************ + Unix-specific (GLX) functionality +************************************************************************************/ + +#if defined(GLE_GLX_ENABLED) + #ifdef __glxext_h_ + #error glxext.h was included before this header. This header needs to be inlcuded instead of or at least before glxext.h + #endif + #define __glxext_h_ + + #if defined(GLX_H) || defined(__GLX_glx_h__) || defined(__glx_h__) + #error glx.h was included before this header. This header needs to be inlcuded instead of or at least before glx.h + #endif + #define GLX_H + #define __GLX_glx_h__ + #define __glx_h__ + + #include + #include + #include + + // GLX version 1.0 functions are assumed to always be present. + #ifndef GLX_VERSION_1_0 + #define GLX_VERSION_1_0 1 + + #define GLX_USE_GL 1 + #define GLX_BUFFER_SIZE 2 + #define GLX_LEVEL 3 + #define GLX_RGBA 4 + #define GLX_DOUBLEBUFFER 5 + #define GLX_STEREO 6 + #define GLX_AUX_BUFFERS 7 + #define GLX_RED_SIZE 8 + #define GLX_GREEN_SIZE 9 + #define GLX_BLUE_SIZE 10 + #define GLX_ALPHA_SIZE 11 + #define GLX_DEPTH_SIZE 12 + #define GLX_STENCIL_SIZE 13 + #define GLX_ACCUM_RED_SIZE 14 + #define GLX_ACCUM_GREEN_SIZE 15 + #define GLX_ACCUM_BLUE_SIZE 16 + #define GLX_ACCUM_ALPHA_SIZE 17 + #define GLX_BAD_SCREEN 1 + #define GLX_BAD_ATTRIBUTE 2 + #define GLX_NO_EXTENSION 3 + #define GLX_BAD_VISUAL 4 + #define GLX_BAD_CONTEXT 5 + #define GLX_BAD_VALUE 6 + #define GLX_BAD_ENUM 7 + + typedef XID GLXDrawable; + typedef XID GLXPixmap; + typedef unsigned int GLXVideoDeviceNV; + typedef struct __GLXcontextRec *GLXContext; + + // GLE_HOOKING_ENABLED + // We don't currently support hooking the following GLX 1.0 functions like we do with the analagous windows wgl functions. + // However, we can do this if needed. We would just have something like this: + // #define glXQueryExtension(...) GLEGetCurrentFunction(glXQueryExtension)(__VA_ARGS__) + // plus a member function like: + // Bool glXQueryExtension_Hook(Display*, int*, int*); + // See wglCopyContext for an example. + + extern Bool glXQueryExtension (Display *dpy, int *errorBase, int *eventBase); + extern Bool glXQueryVersion (Display *dpy, int *major, int *minor); + extern int glXGetConfig (Display *dpy, XVisualInfo *vis, int attrib, int *value); + extern XVisualInfo* glXChooseVisual (Display *dpy, int screen, int *attribList); + extern GLXPixmap glXCreateGLXPixmap (Display *dpy, XVisualInfo *vis, Pixmap pixmap); + extern void glXDestroyGLXPixmap (Display *dpy, GLXPixmap pix); + extern GLXContext glXCreateContext (Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); + extern void glXDestroyContext (Display *dpy, GLXContext ctx); + extern Bool glXIsDirect (Display *dpy, GLXContext ctx); + extern void glXCopyContext (Display *dpy, GLXContext src, GLXContext dst, GLulong mask); + extern Bool glXMakeCurrent (Display *dpy, GLXDrawable drawable, GLXContext ctx); + extern GLXContext glXGetCurrentContext (void); + extern GLXDrawable glXGetCurrentDrawable (void); + extern void glXWaitGL (void); + extern void glXWaitX (void); + extern void glXSwapBuffers (Display *dpy, GLXDrawable drawable); + extern void glXUseXFont (Font font, int first, int count, int listBase); + + #endif // GLX_VERSION_1_0 + + + + #ifndef GLX_VERSION_1_1 + #define GLX_VERSION_1_1 + + #define GLX_VENDOR 0x1 + #define GLX_VERSION 0x2 + #define GLX_EXTENSIONS 0x3 + + // These function pointers are assumed to always be present. + extern const char* glXQueryExtensionsString (Display *dpy, int screen); + extern const char* glXGetClientString (Display *dpy, int name); + extern const char* glXQueryServerString (Display *dpy, int screen, int name); + #endif + + + #ifndef GLX_VERSION_1_2 + #define GLX_VERSION_1_2 1 + + typedef Display* (* PFNGLXGETCURRENTDISPLAYPROC) (void); + + #define glXGetCurrentDisplay GLEGetCurrentFunction(glXGetCurrentDisplay) + #endif + + + + #ifndef GLX_VERSION_1_3 + #define GLX_VERSION_1_3 1 + + #define GLX_FRONT_LEFT_BUFFER_BIT 0x00000001 + #define GLX_RGBA_BIT 0x00000001 + #define GLX_WINDOW_BIT 0x00000001 + #define GLX_COLOR_INDEX_BIT 0x00000002 + #define GLX_FRONT_RIGHT_BUFFER_BIT 0x00000002 + #define GLX_PIXMAP_BIT 0x00000002 + #define GLX_BACK_LEFT_BUFFER_BIT 0x00000004 + #define GLX_PBUFFER_BIT 0x00000004 + #define GLX_BACK_RIGHT_BUFFER_BIT 0x00000008 + #define GLX_AUX_BUFFERS_BIT 0x00000010 + #define GLX_CONFIG_CAVEAT 0x20 + #define GLX_DEPTH_BUFFER_BIT 0x00000020 + #define GLX_X_VISUAL_TYPE 0x22 + #define GLX_TRANSPARENT_TYPE 0x23 + #define GLX_TRANSPARENT_INDEX_VALUE 0x24 + #define GLX_TRANSPARENT_RED_VALUE 0x25 + #define GLX_TRANSPARENT_GREEN_VALUE 0x26 + #define GLX_TRANSPARENT_BLUE_VALUE 0x27 + #define GLX_TRANSPARENT_ALPHA_VALUE 0x28 + #define GLX_STENCIL_BUFFER_BIT 0x00000040 + #define GLX_ACCUM_BUFFER_BIT 0x00000080 + #define GLX_NONE 0x8000 + #define GLX_SLOW_CONFIG 0x8001 + #define GLX_TRUE_COLOR 0x8002 + #define GLX_DIRECT_COLOR 0x8003 + #define GLX_PSEUDO_COLOR 0x8004 + #define GLX_STATIC_COLOR 0x8005 + #define GLX_GRAY_SCALE 0x8006 + #define GLX_STATIC_GRAY 0x8007 + #define GLX_TRANSPARENT_RGB 0x8008 + #define GLX_TRANSPARENT_INDEX 0x8009 + #define GLX_VISUAL_ID 0x800B + #define GLX_SCREEN 0x800C + #define GLX_NON_CONFORMANT_CONFIG 0x800D + #define GLX_DRAWABLE_TYPE 0x8010 + #define GLX_RENDER_TYPE 0x8011 + #define GLX_X_RENDERABLE 0x8012 + #define GLX_FBCONFIG_ID 0x8013 + #define GLX_RGBA_TYPE 0x8014 + #define GLX_COLOR_INDEX_TYPE 0x8015 + #define GLX_MAX_PBUFFER_WIDTH 0x8016 + #define GLX_MAX_PBUFFER_HEIGHT 0x8017 + #define GLX_MAX_PBUFFER_PIXELS 0x8018 + #define GLX_PRESERVED_CONTENTS 0x801B + #define GLX_LARGEST_PBUFFER 0x801C + #define GLX_WIDTH 0x801D + #define GLX_HEIGHT 0x801E + #define GLX_EVENT_MASK 0x801F + #define GLX_DAMAGED 0x8020 + #define GLX_SAVED 0x8021 + #define GLX_WINDOW 0x8022 + #define GLX_PBUFFER 0x8023 + #define GLX_PBUFFER_HEIGHT 0x8040 + #define GLX_PBUFFER_WIDTH 0x8041 + #define GLX_PBUFFER_CLOBBER_MASK 0x08000000 + #define GLX_DONT_CARE 0xFFFFFFFF + + typedef XID GLXFBConfigID; + typedef XID GLXPbuffer; + typedef XID GLXWindow; + typedef struct __GLXFBConfigRec *GLXFBConfig; + + typedef struct { + int event_type; + int draw_type; + unsigned long serial; + Bool send_event; + Display *display; + GLXDrawable drawable; + unsigned int buffer_mask; + unsigned int aux_buffer; + int x, y; + int width, height; + int count; + } GLXPbufferClobberEvent; + + typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + long pad[24]; + } GLXEvent; + + typedef GLXFBConfig* (* PFNGLXCHOOSEFBCONFIGPROC) (::Display *dpy, int screen, const int *attrib_list, int *nelements); + typedef GLXContext (* PFNGLXCREATENEWCONTEXTPROC) (::Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); + typedef GLXPbuffer (* PFNGLXCREATEPBUFFERPROC) (::Display *dpy, GLXFBConfig config, const int *attrib_list); + typedef GLXPixmap (* PFNGLXCREATEPIXMAPPROC) (::Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); + typedef GLXWindow (* PFNGLXCREATEWINDOWPROC) (::Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); + typedef void (* PFNGLXDESTROYPBUFFERPROC) (::Display *dpy, GLXPbuffer pbuf); + typedef void (* PFNGLXDESTROYPIXMAPPROC) (::Display *dpy, GLXPixmap pixmap); + typedef void (* PFNGLXDESTROYWINDOWPROC) (::Display *dpy, GLXWindow win); + typedef GLXDrawable (* PFNGLXGETCURRENTREADDRAWABLEPROC) (void); + typedef int (* PFNGLXGETFBCONFIGATTRIBPROC) (::Display *dpy, GLXFBConfig config, int attribute, int *value); + typedef GLXFBConfig* (* PFNGLXGETFBCONFIGSPROC) (::Display *dpy, int screen, int *nelements); + typedef void (* PFNGLXGETSELECTEDEVENTPROC) (::Display *dpy, GLXDrawable draw, unsigned long *event_mask); + typedef XVisualInfo* (* PFNGLXGETVISUALFROMFBCONFIGPROC) (::Display *dpy, GLXFBConfig config); + typedef Bool (* PFNGLXMAKECONTEXTCURRENTPROC) (::Display *display, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + typedef int (* PFNGLXQUERYCONTEXTPROC) (::Display *dpy, GLXContext ctx, int attribute, int *value); + typedef void (* PFNGLXQUERYDRAWABLEPROC) (::Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); + typedef void (* PFNGLXSELECTEVENTPROC) (::Display *dpy, GLXDrawable draw, unsigned long event_mask); + + #define glXChooseFBConfig GLEGetCurrentFunction(glXChooseFBConfig) + #define glXCreateNewContext GLEGetCurrentFunction(glXCreateNewContext) + #define glXCreatePbuffer GLEGetCurrentFunction(glXCreatePbuffer) + #define glXCreatePixmap GLEGetCurrentFunction(glXCreatePixmap) + #define glXCreateWindow GLEGetCurrentFunction(glXCreateWindow) + #define glXDestroyPbuffer GLEGetCurrentFunction(glXDestroyPbuffer) + #define glXDestroyPixmap GLEGetCurrentFunction(glXDestroyPixmap) + #define glXDestroyWindow GLEGetCurrentFunction(glXDestroyWindow) + #define glXGetCurrentReadDrawable GLEGetCurrentFunction(glXGetCurrentReadDrawable) + #define glXGetFBConfigAttrib GLEGetCurrentFunction(glXGetFBConfigAttrib) + #define glXGetFBConfigs GLEGetCurrentFunction(glXGetFBConfigs) + #define glXGetSelectedEvent GLEGetCurrentFunction(glXGetSelectedEvent) + #define glXGetVisualFromFBConfig GLEGetCurrentFunction(glXGetVisualFromFBConfig) + #define glXMakeContextCurrent GLEGetCurrentFunction(glXMakeContextCurrent) + #define glXQueryContext GLEGetCurrentFunction(glXQueryContext) + #define glXQueryDrawable GLEGetCurrentFunction(glXQueryDrawable) + #define glXSelectEvent GLEGetCurrentFunction(glXSelectEvent) + + #endif // GLX_VERSION_1_3 + + + + #ifndef GLX_VERSION_1_4 + #define GLX_VERSION_1_4 1 + + #define GLX_SAMPLE_BUFFERS 100000 + #define GLX_SAMPLES 100001 + + // This was glXGetProcAddressARB in GLX versions prior to v1.4. + // This function pointer is assumed to always be present. + extern void (* glXGetProcAddress(const GLubyte *procName)) (); + + // For backward compatibility + extern void (* glXGetProcAddressARB(const GLubyte *procName)) (); + #endif + + + + #ifndef GLX_ARB_create_context + #define GLX_ARB_create_context 1 + + #define GLX_CONTEXT_DEBUG_BIT_ARB 0x0001 + #define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002 + #define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 + #define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 + #define GLX_CONTEXT_FLAGS_ARB 0x2094 + + typedef GLXContext (* PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); + + #define glXCreateContextAttribsARB GLEGetCurrentFunction(glXCreateContextAttribsARB) + + #define GLE_GLX_ARB_create_context GLEGetCurrentVariable(gle_GLX_ARB_create_context) + #endif + + + #ifndef GLX_ARB_create_context_profile + #define GLX_ARB_create_context_profile 1 + + #define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 + #define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 + #define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 + + #define GLE_GLX_ARB_create_context_profile GLEGetCurrentVariable(gle_GLX_ARB_create_context_profile) + #endif + + + #ifndef GLX_ARB_create_context_robustness + #define GLX_ARB_create_context_robustness 1 + + #define GLX_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004 + #define GLX_LOSE_CONTEXT_ON_RESET_ARB 0x8252 + #define GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256 + #define GLX_NO_RESET_NOTIFICATION_ARB 0x8261 + + #define GLE_GLX_ARB_create_context_robustness GLEGetCurrentVariable(gle_GLX_ARB_create_context_robustness) + #endif + + + // Note: In order to detect the GLX extensions' availability, we need to call glXQueryExtensionsString instead of glGetString(GL_EXTENSIONS). + #ifndef GLX_EXT_swap_control + #define GLX_EXT_swap_control 1 + + #define GLX_SWAP_INTERVAL_EXT 0x20F1 + #define GLX_MAX_SWAP_INTERVAL_EXT 0x20F2 + + typedef void (* PFNGLXSWAPINTERVALEXTPROC) (Display* dpy, GLXDrawable drawable, int interval); + + #define glXSwapIntervalEXT GLEGetCurrentFunction(glXSwapIntervalEXT) + + #define GLE_GLX_EXT_swap_control GLEGetCurrentVariable(gle_GLX_EXT_swap_control) + #endif + + + #ifndef GLX_OML_sync_control + #define GLX_OML_sync_control 1 + + typedef Bool (* PFNGLXGETMSCRATEOMLPROC) (Display* dpy, GLXDrawable drawable, int32_t* numerator, int32_t* denominator); + typedef Bool (* PFNGLXGETSYNCVALUESOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t* ust, int64_t* msc, int64_t* sbc); + typedef int64_t (* PFNGLXSWAPBUFFERSMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); + typedef Bool (* PFNGLXWAITFORMSCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t* ust, int64_t* msc, int64_t* sbc); + typedef Bool (* PFNGLXWAITFORSBCOMLPROC) (Display* dpy, GLXDrawable drawable, int64_t target_sbc, int64_t* ust, int64_t* msc, int64_t* sbc); + + #define glXGetMscRateOML GLEGetCurrentFunction(glXGetMscRateOML) + #define glXGetSyncValuesOML GLEGetCurrentFunction(glXGetSyncValuesOML) + #define glXSwapBuffersMscOML GLEGetCurrentFunction(glXSwapBuffersMscOML) + #define glXWaitForMscOML GLEGetCurrentFunction(glXWaitForMscOML) + #define glXWaitForSbcOML GLEGetCurrentFunction(glXWaitForSbcOML) + + #define GLE_GLX_OML_sync_control GLEGetCurrentVariable(gle_GLX_OML_sync_control) + #endif + + + #ifndef GLX_MESA_swap_control + #define GLX_MESA_swap_control 1 + + // GLX_MESA_swap_control has the same functionality as GLX_EXT_swap_control but with a different interface, so we have an independent entry for it here. + typedef int (* PFNGLXGETSWAPINTERVALMESAPROC) (void); + typedef int (* PFNGLXSWAPINTERVALMESAPROC) (unsigned int interval); + + #define glXGetSwapIntervalMESA GLEGetCurrentFunction(glXGetSwapIntervalMESA) + #define glXSwapIntervalMESA GLEGetCurrentFunction(glXSwapIntervalMESA) + + #define GLE_MESA_swap_control GLEGetCurrentVariable(gle_MESA_swap_control) + #endif + +#endif // GLE_GLX_ENABLED + + +// Undo some defines, because the user may include after including this header. +#if defined(GLE_WINGDIAPI_DEFINED) + #undef WINGDIAPI +#endif + + +#ifdef __cplusplus +} // extern "C" +#endif + + + +#endif // OVR_CAPI_GLE_GL_h diff --git a/LibOVRKernel/Src/Kernel/OVR_Alg.cpp b/LibOVRKernel/Src/Kernel/OVR_Alg.cpp new file mode 100644 index 0000000..c087777 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Alg.cpp @@ -0,0 +1,57 @@ +/************************************************************************************ + +Filename : OVR_Alg.cpp +Content : Static lookup tables for Alg functions +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Types.h" + +namespace OVR { namespace Alg { + +//------------------------------------------------------------------------ +extern const uint8_t UpperBitTable[256] = +{ + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 +}; + +extern const uint8_t LowerBitTable[256] = +{ + 8,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0, + 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0 +}; + + +}} // OVE::Alg diff --git a/LibOVRKernel/Src/Kernel/OVR_Alg.h b/LibOVRKernel/Src/Kernel/OVR_Alg.h new file mode 100644 index 0000000..f7f461f --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Alg.h @@ -0,0 +1,1062 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Alg.h +Content : Simple general purpose algorithms: Sort, Binary Search, etc. +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Alg_h +#define OVR_Alg_h + +#include "OVR_Types.h" +#include + +namespace OVR { namespace Alg { + + +//----------------------------------------------------------------------------------- +// ***** Operator extensions + +template OVR_FORCE_INLINE void Swap(T &a, T &b) +{ T temp(a); a = b; b = temp; } + + +// ***** min/max are not implemented in Visual Studio 6 standard STL + +template OVR_FORCE_INLINE const T Min(const T a, const T b) +{ return (a < b) ? a : b; } + +template OVR_FORCE_INLINE const T Max(const T a, const T b) +{ return (b < a) ? a : b; } + +template OVR_FORCE_INLINE const T Clamp(const T v, const T minVal, const T maxVal) +{ return Max(minVal, Min(v, maxVal)); } + +template OVR_FORCE_INLINE int Chop(T f) +{ return (int)f; } + +template OVR_FORCE_INLINE T Lerp(T a, T b, T f) +{ return (b - a) * f + a; } + + +// These functions stand to fix a stupid VC++ warning (with /Wp64 on): +// "warning C4267: 'argument' : conversion from 'size_t' to 'const unsigned', possible loss of data" +// Use these functions instead of gmin/gmax if the argument has size +// of the pointer to avoid the warning. Though, functionally they are +// absolutelly the same as regular gmin/gmax. +template OVR_FORCE_INLINE const T PMin(const T a, const T b) +{ + OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); + return (a < b) ? a : b; +} +template OVR_FORCE_INLINE const T PMax(const T a, const T b) +{ + OVR_COMPILER_ASSERT(sizeof(T) == sizeof(size_t)); + return (b < a) ? a : b; +} + + +template OVR_FORCE_INLINE const T Abs(const T v) +{ return (v>=0) ? v : -v; } + + +//----------------------------------------------------------------------------------- +// ***** OperatorLess +// +template struct OperatorLess +{ + static bool Compare(const T& a, const T& b) + { + return a < b; + } +}; + + +//----------------------------------------------------------------------------------- +// ***** QuickSortSliced +// +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. +// The range is specified with start, end, where "end" is exclusive! +// The comparison predicate must be specified. +template +void QuickSortSliced(Array& arr, size_t start, size_t end, Less less) +{ + enum + { + Threshold = 9 + }; + + if(end - start < 2) return; + + intptr_t stack[80]; + intptr_t* top = stack; + intptr_t base = (intptr_t)start; + intptr_t limit = (intptr_t)end; + + for(;;) + { + intptr_t len = limit - base; + intptr_t i, j, pivot; + + if(len > Threshold) + { + // we use base + len/2 as the pivot + pivot = base + len / 2; + Swap(arr[base], arr[pivot]); + + i = base + 1; + j = limit - 1; + + // now ensure that *i <= *base <= *j + if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); + if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); + if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); + + for(;;) + { + do i++; while( less(arr[i], arr[base]) ); + do j--; while( less(arr[base], arr[j]) ); + + if( i > j ) + { + break; + } + + Swap(arr[i], arr[j]); + } + + Swap(arr[base], arr[j]); + + // now, push the largest sub-array + if(j - base > limit - i) + { + top[0] = base; + top[1] = j; + base = i; + } + else + { + top[0] = i; + top[1] = limit; + limit = j; + } + top += 2; + } + else + { + // the sub-array is small, perform insertion sort + j = base; + i = j + 1; + + for(; i < limit; j = i, i++) + { + for(; less(arr[j + 1], arr[j]); j--) + { + Swap(arr[j + 1], arr[j]); + if(j == base) + { + break; + } + } + } + if(top > stack) + { + top -= 2; + base = top[0]; + limit = top[1]; + } + else + { + break; + } + } + } +} + + +//----------------------------------------------------------------------------------- +// ***** QuickSortSliced +// +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. +// The range is specified with start, end, where "end" is exclusive! +// The data type must have a defined "<" operator. +template +void QuickSortSliced(Array& arr, size_t start, size_t end) +{ + typedef typename Array::ValueType ValueType; + QuickSortSliced(arr, start, end, OperatorLess::Compare); +} + +// Same as corresponding G_QuickSortSliced but with checking array limits to avoid +// crash in the case of wrong comparator functor. +template +bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end, Less less) +{ + enum + { + Threshold = 9 + }; + + if(end - start < 2) return true; + + intptr_t stack[80]; + intptr_t* top = stack; + intptr_t base = (intptr_t)start; + intptr_t limit = (intptr_t)end; + + for(;;) + { + intptr_t len = limit - base; + intptr_t i, j, pivot; + + if(len > Threshold) + { + // we use base + len/2 as the pivot + pivot = base + len / 2; + Swap(arr[base], arr[pivot]); + + i = base + 1; + j = limit - 1; + + // now ensure that *i <= *base <= *j + if(less(arr[j], arr[i])) Swap(arr[j], arr[i]); + if(less(arr[base], arr[i])) Swap(arr[base], arr[i]); + if(less(arr[j], arr[base])) Swap(arr[j], arr[base]); + + for(;;) + { + do + { + i++; + if (i >= limit) + return false; + } while( less(arr[i], arr[base]) ); + do + { + j--; + if (j < 0) + return false; + } while( less(arr[base], arr[j]) ); + + if( i > j ) + { + break; + } + + Swap(arr[i], arr[j]); + } + + Swap(arr[base], arr[j]); + + // now, push the largest sub-array + if(j - base > limit - i) + { + top[0] = base; + top[1] = j; + base = i; + } + else + { + top[0] = i; + top[1] = limit; + limit = j; + } + top += 2; + } + else + { + // the sub-array is small, perform insertion sort + j = base; + i = j + 1; + + for(; i < limit; j = i, i++) + { + for(; less(arr[j + 1], arr[j]); j--) + { + Swap(arr[j + 1], arr[j]); + if(j == base) + { + break; + } + } + } + if(top > stack) + { + top -= 2; + base = top[0]; + limit = top[1]; + } + else + { + break; + } + } + } + return true; +} + +template +bool QuickSortSlicedSafe(Array& arr, size_t start, size_t end) +{ + typedef typename Array::ValueType ValueType; + return QuickSortSlicedSafe(arr, start, end, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** QuickSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The comparison predicate must be specified. +template +void QuickSort(Array& arr, Less less) +{ + QuickSortSliced(arr, 0, arr.GetSize(), less); +} + +// checks for boundaries +template +bool QuickSortSafe(Array& arr, Less less) +{ + return QuickSortSlicedSafe(arr, 0, arr.GetSize(), less); +} + + +//----------------------------------------------------------------------------------- +// ***** QuickSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The data type must have a defined "<" operator. +template +void QuickSort(Array& arr) +{ + typedef typename Array::ValueType ValueType; + QuickSortSliced(arr, 0, arr.GetSize(), OperatorLess::Compare); +} + +template +bool QuickSortSafe(Array& arr) +{ + typedef typename Array::ValueType ValueType; + return QuickSortSlicedSafe(arr, 0, arr.GetSize(), OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** InsertionSortSliced +// +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. +// The range is specified with start, end, where "end" is exclusive! +// The comparison predicate must be specified. +// Unlike Quick Sort, the Insertion Sort works much slower in average, +// but may be much faster on almost sorted arrays. Besides, it guarantees +// that the elements will not be swapped if not necessary. For example, +// an array with all equal elements will remain "untouched", while +// Quick Sort will considerably shuffle the elements in this case. +template +void InsertionSortSliced(Array& arr, size_t start, size_t end, Less less) +{ + size_t j = start; + size_t i = j + 1; + size_t limit = end; + + for(; i < limit; j = i, i++) + { + for(; less(arr[j + 1], arr[j]); j--) + { + Swap(arr[j + 1], arr[j]); + if(j <= start) + { + break; + } + } + } +} + + +//----------------------------------------------------------------------------------- +// ***** InsertionSortSliced +// +// Sort any part of any array: plain, Array, ArrayPaged, ArrayUnsafe. +// The range is specified with start, end, where "end" is exclusive! +// The data type must have a defined "<" operator. +template +void InsertionSortSliced(Array& arr, size_t start, size_t end) +{ + typedef typename Array::ValueType ValueType; + InsertionSortSliced(arr, start, end, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** InsertionSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The comparison predicate must be specified. + +template +void InsertionSort(Array& arr, Less less) +{ + InsertionSortSliced(arr, 0, arr.GetSize(), less); +} + +//----------------------------------------------------------------------------------- +// ***** InsertionSort +// +// Sort an array Array, ArrayPaged, ArrayUnsafe. +// The array must have GetSize() function. +// The data type must have a defined "<" operator. +template +void InsertionSort(Array& arr) +{ + typedef typename Array::ValueType ValueType; + InsertionSortSliced(arr, 0, arr.GetSize(), OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** Median +// Returns a median value of the input array. +// Caveats: partially sorts the array, returns a reference to the array element +// TBD: This needs to be optimized and generalized +// +template +typename Array::ValueType& Median(Array& arr) +{ + size_t count = arr.GetSize(); + size_t mid = (count - 1) / 2; + OVR_ASSERT(count > 0); + + for (size_t j = 0; j <= mid; j++) + { + size_t min = j; + for (size_t k = j + 1; k < count; k++) + if (arr[k] < arr[min]) + min = k; + Swap(arr[j], arr[min]); + } + return arr[mid]; +} + +//----------------------------------------------------------------------------------- +// ***** LowerBoundSliced +// +template +size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) +{ + intptr_t first = (intptr_t)start; + intptr_t len = (intptr_t)(end - start); + intptr_t half; + intptr_t middle; + + while(len > 0) + { + half = len >> 1; + middle = first + half; + if(less(arr[middle], val)) + { + first = middle + 1; + len = len - half - 1; + } + else + { + len = half; + } + } + return (size_t)first; +} + + +//----------------------------------------------------------------------------------- +// ***** LowerBoundSliced +// +template +size_t LowerBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) +{ + return LowerBoundSliced(arr, start, end, val, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** LowerBoundSized +// +template +size_t LowerBoundSized(const Array& arr, size_t size, const Value& val) +{ + return LowerBoundSliced(arr, 0, size, val, OperatorLess::Compare); +} + +//----------------------------------------------------------------------------------- +// ***** LowerBound +// +template +size_t LowerBound(const Array& arr, const Value& val, Less less) +{ + return LowerBoundSliced(arr, 0, arr.GetSize(), val, less); +} + + +//----------------------------------------------------------------------------------- +// ***** LowerBound +// +template +size_t LowerBound(const Array& arr, const Value& val) +{ + return LowerBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess::Compare); +} + + + +//----------------------------------------------------------------------------------- +// ***** UpperBoundSliced +// +template +size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val, Less less) +{ + intptr_t first = (intptr_t)start; + intptr_t len = (intptr_t)(end - start); + intptr_t half; + intptr_t middle; + + while(len > 0) + { + half = len >> 1; + middle = first + half; + if(less(val, arr[middle])) + { + len = half; + } + else + { + first = middle + 1; + len = len - half - 1; + } + } + return (size_t)first; +} + + +//----------------------------------------------------------------------------------- +// ***** UpperBoundSliced +// +template +size_t UpperBoundSliced(const Array& arr, size_t start, size_t end, const Value& val) +{ + return UpperBoundSliced(arr, start, end, val, OperatorLess::Compare); +} + + +//----------------------------------------------------------------------------------- +// ***** UpperBoundSized +// +template +size_t UpperBoundSized(const Array& arr, size_t size, const Value& val) +{ + return UpperBoundSliced(arr, 0, size, val, OperatorLess::Compare); +} + + +//----------------------------------------------------------------------------------- +// ***** UpperBound +// +template +size_t UpperBound(const Array& arr, const Value& val, Less less) +{ + return UpperBoundSliced(arr, 0, arr.GetSize(), val, less); +} + + +//----------------------------------------------------------------------------------- +// ***** UpperBound +// +template +size_t UpperBound(const Array& arr, const Value& val) +{ + return UpperBoundSliced(arr, 0, arr.GetSize(), val, OperatorLess::Compare); +} + + +//----------------------------------------------------------------------------------- +// ***** ReverseArray +// +template void ReverseArray(Array& arr) +{ + intptr_t from = 0; + intptr_t to = arr.GetSize() - 1; + while(from < to) + { + Swap(arr[from], arr[to]); + ++from; + --to; + } +} + + +// ***** AppendArray +// +template +void AppendArray(CDst& dst, const CSrc& src) +{ + size_t i; + for(i = 0; i < src.GetSize(); i++) + dst.PushBack(src[i]); +} + +//----------------------------------------------------------------------------------- +// ***** ArrayAdaptor +// +// A simple adapter that provides the GetSize() method and overloads +// operator []. Used to wrap plain arrays in QuickSort and such. +template class ArrayAdaptor +{ +public: + typedef T ValueType; + ArrayAdaptor() : Data(0), Size(0) {} + ArrayAdaptor(T* ptr, size_t size) : Data(ptr), Size(size) {} + size_t GetSize() const { return Size; } + int GetSizeI() const { return (int)GetSize(); } + const T& operator [] (size_t i) const { return Data[i]; } + T& operator [] (size_t i) { return Data[i]; } +private: + T* Data; + size_t Size; +}; + + +//----------------------------------------------------------------------------------- +// ***** GConstArrayAdaptor +// +// A simple const adapter that provides the GetSize() method and overloads +// operator []. Used to wrap plain arrays in LowerBound and such. +template class ConstArrayAdaptor +{ +public: + typedef T ValueType; + ConstArrayAdaptor() : Data(0), Size(0) {} + ConstArrayAdaptor(const T* ptr, size_t size) : Data(ptr), Size(size) {} + size_t GetSize() const { return Size; } + int GetSizeI() const { return (int)GetSize(); } + const T& operator [] (size_t i) const { return Data[i]; } +private: + const T* Data; + size_t Size; +}; + + + +//----------------------------------------------------------------------------------- +extern const uint8_t UpperBitTable[256]; +extern const uint8_t LowerBitTable[256]; + + + +//----------------------------------------------------------------------------------- +inline uint8_t UpperBit(size_t val) +{ +#ifndef OVR_64BIT_POINTERS + + if (val & 0xFFFF0000) + { + return (val & 0xFF000000) ? + UpperBitTable[(val >> 24) ] + 24: + UpperBitTable[(val >> 16) & 0xFF] + 16; + } + return (val & 0xFF00) ? + UpperBitTable[(val >> 8) & 0xFF] + 8: + UpperBitTable[(val ) & 0xFF]; + +#else + + if (val & 0xFFFFFFFF00000000) + { + if (val & 0xFFFF000000000000) + { + return (val & 0xFF00000000000000) ? + UpperBitTable[(val >> 56) ] + 56: + UpperBitTable[(val >> 48) & 0xFF] + 48; + } + return (val & 0xFF0000000000) ? + UpperBitTable[(val >> 40) & 0xFF] + 40: + UpperBitTable[(val >> 32) & 0xFF] + 32; + } + else + { + if (val & 0xFFFF0000) + { + return (val & 0xFF000000) ? + UpperBitTable[(val >> 24) ] + 24: + UpperBitTable[(val >> 16) & 0xFF] + 16; + } + return (val & 0xFF00) ? + UpperBitTable[(val >> 8) & 0xFF] + 8: + UpperBitTable[(val ) & 0xFF]; + } + +#endif +} + +//----------------------------------------------------------------------------------- +inline uint8_t LowerBit(size_t val) +{ +#ifndef OVR_64BIT_POINTERS + + if (val & 0xFFFF) + { + return (val & 0xFF) ? + LowerBitTable[ val & 0xFF]: + LowerBitTable[(val >> 8) & 0xFF] + 8; + } + return (val & 0xFF0000) ? + LowerBitTable[(val >> 16) & 0xFF] + 16: + LowerBitTable[(val >> 24) & 0xFF] + 24; + +#else + + if (val & 0xFFFFFFFF) + { + if (val & 0xFFFF) + { + return (val & 0xFF) ? + LowerBitTable[ val & 0xFF]: + LowerBitTable[(val >> 8) & 0xFF] + 8; + } + return (val & 0xFF0000) ? + LowerBitTable[(val >> 16) & 0xFF] + 16: + LowerBitTable[(val >> 24) & 0xFF] + 24; + } + else + { + if (val & 0xFFFF00000000) + { + return (val & 0xFF00000000) ? + LowerBitTable[(val >> 32) & 0xFF] + 32: + LowerBitTable[(val >> 40) & 0xFF] + 40; + } + return (val & 0xFF000000000000) ? + LowerBitTable[(val >> 48) & 0xFF] + 48: + LowerBitTable[(val >> 56) & 0xFF] + 56; + } + +#endif +} + + + +// ******* Special (optimized) memory routines +// Note: null (bad) pointer is not tested +class MemUtil +{ +public: + + // Memory compare + static int Cmp (const void* p1, const void* p2, size_t byteCount) { return memcmp(p1, p2, byteCount); } + static int Cmp16(const void* p1, const void* p2, size_t int16Count); + static int Cmp32(const void* p1, const void* p2, size_t int32Count); + static int Cmp64(const void* p1, const void* p2, size_t int64Count); +}; + +// ** Inline Implementation + +inline int MemUtil::Cmp16(const void* p1, const void* p2, size_t int16Count) +{ + int16_t* pa = (int16_t*)p1; + int16_t* pb = (int16_t*)p2; + unsigned ic = 0; + if (int16Count == 0) + return 0; + while (pa[ic] == pb[ic]) + if (++ic==int16Count) + return 0; + return pa[ic] > pb[ic] ? 1 : -1; +} +inline int MemUtil::Cmp32(const void* p1, const void* p2, size_t int32Count) +{ + int32_t* pa = (int32_t*)p1; + int32_t* pb = (int32_t*)p2; + unsigned ic = 0; + if (int32Count == 0) + return 0; + while (pa[ic] == pb[ic]) + if (++ic==int32Count) + return 0; + return pa[ic] > pb[ic] ? 1 : -1; +} +inline int MemUtil::Cmp64(const void* p1, const void* p2, size_t int64Count) +{ + int64_t* pa = (int64_t*)p1; + int64_t* pb = (int64_t*)p2; + unsigned ic = 0; + if (int64Count == 0) + return 0; + while (pa[ic] == pb[ic]) + if (++ic==int64Count) + return 0; + return pa[ic] > pb[ic] ? 1 : -1; +} + +// ** End Inline Implementation + + +//----------------------------------------------------------------------------------- +// ******* Byte Order Conversions +namespace ByteUtil { + + // *** Swap Byte Order + + // Swap the byte order of a byte array + inline void SwapOrder(void* pv, int size) + { + uint8_t* pb = (uint8_t*)pv; + uint8_t temp; + for (int i = 0; i < size>>1; i++) + { + temp = pb[size-1-i]; + pb[size-1-i] = pb[i]; + pb[i] = temp; + } + } + + // Swap the byte order of primitive types + inline uint8_t SwapOrder(uint8_t v) { return v; } + inline int8_t SwapOrder(int8_t v) { return v; } + inline uint16_t SwapOrder(uint16_t v) { return uint16_t(v>>8)|uint16_t(v<<8); } + inline int16_t SwapOrder(int16_t v) { return int16_t((uint16_t(v)>>8)|(v<<8)); } + inline uint32_t SwapOrder(uint32_t v) { return (v>>24)|((v&0x00FF0000)>>8)|((v&0x0000FF00)<<8)|(v<<24); } + inline int32_t SwapOrder(int32_t p) { return (int32_t)SwapOrder(uint32_t(p)); } + inline uint64_t SwapOrder(uint64_t v) + { + return (v>>56) | + ((v&uint64_t(0x00FF000000000000ULL))>>40) | + ((v&uint64_t(0x0000FF0000000000ULL))>>24) | + ((v&uint64_t(0x000000FF00000000ULL))>>8) | + ((v&uint64_t(0x00000000FF000000ULL))<<8) | + ((v&uint64_t(0x0000000000FF0000ULL))<<24) | + ((v&uint64_t(0x000000000000FF00ULL))<<40) | + (v<<56); + } + inline int64_t SwapOrder(int64_t v) { return (int64_t)SwapOrder(uint64_t(v)); } + inline float SwapOrder(float p) + { + union { + float p; + uint32_t v; + } u; + u.p = p; + u.v = SwapOrder(u.v); + return u.p; + } + + inline double SwapOrder(double p) + { + union { + double p; + uint64_t v; + } u; + u.p = p; + u.v = SwapOrder(u.v); + return u.p; + } + + // *** Byte-order conversion + +#if (OVR_BYTE_ORDER == OVR_LITTLE_ENDIAN) + // Little Endian to System (LE) + inline uint8_t LEToSystem(uint8_t v) { return v; } + inline int8_t LEToSystem(int8_t v) { return v; } + inline uint16_t LEToSystem(uint16_t v) { return v; } + inline int16_t LEToSystem(int16_t v) { return v; } + inline uint32_t LEToSystem(uint32_t v) { return v; } + inline int32_t LEToSystem(int32_t v) { return v; } + inline uint64_t LEToSystem(uint64_t v) { return v; } + inline int64_t LEToSystem(int64_t v) { return v; } + inline float LEToSystem(float v) { return v; } + inline double LEToSystem(double v) { return v; } + + // Big Endian to System (LE) + inline uint8_t BEToSystem(uint8_t v) { return SwapOrder(v); } + inline int8_t BEToSystem(int8_t v) { return SwapOrder(v); } + inline uint16_t BEToSystem(uint16_t v) { return SwapOrder(v); } + inline int16_t BEToSystem(int16_t v) { return SwapOrder(v); } + inline uint32_t BEToSystem(uint32_t v) { return SwapOrder(v); } + inline int32_t BEToSystem(int32_t v) { return SwapOrder(v); } + inline uint64_t BEToSystem(uint64_t v) { return SwapOrder(v); } + inline int64_t BEToSystem(int64_t v) { return SwapOrder(v); } + inline float BEToSystem(float v) { return SwapOrder(v); } + inline double BEToSystem(double v) { return SwapOrder(v); } + + // System (LE) to Little Endian + inline uint8_t SystemToLE(uint8_t v) { return v; } + inline int8_t SystemToLE(int8_t v) { return v; } + inline uint16_t SystemToLE(uint16_t v) { return v; } + inline int16_t SystemToLE(int16_t v) { return v; } + inline uint32_t SystemToLE(uint32_t v) { return v; } + inline int32_t SystemToLE(int32_t v) { return v; } + inline uint64_t SystemToLE(uint64_t v) { return v; } + inline int64_t SystemToLE(int64_t v) { return v; } + inline float SystemToLE(float v) { return v; } + inline double SystemToLE(double v) { return v; } + + // System (LE) to Big Endian + inline uint8_t SystemToBE(uint8_t v) { return SwapOrder(v); } + inline int8_t SystemToBE(int8_t v) { return SwapOrder(v); } + inline uint16_t SystemToBE(uint16_t v) { return SwapOrder(v); } + inline int16_t SystemToBE(int16_t v) { return SwapOrder(v); } + inline uint32_t SystemToBE(uint32_t v) { return SwapOrder(v); } + inline int32_t SystemToBE(int32_t v) { return SwapOrder(v); } + inline uint64_t SystemToBE(uint64_t v) { return SwapOrder(v); } + inline int64_t SystemToBE(int64_t v) { return SwapOrder(v); } + inline float SystemToBE(float v) { return SwapOrder(v); } + inline double SystemToBE(double v) { return SwapOrder(v); } + +#elif (OVR_BYTE_ORDER == OVR_BIG_ENDIAN) + // Little Endian to System (BE) + inline uint8_t LEToSystem(uint8_t v) { return SwapOrder(v); } + inline int8_t LEToSystem(int8_t v) { return SwapOrder(v); } + inline uint16_t LEToSystem(uint16_t v) { return SwapOrder(v); } + inline int16_t LEToSystem(int16_t v) { return SwapOrder(v); } + inline uint32_t LEToSystem(uint32_t v) { return SwapOrder(v); } + inline int32_t LEToSystem(int32_t v) { return SwapOrder(v); } + inline uint64_t LEToSystem(uint64_t v) { return SwapOrder(v); } + inline int64_t LEToSystem(int64_t v) { return SwapOrder(v); } + inline float LEToSystem(float v) { return SwapOrder(v); } + inline double LEToSystem(double v) { return SwapOrder(v); } + + // Big Endian to System (BE) + inline uint8_t BEToSystem(uint8_t v) { return v; } + inline int8_t BEToSystem(int8_t v) { return v; } + inline uint16_t BEToSystem(uint16_t v) { return v; } + inline int16_t BEToSystem(int16_t v) { return v; } + inline uint32_t BEToSystem(uint32_t v) { return v; } + inline int32_t BEToSystem(int32_t v) { return v; } + inline uint64_t BEToSystem(uint64_t v) { return v; } + inline int64_t BEToSystem(int64_t v) { return v; } + inline float BEToSystem(float v) { return v; } + inline double BEToSystem(double v) { return v; } + + // System (BE) to Little Endian + inline uint8_t SystemToLE(uint8_t v) { return SwapOrder(v); } + inline int8_t SystemToLE(int8_t v) { return SwapOrder(v); } + inline uint16_t SystemToLE(uint16_t v) { return SwapOrder(v); } + inline int16_t SystemToLE(int16_t v) { return SwapOrder(v); } + inline uint32_t SystemToLE(uint32_t v) { return SwapOrder(v); } + inline int32_t SystemToLE(int32_t v) { return SwapOrder(v); } + inline uint64_t SystemToLE(uint64_t v) { return SwapOrder(v); } + inline int64_t SystemToLE(int64_t v) { return SwapOrder(v); } + inline float SystemToLE(float v) { return SwapOrder(v); } + inline double SystemToLE(double v) { return SwapOrder(v); } + + // System (BE) to Big Endian + inline uint8_t SystemToBE(uint8_t v) { return v; } + inline int8_t SystemToBE(int8_t v) { return v; } + inline uint16_t SystemToBE(uint16_t v) { return v; } + inline int16_t SystemToBE(int16_t v) { return v; } + inline uint32_t SystemToBE(uint32_t v) { return v; } + inline int32_t SystemToBE(int32_t v) { return v; } + inline uint64_t SystemToBE(uint64_t v) { return v; } + inline int64_t SystemToBE(int64_t v) { return v; } + inline float SystemToBE(float v) { return v; } + inline double SystemToBE(double v) { return v; } + +#else + #error "OVR_BYTE_ORDER must be defined to OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN" +#endif + +} // namespace ByteUtil + + + +// Used primarily for hardware interfacing such as sensor reports, firmware, etc. +// Reported data is all little-endian. +inline uint16_t DecodeUInt16(const uint8_t* buffer) +{ + return ByteUtil::LEToSystem ( *(const uint16_t*)buffer ); +} + +inline int16_t DecodeSInt16(const uint8_t* buffer) +{ + return ByteUtil::LEToSystem ( *(const int16_t*)buffer ); +} + +inline uint32_t DecodeUInt32(const uint8_t* buffer) +{ + return ByteUtil::LEToSystem ( *(const uint32_t*)buffer ); +} + +inline int32_t DecodeSInt32(const uint8_t* buffer) +{ + return ByteUtil::LEToSystem ( *(const int32_t*)buffer ); +} + +inline float DecodeFloat(const uint8_t* buffer) +{ + union { + uint32_t U; + float F; + }; + + U = DecodeUInt32(buffer); + return F; +} + +inline void EncodeUInt16(uint8_t* buffer, uint16_t val) +{ + *(uint16_t*)buffer = ByteUtil::SystemToLE ( val ); +} + +inline void EncodeSInt16(uint8_t* buffer, int16_t val) +{ + *(int16_t*)buffer = ByteUtil::SystemToLE ( val ); +} + +inline void EncodeUInt32(uint8_t* buffer, uint32_t val) +{ + *(uint32_t*)buffer = ByteUtil::SystemToLE ( val ); +} + +inline void EncodeSInt32(uint8_t* buffer, int32_t val) +{ + *(int32_t*)buffer = ByteUtil::SystemToLE ( val ); +} + +inline void EncodeFloat(uint8_t* buffer, float val) +{ + union { + uint32_t U; + float F; + }; + + F = val; + EncodeUInt32(buffer, U); +} + +// Converts an 8-bit binary-coded decimal +inline int8_t DecodeBCD(uint8_t byte) +{ + uint8_t digit1 = (byte >> 4) & 0x0f; + uint8_t digit2 = byte & 0x0f; + int decimal = digit1 * 10 + digit2; // maximum value = 99 + return (int8_t)decimal; +} + + +}} // OVR::Alg + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Allocator.cpp b/LibOVRKernel/Src/Kernel/OVR_Allocator.cpp new file mode 100644 index 0000000..c4f2ad9 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Allocator.cpp @@ -0,0 +1,842 @@ +/************************************************************************************ + +Filename : OVR_Allocator.cpp +Content : Installable memory allocator implementation +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Allocator.h" +#include "OVR_DebugHelp.h" +#include + +#ifdef OVR_OS_MAC + #include + #include +#else + #include +#endif + +#if defined(OVR_OS_MS) + #include "OVR_Win32_IncludeWindows.h" +#elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) + #include + #include +#endif + +namespace OVR { + + +//----------------------------------------------------------------------------------- +// ***** Allocator + +Allocator* Allocator::pInstance = 0; + +// Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding. +void* Allocator::AllocAligned(size_t size, size_t align) +{ + OVR_ASSERT((align & (align-1)) == 0); + align = (align > sizeof(size_t)) ? align : sizeof(size_t); + size_t p = (size_t)Alloc(size+align); + size_t aligned = 0; + if (p) + { + aligned = (size_t(p) + align-1) & ~(align-1); + if (aligned == p) + aligned += align; + *(((size_t*)aligned)-1) = aligned-p; + } + + trackAlloc((void*)aligned, size); + + return (void*)aligned; +} + +void Allocator::FreeAligned(void* p) +{ + untrackAlloc((void*)p); + + size_t src = size_t(p) - *(((size_t*)p) - 1); + Free((void*)src); +} + + +//------------------------------------------------------------------------ +// ***** Default Allocator + +// This allocator is created and used if no other allocator is installed. +// Default allocator delegates to system malloc. + +void* DefaultAllocator::Alloc(size_t size) +{ + void* p = malloc(size); + trackAlloc(p, size); + return p; +} +void* DefaultAllocator::AllocDebug(size_t size, const char* file, unsigned line) +{ + OVR_UNUSED2(file, line); // should be here for debugopt config + void* p; +#if defined(OVR_CC_MSVC) && defined(_CRTDBG_MAP_ALLOC) + p = _malloc_dbg(size, _NORMAL_BLOCK, file, line); +#else + p = malloc(size); +#endif + trackAlloc(p, size); + return p; +} + +void* DefaultAllocator::Realloc(void* p, size_t newSize) +{ + void* newP = realloc(p, newSize); + + // This used to more efficiently check if (newp != p) but static analyzers were erroneously flagging this. + if(newP) // Need to check newP because realloc doesn't free p unless it returns a valid newP. + { + #if !defined(__clang_analyzer__) // The analyzer complains that we are using p after it was freed. + untrackAlloc(p); + #endif + } + trackAlloc(newP, newSize); + return newP; +} + +void DefaultAllocator::Free(void *p) +{ + untrackAlloc(p); + return free(p); +} + + +// System block allocator: + +void* SafeMMapAlloc(size_t size) +{ + #if defined(OVR_OS_MS) + return VirtualAlloc(nullptr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // size is rounded up to a page. // Returned memory is 0-filled. + + #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) + #if !defined(MAP_FAILED) + #define MAP_FAILED ((void*)-1) + #endif + + void* result = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); // Returned memory is 0-filled. + if(result == MAP_FAILED) // mmap returns MAP_FAILED (-1) upon failure. + result = nullptr; + return result; + #endif +} + +void SafeMMapFree(const void* memory, size_t size) +{ + #if defined(OVR_OS_MS) + OVR_UNUSED(size); + VirtualFree(const_cast(memory), 0, MEM_RELEASE); + + #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) + size_t pageSize = getpagesize(); + size = (((size + (pageSize - 1)) / pageSize) * pageSize); + munmap(const_cast(memory), size); // Must supply the size to munmap. + #endif +} + + +//------------------------------------------------------------------------ +// ***** Track Allocations + +struct TrackedAlloc +{ + TrackedAlloc* pNext; + TrackedAlloc* pPrev; + void* pAlloc; + void* Callstack[64]; + uint32_t FrameCount; + uint32_t Size; +}; + +static TrackedAlloc* TrackHead = nullptr; +static SymbolLookup Symbols; +static bool IsLeakTracking = false; + +void Allocator::SetLeakTracking(bool enabled) +{ +#if defined(OVR_OS_WIN32) && !defined(OVR_OS_WIN64) + // HACK: Currently 32-bit leak tracing is too slow to run in real-time on Windows. + // Note: We can possibly fix this by making a custom Win32 backtrace function which + // takes advantage of the fact that we have enabled stack frames in all builds. + enabled = false; +#endif + + IsLeakTracking = enabled; +} + +bool Allocator::IsTrackingLeaks() +{ + return IsLeakTracking; +} + +void Allocator::trackAlloc(void* p, size_t size) +{ + if (!p || !IsLeakTracking) + return; + + Lock::Locker locker(&TrackLock); + + TrackedAlloc* tracked = (TrackedAlloc*)malloc(sizeof(TrackedAlloc)); + if (tracked) + { + memset(tracked, 0, sizeof(TrackedAlloc)); + + tracked->pAlloc = p; + tracked->pPrev = nullptr; + tracked->FrameCount = (uint32_t)Symbols.GetBacktrace(tracked->Callstack, OVR_ARRAY_COUNT(tracked->Callstack), 2); + tracked->Size = (uint32_t)size; + + tracked->pNext = TrackHead; + if (TrackHead) + { + TrackHead->pPrev = tracked; + } + TrackHead = tracked; + } +} + +void Allocator::untrackAlloc(void* p) +{ + if (!p || !IsLeakTracking) + return; + + Lock::Locker locker(&TrackLock); + + for (TrackedAlloc* t = TrackHead; t; t = t->pNext) + { + if (t->pAlloc == p) + { + if (t->pPrev) + { + t->pPrev->pNext = t->pNext; + } + if (t->pNext) + { + t->pNext->pPrev = t->pPrev; + } + if (TrackHead == t) + { + TrackHead = t->pNext; + } + free(t); + + break; + } + } +} + +int DumpMemory() +{ + const bool symbolLookupWasInitialized = SymbolLookup::IsInitialized(); + const bool symbolLookupAvailable = SymbolLookup::Initialize(); + + if(!symbolLookupWasInitialized) // If SymbolLookup::Initialize was the first time being initialized, we need to refresh the Symbols view of modules, etc. + Symbols.Refresh(); + + // If we're dumping while LibOVR is running, then we should hold the lock. + Allocator* pAlloc = Allocator::GetInstance(); + + // It's possible this is being called after the Allocator was shut down, at which + // point we assume we are the only instance that can be executing at his time. + Lock* lock = pAlloc ? &pAlloc->TrackLock : nullptr; + if (lock) + lock->DoLock(); + + int leakCount = 0; + + for (TrackedAlloc* t = TrackHead; t; t = t->pNext) + { + LogError("[Leak] ** Detected leaked allocation at %p (size = %u) (%d frames)", t->pAlloc, (unsigned)t->Size, (unsigned)t->FrameCount); + + for (size_t i = 0; i < t->FrameCount; ++i) + { + SymbolInfo symbolInfo; + + if (symbolLookupAvailable && Symbols.LookupSymbol((uint64_t)t->Callstack[i], symbolInfo) && (symbolInfo.filePath[0] || symbolInfo.function[0])) + { + if(symbolInfo.filePath[0]) + LogText("%s(%d): %s\n", symbolInfo.filePath, symbolInfo.fileLineNumber, symbolInfo.function[0] ? symbolInfo.function : "(unknown function)"); + else + LogText("%p (unknown source file): %s\n", t->Callstack[i], symbolInfo.function); + } + else + { + LogText("%p (symbols unavailable)\n", t->Callstack[i]); + } + } + + ++leakCount; + } + + if (lock) + lock->Unlock(); + + if(symbolLookupAvailable) + SymbolLookup::Shutdown(); + + return leakCount; +} + + + +//------------------------------------------------------------------------ +// ***** DebugPageAllocator + +static size_t AlignSizeUp(size_t value, size_t alignment) +{ + return ((value + (alignment - 1)) & ~(alignment - 1)); +} + +static size_t AlignSizeDown(size_t value, size_t alignment) +{ + return (value & ~(alignment - 1)); +} + +template +Pointer AlignPointerUp(Pointer p, size_t alignment) +{ + return reinterpret_cast(((reinterpret_cast(p) + (alignment - 1)) & ~(alignment - 1))); +} + +template +Pointer AlignPointerDown(Pointer p, size_t alignment) +{ + return reinterpret_cast(reinterpret_cast(p) & ~(alignment-1)); +} + + +const size_t kFreedBlockArrayMaxSizeDefault = 16384; + + +DebugPageAllocator::DebugPageAllocator() + : FreedBlockArray(nullptr) + , FreedBlockArrayMaxSize(0) + , FreedBlockArraySize(0) + , FreedBlockArrayOldest(0) + , AllocationCount(0) + , OverrunPageEnabled(true) + #if defined(OVR_BUILD_DEBUG) + , OverrunGuardBytesEnabled(true) + #else + , OverrunGuardBytesEnabled(false) + #endif + //PageSize(0) + , Lock() +{ + #if defined(_WIN32) + SYSTEM_INFO systemInfo; + GetSystemInfo(&systemInfo); + PageSize = (size_t)systemInfo.dwPageSize; + #else + PageSize = 4096; + #endif + + SetDelayedFreeCount(kFreedBlockArrayMaxSizeDefault); +} + + +DebugPageAllocator::~DebugPageAllocator() +{ + Shutdown(); +} + + +void DebugPageAllocator::Init() +{ + // Nothing to do. +} + +void DebugPageAllocator::Shutdown() +{ + Lock::Locker autoLock(&Lock); + + for(size_t i = 0; i < FreedBlockArraySize; i++) + { + if(FreedBlockArray[i].BlockPtr) + { + FreePageMemory(FreedBlockArray[i].BlockPtr, FreedBlockArray[i].BlockSize); + FreedBlockArray[i].Clear(); + } + } + + SetDelayedFreeCount(0); + FreedBlockArraySize = 0; + FreedBlockArrayOldest = 0; +} + + +void DebugPageAllocator::EnableOverrunDetection(bool enableOverrunDetection, bool enableOverrunGuardBytes) +{ + OVR_ASSERT(AllocationCount == 0); + + OverrunPageEnabled = enableOverrunDetection; + OverrunGuardBytesEnabled = (enableOverrunDetection && enableOverrunGuardBytes); // Set OverrunGuardBytesEnabled to false if enableOverrunDetection is false. +} + + +void DebugPageAllocator::SetDelayedFreeCount(size_t delayedFreeCount) +{ + OVR_ASSERT(AllocationCount == 0); + + if(FreedBlockArray) + { + SafeMMapFree(FreedBlockArray, FreedBlockArrayMaxSize * sizeof(Block)); + FreedBlockArrayMaxSize = 0; + } + + if(delayedFreeCount) + { + FreedBlockArray = (Block*)SafeMMapAlloc(delayedFreeCount * sizeof(Block)); + OVR_ASSERT(FreedBlockArray); + + if(FreedBlockArray) + { + FreedBlockArrayMaxSize = delayedFreeCount; + #if defined(OVR_BUILD_DEBUG) + memset(FreedBlockArray, 0, delayedFreeCount * sizeof(Block)); + #endif + } + } +} + + +size_t DebugPageAllocator::GetDelayedFreeCount() const +{ + return FreedBlockArrayMaxSize; +} + + +void* DebugPageAllocator::Alloc(size_t size) +{ + #if defined(_WIN32) + return AllocAligned(size, DefaultAlignment); + #else + void* p = malloc(size); + trackAlloc(p, size); + return p; + #endif +} + + +void* DebugPageAllocator::AllocAligned(size_t size, size_t align) +{ + #if defined(_WIN32) + OVR_ASSERT(align <= PageSize); + + Lock::Locker autoLock(&Lock); + + if(align < DefaultAlignment) + align = DefaultAlignment; + + // The actual needed size may be a little less than this, but it's hard to tell how the size and alignments will play out. + size_t maxRequiredSize = AlignSizeUp(size, align) + SizeStorageSize; + + if(align > SizeStorageSize) + { + // Must do: more sophisticated fitting, as maxRequiredSize is potentially too small. + OVR_ASSERT(SizeStorageSize <= align); + } + + size_t blockSize = AlignSizeUp(maxRequiredSize, PageSize); + + if(OverrunPageEnabled) + blockSize += PageSize; // We add another page which will be uncommitted, so any read or write with it will except. + + void* pBlockPtr; + + if((FreedBlockArraySize == FreedBlockArrayMaxSize) && FreedBlockArrayMaxSize && // If there is an old block we can recycle... + (FreedBlockArray[FreedBlockArrayOldest].BlockSize == blockSize)) // We require it to be the exact size, as there would be some headaches for us if it was over-sized. + { + pBlockPtr = EnablePageMemory(FreedBlockArray[FreedBlockArrayOldest].BlockPtr, blockSize); // Convert this memory from PAGE_NOACCESS back to PAGE_READWRITE. + FreedBlockArray[FreedBlockArrayOldest].Clear(); + + if(++FreedBlockArrayOldest == FreedBlockArrayMaxSize) + FreedBlockArrayOldest = 0; + } + else + { + pBlockPtr = AllocCommittedPageMemory(blockSize); // Allocate a new block of one or more pages (via VirtualAlloc). + } + + if(pBlockPtr) + { + void* pUserPtr = GetUserPosition(pBlockPtr, blockSize, size, align); + size_t* pSizePos = GetSizePosition(pUserPtr); + + pSizePos[UserSizeIndex] = size; + pSizePos[BlockSizeIndex] = blockSize; + AllocationCount++; + trackAlloc(pUserPtr, size); + + return pUserPtr; + } + + return nullptr; + #else + OVR_ASSERT_AND_UNUSED(align <= DefaultAlignment, align); + return DebugPageAllocator::Alloc(size); + #endif +} + + +size_t DebugPageAllocator::GetUserSize(const void* p) +{ + #if defined(_WIN32) + return GetSizePosition(p)[UserSizeIndex]; + #elif defined(__APPLE__) + return malloc_size(p); + #else + return malloc_usable_size(const_cast(p)); + #endif +} + + +size_t DebugPageAllocator::GetBlockSize(const void* p) +{ + #if defined(_WIN32) + return GetSizePosition(p)[BlockSizeIndex]; + #else + OVR_UNUSED(p); + return 0; + #endif +} + + +size_t* DebugPageAllocator::GetSizePosition(const void* p) +{ + // No thread safety required as per our design, as we assume that anybody + // who owns a pointer returned by Alloc cannot have another thread take it away. + + // We assume the pointer is a valid pointer allocated by this allocator. + // We store some size values into the memory returned to the user, a few bytes before it. + size_t value = reinterpret_cast(p); + size_t valuePos = (value - SizeStorageSize); + size_t* pSize = reinterpret_cast(valuePos); + + return pSize; +} + + +void* DebugPageAllocator::Realloc(void* p, size_t newSize) +{ + #if defined(_WIN32) + return ReallocAligned(p, newSize, DefaultAlignment); + #else + void* newP = realloc(p, newSize); + + if(newP) // Need to check newP because realloc doesn't free p unless it returns a valid newP. + { + #if !defined(__clang_analyzer__) // The analyzer complains that we are using p after it was freed. + untrackAlloc(p); + #endif + } + trackAlloc(newP, newSize); + return newP; + #endif +} + + +void* DebugPageAllocator::ReallocAligned(void* p, size_t newSize, size_t newAlign) +{ + #if defined(_WIN32) + // The ISO C99 standard states: + // The realloc function deallocates the old object pointed to by ptr and + // returns a pointer to a new object that has the size specified by size. + // The contents of the new object shall be the same as that of the old + // object prior to deallocation, up to the lesser of the new and old sizes. + // Any bytes in the new object beyond the size of the old object have + // indeterminate values. + // + // If ptr is a null pointer, the realloc function behaves like the malloc + // function for the specified size. Otherwise, if ptr does not match a + // pointer earlier returned by the calloc, malloc, or realloc function, + // or if the space has been deallocated by a call to the free or realloc + // function, the behavior is undefined. If memory for the new object + // cannot be allocated, the old object is not deallocated and its value + // is unchanged. + // + // The realloc function returns a pointer to the new object (which may have + // the same value as a pointer to the old object), or a null pointer if + // the new object could not be allocated. + + // A mutex lock isn't required, as the functions below will handle it internally. + // But having it here is a little more efficient because it woudl otherwise be + // locked and unlocked multiple times below, with possible context switches in between. + Lock::Locker autoLock(&Lock); + + void* pReturn = nullptr; + + if(p) + { + if(newSize) + { + pReturn = AllocAligned(newSize, newAlign); + + if(pReturn) + { + size_t prevSize = GetUserSize(p); + + if(newSize > prevSize) + newSize = prevSize; + + memcpy(pReturn, p, newSize); + Free(p); + } // Else fall through, leaving p's memory unmodified and returning nullptr. + } + else + { + Free(p); + } + } + else if(newSize) + { + pReturn = AllocAligned(newSize, newAlign); + } + + return pReturn; + #else + OVR_ASSERT_AND_UNUSED(newAlign <= DefaultAlignment, newAlign); + return DebugPageAllocator::Realloc(p, newSize); + #endif +} + + +void DebugPageAllocator::Free(void *p) +{ + #if defined(_WIN32) + if(p) + { + Lock::Locker autoLock(&Lock); + + if(FreedBlockArrayMaxSize) // If we have a delayed free list... + { + // We don't free the page(s) associated with this but rather put them in the FreedBlockArray in an inaccessible state for later freeing. + // We do this because we don't want those pages to be available again in the near future, so we can detect use-after-free misakes. + Block* pBlockNew; + + if(FreedBlockArraySize == FreedBlockArrayMaxSize) // If we have reached freed block capacity... we can start purging old elements from it as a circular queue. + { + pBlockNew = &FreedBlockArray[FreedBlockArrayOldest]; + + // The oldest element in the container is FreedBlockArrayOldest. + if(pBlockNew->BlockPtr) // Currently this should always be true. + { + FreePageMemory(pBlockNew->BlockPtr, pBlockNew->BlockSize); + pBlockNew->Clear(); + } + + if(++FreedBlockArrayOldest == FreedBlockArrayMaxSize) + FreedBlockArrayOldest = 0; + } + else // Else we are still building the container and not yet treating it a circular. + { + pBlockNew = &FreedBlockArray[FreedBlockArraySize++]; + } + + pBlockNew->BlockPtr = GetBlockPtr(p); + pBlockNew->BlockSize = GetBlockSize(p); + + #if defined(OVR_BUILD_DEBUG) + if(OverrunGuardBytesEnabled) // If we have extra bytes at the end of the user's allocation between it and an inaccessible guard page... + { + const size_t userSize = GetUserSize(p); + const uint8_t* pUserEnd = (static_cast(p) + userSize); + const uint8_t* pPageEnd = AlignPointerUp(pUserEnd, PageSize); + + while(pUserEnd != pPageEnd) + { + if(*pUserEnd++ != GuardFillByte) + { + OVR_FAIL(); + break; + } + } + } + #endif + + DisablePageMemory(pBlockNew->BlockPtr, pBlockNew->BlockSize); // Make it so that future attempts to use this memory result in an exception. + } + else + { + FreePageMemory(GetBlockPtr(p), GetBlockSize(p)); + } + + untrackAlloc(p); + AllocationCount--; + } + #else + untrackAlloc(p); + return free(p); + #endif +} + + +void DebugPageAllocator::FreeAligned(void* p) +{ + return Free(p); +} + + +// Converts a user pointer to the beginning of its page. +void* DebugPageAllocator::GetBlockPtr(void* p) +{ + // We store size info before p in memory, and this will, by design, be always somewhere within + // the first page of a block of pages. So just align down to the beginning of its page. + return AlignPointerDown(GetSizePosition(p), PageSize); +} + + +void* DebugPageAllocator::GetUserPosition(void* pPageMemory, size_t blockSize, size_t userSize, size_t userAlignment) +{ + uint8_t* pUserPosition; + + if(OverrunPageEnabled) + { + // We need to return the highest position within the page memory that fits the user size while being aligned to userAlignment. + const size_t pageEnd = reinterpret_cast(pPageMemory) + (blockSize - PageSize); // pageEnd points to the beginning of the final guard page. + const size_t userPosition = AlignSizeDown(pageEnd - userSize, userAlignment); + pUserPosition = reinterpret_cast(userPosition); + OVR_ASSERT((userPosition + userSize) <= pageEnd); + + // If userSize is not a multiple of userAlignment then there will be (userAlignment - userSize) bytes + // of unused memory between the user allocated space and the end of the page. There is no way around having this. + // For example, a user allocation of 3 bytes with 8 byte alignment will leave 5 unused bytes at the end of the page. + // We optionally fill those unused bytes with a pattern and upon Free verify that the pattern is undisturbed. + // This won't detect reads or writes in that area immediately as with reads or writes beyond that, but it will + // at least detect them at some point (e.g. upon Free). + #if defined(OVR_BUILD_DEBUG) + if(OverrunGuardBytesEnabled) + { + uint8_t* const pUserEnd = (pUserPosition + userSize); + const size_t remainingByteCount = (reinterpret_cast(pageEnd) - pUserEnd); + if(remainingByteCount) // If there are any left-over bytes... + memset(pUserEnd, GuardFillByte, remainingByteCount); + } + #endif + } + else + { + // We need to return the first position in the first page after SizeStorageSize bytes which is aligned to userAlignment. + const size_t lowestPossiblePos = reinterpret_cast(pPageMemory) + SizeStorageSize; + const size_t userPosition = AlignSizeUp(lowestPossiblePos, userAlignment); + pUserPosition = reinterpret_cast(userPosition); + OVR_ASSERT((userPosition + userSize) <= (reinterpret_cast(pPageMemory) + blockSize)); + } + + // Assert that the returned user pointer (actually the size info before it) will be within the first page. + // This is important because it verifieds that we haven't wasted memory and because + // our functionality for telling the start of the page block depends on it. + OVR_ASSERT(AlignPointerDown(GetSizePosition(pUserPosition), PageSize) == pPageMemory); + + return pUserPosition; +} + + +void* DebugPageAllocator::AllocCommittedPageMemory(size_t blockSize) +{ + #if defined(_WIN32) + void* p; + + if(OverrunPageEnabled) + { + // We need to make it so that last page is MEM_RESERVE and the previous pages are MEM_COMMIT + PAGE_READWRITE. + OVR_ASSERT(blockSize > PageSize); // There should always be at least one extra page. + + // Reserve blockSize amount of pages. + // We could possibly use PAGE_GUARD here for the last page. This differs from simply leaving it reserved + // because the OS will generate a one-time-only gaurd page exception. We probabl don't want this, as it's + // more useful for maintaining your own stack than for catching unintended overruns. + p = VirtualAlloc(nullptr, blockSize, MEM_RESERVE, PAGE_READWRITE); + OVR_ASSERT(p); + + if(p) + { + // Commit all but the last page. Leave the last page as merely reserved so that reads from or writes + // to it result in an immediate exception. + p = VirtualAlloc(p, blockSize - PageSize, MEM_COMMIT, PAGE_READWRITE); + OVR_ASSERT(p); + } + } + else + { + // We need to make it so that all pages are MEM_COMMIT + PAGE_READWRITE. + + p = VirtualAlloc(nullptr, blockSize, MEM_COMMIT, PAGE_READWRITE); + } + + return p; + #else + OVR_UNUSED2(blockSize, OverrunPageEnabled); + return nullptr; + #endif +} + + +// We convert disabled page memory (see DisablePageMemory) to enabled page memory. The output is the same +// as with AllocPageMemory. +void* DebugPageAllocator::EnablePageMemory(void* pPageMemory, size_t blockSize) +{ + #if defined(_WIN32) + // Make sure the entire range of memory is of type PAGE_READWRITE. + DWORD dwPrevAccess = 0; + BOOL result = VirtualProtect(pPageMemory, OverrunPageEnabled ? (blockSize - PageSize) : blockSize, PAGE_READWRITE, &dwPrevAccess); + OVR_ASSERT_AND_UNUSED(result, result); + #else + OVR_UNUSED3(pPageMemory, blockSize, OverrunPageEnabled); + #endif + + return pPageMemory; +} + + +void DebugPageAllocator::DisablePageMemory(void* pPageMemory, size_t blockSize) +{ + #if defined(_WIN32) + // Disable access to the page(s). It's faster for us to change the page access than it is to decommit or free the pages. + // However, this results in more committed physical memory usage than we would need if we instead decommitted the memory. + DWORD dwPrevAccesss = 0; + BOOL result = VirtualProtect(pPageMemory, OverrunPageEnabled ? (blockSize - PageSize) : blockSize, PAGE_NOACCESS, &dwPrevAccesss); + OVR_ASSERT_AND_UNUSED(result, result); + #else + OVR_UNUSED2(pPageMemory, blockSize); + #endif +} + + +void DebugPageAllocator::FreePageMemory(void* pPageMemory, size_t /*blockSize*/) +{ + #if defined(_WIN32) + BOOL result = VirtualFree(pPageMemory, 0, MEM_RELEASE); + OVR_ASSERT_AND_UNUSED(result, result); + #else + OVR_UNUSED(pPageMemory); + #endif +} + + + +} // namespace OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_Allocator.h b/LibOVRKernel/Src/Kernel/OVR_Allocator.h new file mode 100644 index 0000000..4eb152b --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Allocator.h @@ -0,0 +1,708 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Allocator.h +Content : Installable memory allocator +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Allocator_h +#define OVR_Allocator_h + +#include "OVR_Types.h" +#include "OVR_Atomic.h" +#include "stdlib.h" +#include "stdint.h" + + +//----------------------------------------------------------------------------------- + +// ***** Disable template-unfriendly MS VC++ warnings +#if defined(OVR_CC_MSVC) +#pragma warning(push) +// Pragma to prevent long name warnings in in VC++ +#pragma warning(disable : 4503) +#pragma warning(disable : 4786) +// In MSVC 7.1, warning about placement new POD default initializer +#pragma warning(disable : 4345) +#endif + +// Un-define new so that placement constructors work +#undef new + + +//----------------------------------------------------------------------------------- +// ***** Placement new overrides + +// Calls constructor on own memory created with "new(ptr) type" +#ifndef __PLACEMENT_NEW_INLINE +#define __PLACEMENT_NEW_INLINE + +# if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU) +# include +# else + // Useful on MSVC + OVR_FORCE_INLINE void* operator new (size_t n, void *ptr) { OVR_UNUSED(n); return ptr; } + OVR_FORCE_INLINE void operator delete (void *, void *) { } +# endif + +#endif // __PLACEMENT_NEW_INLINE + + + +//------------------------------------------------------------------------ +// ***** Macros to redefine class new/delete operators + +// Types specifically declared to allow disambiguation of address in +// class member operator new. + +#define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \ + void* operator new(size_t sz) \ + { void* p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; } \ + void* operator new(size_t sz, const char* file, int line) \ + { OVR_UNUSED2(file, line); void* p = OVR_ALLOC_DEBUG(sz, file, line); return p; } \ + void operator delete(void* p) \ + { check_delete(class_name, p); OVR_FREE(p); } \ + void operator delete(void* p, const char*, int) \ + { check_delete(class_name, p); OVR_FREE(p); } + +#define OVR_MEMORY_DEFINE_PLACEMENT_NEW \ + void* operator new (size_t n, void* ptr) { OVR_UNUSED(n); return ptr; } \ + void operator delete (void* ptr, void* ptr2) { OVR_UNUSED2(ptr, ptr2); } + + +#define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p) + +// Redefined all delete/new operators in a class without custom memory initialization +#define OVR_MEMORY_REDEFINE_NEW(class_name) \ + OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE) + + +namespace OVR { + + +//----------------------------------------------------------------------------------- +// ***** Construct / Destruct + +// Construct/Destruct functions are useful when new is redefined, as they can +// be called instead of placement new constructors. + + +template +OVR_FORCE_INLINE T* Construct(void *p) +{ + return ::new(p) T(); +} + +template +OVR_FORCE_INLINE T* Construct(void *p, const T& source) +{ + return ::new(p) T(source); +} + +// Same as above, but allows for a different type of constructor. +template +OVR_FORCE_INLINE T* ConstructAlt(void *p, const S& source) +{ + return ::new(p) T(source); +} + +template +OVR_FORCE_INLINE T* ConstructAlt(void *p, const S1& src1, const S2& src2) +{ + return ::new(p) T(src1, src2); +} + +// Note: These ConstructArray functions don't properly support the case of a C++ exception occurring midway +// during construction, as they don't deconstruct the successfully constructed array elements before returning. +template +OVR_FORCE_INLINE void ConstructArray(void *p, size_t count) +{ + uint8_t *pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + { + Construct(pdata); + } +} + +template +OVR_FORCE_INLINE void ConstructArray(void *p, size_t count, const T& source) +{ + uint8_t *pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + { + Construct(pdata, source); + } +} + +template +OVR_FORCE_INLINE void Destruct(T *pobj) +{ + pobj->~T(); + OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning. +} + +template +OVR_FORCE_INLINE void DestructArray(T *pobj, size_t count) +{ + for (size_t i=0; i~T(); +} + + +//----------------------------------------------------------------------------------- +// ***** Allocator + +// Allocator defines a memory allocation interface that developers can override +// to to provide memory for OVR; an instance of this class is typically created on +// application startup and passed into System or OVR::System constructor. +// +// +// Users implementing this interface must provide three functions: Alloc, Free, +// and Realloc. Implementations of these functions must honor the requested alignment. +// Although arbitrary alignment requests are possible, requested alignment will +// typically be small, such as 16 bytes or less. + +class Allocator +{ + friend class System; + +public: + virtual ~Allocator() + { + } + + // Returns the pointer to the current globally installed Allocator instance. + // This pointer is used for most of the memory allocations. + static Allocator* GetInstance() + { + return pInstance; + } + + + // *** Standard Alignment Alloc/Free + + // Allocate memory of specified size with default alignment. + // Alloc of size==0 will allocate a tiny block & return a valid pointer; + // this makes it suitable for new operator. + virtual void* Alloc(size_t size) = 0; + + // Same as Alloc, but provides an option of passing debug data. + virtual void* AllocDebug(size_t size, const char* /*file*/, unsigned /*line*/) + { return Alloc(size); } + + // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to + // new memory block, which may be the same as original pointer. Will return 0 if reallocation + // failed, in which case previous memory is still valid. + // Realloc to decrease size will never fail. + // Realloc of pointer == 0 is equivalent to Alloc + // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free(). + virtual void* Realloc(void* p, size_t newSize) = 0; + + // Frees memory allocated by Alloc/Realloc. + // Free of null pointer is valid and will do nothing. + virtual void Free(void *p) = 0; + + + // *** Standard Alignment Alloc/Free + + // Allocate memory of specified alignment. + // Memory allocated with AllocAligned MUST be freed with FreeAligned. + // Default implementation will delegate to Alloc/Free after doing rounding. + virtual void* AllocAligned(size_t size, size_t align); + // Frees memory allocated with AllocAligned. + virtual void FreeAligned(void* p); + +protected: + // *** Tracking of allocations w/ callstacks for debug builds. + + // Add the allocation & the callstack to the tracking database + void trackAlloc(void* p, size_t size); + // Remove the allocation from the tracking database + void untrackAlloc(void* p); + +protected: + // onSystemShutdown is called on the allocator during System::Shutdown. + // At this point, all allocations should've been freed. + virtual void onSystemShutdown() + { } + +public: + static void setInstance(Allocator* palloc) + { + OVR_ASSERT((pInstance == 0) || (palloc == 0)); + pInstance = palloc; + } + +private: + static Allocator* pInstance; + +public: + // Lock used during LibOVR execution to guard the tracked allocation list. + Lock TrackLock; + + static void SetLeakTracking(bool enabled); + static bool IsTrackingLeaks(); +}; + + +//------------------------------------------------------------------------ +// ***** Allocator_SingletonSupport + +// Allocator_SingletonSupport is a Allocator wrapper class that implements +// the InitSystemSingleton static function, used to create a global singleton +// used for the OVR::System default argument initialization. +// +// End users implementing custom Allocator interface don't need to make use of this base +// class; they can just create an instance of their own class on stack and pass it to System. + +template +class Allocator_SingletonSupport : public Allocator +{ + struct AllocContainer + { + size_t Data[(sizeof(D) + sizeof(size_t)-1) / sizeof(size_t)]; + bool Initialized; + AllocContainer() : Initialized(0) { } + }; + + AllocContainer* pContainer; + +public: + Allocator_SingletonSupport() : pContainer(0) + { } + + // Creates a singleton instance of this Allocator class used + // on OVR_DEFAULT_ALLOCATOR during System initialization. + static D* InitSystemSingleton() + { + static AllocContainer Container; + OVR_ASSERT(Container.Initialized == false); + + Allocator_SingletonSupport *presult = Construct((void*)Container.Data); + presult->pContainer = &Container; + Container.Initialized = true; + return (D*)presult; + } + +protected: + virtual void onSystemShutdown() + { + Allocator::onSystemShutdown(); + if (pContainer) + { + pContainer->Initialized = false; + pContainer = nullptr; + Destruct((D*)this); + } + } +}; + + +//------------------------------------------------------------------------ +// ***** DefaultAllocator + +// This allocator is created and used if no other allocator is installed. +// Default allocator delegates to system malloc. + +class DefaultAllocator : public Allocator_SingletonSupport +{ +public: + virtual void* Alloc(size_t size); + virtual void* AllocDebug(size_t size, const char* file, unsigned line); + virtual void* Realloc(void* p, size_t newSize); + virtual void Free(void *p); +}; + + +//------------------------------------------------------------------------ +// ***** DebugPageAllocator +// +// Implements a page-protected allocator: +// Detects use-after-free and memory overrun bugs immediately at the time of usage via an exception. +// Can detect a memory read or write beyond the valid memory immediately at the +// time of usage via an exception (if EnableOverrunDetection is enabled). +// This doesn't replace valgrind but implements a subset of its functionality +// in a way that performs well enough to avoid interfering with app execution. +// The point of this is that immediately detects these two classes of errors while +// being much faster than external tools such as valgrind, etc. This is at a cost of +// as much as a page of extra bytes per allocation (two if EnableOverrunDetection is enabled). +// On Windows the Alloc and Free functions average about 12000 cycles each. This isn't small but +// it should be low enough for many testing circumstances with apps that are prudent with +// memory allocation volume. +// The amount of system memory needed for this isn't as high as one might initially guess, as it +// takes hundreds of thousands of memory allocations in order to make a dent in the gigabytes of +// memory most computers have. +// +// +// Technical design for the Windows platform: +// Every Alloc is satisfied via a VirtualAlloc return of a memory block of one or more pages; +// the minimum needed to satisy the user's size and alignment requirements. +// Upon Free the memory block (which is one or more pages) is not passed to VirtualFree but rather +// is converted to PAGE_NOACCESS and put into a delayed free list (FreedBlockArray) to be passed +// to VirtualFree later. The result of this is that any further attempts to read or write the +// memory will result in an exception. +// The delayed-free list increases each time Free is called until it reached maximum capacity, +// at which point the oldest memory block in the list is passed to VirtualFree and its +// entry in the list is filled with this newly Freed (PAGE_NOACCESS) memory block. +// Once the delayed-free list reaches maximum capacity it thus acts as a ring buffer of blocks. +// The maximum size of this list is currently determined at compile time as a constant. +// The EnableOverrunDetection is an additional feature which allows reads or writes beyond valid +// memory to be detected as they occur. This is implemented by adding an allocating an additional +// page of memory at the end of the usual pages and leaving it uncommitted (MEM_RESERVE). +// When this option is used, we return a pointer to the user that's at the end of the valid +// memory block as opposed to at the beginning. This is so that the space right after the +// user space is invalid. If there are some odd bytes remaining between the end of the user's +// space and the page (due to alignment requirements), we optionally fill these with guard bytes. +// We do not currently support memory underrun detection, which could be implemented via an +// extra un-accessible page before the user page(s). In practice this is rarely needed. +// Currently the choice to use EnableOverrunDetection must be done before any calls to Alloc, etc. +// as the logic is simpler and faster if we don't have to dynamically handle either case at runtime. +// We store within the memory block the size of the block and the size of the original user Alloc +// request. This is done as two size_t values written before the memory returned to the user. +// Thus the pointer returned to the user will never be at the very beginning of the memory block, +// because there will be two size_t's before it. +// This class itself allocates no memory, as that could interfere with its ability to supply +// memory, especially if the global malloc and new functions are replaced with this class. +// We could in fact support this class allocating memory as long as it used a system allocator +// and not malloc, new, etc. +// As of this writing we don't do debug fill patterns in the returned memory, because we mostly +// don't need it because memory exceptions take the place of unexpected fill value validation. +// However, there is some value in doing a small debug fill of the last few bytes after the +// user's bytes but before the next page, which will happen for odd sizes passed to Alloc. +// +// Technical design for Mac and Linux platforms: +// Apple's XCode malloc functionality includes something called MallocGuardEdges which is similar +// to DebugPageAllocator, though it protects only larger sized allocations and not smaller ones. +// Our approach for this on Mac and Linux is to use mmap and mprotect in a way similar to VirtualAlloc and +// VirtualProtect. Unix doesn't have the concept of Windows MEM_RESERVE vs. MEM_COMMIT, but we can +// simulate MEM_RESERVE by having an extra page that's PROT_NONE instead of MEM_RESERVE. Since Unix +// platforms don't commit pages pages to physical memory until they are first accessed, this extra +// page will in practice act similar to Windows MEM_RESERVE at runtime. +// +// Allocation inteface: +// Alloc sizes can be any size_t >= 0. +// An alloc size of 0 returns a non-nullptr. +// Alloc functions may fail (usually due to insufficent memory), in which case they return nullptr. +// All returned allocations are aligned on a power-of-two boundary of at least DebugPageAllocator::DefaultAlignment. +// AllocAligned supports any alignment power-of-two value from 1 to 256. Other values result in undefined behavior. +// AllocAligned may return a pointer that's aligned greater than the requested alignment. +// Realloc acts as per the C99 Standard realloc. +// Free requires the supplied pointer to be a valid pointer returned by this allocator's Alloc functions, else the behavior is undefined. +// You may not Free a pointer a second time, else the behavior is undefined. +// Free otherwise always succeeds. +// Allocations made with AllocAligned or ReallocAligned must be Freed via FreeAligned, as per the base class requirement. +// + +class DebugPageAllocator : public Allocator_SingletonSupport +{ +public: + DebugPageAllocator(); + virtual ~DebugPageAllocator(); + + void Init(); + void Shutdown(); + + void SetDelayedFreeCount(size_t delayedFreeCount); // Sets how many freed blocks we should save before purging the oldest of them. + size_t GetDelayedFreeCount() const; + void EnableOverrunDetection(bool enableOverrunDetection, bool enableOverrunGuardBytes); // enableOverrunDetection is by default. enableOverrunGuardBytes is enabled by default in debug builds. + + void* Alloc(size_t size); + void* AllocAligned(size_t size, size_t align); + void* Realloc(void* p, size_t newSize); + void* ReallocAligned(void* p, size_t newSize, size_t newAlign); + void Free(void* p); + void FreeAligned(void* p); + size_t GetAllocSize(const void* p) const { return GetUserSize(p); } + size_t GetPageSize() const { return PageSize; } + +protected: + struct Block + { + void* BlockPtr; // The pointer to the first page of the contiguous set of pages that make up this block. + size_t BlockSize; // (page size) * (page count). Will be >= (SizeStorageSize + UserSize). + + void Clear() { BlockPtr = nullptr; BlockSize = 0; } + }; + + Block* FreedBlockArray; // Currently a very simple array-like container that acts as a ring buffer of delay-freed (but inaccessible) blocks. + size_t FreedBlockArrayMaxSize; // The max number of Freed blocks to put into FreedBlockArray before they start getting purged. Must be <= kFreedBlockArrayCapacity. + size_t FreedBlockArraySize; // The amount of valid elements within FreedBlockArray. Increases as elements are added until it reaches kFreedBlockArrayCapacity. Then stays that way until Shutdown. + size_t FreedBlockArrayOldest; // The oldest entry in the FreedBlockArray ring buffer. + size_t AllocationCount; // Number of currently live Allocations. Incremented by successful calls to Alloc (etc.) Decremented by successful calss to Free. + bool OverrunPageEnabled; // If true then we implement memory overrun detection, at the cost of an extra page per user allocation. + bool OverrunGuardBytesEnabled; // If true then any remaining bytes between the end of the user's allocation and the end of the page are filled with guard bytes and verified upon Free. Valid only if OverrunPageEnabled is true. + size_t PageSize; // The current default platform memory page size (e.g. 4096). We allocated blocks in multiples of pages. + OVR::Lock Lock; // Mutex which allows an instance of this class to be used by multiple threads simultaneously. + +public: + #if defined(_WIN64) || defined(_M_IA64) || defined(__LP64__) || defined(__LP64__) || defined(__arch64__) || defined(__APPLE__) + static const size_t DefaultAlignment = 16; // 64 bit platforms and all Apple platforms. + #else + static const size_t DefaultAlignment = 8; // 32 bit platforms. We want DefaultAlignment as low as possible because that means less unused bytes between a user allocation and the end of the page. + #endif + #if defined(_WIN32) + static const size_t MaxAlignment = 2048; // Half a page size. + #else + static const size_t MaxAlignment = DefaultAlignment; // Currently a low limit because we don't have full page allocator support yet. + #endif + +protected: + static const size_t SizeStorageSize = DefaultAlignment; // Where the user size and block size is stored. Needs to be at least 2 * sizeof(size_t). + static const size_t UserSizeIndex = 0; // We store block sizes within the memory itself, and this serves to identify it. + static const size_t BlockSizeIndex = 1; + static const uint8_t GuardFillByte = 0xfd; // Same value VC++ uses for heap guard bytes. + + static size_t GetUserSize(const void* p); // Returns the size that the user requested in Alloc, etc. + static size_t GetBlockSize(const void* p); // Returns the actual number of bytes in the returned block. Will be a multiple of PageSize. + static size_t* GetSizePosition(const void* p); // We store the user and block size as two size_t values within the returned memory to the user, before the user pointer. This gets that location. + + void* GetBlockPtr(void* p); + void* GetUserPosition(void* pPageMemory, size_t blockSize, size_t userSize, size_t userAlignment); + void* AllocCommittedPageMemory(size_t blockSize); + void* EnablePageMemory(void* pPageMemory, size_t blockSize); + void DisablePageMemory(void* pPageMemory, size_t blockSize); + void FreePageMemory(void* pPageMemory, size_t blockSize); +}; + + + + +///------------------------------------------------------------------------ +/// ***** OVR_malloca / OVR_freea +/// +/// Implements a safer version of alloca. However, see notes below. +/// +/// Allocates memory from the stack via alloca (or similar) for smaller +/// allocation sizes, else falls back to operator new. This is very similar +/// to the Microsoft _malloca and _freea functions, and the implementation +/// is nearly the same aside from using operator new instead of malloc. +/// +/// Unlike alloca, calls to OVR_malloca must be matched by calls to OVR_freea, +/// and the OVR_freea call must be in the same function scope as the original +/// call to OVR_malloca. +/// +/// Note: +/// While this function reduces the likelihood of a stack overflow exception, +/// it cannot guarantee it, as even small allocation sizes done by alloca +/// can exhaust the stack when it is nearly full. However, the majority of +/// stack overflows due to alloca usage are due to large allocation size +/// requests. +/// +/// Declarations: +/// void* OVR_malloca(size_t size); +/// void OVR_freea(void* p); +/// +/// Example usage: +/// void TestMalloca() +/// { +/// char* charArray = (char*)OVR_malloca(37000); +/// +/// if(charArray) +/// { +/// // +/// OVR_freea(charArray); +/// } +/// } +/// +#if !defined(OVR_malloca) + #define OVR_MALLOCA_ALLOCA_ID UINT32_C(0xcccccccc) + #define OVR_MALLOCA_MALLOC_ID UINT32_C(0xdddddddd) + #define OVR_MALLOCA_ID_SIZE 16 // Needs to be at least 2 * sizeof(uint32_t) and at least the minimum alignment for malloc on the platform. 16 works for all platforms. + #if defined(_MSC_VER) + #define OVR_MALLOCA_SIZE_THRESHOLD 8192 + #else + #define OVR_MALLOCA_SIZE_THRESHOLD 1024 // Non-Microsoft platforms tend to exhaust stack space sooner due to non-automatic stack expansion. + #endif + + #define OVR_malloca(size) \ + ((((size) + OVR_MALLOCA_ID_SIZE) < OVR_MALLOCA_SIZE_THRESHOLD) ? \ + OVR::malloca_SetId(static_cast(alloca((size) + OVR_MALLOCA_ID_SIZE)), OVR_MALLOCA_ALLOCA_ID) : \ + OVR::malloca_SetId(static_cast(new char[(size) + OVR_MALLOCA_ID_SIZE]), OVR_MALLOCA_MALLOC_ID)) + + inline void* malloca_SetId(char* p, uint32_t id) + { + if(p) + { + *reinterpret_cast(p) = id; + p = reinterpret_cast(p) + OVR_MALLOCA_ID_SIZE; + } + + return p; + } +#endif + +#if !defined(OVR_freea) + #define OVR_freea(p) OVR::freea_Impl(reinterpret_cast(p)) + + inline void freea_Impl(char* p) + { + if (p) + { + // We store the allocation type id at the first uint32_t in the returned memory. + static_assert(OVR_MALLOCA_ID_SIZE >= sizeof(uint32_t), "Insufficient OVR_MALLOCA_ID_SIZE size."); + p -= OVR_MALLOCA_ID_SIZE; + uint32_t id = *reinterpret_cast(p); + + if(id == OVR_MALLOCA_MALLOC_ID) + delete[] p; + #if defined(OVR_BUILD_DEBUG) + else if(id != OVR_MALLOCA_ALLOCA_ID) + OVR_FAIL_M("OVR_freea memory corrupt or not allocated by OVR_alloca."); + #endif + } + } +#endif + + +///------------------------------------------------------------------------ +/// ***** OVR_newa / OVR_deletea +/// +/// Implements a C++ array version of OVR_malloca/OVR_freea. +/// Expresses failure via a nullptr return value and not via a C++ exception. +/// If a handled C++ exception occurs midway during construction in OVR_newa, +// there is no automatic destruction of the successfully constructed elements. +/// +/// Declarations: +/// T* OVR_newa(T, size_t count); +/// void OVR_deletea(T, T* pTArray); +/// +/// Example usage: +/// void TestNewa() +/// { +/// Widget* pWidgetArray = OVR_newa(Widget, 37000); +/// +/// if(pWidgetArray) +/// { +/// // +/// OVR_deletea(Widget, pWidgetArray); +/// } +/// } +/// + +#if !defined(OVR_newa) + #define OVR_newa(T, count) OVR::newa_Impl(static_cast(OVR_malloca(count * sizeof(T))), count) +#endif + +template +T* newa_Impl(char* pTArray, size_t count) +{ + if(pTArray) + { + OVR::ConstructArray(pTArray, count); + + // We store the count at the second uint32_t in the returned memory. + static_assert(OVR_MALLOCA_ID_SIZE >= (2 * sizeof(uint32_t)), "Insufficient OVR_MALLOCA_ID_SIZE size."); + reinterpret_cast((reinterpret_cast(pTArray) - OVR_MALLOCA_ID_SIZE))[1] = (uint32_t)count; + } + return reinterpret_cast(pTArray); +} + +#if !defined(OVR_deletea) + #define OVR_deletea(T, pTArray) OVR::deletea_Impl(pTArray) +#endif + +template +void deletea_Impl(T* pTArray) +{ + if(pTArray) + { + uint32_t count = reinterpret_cast((reinterpret_cast(pTArray) - OVR_MALLOCA_ID_SIZE))[1]; + OVR::DestructArray(pTArray, count); + OVR_freea(pTArray); + } +} + + + + + +//------------------------------------------------------------------------ +// ***** Memory Allocation Macros + +// These macros should be used for global allocation. In the future, these +// macros will allows allocation to be extended with debug file/line information +// if necessary. + +#define OVR_REALLOC(p,s) OVR::Allocator::GetInstance()->Realloc((p),(s)) +#define OVR_FREE(p) OVR::Allocator::GetInstance()->Free((p)) +#define OVR_ALLOC_ALIGNED(s,a) OVR::Allocator::GetInstance()->AllocAligned((s),(a)) +#define OVR_FREE_ALIGNED(p) OVR::Allocator::GetInstance()->FreeAligned((p)) + +#ifdef OVR_BUILD_DEBUG +#define OVR_ALLOC(s) OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__) +#define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->AllocDebug((s), f, l) +#else +#define OVR_ALLOC(s) OVR::Allocator::GetInstance()->Alloc((s)) +#define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->Alloc((s)) +#endif + + +//------------------------------------------------------------------------ + +// Base class that overrides the new and delete operators. +// Deriving from this class, even as a multiple base, incurs no space overhead. +class NewOverrideBase +{ +public: + + // Redefine all new & delete operators. + OVR_MEMORY_REDEFINE_NEW(NewOverrideBase) +}; + + +//------------------------------------------------------------------------ +// ***** DumpMemory + +// Displays information about outstanding allocations, typically for the +// purpose of reporting leaked memory on application or module shutdown. +// This should be used instead of, for example, VC++ _CrtDumpMemoryLeaks +// because it allows us to dump additional information about our allocations. +// Returns the number of currently outstanding heap allocations. +int DumpMemory(); + + +//------------------------------------------------------------------------ +// ***** Mapped memory allocation +// +// Equates to VirtualAlloc/VirtualFree on Windows, mmap/munmap on Unix. +// These are useful for when you need system-supplied memory pages. +// These are also useful for when you need to allocate memory in a way +// that doesn't affect the application heap. + +void* SafeMMapAlloc(size_t size); +void SafeMMapFree (const void* memory, size_t size); + + +} // OVR + + +// Redefine operator 'new' if necessary. +#if defined(OVR_DEFINE_NEW) +#define new OVR_DEFINE_NEW +#endif + +#if defined(OVR_CC_MSVC) +#pragma warning(pop) +#endif + +#endif // OVR_Memory diff --git a/LibOVRKernel/Src/Kernel/OVR_Array.h b/LibOVRKernel/Src/Kernel/OVR_Array.h new file mode 100644 index 0000000..28c2fac --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Array.h @@ -0,0 +1,837 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Array.h +Content : Template implementation for Array +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Array_h +#define OVR_Array_h + +#include "OVR_ContainerAllocator.h" + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** ArrayDefaultPolicy +// +// Default resize behavior. No minimal capacity, Granularity=4, +// Shrinking as needed. ArrayConstPolicy actually is the same as +// ArrayDefaultPolicy, but parametrized with constants. +// This struct is used only in order to reduce the template "matroska". +struct ArrayDefaultPolicy +{ + ArrayDefaultPolicy() : Capacity(0) {} + ArrayDefaultPolicy(const ArrayDefaultPolicy&) : Capacity(0) {} + + size_t GetMinCapacity() const { return 0; } + size_t GetGranularity() const { return 4; } + bool NeverShrinking() const { return 1; } + + size_t GetCapacity() const { return Capacity; } + void SetCapacity(size_t capacity) { Capacity = capacity; } +private: + size_t Capacity; +}; + + +//----------------------------------------------------------------------------------- +// ***** ArrayConstPolicy +// +// Statically parametrized resizing behavior: +// MinCapacity, Granularity, and Shrinking flag. +template +struct ArrayConstPolicy +{ + typedef ArrayConstPolicy SelfType; + + ArrayConstPolicy() : Capacity(0) {} + ArrayConstPolicy(const SelfType&) : Capacity(0) {} + + size_t GetMinCapacity() const { return MinCapacity; } + size_t GetGranularity() const { return Granularity; } + bool NeverShrinking() const { return NeverShrink; } + + size_t GetCapacity() const { return Capacity; } + void SetCapacity(size_t capacity) { Capacity = capacity; } +private: + size_t Capacity; +}; + +//----------------------------------------------------------------------------------- +// ***** ArrayDataBase +// +// Basic operations with array data: Reserve, Resize, Free, ArrayPolicy. +// For internal use only: ArrayData,ArrayDataCC and others. +template +struct ArrayDataBase +{ + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase SelfType; + + ArrayDataBase() + : Data(0), Size(0), Policy() {} + + ArrayDataBase(const SizePolicy& p) + : Data(0), Size(0), Policy(p) {} + + ~ArrayDataBase() + { + Allocator::DestructArray(Data, Size); + Allocator::Free(Data); + } + + size_t GetCapacity() const + { + return Policy.GetCapacity(); + } + + void ClearAndRelease() + { + Allocator::DestructArray(Data, Size); + Allocator::Free(Data); + Data = 0; + Size = 0; + Policy.SetCapacity(0); + } + + void Reserve(size_t newCapacity) + { + if (Policy.NeverShrinking() && newCapacity < GetCapacity()) + return; + + if (newCapacity < Policy.GetMinCapacity()) + newCapacity = Policy.GetMinCapacity(); + + // Resize the buffer. + if (newCapacity == 0) + { + if (Data) + { + Allocator::Free(Data); + Data = 0; + } + Policy.SetCapacity(0); + } + else + { + size_t gran = Policy.GetGranularity(); + newCapacity = (newCapacity + gran - 1) / gran * gran; + if (Data) + { + if (Allocator::IsMovable()) + { + Data = (T*)Allocator::Realloc(Data, sizeof(T) * newCapacity); + } + else + { + T* newData = (T*)Allocator::Alloc(sizeof(T) * newCapacity); + size_t i, s; + s = (Size < newCapacity) ? Size : newCapacity; + for (i = 0; i < s; ++i) + { + Allocator::Construct(&newData[i], Data[i]); + Allocator::Destruct(&Data[i]); + } + for (i = s; i < Size; ++i) + { + Allocator::Destruct(&Data[i]); + } + Allocator::Free(Data); + Data = newData; + } + } + else + { + Data = (T*)Allocator::Alloc(sizeof(T) * newCapacity); + //memset(Buffer, 0, (sizeof(ValueType) * newSize)); // Do we need this? + } + Policy.SetCapacity(newCapacity); + // OVR_ASSERT(Data); // need to throw (or something) on alloc failure! + } + } + + // This version of Resize DOES NOT construct the elements. + // It's done to optimize PushBack, which uses a copy constructor + // instead of the default constructor and assignment + void ResizeNoConstruct(size_t newSize) + { + size_t oldSize = Size; + + if (newSize < oldSize) + { + Allocator::DestructArray(Data + newSize, oldSize - newSize); + if (newSize < (Policy.GetCapacity() >> 1)) + { + Reserve(newSize); + } + } + else if(newSize >= Policy.GetCapacity()) + { + Reserve(newSize + (newSize >> 2)); + } + //! IMPORTANT to modify Size only after Reserve completes, because garbage collectable + // array may use this array and may traverse it during Reserve (in the case, if + // collection occurs because of heap limit exceeded). + Size = newSize; + } + + ValueType* Data; + size_t Size; + SizePolicy Policy; +}; + + + +//----------------------------------------------------------------------------------- +// ***** ArrayData +// +// General purpose array data. +// For internal use only in Array, ArrayLH, ArrayPOD and so on. +template +struct ArrayData : ArrayDataBase +{ + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase BaseType; + typedef ArrayData SelfType; + + ArrayData() + : BaseType() { } + + ArrayData(size_t size) + : BaseType() { Resize(size); } + + ArrayData(const SelfType& a) + : BaseType(a.Policy) { Append(a.Data, a.Size); } + + + void Resize(size_t newSize) + { + size_t oldSize = this->Size; + BaseType::ResizeNoConstruct(newSize); + if(newSize > oldSize) + Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize); + } + + void PushBack(const ValueType& val) + { + BaseType::ResizeNoConstruct(this->Size + 1); + OVR_ASSERT(this->Data != NULL); + Allocator::Construct(this->Data + this->Size - 1, val); + } + + template + void PushBackAlt(const S& val) + { + BaseType::ResizeNoConstruct(this->Size + 1); + Allocator::ConstructAlt(this->Data + this->Size - 1, val); + } + + // Append the given data to the array. + void Append(const ValueType other[], size_t count) + { + if (count) + { + size_t oldSize = this->Size; + BaseType::ResizeNoConstruct(this->Size + count); + Allocator::ConstructArray(this->Data + oldSize, count, other); + } + } +}; + + + +//----------------------------------------------------------------------------------- +// ***** ArrayDataCC +// +// A modification of ArrayData that always copy-constructs new elements +// using a specified DefaultValue. For internal use only in ArrayCC. +template +struct ArrayDataCC : ArrayDataBase +{ + typedef T ValueType; + typedef Allocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayDataBase BaseType; + typedef ArrayDataCC SelfType; + + ArrayDataCC(const ValueType& defval) + : BaseType(), DefaultValue(defval) { } + + ArrayDataCC(const ValueType& defval, size_t size) + : BaseType(), DefaultValue(defval) { Resize(size); } + + ArrayDataCC(const SelfType& a) + : BaseType(a.Policy), DefaultValue(a.DefaultValue) { Append(a.Data, a.Size); } + + + void Resize(size_t newSize) + { + size_t oldSize = this->Size; + BaseType::ResizeNoConstruct(newSize); + if(newSize > oldSize) + Allocator::ConstructArray(this->Data + oldSize, newSize - oldSize, DefaultValue); + } + + void PushBack(const ValueType& val) + { + BaseType::ResizeNoConstruct(this->Size + 1); + Allocator::Construct(this->Data + this->Size - 1, val); + } + + template + void PushBackAlt(const S& val) + { + BaseType::ResizeNoConstruct(this->Size + 1); + Allocator::ConstructAlt(this->Data + this->Size - 1, val); + } + + // Append the given data to the array. + void Append(const ValueType other[], size_t count) + { + if (count) + { + size_t oldSize = this->Size; + BaseType::ResizeNoConstruct(this->Size + count); + Allocator::ConstructArray(this->Data + oldSize, count, other); + } + } + + ValueType DefaultValue; +}; + + + + + +//----------------------------------------------------------------------------------- +// ***** ArrayBase +// +// Resizable array. The behavior can be POD (suffix _POD) and +// Movable (no suffix) depending on the allocator policy. +// In case of _POD the constructors and destructors are not called. +// +// Arrays can't handle non-movable objects! Don't put anything in here +// that can't be moved around by bitwise copy. +// +// The addresses of elements are not persistent! Don't keep the address +// of an element; the array contents will move around as it gets resized. +template +class ArrayBase +{ +public: + typedef typename ArrayData::ValueType ValueType; + typedef typename ArrayData::AllocatorType AllocatorType; + typedef typename ArrayData::SizePolicyType SizePolicyType; + typedef ArrayBase SelfType; + + +#undef new + OVR_MEMORY_REDEFINE_NEW(ArrayBase) +// Redefine operator 'new' if necessary. +#if defined(OVR_DEFINE_NEW) +#define new OVR_DEFINE_NEW +#endif + + + ArrayBase() + : Data() {} + ArrayBase(size_t size) + : Data(size) {} + ArrayBase(const SelfType& a) + : Data(a.Data) {} + + ArrayBase(const ValueType& defval) + : Data(defval) {} + ArrayBase(const ValueType& defval, size_t size) + : Data(defval, size) {} + + SizePolicyType* GetSizePolicy() const { return Data.Policy; } + void SetSizePolicy(const SizePolicyType& p) { Data.Policy = p; } + + bool NeverShrinking()const { return Data.Policy.NeverShrinking(); } + size_t GetSize() const { return Data.Size; } + int GetSizeI() const { return (int)Data.Size; } + bool IsEmpty() const { return Data.Size == 0; } + size_t GetCapacity() const { return Data.GetCapacity(); } + size_t GetNumBytes() const { return Data.GetCapacity() * sizeof(ValueType); } + + void ClearAndRelease() { Data.ClearAndRelease(); } + void Clear() { Data.Resize(0); } + void Resize(size_t newSize) { Data.Resize(newSize); } + + // Reserve can only increase the capacity + void Reserve(size_t newCapacity) + { + if (newCapacity > Data.GetCapacity()) + Data.Reserve(newCapacity); + } + + // Basic access. + ValueType& At(size_t index) + { + OVR_ASSERT((Data.Data) && (index < Data.Size)); // Asserting that Data.Data is valid helps static analysis tools. + return Data.Data[index]; + } + const ValueType& At(size_t index) const + { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; + } + + ValueType ValueAt(size_t index) const + { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; + } + + // Basic access. + ValueType& operator [] (size_t index) + { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; + } + const ValueType& operator [] (size_t index) const + { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + return Data.Data[index]; + } + + // Raw pointer to the data. Use with caution! + const ValueType* GetDataPtr() const { return Data.Data; } + ValueType* GetDataPtr() { return Data.Data; } + + // Insert the given element at the end of the array. + void PushBack(const ValueType& val) + { + // DO NOT pass elements of your own vector into + // push_back()! Since we're using references, + // resize() may munge the element storage! + // OVR_ASSERT(&val < &Buffer[0] || &val > &Buffer[BufferSize]); + Data.PushBack(val); + } + + template + void PushBackAlt(const S& val) + { + Data.PushBackAlt(val); + } + + // Remove the last element. + void PopBack(size_t count = 1) + { + OVR_ASSERT(Data.Size >= count); + Data.Resize(Data.Size - count); + } + + ValueType& PushDefault() + { + Data.PushBack(ValueType()); + return Back(); + } + + ValueType Pop() + { + OVR_ASSERT((Data.Data) && (Data.Size > 0)); + ValueType t = Back(); + PopBack(); + return t; + } + + + // Access the first element. + ValueType& Front() { return At(0); } + const ValueType& Front() const { return At(0); } + + // Access the last element. + ValueType& Back() { return At(Data.Size - 1); } + const ValueType& Back() const { return At(Data.Size - 1); } + + // Array copy. Copies the contents of a into this array. + const SelfType& operator = (const SelfType& a) + { + Resize(a.GetSize()); + OVR_ASSERT((Data.Data != NULL) || (Data.Size == 0)); + for (size_t i = 0; i < Data.Size; i++) { + *(Data.Data + i) = a[i]; + } + return *this; + } + + // Removing multiple elements from the array. + void RemoveMultipleAt(size_t index, size_t num) + { + OVR_ASSERT(index + num <= Data.Size); + if (Data.Size == num) + { + Clear(); + } + else + { + AllocatorType::DestructArray(Data.Data + index, num); + AllocatorType::CopyArrayForward( + Data.Data + index, + Data.Data + index + num, + Data.Size - num - index); + Data.Size -= num; + } + } + + // Removing an element from the array is an expensive operation! + // It compacts only after removing the last element. + // If order of elements in the array is not important then use + // RemoveAtUnordered, that could be much faster than the regular + // RemoveAt. + void RemoveAt(size_t index) + { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + if (Data.Size == 1) + { + Clear(); + } + else + { + AllocatorType::Destruct(Data.Data + index); + AllocatorType::CopyArrayForward( + Data.Data + index, + Data.Data + index + 1, + Data.Size - 1 - index); + --Data.Size; + } + } + + // Removes an element from the array without respecting of original order of + // elements for better performance. Do not use on array where order of elements + // is important, otherwise use it instead of regular RemoveAt(). + void RemoveAtUnordered(size_t index) + { + OVR_ASSERT((Data.Data) && (index < Data.Size)); + if (Data.Size == 1) + { + Clear(); + } + else + { + // copy the last element into the 'index' position + // and decrement the size (instead of moving all elements + // in [index + 1 .. size - 1] range). + const size_t lastElemIndex = Data.Size - 1; + if (index < lastElemIndex) + { + AllocatorType::Destruct(Data.Data + index); + AllocatorType::Construct(Data.Data + index, Data.Data[lastElemIndex]); + } + AllocatorType::Destruct(Data.Data + lastElemIndex); + --Data.Size; + } + } + + // Insert the given object at the given index shifting all the elements up. + void InsertAt(size_t index, const ValueType& val = ValueType()) + { + OVR_ASSERT(index <= Data.Size); + + Data.Resize(Data.Size + 1); + if (index < Data.Size - 1) + { + AllocatorType::CopyArrayBackward( + Data.Data + index + 1, + Data.Data + index, + Data.Size - 1 - index); + } + AllocatorType::Construct(Data.Data + index, val); + } + + // Insert the given object at the given index shifting all the elements up. + void InsertMultipleAt(size_t index, size_t num, const ValueType& val = ValueType()) + { + OVR_ASSERT(index <= Data.Size); + + Data.Resize(Data.Size + num); + if (index < Data.Size - num) + { + AllocatorType::CopyArrayBackward( + Data.Data + index + num, + Data.Data + index, + Data.Size - num - index); + } + for (size_t i = 0; i < num; ++i) + AllocatorType::Construct(Data.Data + index + i, val); + } + + // Append the given data to the array. + void Append(const SelfType& other) + { + Append(other.Data.Data, other.GetSize()); + } + + // Append the given data to the array. + void Append(const ValueType other[], size_t count) + { + Data.Append(other, count); + } + + class Iterator + { + SelfType* pArray; + intptr_t CurIndex; + + public: + Iterator() : pArray(0), CurIndex(-1) {} + Iterator(SelfType* parr, intptr_t idx = 0) : pArray(parr), CurIndex(idx) {} + + bool operator==(const Iterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } + bool operator!=(const Iterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } + + Iterator& operator++() + { + if (pArray) + { + if (CurIndex < (intptr_t)pArray->GetSize()) + ++CurIndex; + } + return *this; + } + Iterator operator++(int) + { + Iterator it(*this); + operator++(); + return it; + } + Iterator& operator--() + { + if (pArray) + { + if (CurIndex >= 0) + --CurIndex; + } + return *this; + } + Iterator operator--(int) + { + Iterator it(*this); + operator--(); + return it; + } + Iterator operator+(int delta) const + { + return Iterator(pArray, CurIndex + delta); + } + Iterator operator-(int delta) const + { + return Iterator(pArray, CurIndex - delta); + } + intptr_t operator-(const Iterator& right) const + { + OVR_ASSERT(pArray == right.pArray); + return CurIndex - right.CurIndex; + } + ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } + ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } + ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } + + bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } + + void Remove() + { + if (!IsFinished()) + pArray->RemoveAt(CurIndex); + } + + intptr_t GetIndex() const { return CurIndex; } + }; + + Iterator Begin() { return Iterator(this); } + Iterator End() { return Iterator(this, (intptr_t)GetSize()); } + Iterator Last() { return Iterator(this, (intptr_t)GetSize() - 1); } + + class ConstIterator + { + const SelfType* pArray; + intptr_t CurIndex; + + public: + ConstIterator() : pArray(0), CurIndex(-1) {} + ConstIterator(const SelfType* parr, intptr_t idx = 0) : pArray(parr), CurIndex(idx) {} + + bool operator==(const ConstIterator& it) const { return pArray == it.pArray && CurIndex == it.CurIndex; } + bool operator!=(const ConstIterator& it) const { return pArray != it.pArray || CurIndex != it.CurIndex; } + + ConstIterator& operator++() + { + if (pArray) + { + if (CurIndex < (int)pArray->GetSize()) + ++CurIndex; + } + return *this; + } + ConstIterator operator++(int) + { + ConstIterator it(*this); + operator++(); + return it; + } + ConstIterator& operator--() + { + if (pArray) + { + if (CurIndex >= 0) + --CurIndex; + } + return *this; + } + ConstIterator operator--(int) + { + ConstIterator it(*this); + operator--(); + return it; + } + ConstIterator operator+(int delta) const + { + return ConstIterator(pArray, CurIndex + delta); + } + ConstIterator operator-(int delta) const + { + return ConstIterator(pArray, CurIndex - delta); + } + intptr_t operator-(const ConstIterator& right) const + { + OVR_ASSERT(pArray == right.pArray); + return CurIndex - right.CurIndex; + } + const ValueType& operator*() const { OVR_ASSERT(pArray); return (*pArray)[CurIndex]; } + const ValueType* operator->() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } + const ValueType* GetPtr() const { OVR_ASSERT(pArray); return &(*pArray)[CurIndex]; } + + bool IsFinished() const { return !pArray || CurIndex < 0 || CurIndex >= (int)pArray->GetSize(); } + + intptr_t GetIndex() const { return CurIndex; } + }; + ConstIterator Begin() const { return ConstIterator(this); } + ConstIterator End() const { return ConstIterator(this, (intptr_t)GetSize()); } + ConstIterator Last() const { return ConstIterator(this, (intptr_t)GetSize() - 1); } + +protected: + ArrayData Data; +}; + + + +//----------------------------------------------------------------------------------- +// ***** Array +// +// General purpose array for movable objects that require explicit +// construction/destruction. +template +class Array : public ArrayBase, SizePolicy> > +{ +public: + typedef T ValueType; + typedef ContainerAllocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef Array SelfType; + typedef ArrayBase, SizePolicy> > BaseType; + + Array() : BaseType() {} + explicit Array(size_t size) : BaseType(size) {} + Array(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } + Array(const SelfType& a) : BaseType(a) {} + const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } +}; + +// ***** ArrayPOD +// +// General purpose array for movable objects that DOES NOT require +// construction/destruction. Constructors and destructors are not called! +// Global heap is in use. +template +class ArrayPOD : public ArrayBase, SizePolicy> > +{ +public: + typedef T ValueType; + typedef ContainerAllocator_POD AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayPOD SelfType; + typedef ArrayBase, SizePolicy> > BaseType; + + ArrayPOD() : BaseType() {} + explicit ArrayPOD(size_t size) : BaseType(size) {} + ArrayPOD(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } + ArrayPOD(const SelfType& a) : BaseType(a) {} + const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } +}; + + +// ***** ArrayCPP +// +// General purpose, fully C++ compliant array. Can be used with non-movable data. +// Global heap is in use. +template +class ArrayCPP : public ArrayBase, SizePolicy> > +{ +public: + typedef T ValueType; + typedef ContainerAllocator_CPP AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayCPP SelfType; + typedef ArrayBase, SizePolicy> > BaseType; + + ArrayCPP() : BaseType() {} + explicit ArrayCPP(size_t size) : BaseType(size) {} + ArrayCPP(const SizePolicyType& p) : BaseType() { SetSizePolicy(p); } + ArrayCPP(const SelfType& a) : BaseType(a) {} + const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } +}; + + +// ***** ArrayCC +// +// A modification of the array that uses the given default value to +// construct the elements. The constructors and destructors are +// properly called, the objects must be movable. + +template +class ArrayCC : public ArrayBase, SizePolicy> > +{ +public: + typedef T ValueType; + typedef ContainerAllocator AllocatorType; + typedef SizePolicy SizePolicyType; + typedef ArrayCC SelfType; + typedef ArrayBase, SizePolicy> > BaseType; + + ArrayCC(const ValueType& defval) : BaseType(defval) {} + ArrayCC(const ValueType& defval, size_t size) : BaseType(defval, size) {} + ArrayCC(const ValueType& defval, const SizePolicyType& p) : BaseType(defval) { SetSizePolicy(p); } + ArrayCC(const SelfType& a) : BaseType(a) {} + const SelfType& operator=(const SelfType& a) { BaseType::operator=(a); return *this; } +}; + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Atomic.cpp b/LibOVRKernel/Src/Kernel/OVR_Atomic.cpp new file mode 100644 index 0000000..f7cf9a6 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Atomic.cpp @@ -0,0 +1,139 @@ +/************************************************************************************ + +Filename : OVR_Atomic.cpp +Content : Contains atomic operations and inline fastest locking + functionality. Will contain #ifdefs for OS efficiency. + Have non-thread-safe implementation if not available. +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Atomic.h" +#include "OVR_Allocator.h" + +#ifdef OVR_ENABLE_THREADS + +// Include Windows 8-Metro compatible Synchronization API +#if defined(OVR_OS_MS) && defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) +#include +#endif + + +namespace OVR { + +// ***** Windows Lock implementation + +#if defined(OVR_OS_MS) + +// ***** Standard Win32 Lock implementation + +// Constructors +Lock::Lock(unsigned spinCount) +{ + #if defined(NTDDI_WIN8) && (NTDDI_VERSION >= NTDDI_WIN8) + // On Windows 8 we use InitializeCriticalSectionEx due to Metro-Compatibility + InitializeCriticalSectionEx(&cs, (DWORD)spinCount, + OVR_DEBUG_SELECT(NULL, CRITICAL_SECTION_NO_DEBUG_INFO)); + #else + ::InitializeCriticalSectionAndSpinCount(&cs, (DWORD)spinCount); // This is available with WindowsXP+. + #endif +} + + +Lock::~Lock() +{ + DeleteCriticalSection(&cs); +} + + +#endif + + +//------------------------------------------------------------------------------------- +// ***** SharedLock + +// This is a general purpose globally shared Lock implementation that should probably be +// moved to Kernel. +// May in theory busy spin-wait if we hit contention on first lock creation, +// but this shouldn't matter in practice since Lock* should be cached. + + +enum { LockInitMarker = 0xFFFFFFFF }; + +Lock* SharedLock::GetLockAddRef() +{ + int oldUseCount; + + do { + oldUseCount = UseCount; + if (oldUseCount == (int)LockInitMarker) + continue; + + if (oldUseCount == 0) + { + // Initialize marker + if (AtomicOps::CompareAndSet_Sync(&UseCount, 0, LockInitMarker)) + { + Construct(Buffer); + do { } + while (!AtomicOps::CompareAndSet_Sync(&UseCount, LockInitMarker, 1)); + return toLock(); + } + continue; + } + + } while (!AtomicOps::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount + 1)); + + return toLock(); +} + +void SharedLock::ReleaseLock(Lock* plock) +{ + OVR_UNUSED(plock); + OVR_ASSERT(plock == toLock()); + + int oldUseCount; + + do { + oldUseCount = UseCount; + OVR_ASSERT(oldUseCount != (int)LockInitMarker); + + if (oldUseCount == 1) + { + // Initialize marker + if (AtomicOps::CompareAndSet_Sync(&UseCount, 1, LockInitMarker)) + { + Destruct(toLock()); + + do { } + while (!AtomicOps::CompareAndSet_Sync(&UseCount, LockInitMarker, 0)); + + return; + } + continue; + } + + } while (!AtomicOps::CompareAndSet_NoSync(&UseCount, oldUseCount, oldUseCount - 1)); +} + +} // OVR + +#endif // OVR_ENABLE_THREADS diff --git a/LibOVRKernel/Src/Kernel/OVR_Atomic.h b/LibOVRKernel/Src/Kernel/OVR_Atomic.h new file mode 100644 index 0000000..0606157 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Atomic.h @@ -0,0 +1,912 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Atomic.h +Content : Contains atomic operations and inline fastest locking + functionality. Will contain #ifdefs for OS efficiency. + Have non-thread-safe implementaion if not available. +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Atomic_h +#define OVR_Atomic_h + +#include "OVR_Types.h" + +// Include System thread functionality. +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) +#include "OVR_Win32_IncludeWindows.h" +#else +#include +#endif + +#ifdef OVR_CC_MSVC +#include +#pragma intrinsic(_ReadBarrier, _WriteBarrier, _ReadWriteBarrier) +#endif + +namespace OVR { + + +// ****** Declared classes + +// If there is NO thread support we implement AtomicOps and +// Lock objects as no-ops. The other classes are not defined. +template class AtomicOps; +template class AtomicInt; +template class AtomicPtr; + +class Lock; + + +//----------------------------------------------------------------------------------- +// ***** AtomicOps + +// Atomic operations are provided by the AtomicOps templates class, +// implemented through system-specific AtomicOpsRaw specializations. +// It provides several fundamental operations such as Exchange, ExchangeAdd +// CompareAndSet, and Store_Release. Each function includes several memory +// synchronization versions, important for multiprocessing CPUs with weak +// memory consistency. The following memory fencing strategies are supported: +// +// - NoSync. No memory synchronization is done for atomic op. +// - Release. All other memory writes are completed before atomic op +// writes its results. +// - Acquire. Further memory reads are forced to wait until atomic op +// executes, guaranteeing that the right values will be seen. +// - Sync. A combination of Release and Acquire. + + +// *** AtomicOpsRaw + +// AtomicOpsRaw is a specialized template that provides atomic operations +// used by AtomicOps. This class has two fundamental qualities: (1) it +// defines a type T of correct size, and (2) provides operations that work +// atomically, such as Exchange_Sync and CompareAndSet_Release. + +// AtomicOpsRawBase class contains shared constants/classes for AtomicOpsRaw. +// The primary thing is does is define sync class objects, whose destructor and +// constructor provide places to insert appropriate synchronization calls, on +// systems where such calls are necessary. So far, the breakdown is as follows: +// +// - X86 systems don't need custom syncs, since their exchange/atomic +// instructions are implicitly synchronized. +// - PowerPC requires lwsync/isync instructions that can use this mechanism. +// - If some other systems require a mechanism where syncing type is associated +// with a particular instruction, the default implementation (which implements +// all Sync, Acquire, and Release modes in terms of NoSync and fence) may not +// work. Ii that case it will need to be #ifdef-ed conditionally. + +struct AtomicOpsRawBase +{ +#if !defined(OVR_ENABLE_THREADS) || defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) + // Need to have empty constructor to avoid class 'unused' variable warning. + struct FullSync { inline FullSync() { } }; + struct AcquireSync { inline AcquireSync() { } }; + struct ReleaseSync { inline ReleaseSync() { } }; + +#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC) + struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("isync\n"); } }; + struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("isync\n"); } }; + struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } }; + +#elif defined(OVR_CPU_MIPS) + struct FullSync { inline FullSync() { asm volatile("sync\n"); } ~FullSync() { asm volatile("sync\n"); } }; + struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("sync\n"); } }; + struct ReleaseSync { inline ReleaseSync() { asm volatile("sync\n"); } }; + +#elif defined(OVR_CPU_ARM) // Includes Android and iOS. + struct FullSync { inline FullSync() { asm volatile("dmb\n"); } ~FullSync() { asm volatile("dmb\n"); } }; + struct AcquireSync { inline AcquireSync() { } ~AcquireSync() { asm volatile("dmb\n"); } }; + struct ReleaseSync { inline ReleaseSync() { asm volatile("dmb\n"); } }; + +#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4) + // __sync functions are already full sync + struct FullSync { inline FullSync() { } }; + struct AcquireSync { inline AcquireSync() { } }; + struct ReleaseSync { inline ReleaseSync() { } }; +#endif +}; + + +// 4-Byte raw data atomic op implementation class. +struct AtomicOpsRaw_4ByteImpl : public AtomicOpsRawBase +{ +#if !defined(OVR_ENABLE_THREADS) + + // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl. + typedef uint32_t T; + + // *** Thread - Safe Atomic Versions. + +#elif defined(OVR_OS_MS) + + // Use special defined for VC6, where volatile is not used and + // InterlockedCompareExchange is declared incorrectly. + typedef LONG T; +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC < 1300) + typedef T* InterlockTPtr; + typedef LPVOID ET; + typedef ET* InterlockETPtr; +#else + typedef volatile T* InterlockTPtr; + typedef T ET; + typedef InterlockTPtr InterlockETPtr; +#endif + inline static T Exchange_NoSync(volatile T* p, T val) { return InterlockedExchange((InterlockTPtr)p, val); } + inline static T ExchangeAdd_NoSync(volatile T* p, T val) { return InterlockedExchangeAdd((InterlockTPtr)p, val); } + inline static bool CompareAndSet_NoSync(volatile T* p, T c, T val) { return InterlockedCompareExchange((InterlockETPtr)p, (ET)val, (ET)c) == (ET)c; } + +#elif defined(OVR_CPU_PPC64) || defined(OVR_CPU_PPC) + typedef uint32_t T; + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) + { + uint32_t ret; + + asm volatile("1:\n\t" + "lwarx %[r],0,%[i]\n\t" + "stwcx. %[j],0,%[i]\n\t" + "bne- 1b\n" + : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [j] "b" (j) : "cc", "memory"); + + return ret; + } + + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) + { + uint32_t dummy, ret; + + asm volatile("1:\n\t" + "lwarx %[r],0,%[i]\n\t" + "add %[o],%[r],%[j]\n\t" + "stwcx. %[o],0,%[i]\n\t" + "bne- 1b\n" + : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc", "memory"); + + return ret; + } + + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) + { + uint32_t ret; + + asm volatile("1:\n\t" + "lwarx %[r],0,%[i]\n\t" + "cmpw 0,%[r],%[cmp]\n\t" + "mfcr %[r]\n\t" + "bne- 2f\n\t" + "stwcx. %[val],0,%[i]\n\t" + "bne- 1b\n\t" + "2:\n" + : "+m" (*i), [r] "=&b" (ret) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc", "memory"); + + return (ret & 0x20000000) ? 1 : 0; + } + +#elif defined(OVR_CPU_MIPS) + typedef uint32_t T; + + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) + { + uint32_t ret; + + asm volatile("1:\n\t" + "ll %[r],0(%[i])\n\t" + "sc %[j],0(%[i])\n\t" + "beq %[j],$0,1b\n\t" + "nop \n" + : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory"); + + return ret; + } + + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) + { + uint32_t ret; + + asm volatile("1:\n\t" + "ll %[r],0(%[i])\n\t" + "addu %[j],%[r],%[j]\n\t" + "sc %[j],0(%[i])\n\t" + "beq %[j],$0,1b\n\t" + "nop \n" + : "+m" (*i), [r] "=&d" (ret) : [i] "d" (i), [j] "d" (j) : "cc", "memory"); + + return ret; + } + + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) + { + uint32_t ret, dummy; + + asm volatile("1:\n\t" + "move %[r],$0\n\t" + "ll %[o],0(%[i])\n\t" + "bne %[o],%[c],2f\n\t" + "move %[r],%[v]\n\t" + "sc %[r],0(%[i])\n\t" + "beq %[r],$0,1b\n\t" + "nop \n\t" + "2:\n" + : "+m" (*i),[r] "=&d" (ret), [o] "=&d" (dummy) : [i] "d" (i), [c] "d" (c), [v] "d" (value) + : "cc", "memory"); + + return ret; + } + +#elif defined(OVR_CPU_ARM) && defined(OVR_CC_ARM) + typedef uint32_t T; + + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) + { + for(;;) + { + T r = __ldrex(i); + if (__strex(j, i) == 0) + return r; + } + } + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) + { + for(;;) + { + T r = __ldrex(i); + if (__strex(r + j, i) == 0) + return r; + } + } + + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) + { + for(;;) + { + T r = __ldrex(i); + if (r != c) + return 0; + if (__strex(value, i) == 0) + return 1; + } + } + +#elif defined(OVR_CPU_ARM) + typedef uint32_t T; + + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) + { + uint32_t ret, dummy; + + asm volatile("1:\n\t" + "ldrex %[r],[%[i]]\n\t" + "strex %[t],%[j],[%[i]]\n\t" + "cmp %[t],#0\n\t" + "bne 1b\n\t" + : "+m" (*i), [r] "=&r" (ret), [t] "=&r" (dummy) : [i] "r" (i), [j] "r" (j) : "cc", "memory"); + + return ret; + } + + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) + { + uint32_t ret, dummy, test; + + asm volatile("1:\n\t" + "ldrex %[r],[%[i]]\n\t" + "add %[o],%[r],%[j]\n\t" + "strex %[t],%[o],[%[i]]\n\t" + "cmp %[t],#0\n\t" + "bne 1b\n\t" + : "+m" (*i), [r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [j] "r" (j) : "cc", "memory"); + + return ret; + } + + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) + { + uint32_t ret = 1, dummy, test; + + asm volatile("1:\n\t" + "ldrex %[o],[%[i]]\n\t" + "cmp %[o],%[c]\n\t" + "bne 2f\n\t" + "strex %[r],%[v],[%[i]]\n\t" + "cmp %[r],#0\n\t" + "bne 1b\n\t" + "2:\n" + : "+m" (*i),[r] "=&r" (ret), [o] "=&r" (dummy), [t] "=&r" (test) : [i] "r" (i), [c] "r" (c), [v] "r" (value) + : "cc", "memory"); + + return !ret; + } + +#elif defined(OVR_CPU_X86) + typedef uint32_t T; + + static inline uint32_t Exchange_NoSync(volatile uint32_t *i, uint32_t j) + { + asm volatile("xchgl %1,%[i]\n" + : "+m" (*i), "=q" (j) : [i] "m" (*i), "1" (j) : "cc", "memory"); + + return j; + } + + static inline uint32_t ExchangeAdd_NoSync(volatile uint32_t *i, uint32_t j) + { + asm volatile("lock; xaddl %1,%[i]\n" + : "+m" (*i), "+q" (j) : [i] "m" (*i) : "cc", "memory"); + + return j; + } + + static inline bool CompareAndSet_NoSync(volatile uint32_t *i, uint32_t c, uint32_t value) + { + uint32_t ret; + + asm volatile("lock; cmpxchgl %[v],%[i]\n" + : "+m" (*i), "=a" (ret) : [i] "m" (*i), "1" (c), [v] "q" (value) : "cc", "memory"); + + return (ret == c); + } + +#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1) + + typedef uint32_t T; + + static inline T Exchange_NoSync(volatile T *i, T j) + { + T v; + do { + v = *i; + } while (!__sync_bool_compare_and_swap(i, v, j)); + return v; + } + + static inline T ExchangeAdd_NoSync(volatile T *i, T j) + { + return __sync_fetch_and_add(i, j); + } + + static inline bool CompareAndSet_NoSync(volatile T *i, T c, T value) + { + return __sync_bool_compare_and_swap(i, c, value); + } + +#endif // OS +}; + + +// 8-Byte raw data data atomic op implementation class. +// Currently implementation is provided only on systems with 64-bit pointers. +struct AtomicOpsRaw_8ByteImpl : public AtomicOpsRawBase +{ +#if !defined(OVR_64BIT_POINTERS) || !defined(OVR_ENABLE_THREADS) + + // Provide a type for no-thread-support cases. Used by AtomicOpsRaw_DefImpl. + typedef uint64_t T; + + // *** Thread - Safe OS specific versions. +#elif defined(OVR_OS_MS) + + // This is only for 64-bit systems. + typedef LONG64 T; + typedef volatile T* InterlockTPtr; + inline static T Exchange_NoSync(volatile T* p, T val) { return InterlockedExchange64((InterlockTPtr)p, val); } + inline static T ExchangeAdd_NoSync(volatile T* p, T val) { return InterlockedExchangeAdd64((InterlockTPtr)p, val); } + inline static bool CompareAndSet_NoSync(volatile T* p, T c, T val) { return InterlockedCompareExchange64((InterlockTPtr)p, val, c) == c; } + +#elif defined(OVR_CPU_PPC64) + + typedef uint64_t T; + + static inline uint64_t Exchange_NoSync(volatile uint64_t *i, uint64_t j) + { + uint64_t dummy, ret; + + asm volatile("1:\n\t" + "ldarx %[r],0,%[i]\n\t" + "mr %[o],%[j]\n\t" + "stdcx. %[o],0,%[i]\n\t" + "bne- 1b\n" + : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc"); + + return ret; + } + + static inline uint64_t ExchangeAdd_NoSync(volatile uint64_t *i, uint64_t j) + { + uint64_t dummy, ret; + + asm volatile("1:\n\t" + "ldarx %[r],0,%[i]\n\t" + "add %[o],%[r],%[j]\n\t" + "stdcx. %[o],0,%[i]\n\t" + "bne- 1b\n" + : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [j] "b" (j) : "cc"); + + return ret; + } + + static inline bool CompareAndSet_NoSync(volatile uint64_t *i, uint64_t c, uint64_t value) + { + uint64_t ret, dummy; + + asm volatile("1:\n\t" + "ldarx %[r],0,%[i]\n\t" + "cmpw 0,%[r],%[cmp]\n\t" + "mfcr %[r]\n\t" + "bne- 2f\n\t" + "stdcx. %[val],0,%[i]\n\t" + "bne- 1b\n\t" + "2:\n" + : "+m" (*i), [r] "=&b" (ret), [o] "=&r" (dummy) : [i] "b" (i), [cmp] "b" (c), [val] "b" (value) : "cc"); + + return (ret & 0x20000000) ? 1 : 0; + } + +#elif defined(OVR_CC_GNU) && (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1) + + typedef uint64_t T; + + static inline T Exchange_NoSync(volatile T *i, T j) + { + T v; + do { + v = *i; + } while (!__sync_bool_compare_and_swap(i, v, j)); + return v; + } + + static inline T ExchangeAdd_NoSync(volatile T *i, T j) + { + return __sync_fetch_and_add(i, j); + } + + static inline bool CompareAndSet_NoSync(volatile T *i, T c, T value) + { + return __sync_bool_compare_and_swap(i, c, value); + } + +#endif // OS +}; + + +// Default implementation for AtomicOpsRaw; provides implementation of mem-fenced +// atomic operations where fencing is done with a sync object wrapped around a NoSync +// operation implemented in the base class. If such implementation is not possible +// on a given platform, #ifdefs can be used to disable it and then op functions can be +// implemented individually in the appropriate AtomicOpsRaw class. + +template +struct AtomicOpsRaw_DefImpl : public O +{ + typedef typename O::T O_T; + typedef typename O::FullSync O_FullSync; + typedef typename O::AcquireSync O_AcquireSync; + typedef typename O::ReleaseSync O_ReleaseSync; + + // If there is no thread support, provide the default implementation. In this case, + // the base class (0) must still provide the T declaration. +#ifndef OVR_ENABLE_THREADS + + // Atomic exchange of val with argument. Returns old val. + inline static O_T Exchange_NoSync(volatile O_T* p, O_T val) { O_T old = *p; *p = val; return old; } + // Adds a new val to argument; returns its old val. + inline static O_T ExchangeAdd_NoSync(volatile O_T* p, O_T val) { O_T old = *p; *p += val; return old; } + // Compares the argument data with 'c' val. + // If succeeded, stores val int '*p' and returns true; otherwise returns false. + inline static bool CompareAndSet_NoSync(volatile O_T* p, O_T c, O_T val) { if (*p==c) { *p = val; return 1; } return 0; } + +#endif + + // If NoSync wrapped implementation may not be possible, it this block should be + // replaced with per-function implementation in O. + // "AtomicOpsRaw_DefImpl::" prefix in calls below. + inline static O_T Exchange_Sync(volatile O_T* p, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::Exchange_NoSync(p, val); } + inline static O_T Exchange_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::Exchange_NoSync(p, val); } + inline static O_T Exchange_Acquire(volatile O_T* p, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::Exchange_NoSync(p, val); } + inline static O_T ExchangeAdd_Sync(volatile O_T* p, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::ExchangeAdd_NoSync(p, val); } + inline static O_T ExchangeAdd_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::ExchangeAdd_NoSync(p, val); } + inline static O_T ExchangeAdd_Acquire(volatile O_T* p, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::ExchangeAdd_NoSync(p, val); } + inline static bool CompareAndSet_Sync(volatile O_T* p, O_T c, O_T val) { O_FullSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::CompareAndSet_NoSync(p,c,val); } + inline static bool CompareAndSet_Release(volatile O_T* p, O_T c, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::CompareAndSet_NoSync(p,c,val); } + inline static bool CompareAndSet_Acquire(volatile O_T* p, O_T c, O_T val) { O_AcquireSync sync; OVR_UNUSED(sync); return AtomicOpsRaw_DefImpl::CompareAndSet_NoSync(p,c,val); } + + // Loads and stores with memory fence. These have only the relevant versions. +#ifdef OVR_CPU_X86 + // On X86, Store_Release is implemented as exchange. Note that we can also + // consider 'sfence' in the future, although it is not as compatible with older CPUs. + inline static void Store_Release(volatile O_T* p, O_T val) { Exchange_Release(p, val); } +#else + inline static void Store_Release(volatile O_T* p, O_T val) { O_ReleaseSync sync; OVR_UNUSED(sync); *p = val; } +#endif + inline static O_T Load_Acquire(const volatile O_T* p) + { + O_AcquireSync sync; + OVR_UNUSED(sync); + +#if defined(OVR_CC_MSVC) + _ReadBarrier(); // Compiler fence and load barrier +#elif defined(OVR_CC_INTEL) + __memory_barrier(); // Compiler fence +#else + // GCC-compatible: + asm volatile ("" : : : "memory"); // Compiler fence +#endif + + return *p; + } +}; + + +template +struct AtomicOpsRaw : public AtomicOpsRawBase { }; + +template<> +struct AtomicOpsRaw<4> : public AtomicOpsRaw_DefImpl +{ + // Ensure that assigned type size is correct. + AtomicOpsRaw() + { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl::T) == 4); } +}; +template<> +struct AtomicOpsRaw<8> : public AtomicOpsRaw_DefImpl +{ + AtomicOpsRaw() + { OVR_COMPILER_ASSERT(sizeof(AtomicOpsRaw_DefImpl::T) == 8); } +}; + + +// *** AtomicOps - implementation of atomic Ops for specified class + +// Implements atomic ops on a class, provided that the object is either +// 4 or 8 bytes in size (depending on the AtomicOpsRaw specializations +// available). Relies on AtomicOpsRaw for much of implementation. + +template +class AtomicOps +{ + typedef AtomicOpsRaw Ops; + typedef typename Ops::T T; + typedef volatile typename Ops::T* PT; + // We cast through unions to (1) avoid pointer size compiler warnings + // and (2) ensure that there are no problems with strict pointer aliasing. + union C2T_union { C c; T t; }; + +public: + // General purpose implementation for standard syncs. + inline static C Exchange_Sync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Sync((PT)p, u.t); return u.c; } + inline static C Exchange_Release(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Release((PT)p, u.t); return u.c; } + inline static C Exchange_Acquire(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_Acquire((PT)p, u.t); return u.c; } + inline static C Exchange_NoSync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::Exchange_NoSync((PT)p, u.t); return u.c; } + inline static C ExchangeAdd_Sync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Sync((PT)p, u.t); return u.c; } + inline static C ExchangeAdd_Release(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Release((PT)p, u.t); return u.c; } + inline static C ExchangeAdd_Acquire(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_Acquire((PT)p, u.t); return u.c; } + inline static C ExchangeAdd_NoSync(volatile C* p, C val) { C2T_union u; u.c = val; u.t = Ops::ExchangeAdd_NoSync((PT)p, u.t); return u.c; } + inline static bool CompareAndSet_Sync(volatile C* p, C c, C val) { C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Sync((PT)p, cu.t, u.t); } + inline static bool CompareAndSet_Release(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Release((PT)p, cu.t, u.t); } + inline static bool CompareAndSet_Acquire(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Acquire((PT)p, cu.t, u.t); } + inline static bool CompareAndSet_NoSync(volatile C* p, C c, C val) { C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_NoSync((PT)p, cu.t, u.t); } + + // Loads and stores with memory fence. These have only the relevant versions. + inline static void Store_Release(volatile C* p, C val) { C2T_union u; u.c = val; Ops::Store_Release((PT)p, u.t); } + inline static C Load_Acquire(const volatile C* p) { C2T_union u; u.t = Ops::Load_Acquire((PT)p); return u.c; } + + // Deprecated typo error: + inline static bool CompareAndSet_Relse(volatile C* p, C c, C val){ C2T_union u,cu; u.c = val; cu.c = c; return Ops::CompareAndSet_Acquire((PT)p, cu.t, u.t); } +}; + + + +// Atomic value base class - implements operations shared for integers and pointers. +template +class AtomicValueBase +{ +protected: + typedef AtomicOps Ops; +public: + + volatile T Value; + + inline AtomicValueBase() { } + explicit inline AtomicValueBase(T val) { Ops::Store_Release(&Value, val); } + + // Most libraries (TBB and Joshua Scholar's) library do not do Load_Acquire + // here, since most algorithms do not require atomic loads. Needs some research. + inline operator T() const { return Value; } + + // *** Standard Atomic inlines + inline T Exchange_Sync(T val) { return Ops::Exchange_Sync(&Value, val); } + inline T Exchange_Release(T val) { return Ops::Exchange_Release(&Value, val); } + inline T Exchange_Acquire(T val) { return Ops::Exchange_Acquire(&Value, val); } + inline T Exchange_NoSync(T val) { return Ops::Exchange_NoSync(&Value, val); } + inline bool CompareAndSet_Sync(T c, T val) { return Ops::CompareAndSet_Sync(&Value, c, val); } + inline bool CompareAndSet_Release(T c, T val) { return Ops::CompareAndSet_Release(&Value, c, val); } + inline bool CompareAndSet_Acquire(T c, T val) { return Ops::CompareAndSet_Acquire(&Value, c, val); } + inline bool CompareAndSet_NoSync(T c, T val) { return Ops::CompareAndSet_NoSync(&Value, c, val); } + // Load & Store. + inline void Store_Release(T val) { Ops::Store_Release(&Value, val); } + inline T Load_Acquire() const { return Ops::Load_Acquire(&Value); } +}; + + +// ***** AtomicPtr - Atomic pointer template + +// This pointer class supports atomic assignments with release, +// increment / decrement operations, and conditional compare + set. + +template +class AtomicPtr : public AtomicValueBase +{ + typedef typename AtomicValueBase::Ops Ops; + +public: + // Initialize pointer value to 0 by default; use Store_Release only with explicit constructor. + inline AtomicPtr() : AtomicValueBase() { this->Value = 0; } + explicit inline AtomicPtr(T* val) : AtomicValueBase(val) { } + + // Pointer access. + inline T* operator -> () const { return this->Load_Acquire(); } + + // It looks like it is convenient to have Load_Acquire characteristics + // for this, since that is convenient for algorithms such as linked + // list traversals that can be added to bu another thread. + inline operator T* () const { return this->Load_Acquire(); } + + + // *** Standard Atomic inlines (applicable to pointers) + + // ExhangeAdd considers pointer size for pointers. + template + inline T* ExchangeAdd_Sync(I incr) { return Ops::ExchangeAdd_Sync(&this->Value, ((T*)0) + incr); } + template + inline T* ExchangeAdd_Release(I incr) { return Ops::ExchangeAdd_Release(&this->Value, ((T*)0) + incr); } + template + inline T* ExchangeAdd_Acquire(I incr) { return Ops::ExchangeAdd_Acquire(&this->Value, ((T*)0) + incr); } + template + inline T* ExchangeAdd_NoSync(I incr) { return Ops::ExchangeAdd_NoSync(&this->Value, ((T*)0) + incr); } + + // *** Atomic Operators + + inline T* operator = (T* val) { this->Store_Release(val); return val; } + + template + inline T* operator += (I val) { return ExchangeAdd_Sync(val) + val; } + template + inline T* operator -= (I val) { return operator += (-val); } + + inline T* operator ++ () { return ExchangeAdd_Sync(1) + 1; } + inline T* operator -- () { return ExchangeAdd_Sync(-1) - 1; } + inline T* operator ++ (int) { return ExchangeAdd_Sync(1); } + inline T* operator -- (int) { return ExchangeAdd_Sync(-1); } +}; + + +// ***** AtomicInt - Atomic integer template + +// Implements an atomic integer type; the exact type to use is provided +// as an argument. Supports atomic Acquire / Release semantics, atomic +// arithmetic operations, and atomic conditional compare + set. + +template +class AtomicInt : public AtomicValueBase +{ + typedef typename AtomicValueBase::Ops Ops; + +public: + inline AtomicInt() : AtomicValueBase() { } + explicit inline AtomicInt(T val) : AtomicValueBase(val) { } + + + // *** Standard Atomic inlines (applicable to int) + inline T ExchangeAdd_Sync(T val) { return Ops::ExchangeAdd_Sync(&this->Value, val); } + inline T ExchangeAdd_Release(T val) { return Ops::ExchangeAdd_Release(&this->Value, val); } + inline T ExchangeAdd_Acquire(T val) { return Ops::ExchangeAdd_Acquire(&this->Value, val); } + inline T ExchangeAdd_NoSync(T val) { return Ops::ExchangeAdd_NoSync(&this->Value, val); } + // These increments could be more efficient because they don't return a value. + inline void Increment_Sync() { ExchangeAdd_Sync((T)1); } + inline void Increment_Release() { ExchangeAdd_Release((T)1); } + inline void Increment_Acquire() { ExchangeAdd_Acquire((T)1); } + inline void Increment_NoSync() { ExchangeAdd_NoSync((T)1); } + + // *** Atomic Operators + + inline T operator = (T val) { this->Store_Release(val); return val; } + inline T operator += (T val) { return ExchangeAdd_Sync(val) + val; } + inline T operator -= (T val) { return ExchangeAdd_Sync(0 - val) - val; } + + inline T operator ++ () { return ExchangeAdd_Sync((T)1) + 1; } + inline T operator -- () { return ExchangeAdd_Sync(((T)0)-1) - 1; } + inline T operator ++ (int) { return ExchangeAdd_Sync((T)1); } + inline T operator -- (int) { return ExchangeAdd_Sync(((T)0)-1); } + + // More complex atomic operations. Leave it to compiler whether to optimize them or not. + T operator &= (T arg) + { + T comp, newVal; + do { + comp = this->Value; + newVal = comp & arg; + } while(!this->CompareAndSet_Sync(comp, newVal)); + return newVal; + } + + T operator |= (T arg) + { + T comp, newVal; + do { + comp = this->Value; + newVal = comp | arg; + } while(!this->CompareAndSet_Sync(comp, newVal)); + return newVal; + } + + T operator ^= (T arg) + { + T comp, newVal; + do { + comp = this->Value; + newVal = comp ^ arg; + } while(!this->CompareAndSet_Sync(comp, newVal)); + return newVal; + } + + T operator *= (T arg) + { + T comp, newVal; + do { + comp = this->Value; + newVal = comp * arg; + } while(!this->CompareAndSet_Sync(comp, newVal)); + return newVal; + } + + T operator /= (T arg) + { + T comp, newVal; + do { + comp = this->Value; + newVal = comp / arg; + } while(!CompareAndSet_Sync(comp, newVal)); + return newVal; + } + + T operator >>= (unsigned bits) + { + T comp, newVal; + do { + comp = this->Value; + newVal = comp >> bits; + } while(!CompareAndSet_Sync(comp, newVal)); + return newVal; + } + + T operator <<= (unsigned bits) + { + T comp, newVal; + do { + comp = this->Value; + newVal = comp << bits; + } while(!this->CompareAndSet_Sync(comp, newVal)); + return newVal; + } +}; + + +//----------------------------------------------------------------------------------- +// ***** Lock + +// Lock is a simplest and most efficient mutual-exclusion lock class. +// Unlike Mutex, it cannot be waited on. + +class Lock +{ + // NOTE: Locks are not allocatable and they themselves should not allocate + // memory by standard means. This is the case because StandardAllocator + // relies on this class. + // Make 'delete' private. Don't do this for 'new' since it can be redefined. + void operator delete(void*) {} + + + // *** Lock implementation for various platforms. + +#if !defined(OVR_ENABLE_THREADS) + +public: + // With no thread support, lock does nothing. + inline Lock() { } + inline Lock(unsigned) { } + inline ~Lock() { } + inline void DoLock() { } + inline void Unlock() { } + + // Windows. +#elif defined(OVR_OS_MS) + + CRITICAL_SECTION cs; +public: + Lock(unsigned spinCount = 10000); // Mutexes with non-zero spin counts usually result in better performance. + ~Lock(); + // Locking functions. + inline void DoLock() { ::EnterCriticalSection(&cs); } + inline void Unlock() { ::LeaveCriticalSection(&cs); } + +#else + pthread_mutex_t mutex; + +public: + static pthread_mutexattr_t RecursiveAttr; + static bool RecursiveAttrInit; + + Lock (unsigned spinCount = 0) // To do: Support spin count, probably via a custom lock implementation. + { + OVR_UNUSED(spinCount); + if (!RecursiveAttrInit) + { + pthread_mutexattr_init(&RecursiveAttr); + pthread_mutexattr_settype(&RecursiveAttr, PTHREAD_MUTEX_RECURSIVE); + RecursiveAttrInit = 1; + } + pthread_mutex_init(&mutex,&RecursiveAttr); + } + ~Lock () { pthread_mutex_destroy(&mutex); } + inline void DoLock() { pthread_mutex_lock(&mutex); } + inline void Unlock() { pthread_mutex_unlock(&mutex); } + +#endif // OVR_ENABLE_THREDS + + +public: + // Locker class, used for automatic locking + class Locker + { + public: + Lock *pLock; + inline Locker(Lock *plock) + { pLock = plock; pLock->DoLock(); } + inline ~Locker() + { pLock->Unlock(); } + }; +}; + + +//------------------------------------------------------------------------------------- +// Globally shared Lock implementation used for MessageHandlers, etc. + +class SharedLock +{ +public: + SharedLock() : UseCount(0) {} + + Lock* GetLockAddRef(); + void ReleaseLock(Lock* plock); + +private: + Lock* toLock() { return (Lock*)Buffer; } + + // UseCount and max alignment. + volatile int UseCount; + uint64_t Buffer[(sizeof(Lock)+sizeof(uint64_t)-1)/sizeof(uint64_t)]; +}; + + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_CRC32.cpp b/LibOVRKernel/Src/Kernel/OVR_CRC32.cpp new file mode 100644 index 0000000..82cbe7f --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_CRC32.cpp @@ -0,0 +1,85 @@ +/************************************************************************************ + +Filename : OVR_CRC32.cpp +Content : CRC-32 with polynomial used for sensor devices +Created : June 20, 2014 +Author : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_CRC32.h" + +namespace OVR { + + +static const uint32_t CRC_Table[256] = { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, + 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, + 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, + 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, + 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, + 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, + 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, + 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, + 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, + 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, + 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, + 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, + 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, + 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, + 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, + 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, + 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, + 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, + 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, + 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, + 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, + 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 +}; + + +//// CRC-32 + +uint32_t CRC32_Calculate(const void* data, int bytes, uint32_t accumulator) +{ + const uint8_t* inputBytes = reinterpret_cast( data ); + + for (int j = 0; j < bytes; ++j) + { + int i = ((uint32_t)(accumulator >> 24) ^ *inputBytes++) & 0xFF; + + accumulator = (accumulator << 8) ^ CRC_Table[i]; + } + + return ~accumulator; +} + + +} // OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_CRC32.h b/LibOVRKernel/Src/Kernel/OVR_CRC32.h new file mode 100644 index 0000000..e4edd65 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_CRC32.h @@ -0,0 +1,45 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_CRC32.h +Content : CRC-32 with polynomial used for sensor devices +Created : June 20, 2014 +Author : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CRC32_h +#define OVR_CRC32_h + +#include "OVR_Types.h" + +namespace OVR { + + +//----------------------------------------------------------------------------------- +// ***** CRC-32 + +// Polynomial used and algorithm details are proprietary to our sensor board +uint32_t CRC32_Calculate(const void* data, int bytes, uint32_t prevCRC = 0); + + +} // namespace OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp b/LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp new file mode 100644 index 0000000..69d6557 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Callbacks.cpp @@ -0,0 +1,41 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_Callbacks.cpp +Content : Callback library +Created : Nov 17, 2014 +Author : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Callbacks.h" + +namespace OVR { + + +// Global emitter lock +// +// Add/remove operations on callbacks happen infrequently, and are already fairly +// serialized in order of construction by design. Therefore contention for this +// lock between call()/shutdown() is the main concern and is also rare. +Lock CallbackEmitterBase::EmitterLock; + + +} // namespace OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_Callbacks.h b/LibOVRKernel/Src/Kernel/OVR_Callbacks.h new file mode 100644 index 0000000..b02c4ff --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Callbacks.h @@ -0,0 +1,320 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_Callbacks.h +Content : Callback library +Created : June 20, 2014 +Author : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Callbacks_h +#define OVR_Callbacks_h + +#include "OVR_CallbacksInternal.h" + +#include "OVR_String.h" // For CallbackHash +#include "OVR_Hash.h" // For CallbackHash + +namespace OVR { + + +//----------------------------------------------------------------------------- +// CallbackEmitter +// +// Emitter of callbacks. +// Thread-safety: All public members may be safely called concurrently. +template +class CallbackEmitter : public NewOverrideBase +{ +public: + CallbackEmitter(); + ~CallbackEmitter(); + + // Add a listener. + bool AddListener(CallbackListener* listener); + + // Get the current number of listeners. Note that this can change as other threads + // add listeners to the emitter. + int GetListenerCount() const; + + void Call() + { + Emitter->Call(); + } + template + void Call(Param1* p1) + { + Emitter->Call(p1); + } + template + void Call(Param1& p1) + { + Emitter->Call(p1); + } + template + void Call(Param1* p1, Param2* p2) + { + Emitter->Call(p1, p2); + } + template + void Call(Param1& p1, Param2& p2) + { + Emitter->Call(p1, p2); + } + template + void Call(Param1* p1, Param2* p2, Param3* p3) + { + Emitter->Call(p1, p2, p3); + } + template + void Call(Param1& p1, Param2& p2, Param3& p3) + { + Emitter->Call(p1, p2, p3); + } + + // Remove all listeners and prevent further listeners from being added. + void Shutdown(); + +protected: + Ptr< FloatingCallbackEmitter > Emitter; +}; + + +//----------------------------------------------------------------------------- +// CallbackListener +// +// Listener for callbacks. +// Thread-safety: Operations on a listener are not thread-safe. +// The listener may only listen to *one emitter* at a time. +template +class CallbackListener : public NewOverrideBase +{ + friend class CallbackEmitter; + +public: + CallbackListener(); + ~CallbackListener(); + + // Stop listening to callbacks. + // And set a new handler for callbacks. + void SetHandler(DelegateT handler); + + // Is listening to an emitter at this instant? + // If the Emitter has shutdown, then this may inaccurately return true. + bool IsListening() const; + + // Stops listening to callbacks. + void Cancel(); + +protected: + /// Internal data: + + // Reference to the associated listener. + Ptr< FloatingCallbackListener > FloatingListener; + + // Reference to the associated emitter. + Ptr< FloatingCallbackEmitter > FloatingEmitter; + + DelegateT Handler; +}; + + +//----------------------------------------------------------------------------- +// Template Implementation: CallbackEmitter + +template +CallbackEmitter::CallbackEmitter() +{ + Emitter = *new FloatingCallbackEmitter; +} + +template +CallbackEmitter::~CallbackEmitter() +{ + Emitter->Shutdown(); + // Emitter goes out of scope here. +} + +template +bool CallbackEmitter::AddListener(CallbackListener* listener) +{ + // The listener object can only be attached to one emitter at a time. + // The caller should explicitly Cancel() a listener before listening + // to a new emitter, even if it is the same emitter. + OVR_ASSERT(!listener->FloatingEmitter && !listener->FloatingListener); + + if (listener->FloatingEmitter || listener->FloatingListener) + { + // Cancel any previous listening + listener->Cancel(); + } + + // Set the floating listener and emitter + listener->FloatingListener = *new FloatingCallbackListener(listener->Handler); + listener->FloatingEmitter = Emitter.GetPtr(); + + // The remaining input checks are performed inside. + return Emitter->AddListener(listener->FloatingListener); +} + +template +int CallbackEmitter::GetListenerCount() const +{ + return Emitter->Listeners.GetSizeI(); +} + +template +void CallbackEmitter::Shutdown() +{ + Emitter->Shutdown(); +} + + +//----------------------------------------------------------------------------- +// Template Implementation: CallbackListener + +template +CallbackListener::CallbackListener() +{ + // Listener is null until a handler is set. +} + +template +CallbackListener::~CallbackListener() +{ + Cancel(); +} + +template +void CallbackListener::Cancel() +{ + if (FloatingListener) + { + FloatingListener->EnterCancelState(); + } + + if (FloatingEmitter) + { + if (FloatingListener) + { + FloatingEmitter->OnListenerCancel(FloatingListener); + } + } + + // FloatingEmitter goes out of scope here. + FloatingEmitter = nullptr; + + // FloatingListener goes out of scope here. + FloatingListener = nullptr; +} + +template +void CallbackListener::SetHandler(DelegateT handler) +{ + Cancel(); + + Handler = handler; +} + +template +bool CallbackListener::IsListening() const +{ + if (!FloatingListener.GetPtr()) + { + return false; + } + + return FloatingListener->IsValid(); +} + + +//----------------------------------------------------------------------------- +// CallbackHash +// +// A hash containing CallbackEmitters +template +class CallbackHash : public NewOverrideBase +{ + typedef Hash*, String::HashFunctor> HashTable; + +public: + ~CallbackHash() + { + Clear(); + } + + void Clear() + { + for (auto ii = Table.Begin(); ii != Table.End(); ++ii) + { + delete ii->Second; + } + + Table.Clear(); + } + + CallbackEmitter* GetKey(String key) + { + CallbackEmitter** emitter = Table.Get(key); + if (emitter) + { + return *emitter; + } + return nullptr; + } + + void AddListener(String key, CallbackListener* listener) + { + CallbackEmitter** pEmitter = Table.Get(key); + CallbackEmitter* emitter = nullptr; + + if (!pEmitter) + { + emitter = new CallbackEmitter; + Table.Add(key, emitter); + } + else + { + emitter = *pEmitter; + } + + emitter->AddListener(listener); + } + + void RemoveKey(String key) + { + CallbackEmitter** emitter = Table.Get(key); + + if (emitter) + { + delete *emitter; + Table.Remove(key); + } + } + +protected: + HashTable Table; // Hash table +}; + + +} // namespace OVR + +#endif // OVR_Callbacks_h diff --git a/LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h b/LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h new file mode 100644 index 0000000..a0c0a31 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_CallbacksInternal.h @@ -0,0 +1,331 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_CallbacksInternal.h +Content : Callback library +Created : Nov 11, 2014 +Author : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_CallbacksInternal_h +#define OVR_CallbacksInternal_h + +#include "OVR_Atomic.h" +#include "OVR_RefCount.h" +#include "OVR_Delegates.h" +#include "OVR_Array.h" + +namespace OVR { + +template class FloatingCallbackEmitter; // Floating emitter object +template class CallbackEmitter; +template class FloatingCallbackListener; // Floating listener object +template class CallbackListener; + + +//----------------------------------------------------------------------------- +// FloatingCallbackEmitter +// +// The Call() function is not thread-safe. +// TBD: Should we add a thread-safe Call() option to constructor? + +class CallbackEmitterBase +{ +protected: + static Lock EmitterLock; +}; + +template +class FloatingCallbackEmitter : public CallbackEmitterBase, public RefCountBase< FloatingCallbackEmitter > +{ + friend class CallbackEmitter; + + FloatingCallbackEmitter() : + IsShutdown(false), + DirtyListenersCache(0) + { + } + +public: + typedef Array< Ptr< FloatingCallbackListener > > ListenerPtrArray; + + ~FloatingCallbackEmitter() + { + OVR_ASSERT(Listeners.GetSizeI() == 0); + // ListenersCache will be emptied here. + } + + bool AddListener(FloatingCallbackListener* listener); + void Shutdown(); + + // Called from the listener object as it is transitioning to canceled state. + // The listener's mutex is not held during this call. + void OnListenerCancel(FloatingCallbackListener* listener); + +public: + void Call(); + + template + void Call(Param1* p1); + + template + void Call(Param1& p1); + + template + void Call(Param1* p1, Param2* p2); + + template + void Call(Param1& p1, Param2& p2); + + template + void Call(Param1* p1, Param2* p2, Param3* p3); + + template + void Call(Param1& p1, Param2& p2, Param3& p3); + +protected: + // Is the emitter shut down? This prevents more listeners from being added during shutdown. + bool IsShutdown; + + // Array of added listeners. + ListenerPtrArray Listeners; + + // Is the cache dirty? This avoids locking and memory allocation in steady state. + AtomicInt DirtyListenersCache; + + // Cache of listeners used by the Call() function. + ListenerPtrArray ListenersCacheForCalls; + + // Update the ListenersCache array in response to an insertion or removal. + // This is how AddListener() insertions get rolled into the listeners array. + // This is how RemoveListener() removals get purged from the cache. + void updateListenersCache() + { + if (DirtyListenersCache != 0) + { + Lock::Locker locker(&EmitterLock); + + // TBD: Should memory allocation be further reduced here? + ListenersCacheForCalls = Listeners; + DirtyListenersCache = 0; + } + } + + // Without holding a lock, find and remove the given listener from the array of listeners. + void noLockFindAndRemoveListener(FloatingCallbackListener* listener) + { + const int count = Listeners.GetSizeI(); + for (int i = 0; i < count; ++i) + { + if (Listeners[i] == listener) + { + Listeners.RemoveAt(i); + + // After removing it from the array, set the dirty flag. + // Note: Because the flag is atomic, a portable memory fence is implied. + DirtyListenersCache = 1; + + break; + } + } + } +}; + + +//----------------------------------------------------------------------------- +// FloatingCallbackListener +// +// Internal implementation class for the CallbackListener. +// This can only be associated with one CallbackListener object for its lifetime. +template +class FloatingCallbackListener : public RefCountBase< FloatingCallbackListener > +{ +public: + FloatingCallbackListener(DelegateT handler); + ~FloatingCallbackListener(); + + void EnterCancelState(); + + bool IsValid() const + { + return Handler.IsValid(); + } + + // TBD: Should these be binned to reduce the lock count? + // Boost does not do that. And I am worried about deadlocks when misused. + mutable Lock ListenerLock; + + // Handler function + DelegateT Handler; +}; + + +//----------------------------------------------------------------------------- +// Template Implementation: FloatingCallbackEmitter + +template +bool FloatingCallbackEmitter::AddListener(FloatingCallbackListener* listener) +{ + Lock::Locker locker(&EmitterLock); + + if (IsShutdown) + { + return false; + } + + // Add the listener to our list + Listeners.PushBack(listener); + + // After adding it to the array, set the dirty flag. + // Note: Because the flag is atomic, a portable memory fence is implied. + DirtyListenersCache = 1; + + return true; +} + +// Called from the listener object as it is transitioning to canceled state. +// The listener's mutex is not held during this call. +template +void FloatingCallbackEmitter::OnListenerCancel(FloatingCallbackListener* listener) +{ + Lock::Locker emitterLocker(&EmitterLock); + + // If not shut down, + // Note that if it is shut down then there will be no listeners in the array. + if (!IsShutdown) + { + // Remove it. + noLockFindAndRemoveListener(listener); + } +} + +template +void FloatingCallbackEmitter::Shutdown() +{ + Lock::Locker locker(&EmitterLock); + + IsShutdown = true; + + Listeners.ClearAndRelease(); + + // Note: Because the flag is atomic, a portable memory fence is implied. + DirtyListenersCache = 1; +} + +//----------------------------------------------------------------------------- +// Call function +// +// (1) Update the cache of listener references, if it has changed. +// (2) For each listener, +// (a) Hold ListenerLock. +// (b) If listener handler is valid, call the handler. +#define OVR_EMITTER_CALL_BODY(params) \ + updateListenersCache(); \ + if (IsShutdown) return; /* Pure optimization. It is fine if this races. */ \ + const int count = ListenersCacheForCalls.GetSizeI(); \ + for (int i = 0; i < count; ++i) \ + { \ + Lock::Locker locker(&ListenersCacheForCalls[i]->ListenerLock); \ + if (ListenersCacheForCalls[i]->Handler.IsValid()) \ + { \ + ListenersCacheForCalls[i]->Handler params; /* Using a macro for this line. */ \ + } \ + } + +template +void FloatingCallbackEmitter::Call() +{ + OVR_EMITTER_CALL_BODY(()) +} + +template +template +void FloatingCallbackEmitter::Call(Param1* p1) +{ + OVR_EMITTER_CALL_BODY((p1)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1& p1) +{ + OVR_EMITTER_CALL_BODY((p1)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1* p1, Param2* p2) +{ + OVR_EMITTER_CALL_BODY((p1, p2)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1& p1, Param2& p2) +{ + OVR_EMITTER_CALL_BODY((p1, p2)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1* p1, Param2* p2, Param3* p3) +{ + OVR_EMITTER_CALL_BODY((p1, p2, p3)) +} + +template +template +void FloatingCallbackEmitter::Call(Param1& p1, Param2& p2, Param3& p3) +{ + OVR_EMITTER_CALL_BODY((p1, p2, p3)) +} + +#undef OVR_EMITTER_CALL_BODY + + +//----------------------------------------------------------------------------- +// Template Implementation: FloatingCallbackListener + +template +FloatingCallbackListener::FloatingCallbackListener(DelegateT handler) : + Handler(handler) +{ + OVR_ASSERT(Handler.IsValid()); +} + +template +FloatingCallbackListener::~FloatingCallbackListener() +{ + OVR_ASSERT(!Handler.IsValid()); +} + +template +void FloatingCallbackListener::EnterCancelState() +{ + ListenerLock.DoLock(); + Handler.Invalidate(); + ListenerLock.Unlock(); +} + + +} // namespace OVR + +#endif // OVR_CallbacksInternal_h diff --git a/LibOVRKernel/Src/Kernel/OVR_Color.h b/LibOVRKernel/Src/Kernel/OVR_Color.h new file mode 100644 index 0000000..7b5e966 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Color.h @@ -0,0 +1,73 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Color.h +Content : Contains color struct. +Created : February 7, 2013 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ +#ifndef OVR_Color_h +#define OVR_Color_h + +#include "OVR_Types.h" + +namespace OVR { + + +struct Color +{ + uint8_t R,G,B,A; + + Color() + { + #if defined(OVR_BUILD_DEBUG) + R = G = B = A = 0; + #endif + } + + // Constructs color by channel. Alpha is set to 0xFF (fully visible) + // if not specified. + Color(unsigned char r,unsigned char g,unsigned char b, unsigned char a = 0xFF) + : R(r), G(g), B(b), A(a) { } + + // 0xAARRGGBB - Common HTML color Hex layout + Color(unsigned c) + : R((unsigned char)(c>>16)), G((unsigned char)(c>>8)), + B((unsigned char)c), A((unsigned char)(c>>24)) { } + + bool operator==(const Color& b) const + { + return R == b.R && G == b.G && B == b.B && A == b.A; + } + + void GetRGBA(float *r, float *g, float *b, float* a) const + { + *r = R / 255.0f; + *g = G / 255.0f; + *b = B / 255.0f; + *a = A / 255.0f; + } +}; + + +} // namespace OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Compiler.h b/LibOVRKernel/Src/Kernel/OVR_Compiler.h new file mode 100644 index 0000000..4541795 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Compiler.h @@ -0,0 +1,1543 @@ +/************************************************************************************ + +PublicHeader: OVR_Types.h +Filename : OVR_Compiler.h +Content : Compiler-specific feature identification and utilities +Created : June 19, 2014 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + + +#ifndef OVR_Compiler_h +#define OVR_Compiler_h + +#pragma once + + +// References +// https://gcc.gnu.org/projects/cxx0x.html +// https://gcc.gnu.org/projects/cxx1y.html +// http://clang.llvm.org/cxx_status.html +// http://msdn.microsoft.com/en-us/library/hh567368.aspx +// https://docs.google.com/spreadsheet/pub?key=0AoBblDsbooe4dHZuVTRoSTFBejk5eFBfVk1GWlE5UlE&output=html +// http://nadeausoftware.com/articles/2012/10/c_c_tip_how_detect_compiler_name_and_version_using_compiler_predefined_macros + + +//----------------------------------------------------------------------------------- +// ***** Compiler +// +// The following compilers are defined: (OVR_CC_x) +// +// MSVC - Microsoft Visual C/C++ +// INTEL - Intel C++ for Linux / Windows +// GNU - GNU C++ +// ARM - ARM C/C++ + +#if defined(__INTEL_COMPILER) +// Intel 4.0 = 400 +// Intel 5.0 = 500 +// Intel 6.0 = 600 +// Intel 8.0 = 800 +// Intel 9.0 = 900 +# define OVR_CC_INTEL __INTEL_COMPILER + +#elif defined(_MSC_VER) +// MSVC 5.0 = 1100 +// MSVC 6.0 = 1200 +// MSVC 7.0 (VC2002) = 1300 +// MSVC 7.1 (VC2003) = 1310 +// MSVC 8.0 (VC2005) = 1400 +// MSVC 9.0 (VC2008) = 1500 +// MSVC 10.0 (VC2010) = 1600 +// MSVC 11.0 (VC2012) = 1700 +// MSVC 12.0 (VC2013) = 1800 +# define OVR_CC_MSVC _MSC_VER + +#if _MSC_VER == 0x1600 +# if _MSC_FULL_VER < 160040219 +# error "Oculus does not support VS2010 without SP1 installed." +# endif +#endif + +#elif defined(__GNUC__) +# define OVR_CC_GNU + +#elif defined(__clang__) +# define OVR_CC_CLANG + +#elif defined(__CC_ARM) +# define OVR_CC_ARM + +#else +# error "Oculus does not support this Compiler" +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CC_VERSION +// +// M = major version +// m = minor version +// p = patch release +// b = build number +// +// Compiler Format Example +// ---------------------------- +// OVR_CC_GNU Mmm 408 means GCC 4.8 +// OVR_CC_CLANG Mmm 305 means clang 3.5 +// OVR_CC_MSVC MMMM 1700 means VS2012 +// OVR_CC_ARM Mmpbbb 401677 means 4.0, patch 1, build 677 +// OVR_CC_INTEL MMmm 1210 means 12.10 +// OVR_CC_EDG Mmm 407 means EDG 4.7 +// +#if defined(OVR_CC_GNU) + #define OVR_CC_VERSION ((__GNUC__ * 100) + __GNUC_MINOR__) +#elif defined(OVR_CC_CLANG) + #define OVR_CC_VERSION ((__clang_major__ * 100) + __clang_minor__) +#elif defined(OVR_CC_MSVC) + #define OVR_CC_VERSION _MSC_VER // Question: Should we recognize _MSC_FULL_VER? +#elif defined(OVR_CC_ARM) + #define OVR_CC_VERSION __ARMCC_VERSION +#elif defined(OVR_CC_INTEL) + #if defined(__INTEL_COMPILER) + #define OVR_CC_VERSION __INTEL_COMPILER + #elif defined(__ICL) + #define OVR_CC_VERSION __ICL + #elif defined(__ICC) + #define OVR_CC_VERSION __ICC + #elif defined(__ECC) + #define OVR_CC_VERSION __ECC + #endif +#elif defined(OVR_CC_EDG) + #define OVR_CC_VERSION __EDG_VERSION__ // This is a generic fallback for EDG-based compilers which aren't specified above (e.g. as OVR_CC_ARM) +#endif + + + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_OPTIMIZATION / OVR_RESTORE_OPTIMIZATION +// +// Allows for the dynamic disabling and restoring of compiler optimizations in code. +// This is useful for helping deal with potential compiler code generation problems. +// With VC++ the usage must be outside of function bodies. This can be used only to +// temporarily disable optimization for a block of code and not to temporarily enable +// optimization for a block of code. +// +// Clang doesn't support this as of June 2014, though function __attribute__((optimize(0)) +// is supposedly supported by clang in addition to GCC. To consider: Make a wrapper for +// this attribute-based functionality. +// +// Example usage: +// OVR_DISABLE_OPTIMIZATION() +// void Test() { ... } +// OVR_RESTORE_OPTIMIZATION() +// +#if !defined(OVR_DISABLE_OPTIMIZATION) + #if defined(OVR_CC_GNU) && (OVR_CC_VERSION > 404) && (defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)) + #define OVR_DISABLE_OPTIMIZATION() \ + _Pragma("GCC push_options") \ + _Pragma("GCC optimize 0") + #elif defined(OVR_CC_MSVC) + #define OVR_DISABLE_OPTIMIZATION() __pragma(optimize("", off)) + #else + #define OVR_DISABLE_OPTIMIZATION() + #endif +#endif + +#if !defined(OVR_RESTORE_OPTIMIZATION) + #if defined(OVR_CC_GNU) && (OVR_CC_VERSION > 404) && (defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64)) + #define OVR_RESTORE_OPTIMIZATION() _Pragma("GCC pop_options") + #elif defined(OVR_CC_MSVC) + #define OVR_RESTORE_OPTIMIZATION() __pragma(optimize("", on)) + #else + #define OVR_RESTORE_OPTIMIZATION() + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_GNU_WARNING / OVR_RESTORE_GNU_WARNING +// +// Portable wrapper for disabling GCC compiler warnings, one at a time. See example +// usage for usage by example. +// +// Example usage: +// OVR_DISABLE_GNU_WARNING(-Wmissing-braces) // Only one warning per usage. +// OVR_DISABLE_GNU_WARNING(-Wunused-variable) +// +// OVR_RESTORE_GNU_WARNINGS() +// OVR_RESTORE_GNU_WARNINGS() // Must match each disable with a restore. +// +#if !defined(OVR_DISABLE_GNU_WARNING) + #if defined(OVR_CC_GNU) + #define ODGW1(x) #x + #define ODGW2(x) ODGW1(GCC diagnostic ignored x) + #define ODGW3(x) ODGW2(#x) + #endif + + #if defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 406) + #define OVR_DISABLE_GNU_WARNING(w) \ + _Pragma("GCC diagnostic push") \ + _Pragma(ODGW3(w)) + #elif defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 404) // GCC 4.4 doesn't support diagnostic push, but supports disabling warnings. + #define OVR_DISABLE_GNU_WARNING(w) \ + _Pragma(ODGW3(w)) + #else + #define OVR_DISABLE_GNU_WARNING(w) + #endif +#endif + +#if !defined(OVR_RESTORE_GNU_WARNING) + #if defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 4006) + #define OVR_RESTORE_GNU_WARNINGS() \ + _Pragma("GCC diagnostic pop") + #else + #define OVR_RESTORE_GNU_WARNING() + #endif +#endif + + + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_CLANG_WARNING / OVR_RESTORE_CLANG_WARNING +// +// Portable wrapper for disabling GCC compiler warnings, one at a time. See example +// usage for usage by example. +// +// Example usage: +// OVR_DISABLE_CLANG_WARNING(-Wmissing-braces) // Only one warning per usage. +// OVR_DISABLE_CLANG_WARNING(-Wunused-variable) +// +// OVR_RESTORE_CLANG_WARNINGS() +// OVR_RESTORE_CLANG_WARNINGS() // Must match each disable with a restore. +// +// +#if !defined(OVR_DISABLE_CLANG_WARNING) + #if defined(OVR_CC_CLANG) + #define ODCW1(x) #x + #define ODCW2(x) ODCW1(clang diagnostic ignored x) + #define ODCW3(x) ODCW2(#x) + + #define OVR_DISABLE_CLANG_WARNING(w) \ + _Pragma("clang diagnostic push") \ + _Pragma(ODCW3(w)) + #else + #define OVR_DISABLE_CLANG_WARNING(w) + #endif +#endif + +#if !defined(OVR_RESTORE_CLANG_WARNING) + #if defined(OVR_CC_CLANG) + #define OVR_RESTORE_CLANG_WARNING() \ + _Pragma("clang diagnostic pop") + #else + #define OVR_RESTORE_CLANG_WARNING() + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_MSVC_WARNING / OVR_RESTORE_MSVC_WARNING +// +// Portable wrapper for disabling VC++ compiler warnings. See example usage for usage +// by example. +// +// Example usage: +// OVR_DISABLE_MSVC_WARNING(4556 4782 4422) +// +// OVR_RESTORE_MSVC_WARNING() +// +#if !defined(OVR_DISABLE_MSVC_WARNING) + #if defined(OVR_CC_MSVC) + #define OVR_DISABLE_MSVC_WARNING(w) \ + __pragma(warning(push)) \ + __pragma(warning(disable:w)) + #else + #define OVR_DISABLE_MSVC_WARNING(w) + #endif +#endif + +#if !defined(OVR_RESTORE_MSVC_WARNING) + #if defined(OVR_CC_MSVC) + #define OVR_RESTORE_MSVC_WARNING() \ + __pragma(warning(pop)) + #else + #define OVR_RESTORE_MSVC_WARNING() + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_DISABLE_ALL_MSVC_WARNINGS / OVR_RESTORE_ALL_MSVC_WARNINGS +// +// Portable wrapper for disabling all VC++ compiler warnings. +// OVR_RESTORE_ALL_MSVC_WARNINGS restores warnings that were disabled by +// OVR_DISABLE_ALL_MSVC_WARNINGS. Any previously enabled warnings will still be +// enabled after OVR_RESTORE_ALL_MSVC_WARNINGS. +// +// Example usage: +// OVR_DISABLE_ALL_MSVC_WARNINGS() +// +// OVR_RESTORE_ALL_MSVC_WARNINGS() + +#if !defined(OVR_DISABLE_ALL_MSVC_WARNINGS) + #if defined(OVR_CC_MSVC) + #define OVR_DISABLE_ALL_MSVC_WARNINGS() \ + __pragma(warning(push, 0)) \ + __pragma(warning(disable: 4263 4264 4266)) + #else + #define OVR_DISABLE_ALL_MSVC_WARNINGS() + #endif +#endif + +#if !defined(OVR_RESTORE_ALL_MSVC_WARNINGS) + #if defined(OVR_CC_MSVC) + #define OVR_RESTORE_ALL_MSVC_WARNINGS() \ + __pragma(warning(pop)) + #else + #define OVR_RESTORE_ALL_MSVC_WARNINGS() + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CC_HAS_FEATURE +// +// This is a portable way to use compile-time feature identification available +// with some compilers in a clean way. Direct usage of __has_feature in preprocessing +// statements of non-supporting compilers results in a preprocessing error. +// +// Example usage: +// #if OVR_CC_HAS_FEATURE(is_pod) +// if(__is_pod(T)) // If the type is plain data then we can safely memcpy it. +// memcpy(&destObject, &srcObject, sizeof(object)); +// #endif +// +#if !defined(OVR_CC_HAS_FEATURE) + #if defined(__clang__) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 + #define OVR_CC_HAS_FEATURE(x) __has_feature(x) + #else + #define OVR_CC_HAS_FEATURE(x) 0 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CC_HAS_BUILTIN +// +// +// This is a portable way to use compile-time builtin identification available +// with some compilers in a clean way. Direct usage of __has_builtin in preprocessing +// statements of non-supporting compilers results in a preprocessing error. +// +// Example usage: +// #if OVR_CC_HAS_BUILTIN(__builtin_trap) +// #define DEBUG_BREAK __builtin_trap +// #endif +// +#if !defined(OVR_CC_HAS_BUILTIN) + #if defined(__clang__) + #define OVR_CC_HAS_BUILTIN(x) __has_builtin(x) // http://clang.llvm.org/docs/LanguageExtensions.html#id2 + #else + #define OVR_CC_HAS_BUILTIN(x) 0 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP11_ENABLED / OVR_CPP_CPP14_ENABLED +// +// Defined as 1 if the compiler has its available C++11 support enabled, else undefined. +// This does not mean that all of C++11 or any particular feature of C++11 is supported +// by the compiler. It means that whatever C++11 support the compiler has is enabled. +// This also includes existing and older compilers that still identify C++11 as C++0x. +// +#if !defined(OVR_CPP11_ENABLED) && defined(__cplusplus) + #if defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__) + #define OVR_CPP11_ENABLED 1 + #elif defined(_MSC_VER) && (_MSC_VER >= 1500) // VS2010+, the first version with any significant C++11 support. + #define OVR_CPP11_ENABLED 1 + #elif (__cplusplus >= 201103L) // 201103 is the first C++11 version. + #define OVR_CPP11_ENABLED 1 + #else + // Leave undefined + #endif +#endif + +#if !defined(OVR_CPP_CPP14_ENABLED) && defined(__cplusplus) + #if defined(_MSC_VER) && (_MSC_VER >= 1800) // VS2013+, the first version with any significant C++14 support. + #define OVR_CPP_CPP14_ENABLED 1 + #elif (__cplusplus > 201103L) + #define OVR_CPP_CPP14_ENABLED 1 + #else + // Leave undefined + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXCEPTIONS / OVR_CPP_NO_UNWIND +// +// OVR_CPP_NO_EXCEPTIONS is defined as 1 if the compiler doesn't support C++ +// exceptions or is configured to disable support for them. Else not defined. +// If OVR_CPP_NO_EXCEPTIONS is defined then attempts to use try/catch +// related C++ statements result in a compilation error with many +// compilers. +// +// OVR_CPP_NO_UNWIND is defined as 1 if the compiler supports exceptions but +// doesn't support stack unwinding in the presence of an exception. Else not defined. +// For the Microsoft compiler, disabling exceptions means disabling stack unwinding +// and not disabling exceptions themselves. +// +// Example usage: +// void Test() { +// #if !defined(OVR_CPP_NO_EXCEPTIONS) +// try { +// #endif +// void* ptr = new Object; +// #if !defined(OVR_CPP_NO_EXCEPTIONS) +// catch(...) { ... } +// #endif + +#if !defined(OVR_CPP_NO_EXCEPTIONS) + #if defined(OVR_CPP_GNUC) && defined(_NO_EX) + #define OVR_CPP_NO_EXCEPTIONS 1 + #elif (defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) || defined(OVR_CC_INTEL) || defined(OVR_CC_ARM)) && !defined(__EXCEPTIONS) + #define OVR_CPP_NO_EXCEPTIONS 1 + #elif defined(OVR_CC_MSVC) && !defined(_CPPUNWIND) + #define OVR_CPP_NO_UNWIND 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_RTTI +// +// Defined as 1 if C++ run-time type information support is unavailable or disabled +// by the compiler. Else undefined. Allows you to write portable code in the face +// of the possibility that RTTI is disabled. +// +// Example usage: +// #if !OVR_CPP_NO_RTTI +// #include +// int x = std::dynamic_cast(3.4f); +// #endif + +#if defined(__clang__) && !OVR_CC_HAS_FEATURE(cxx_rtti) + #define OVR_CPP_NO_RTTI 1 +#elif defined(__GNUC__) && !defined(__GXX_RTTI) + #define OVR_CPP_NO_RTTI 1 +#elif defined(_MSC_VER) && !defined(_CPPRTTI) + #define OVR_CPP_NO_RTTI 1 +#elif defined(__CC_ARM) && defined(__TARGET_CPU_MPCORE) && !defined(__RTTI) + #define OVR_CPP_NO_RTTI 1 +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_STATIC_ASSERT +// +// Defined as 1 if C++ run-time type information support is available and enabled +// by the compiler. Else undefined. +// +// Example usage: +// #if OVR_CPP_NO_STATIC_ASSERT +// #define MY_ASSERT(x) { int zero = 0; switch(zero) {case 0: case (x):;} } +// #else +// #define MY_ASSERT(x) static_assert((x), #x) +// #endif + +#if !defined(OVR_CPP_NO_STATIC_ASSERT) + #if !(defined(__GNUC__) && (defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && (__cplusplus >= 201103L)))) && \ + !(defined(__clang__) && defined(__cplusplus) && OVR_CC_HAS_FEATURE(cxx_static_assert)) && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(__cplusplus)) && /* VS2010+ */ \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401) && defined(OVR_CPP11_ENABLED)) /* EDG 4.1+ */ + #define OVR_CPP_NO_STATIC_ASSERT 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NULLPTR +// +// Defined as 1 if the compiler doesn't support C++11 nullptr built in type. +// Otherwise undefined. Does not identify if the standard library defines +// std::nullptr_t, as some standard libraries are further behind in standardization +// than the compilers using them (e.g. Apple clang with the supplied libstdc++). +// +// OVR_Nullptr.h provides a portable nullptr and std::nullptr_t for when the +// compiler or standard library do not. + +#if !defined(OVR_CPP_NO_NULLPTR) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_nullptr)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ + #define OVR_CPP_NO_NULLPTR 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_RVALUE_REFERENCES +// +// Defined as 1 if the compiler doesn't support C++11 rvalue references and move semantics. +// Otherwise undefined. + +#if !defined(OVR_CPP_NO_RVALUE_REFERENCES) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_rvalue_references)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ + #define OVR_CPP_NO_RVALUE_REFERENCES 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_AUTO +// +// Defined as 1 if the compiler doesn't support C++11 auto keyword. Otherwise undefined. + +#if !defined(OVR_CPP_NO_AUTO) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_auto_type)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 309))) /* EDG 3.9+ */ + #define OVR_CPP_NO_AUTO 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_RANGE_BASED_FOR_LOOP +// +// Defined as 1 if the compiler doesn't support C++11 range-based for loops. +// Otherwise undefined. + +#if !defined(OVR_CPP_NO_RANGE_BASED_FOR_LOOP) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_range_for)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ + #define OVR_CPP_NO_RANGE_BASED_FOR_LOOP 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_CONSTEXPR / OVR_CPP_NO_RELAXED_CONSTEXPR +// +// OVR_CPP_NO_CONSTEXPR is defined as 1 if the compiler doesn't support C++11 constexpr. +// OVR_CPP_NO_RELAXED_CONSTEXPR is defined as 1 if the compiler doesn't support C++14 constexpr. +// Otherwise undefined. +// See the OVR_CONSTEXPR / OVR_CONSTEXPR_OR_CONST macros for portable wrappers of this functionality. + +#if !defined(OVR_CPP_NO_CONSTEXPR) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_constexpr)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ + // Not supported by VC++ through at least VS2013. + #define OVR_CPP_NO_CONSTEXPR 1 + #endif +#endif + +#if !defined(OVR_CPP_NO_RELAXED_CONSTEXPR) + #if !defined(OVR_CPP14_ENABLED) || \ + !(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_relaxed_constexpr)) /* clang */ + // Supported only by clang as of this writing. + #define OVR_CPP_NO_RELAXED_CONSTEXPR 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_LAMBDA_EXPRESSIONS +// +// Defined as 1 if the compiler doesn't support C++11 lambda expressions. Otherwise undefined. +// Some compilers have slightly crippled versions of this. + +#if !defined(OVR_CPP_NO_LAMBDA_EXPRESSIONS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_lambdas)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ + // Conversion of lambdas to function pointers is not supported until EDG 4.5. + #define OVR_CPP_NO_LAMBDA_EXPRESSIONS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_ALIGNOF +// +// Defined as 1 if the compiler supports C++11 alignof. Otherwise undefined. +// Some compilers support __alignof__ instead of alignof, so for portability you +// should use OVR_ALIGNOF instead of directly using C++11 alignof. + +#if !defined(OVR_CPP_NO_ALIGNOF) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 300)) /* Apple clang 3.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 401)) /* GCC 4.1+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400))) /* EDG 4.0+ */ + #define OVR_CPP_NO_ALIGNOF 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_ALIGNAS +// +// Defined as 1 if the compiler supports C++11 alignas. Otherwise undefined. +// See the OVR_ALIGNAS for a portable wrapper for alignas functionality. + +#if !defined(OVR_CPP_NO_ALIGNAS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ + #define OVR_CPP_NO_ALIGNAS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_OVERRIDE +// +// Defined as 1 if the compiler doesn't support C++11 override. Otherwise undefined. +// See the OVR_OVERRIDE and OVR_FINALOVERRIDE macros for a portable wrapper. + +#if !defined(OVR_CPP_NO_OVERRIDE) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ + #define OVR_CPP_NO_OVERRIDE 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_FINAL +// +// Defined as 1 if the compiler doesn't support C++11 final attribute. Otherwise undefined. +// See the OVR_FINAL and OVR_FINALOVERRIDE macros for a portable wrapper. + +#if !defined(OVR_CPP_NO_FINAL) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ + #define OVR_CPP_NO_FINAL 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXTERN_TEMPLATE +// +// Defined as 1 if the compiler doesn't support C++11 extern template. +// Otherwise undefined. See OVR_EXTERN_TEMPLATE for wrapper macro. + +#if !defined(OVR_CPP_NO_EXTERN_TEMPLATE) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ + #define OVR_CPP_NO_EXTERN_TEMPLATE 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_VARIADIC_TEMPLATES +// +// Defined as 1 if the compiler doesn't support C++11 variadic templates. Otherwise undefined. + +#if !defined(OVR_CPP_NO_VARIADIC_TEMPLATES) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_variadic_templates)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ + #define OVR_CPP_NO_VARIADIC_TEMPLATES 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NOEXCEPT +// +// Defined as 1 if the compiler supports C++11 noexcept. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/noexcept +// See OVR_NOEXCEPT / OVR_NOEXCEPT_IF / OVR_NOEXCEPT_EXPR for a portable wrapper +// for noexcept functionality. + +#if !defined(OVR_CPP_NO_NOEXCEPT) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_noexcept)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ + #define OVR_CPP_NO_NOEXCEPT 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DECLTYPE +// +// Defined as 1 if the compiler doesn't support C++11 decltype. Otherwise undefined. +// Some compilers (e.g. VS2012) support most uses of decltype but don't support +// decltype with incomplete types (which is an uncommon usage seen usually in +// template metaprogramming). We don't include this support as a requirement for +// our definition of decltype support here. + +#if !defined(OVR_CPP_NO_DECLTYPE) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_decltype)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ + // VC++ fails to support decltype for incomplete types until VS2013. + // EDG fails to support decltype for incomplete types until v4.8. + #define OVR_CPP_NO_DECLTYPE 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DEFAULTED_FUNCTIONS +// +// Defined as 1 if the compiler doesn't support C++11 defaulted functions. Otherwise undefined. +// Some compilers have slightly crippled versions of this. + +#if !defined(OVR_CPP_NO_DEFAULTED_FUNCTIONS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_defaulted_functions))/* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ + // Up through at least VS2013 it's unsupported for defaulted move constructors and move assignment operators. + // Until EDG 4.8 it's unsupported for defaulted move constructors and move assigment operators. + #define OVR_CPP_NO_DEFAULTED_FUNCTIONS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DELETED_FUNCTIONS +// +// Defined as 1 if the compiler doesn't support C++11 deleted functions. Otherwise undefined. +// Some compilers have slightly crippled versions of this. + +#if !defined(OVR_CPP_NO_DELETED_FUNCTIONS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_defaulted_functions)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ + // Up through at least VS2013 it's unsupported for defaulted move constructors and move assignment operators. + // Until EDG 4.8 it's unsupported for defaulted move constructors and move assigment operators. + #define OVR_CPP_NO_DELETED_FUNCTIONS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_STANDARD_LAYOUT_TYPES +// +// Defined as 1 if the compiler doesn't support C++11 standard layout (relaxed POD). Otherwise undefined. +// http://en.cppreference.com/w/cpp/types/is_standard_layout + +#if !defined(OVR_CPP_NO_STANDARD_LAYOUT_TYPES) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ + #define OVR_CPP_NO_STANDARD_LAYOUT_TYPES 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_FORWARD_DECLARED_ENUMS +// +// Defined as 1 if the compiler doesn't support C++11 forward declared enums. Otherwise undefined. + +#if !defined(OVR_CPP_NO_FORWARD_DECLARED_ENUMS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ + #define OVR_CPP_NO_FORWARD_DECLARED_ENUMS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_STRONGLY_TYPED_ENUMS +// +// Defined as 1 if the compiler doesn't support C++11 strongly typed enums. Otherwise undefined. + +#if !defined(OVR_CPP_NO_STRONGLY_TYPED_ENUMS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_strong_enums)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1700)) /* VS2012+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 400))) /* EDG 4.0+ */ + #define OVR_CPP_NO_STRONGLY_TYPED_ENUMS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_TRAILING_RETURN_TYPES +// +// Defined as 1 if the compiler doesn't support C++11 trailing return types. Otherwise undefined. +// http://en.wikipedia.org/wiki/C%2B%2B11#Alternative_function_syntax + +#if !defined(OVR_CPP_NO_TRAILING_RETURN_TYPES) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_trailing_return)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ + #define OVR_CPP_NO_TRAILING_RETURN_TYPES 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_TEMPLATE_ALIASES +// +// Defined as 1 if the compiler doesn't support C++11 template aliases. Otherwise undefined. + +#if !defined(OVR_CPP_NO_TEMPLATE_ALIASES) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_alias_templates)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ + #define OVR_CPP_NO_TEMPLATE_ALIASES 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_INITIALIZER_LISTS +// +// Defined as 1 if the compiler doesn't support C++11 initializer lists. Otherwise undefined. +// This refers to the compiler support for this and not the Standard Library support for std::initializer_list, +// as a new compiler with an old standard library (e.g. Apple clang with libstdc++) may not support std::initializer_list. + +#if !defined(OVR_CPP_NO_INITIALIZER_LISTS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_generalized_initializers)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ + #define OVR_CPP_NO_INITIALIZER_LISTS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NORETURN +// +// Defined as 1 if the compiler doesn't support the C++11 noreturn attribute. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/attributes +// +#if !defined(OVR_CPP_NO_NORETURN) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1500)) /* VS2008+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ + // Supported with VC++ only via __declspec(noreturn) (see OVR_NORETURN). + #define OVR_CPP_NO_NORETURN 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS +// +// Defined as 1 if the compiler doesn't support C++11 in-class non-static member initializers. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/data_members + +#if !defined(OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ + #define OVR_CPP_NO_NONSTATIC_MEMBER_INITIALIZERS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DOUBLE_TEMPLATE_BRACKETS +// +// Defined as 1 if the compiler supports nested template declarations with >>, +// as supported by C++11. Otherwise undefined. + +#if !defined(OVR_CPP_NO_DOUBLE_TEMPLATE_ANGLE_BRACKETS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ + #define OVR_CPP_NO_DOUBLE_TEMPLATE_BRACKETS 1 + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_INHERITING_CONSTRUCTORS +// +// Defined as 1 if the compiler supports C++11 inheriting constructors. Otherwise undefined. +// Example usage: +// struct A { explicit A(int x){} }; +// struct B : public A { using A::A; }; // As if B redeclared A::A(int). + +#if !defined(OVR_CPP_NO_INHERITING_CONSTRUCTORS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_inheriting_constructors)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ + #define OVR_CPP_NO_INHERITING_CONSTRUCTORS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_DELEGATING_CONSTRUCTORS +// +// Defined as 1 if the compiler supports C++11 delegating constructors. Otherwise undefined. + +#if !defined(OVR_CPP_NO_DELEGATING_CONSTRUCTORS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 300)) /* clang 3.0+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ + #define OVR_CPP_NO_DELEGATING_CONSTRUCTORS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS +// +// Defined as 1 if the compiler supports C++11 function template default arguments. Otherwise undefined. + +#if !defined(OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 403)) /* GCC 4.3+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 403))) /* EDG 4.3+ */ + #define OVR_CPP_NO_FUNCTION_TEMPLATE_DEFAULT_ARGS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_UNRESTRICTED_UNIONS +// +// Defined as 1 if the compiler supports C++11 unrestricted unions. Otherwise undefined. + +#if !defined(OVR_CPP_NO_UNRESTRICTED_UNIONS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 406)) /* GCC 4.6+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ + // Not supported by VC++ as of VS2013. + #define OVR_CPP_NO_UNRESTRICTED_UNIONS 1 + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXTENDED_SIZEOF +// +// Defined as 1 if the compiler supports C++11 class sizeof extensions (e.g. sizeof SomeClass::someMember). +// Otherwise undefined. + +#if !defined(OVR_CPP_NO_EXTENDED_SIZEOF) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1900)) /* VS2014+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ + #define OVR_CPP_NO_EXTENDED_SIZEOF 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_INLINE_NAMESPACES +// +// Defined as 1 if the compiler supports C++11 inlined namespaces. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/namespace#Inline_namespaces + +#if !defined(OVR_CPP_NO_INLINE_NAMESPACES) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 405))) /* EDG 4.5+ */ + // Not supported by VC++ as of VS2013. + #define OVR_CPP_NO_INLINE_NAMESPACES 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS +// +// Defined as 1 if the compiler supports C++11 explicit conversion operators. Otherwise undefined. +// http://en.cppreference.com/w/cpp/language/explicit + +#if !defined(OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_explicit_conversions)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 404))) /* EDG 4.4+ */ + #define OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS +// +// Defined as 1 if the compiler supports C++11 local class template parameters. Otherwise undefined. +// Example: +// void Test() { +// struct LocalClass{ }; +// SomeTemplateClass t; // Allowed only in C++11 +// } + +#if !defined(OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_local_type_template_args)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 402))) /* EDG 4.2+ */ + #define OVR_CPP_NO_LOCAL_CLASS_TEMPLATE_PARAMETERS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_NEW_CHARACTER_TYPES +// +// Defined as 1 if the compiler natively supports C++11 char16_t and char32_t. Otherwise undefined. +// VC++ through at least VS2013 defines char16_t as unsigned short in its standard library, +// but it is not a native type or unique type, nor can you for a string literal with it. + +#if !defined(OVR_CPP_NO_NEW_CHARACTER_TYPES) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_unicode_literals)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ + // Not supported by VC++ as of VS2013. + #define OVR_CPP_NO_NEW_CHARACTER_TYPES 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS +// +// Defined as 1 if the compiler supports C++11 \u and \U character literals for +// native char16_t and char32_t types. +// +#if !defined(OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ + // Not supported by VC++ as of VS2013. VC++'s existing \U and \u are non-conforming. + #define OVR_CPP_NO_UNICODE_CHAR_NAME_LITERALS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_USER_DEFINED_LITERALS +// +// Defined as 1 if the compiler supports C++11 user-defined literals. Otherwise undefined. + +#if !defined(OVR_CPP_NO_USER_DEFINED_LITERALS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 301)) /* clang 3.1+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 401)) /* Apple clang 4.1+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ + // Not supported by VC++ as of VS2013. + #define OVR_CPP_NO_USER_DEFINED_LITERALS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_UNICODE_STRING_LITERALS +// +// Defined as 1 if the compiler supports C++11 Unicode string literals. Otherwise undefined. +// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals + +#if !defined(OVR_CPP_NO_UNICODE_STRING_LITERALS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_unicode_literals)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ + // Not supported by VC++ as of VS2013. + #define OVR_CPP_NO_UNICODE_STRING_LITERALS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_RAW_STRING_LITERALS +// +// Defined as 1 if the compiler supports C++11 raw literals. Otherwise undefined. +// http://en.wikipedia.org/wiki/C%2B%2B11#New_string_literals + +#if !defined(OVR_CPP_NO_RAW_STRING_LITERALS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_raw_string_literals)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 405)) /* GCC 4.5+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 407))) /* EDG 4.7+ */ + // Not supported by VC++ as of VS2013. + #define OVR_CPP_NO_RAW_STRING_LITERALS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX +// +// Defined as 1 if the compiler supports C++11 unified initialization. +// http://en.wikipedia.org/wiki/C%2B%2B11#Uniform_initialization + +#if !defined(OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_generalized_initializers)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 404)) /* GCC 4.4+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1800)) /* VS2013+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 406))) /* EDG 4.6+ */ + #define OVR_CPP_NO_UNIFIED_INITIALIZATION_SYNTAX 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS +// +// Defined as 1 if the compiler supports C++11 extended friends. + +#if !defined(OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && !defined(__APPLE__) && (__clang__ >= 209)) /* clang 2.9+ */ && \ + !(defined(__clang__) && defined(__APPLE__) && (__clang__ >= 400)) /* Apple clang 4.0+ */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 407)) /* GCC 4.7+ */ && \ + !(defined(_MSC_VER) && (_MSC_VER >= 1600)) /* VS2010+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 401))) /* EDG 4.1+ */ + #define OVR_CPP_NO_EXTENDED_FRIEND_DECLARATIONS 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_CPP_NO_THREAD_LOCAL +// +// Defined as 1 if the compiler supports C++11 thread_local. Else undefined. Does not +// indicate if the compiler supports C thread-local compiler extensions such as __thread +// and declspec(thread). Use OVR_THREAD_LOCAL if you want to declare a thread-local +// variable that supports C++11 thread_local when available but the C extension when +// it's available. The primary difference between C++11 thread_local and C extensions is +// that C++11 thread_local supports non-PODs and calls their constructors and destructors. +// +// Note that thread_local requires both compiler and linker support, and so it's possible +// that the compiler may support thread_local but the linker does not. + +#if !defined(OVR_CPP_NO_THREAD_LOCAL) + #if !defined(OVR_CPP11_ENABLED) || \ + (!(defined(__clang__) && OVR_CC_HAS_FEATURE(cxx_thread_local)) /* clang */ && \ + !(defined(__GNUC__) && (OVR_CC_VERSION >= 408)) /* GCC 4.8+ */ && \ + !(defined(__EDG_VERSION__) && (__EDG_VERSION__ >= 408))) /* EDG 4.8+ */ + #define OVR_CPP_NO_THREAD_LOCAL 1 + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_ALIGNAS / OVR_ALIGNOF +// +// OVR_ALIGNAS(n) // Specifies a size_t power of two alignment for a type or instance. +// OVR_ALIGNOF(type) // Returns the size_t alignment of a type or instance. +// +// Example usage: +// OVR_ALIGNAS(8) char c = 'c'; // Specifies that the instance c be aligned to an 8 byte boundary. +// typedef OVR_ALIGNAS(8) char C; // Specifies that the type C be aligned to an 8 byte boundary. +// struct OVR_ALIGNAS(64) S{ char array[16]; }; // Specfies that the struct S have a natural alignment of 64. +// OVR_ALIGNAS(32) S s; // Specifies that the instance s of struct S be aligned to an 32 byte boundary. +// OVR_ALIGNAS(32) struct T{ char array[16]; } t; // Specfies that the instance t of struct T have a natural alignment of 32. +// struct OVR_ALIGNAS(T) U{}; // Specifes that U be aligned the same as T. Supported only by C++11 compilers (see OVR_CPP_NO_ALIGNAS). +// +// size_t a = OVR_ALIGNOF(double); // Returns the natural alignment of the double type. +// size_t a = OVR_ALIGNOF(S); // Returns the natural alignment of the struct S type. +// +// Note: If C++11 alignas is supported, then alignas/OVR_ALIGNAS may take a const expression in addition to a constant. +// Note: The C11 Standard species the _Alignas keyword and alignas as a macro for it in + +#if !defined(OVR_ALIGNAS) + #if defined(OVR_CC_GNU) && !defined(OVR_CPP_NO_ALIGNAS) // If C++11 alignas is supported... + #define OVR_ALIGNAS(n) alignas(n) + #elif defined(__clang__) && !defined(OVR_CPP_NO_ALIGNAS) + #define OVR_ALIGNAS(n) alignas(n) + #elif defined(OVR_CC_GNU) || defined(__clang__) + #define OVR_ALIGNAS(n) __attribute__((aligned(n))) + #elif defined(OVR_CC_MSVC) || defined(OVR_CC_INTEL) + #define OVR_ALIGNAS(n) __declspec(align(n)) // For Microsoft the alignment must be a literal integer. + #elif defined(OVR_CC_ARM) + #define OVR_ALIGNAS(n) __align(n) + #else + #error Need to define OVR_ALIGNAS + #endif +#endif + +#if !defined(OVR_ALIGNOF) + #if defined(OVR_CC_GNU) && !defined(OVR_CPP_NO_ALIGNOF) // If C++11 alignof is supported... + #define OVR_ALIGNOF(type) alignof(type) + #elif defined(__clang__) && !defined(OVR_CPP_NO_ALIGNOF) + #define OVR_ALIGNOF(type) alignof(type) + #elif defined(OVR_CC_GNU) || defined(__clang__) + #define OVR_ALIGNOF(type) ((size_t)__alignof__(type)) + #elif defined(OVR_CC_MSVC) || defined(OVR_CC_INTEL) + #define OVR_ALIGNOF(type) ((size_t)__alignof(type)) + #elif defined(OVR_CC_ARM) + #define OVR_ALIGNOF(type) ((size_t)__ALIGNOF__(type)) + #else + #error Need to define OVR_ALIGNOF + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_ASSUME / OVR_ANALYSIS_ASSUME +// +// This is a portable wrapper for VC++'s __assume and __analysis_assume. +// __analysis_assume is typically used to quell VC++ static analysis warnings. +// +// Example usage: +// void Test(char c){ +// switch(c){ +// case 'a': +// case 'b': +// case 'c': +// case 'd': +// break; +// default: +// OVR_ASSUME(0); // Unreachable code. +// } +// } +// +// size_t Test(char* str){ +// OVR_ANALYSIS_ASSUME(str != nullptr); +// return strlen(str); +// } + +#if !defined(OVR_ASSUME) + #if defined(OVR_CC_MSVC) + #define OVR_ASSUME(x) __assume(x) + #define OVR_ANALYSIS_ASSUME(x) __analysis_assume(!!(x)) + #else + #define OVR_ASSUME(x) + #define OVR_ANALYSIS_ASSUME(x) + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_RESTRICT +// +// Wraps the C99 restrict keyword in a portable way. +// C++11 and C++14 don't have restrict but this functionality is supported by +// all C++ compilers. +// +// Example usage: +// void* memcpy(void* OVR_RESTRICT s1, const void* OVR_RESTRICT s2, size_t n); + +#if !defined(OVR_RESTRICT) + #define OVR_RESTRICT __restrict // Currently supported by all compilers of significance to us. +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_NOEXCEPT / OVR_NOEXCEPT_IF(predicate) / OVR_NOEXCEPT_EXPR(expression) +// +// Implements a portable wrapper for C++11 noexcept. +// http://en.cppreference.com/w/cpp/language/noexcept +// +// Example usage: +// void Test() OVR_NOEXCEPT {} // This function doesn't throw. +// +// template +// void DoNothing() OVR_NOEXCEPT_IF(OVR_NOEXCEPT_EXPR(T())) // Throws an if and only if T::T(int) throws. +// { T t(3); } +// +#if !defined(OVR_NOEXCEPT) + #if defined(OVR_CPP_NOEXCEPT) + #define OVR_NOEXCEPT + #define OVR_NOEXCEPT_IF(predicate) + #define OVR_NOEXCEPT_EXPR(expression) false + #else + #define OVR_NOEXCEPT noexcept + #define OVR_NOEXCEPT_IF(predicate) noexcept((predicate)) + #define OVR_NOEXCEPT_EXPR(expression) noexcept((expression)) + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_FINAL +// +// Wraps the C++11 final keyword in a portable way. +// http://en.cppreference.com/w/cpp/language/final +// +// Example usage: +// struct Test { virtual int GetValue() OVR_FINAL; }; + +#if !defined(OVR_FINAL) + #if defined(OVR_CC_MSVC) && (OVR_CC_VERSION < 1700) // VC++ 2012 and earlier + #define OVR_FINAL sealed + #elif defined(OVR_CPP_INHERITANCE_FINAL) + #define OVR_FINAL + #else + #define OVR_FINAL final + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_OVERRIDE +// +// Wraps the C++11 override keyword in a portable way. +// http://en.cppreference.com/w/cpp/language/override +// +// Example usage: +// struct Parent { virtual void Func(int); }; +// struct Child : public Parent { void Func(int) OVR_OVERRIDE; }; + +#if !defined(OVR_CPP11_ENABLED) +#define OVR_OVERRIDE +#elif !defined(OVR_OVERRIDE) + #if defined(OVR_CPP_OVERRIDE) + #define OVR_OVERRIDE + #else + #if (defined(_MSC_VER) && (_MSC_VER <= 1600)) + #pragma warning(disable : 4481) + #endif + #define OVR_OVERRIDE override + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_FINAL_OVERRIDE +// +// Wraps the C++11 final+override keywords (a common combination) in a portable way. +// +// Example usage: +// struct Parent { virtual void Func(); }; +// struct Child : public Parent { virtual void Func() OVR_FINAL_OVERRIDE; }; + +#if !defined(OVR_FINAL_OVERRIDE) + #define OVR_FINAL_OVERRIDE OVR_FINAL OVR_OVERRIDE +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_EXTERN_TEMPLATE +// +// Portable wrapper for C++11 extern template. This tells the compiler to not instantiate +// the template in the current translation unit, which can significantly speed up +// compilation and avoid problems due to two translation units compiling code with +// different settings. +// +// Example usage: +// OVR_EXTERN_TEMPLATE(class basic_string); // Nothing to do for non-C++11 compilers. + +#if !defined(OVR_EXTERN_TEMPLATE) + #if defined(OVR_CPP_EXTERN_TEMPLATE) + #define OVR_EXTERN_TEMPLATE(decl) + #else + #define OVR_EXTERN_TEMPLATE(decl) extern template decl + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_CONSTEXPR / OVR_CONSTEXPR_OR_CONST +// +// Portable wrapper for C++11 constexpr. Doesn't include C++14 relaxed constexpr, +// for which a different wrapper name is reserved. +// +// Example usage: +// OVR_CONSTEXPR int Test() { return 15; } // This can be optimized better by a C++11 compiler that supports constexpr. +// OVR_CONSTEXPR_OR_CONST float x = 3.14159f; // This can be optimized better by a C++11 compiler, but if not then at least make it const. + +#if !defined(OVR_CONSTEXPR) + #if defined(OVR_CPP_NO_CONSTEXPR) + #define OVR_CONSTEXPR + #else + #define OVR_CONSTEXPR constexpr + #endif +#endif + +#if !defined(OVR_CONSTEXPR_OR_CONST) + #if defined(OVR_CPP_NO_CONSTEXPR) + #define OVR_CONSTEXPR_OR_CONST const + #else + #define OVR_CONSTEXPR_OR_CONST constexpr + #endif +#endif + + + +// ----------------------------------------------------------------------------------- +// ***** OVR_FUNCTION_DELETE / OVR_FUNCTION_DEFAULT +// +// Wraps the C++11 delete and default keywords in a way that allows for cleaner code +// while making for a better version of uncallable or default functions. +// +// Example usage: +// struct Test{ +// Test() OVR_FUNCTION_DEFAULT; // Non-C++11 compilers will require a separate definition for Test(). +// private: // Users should put OVR_FUNCTION_DELETE usage in a private +// void Uncallable() OVR_FUNCTION_DELETE; // area for compatibility with pre-C++11 compilers. +// }; + +#if defined(OVR_CPP_NO_DELETED_FUNCTIONS) + #define OVR_FUNCTION_DELETE +#else + #define OVR_FUNCTION_DELETE = delete +#endif + +#if defined(OVR_CPP_NO_DEFAULTED_FUNCTIONS) + #define OVR_FUNCTION_DEFAULT +#else + #define OVR_FUNCTION_DEFAULT = default +#endif + + + +// ----------------------------------------------------------------------------------- +// ***** OVR_NON_COPYABLE +// +// Allows you to specify a class as being neither copy-constructible nor assignable, +// which is a commonly needed pattern in C++ programming. Classes with this declaration +// are required to be default constructible (as are most classes). For pre-C++11 +// compilers this macro declares a private section for the class, which will be +// inherited by whatever code is directly below the macro invocation by default. +// +// Example usage: +// struct Test { +// Test(); +// ... +// OVR_NON_COPYABLE(Test) +// }; + +#if !defined(OVR_NON_COPYABLE) + #if defined(OVR_CPP_NO_DELETED_FUNCTIONS) + #define OVR_NON_COPYABLE(Type) \ + private: \ + Type(const Type&); \ + void operator=(const Type&); + #else + #define OVR_NON_COPYABLE(Type) \ + Type(const Type&) = delete; \ + void operator=(const Type&) = delete; + #endif +#endif + + + +// ----------------------------------------------------------------------------------- +// ***** OVR_BUILD_DEBUG +// +// Defines OVR_BUILD_DEBUG when the compiler default debug preprocessor is set. +// +// If you want to control the behavior of these flags, then explicitly define +// either -DOVR_BUILD_RELEASE or -DOVR_BUILD_DEBUG in the compiler arguments. + +#if !defined(OVR_BUILD_DEBUG) && !defined(OVR_BUILD_RELEASE) + #if defined(OVR_CC_MSVC) + #if defined(_DEBUG) + #define OVR_BUILD_DEBUG + #endif + #else + #if defined(DEBUG) + #define OVR_BUILD_DEBUG + #endif + #endif +#endif + + + +#endif // header include guard diff --git a/LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h b/LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h new file mode 100644 index 0000000..30cf3cc --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_ContainerAllocator.h @@ -0,0 +1,281 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_ContainerAllocator.h +Content : Template allocators and constructors for containers. +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_ContainerAllocator_h +#define OVR_ContainerAllocator_h + +#include "OVR_Allocator.h" +#include + + +namespace OVR { + + +//----------------------------------------------------------------------------------- +// ***** Container Allocator + +// ContainerAllocator serves as a template argument for allocations done by +// containers, such as Array and Hash; replacing it could allow allocator +// substitution in containers. + +class ContainerAllocatorBase +{ +public: + static void* Alloc(size_t size) + { return OVR_ALLOC(size); } + + static void* Realloc(void* p, size_t newSize) + { return OVR_REALLOC(p, newSize); } + + static void Free(void *p) + { OVR_FREE(p); } +}; + + + +//----------------------------------------------------------------------------------- +// ***** Constructors, Destructors, Copiers + +// Plain Old Data - movable, no special constructors/destructor. +template +class ConstructorPOD +{ +public: + static void Construct(void *) + {} + + static void Construct(void *p, const T& source) + { + *(T*)p = source; + } + + // Same as above, but allows for a different type of constructor. + template + static void ConstructAlt(void *p, const S& source) + { + *(T*)p = source; + } + + static void ConstructArray(void*, size_t) + {} + + static void ConstructArray(void* p, size_t count, const T& source) + { + uint8_t *pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + *(T*)pdata = source; + } + + static void ConstructArray(void* p, size_t count, const T* psource) + { + memcpy(p, psource, sizeof(T) * count); + } + + static void Destruct(T*) + {} + + static void DestructArray(T*, size_t) + {} + + static void CopyArrayForward(T* dst, const T* src, size_t count) + { + memmove(dst, src, count * sizeof(T)); + } + + static void CopyArrayBackward(T* dst, const T* src, size_t count) + { + memmove(dst, src, count * sizeof(T)); + } + + static bool IsMovable() + { return true; } +}; + + +//----------------------------------------------------------------------------------- +// ***** ConstructorMov +// +// Correct C++ construction and destruction for movable objects +template +class ConstructorMov +{ +public: + static void Construct(void* p) + { + OVR::Construct(p); + } + + static void Construct(void* p, const T& source) + { + OVR::Construct(p, source); + } + + // Same as above, but allows for a different type of constructor. + template + static void ConstructAlt(void* p, const S& source) + { + OVR::ConstructAlt(p, source); + } + + static void ConstructArray(void* p, size_t count) + { + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + Construct(pdata); + } + + static void ConstructArray(void* p, size_t count, const T& source) + { + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + Construct(pdata, source); + } + + static void ConstructArray(void* p, size_t count, const T* psource) + { + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + Construct(pdata, *psource++); + } + + static void Destruct(T* p) + { + p->~T(); + OVR_UNUSED(p); // Suppress silly MSVC warning + } + + static void DestructArray(T* p, size_t count) + { + p = p + count - 1; + for (size_t i=0; i~T(); + } + + static void CopyArrayForward(T* dst, const T* src, size_t count) + { + memmove(dst, src, count * sizeof(T)); + } + + static void CopyArrayBackward(T* dst, const T* src, size_t count) + { + memmove(dst, src, count * sizeof(T)); + } + + static bool IsMovable() + { return true; } +}; + + +//----------------------------------------------------------------------------------- +// ***** ConstructorCPP +// +// Correct C++ construction and destruction for movable objects +template +class ConstructorCPP +{ +public: + static void Construct(void* p) + { + OVR::Construct(p); + } + + static void Construct(void* p, const T& source) + { + OVR::Construct(p, source); + } + + // Same as above, but allows for a different type of constructor. + template + static void ConstructAlt(void* p, const S& source) + { + OVR::ConstructAlt(p, source); + } + + static void ConstructArray(void* p, size_t count) + { + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + Construct(pdata); + } + + static void ConstructArray(void* p, size_t count, const T& source) + { + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + Construct(pdata, source); + } + + static void ConstructArray(void* p, size_t count, const T* psource) + { + uint8_t* pdata = (uint8_t*)p; + for (size_t i=0; i< count; ++i, pdata += sizeof(T)) + Construct(pdata, *psource++); + } + + static void Destruct(T* p) + { + p->~T(); + OVR_UNUSED(p); // Suppress silly MSVC warning + } + + static void DestructArray(T* p, size_t count) + { + p += count - 1; + for (size_t i=0; i~T(); + } + + static void CopyArrayForward(T* dst, const T* src, size_t count) + { + for(size_t i = 0; i < count; ++i) + dst[i] = src[i]; + } + + static void CopyArrayBackward(T* dst, const T* src, size_t count) + { + for(size_t i = count; i; --i) + dst[i-1] = src[i-1]; + } + + static bool IsMovable() + { return false; } +}; + + +//----------------------------------------------------------------------------------- +// ***** Container Allocator with movement policy +// +// Simple wraps as specialized allocators +template struct ContainerAllocator_POD : ContainerAllocatorBase, ConstructorPOD {}; +template struct ContainerAllocator : ContainerAllocatorBase, ConstructorMov {}; +template struct ContainerAllocator_CPP : ContainerAllocatorBase, ConstructorCPP {}; + + +} // OVR + + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp b/LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp new file mode 100644 index 0000000..ea39fb0 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_DebugHelp.cpp @@ -0,0 +1,4101 @@ +/************************************************************************************ + +Filename : ExceptionHandler.cpp +Content : Platform-independent exception handling interface +Created : October 6, 2014 + +Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_DebugHelp.h" +#include "OVR_Types.h" +#include "OVR_UTF8Util.h" +#include "OVR_Atomic.h" +#include "OVR_SysFile.h" +#include "Util/Util_SystemGUI.h" + +#include +#include + +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + #pragma warning(push, 0) + #include "OVR_Win32_IncludeWindows.h" + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #pragma warning(pop) + + #pragma comment(lib, "Psapi.lib") // To consider: It may be a problem to statically link to these libraries if the application at runtime intends to dynamically + #pragma comment(lib, "ole32.lib") // link to a different version of the same library, and we are statically linked into that application instead of being a DLL. + #pragma comment(lib, "shell32.lib") + #pragma comment(lib, "Version.lib") + + // NtQueryInformation and THREAD_BASIC_INFORMATION are undocumented but frequently needed for digging into thread information. + typedef LONG (WINAPI *NtQueryInformationThreadFunc)(HANDLE, int, PVOID, ULONG, PULONG); + + struct THREAD_BASIC_INFORMATION + { + LONG ExitStatus; + PVOID TebBaseAddress; + PVOID UniqueProcessId; + PVOID UniqueThreadId; + PVOID Priority; + PVOID BasePriority; + }; + + #ifndef UNW_FLAG_NHANDLER // Older Windows SDKs don't support this. + #define UNW_FLAG_NHANDLER 0 + #endif + +#elif defined(OVR_OS_MAC) + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include "OVR_mach_exc_OSX.h" + + #if defined(__LP64__) + typedef struct mach_header_64 MachHeader; + typedef struct segment_command_64 SegmentCommand; + typedef struct section_64 Section; + #define kLCSegment LC_SEGMENT_64 + #else + typedef struct mach_header MachHeader; + typedef struct segment_command SegmentCommand; + typedef struct section Section; + #define kLCSegment LC_SEGMENT + #endif + + extern "C" const struct dyld_all_image_infos* _dyld_get_all_image_infos(); // From libdyld.dylib + +#elif defined(OVR_OS_UNIX) + #include + #include "sys/stat.h" +#if defined(OVR_OS_ANDROID) + #include +#else + #include +#endif + #include + #include + #include + #include + #include + #include + #include + #include + #include +#if !defined(OVR_OS_ANDROID) + #include +#endif + #include + //#include // Can't use this until we can ensure that we have an installed version of it. +#endif + +#if !defined(MIN) + #define MIN(X,Y) ((X) < (Y) ? (X) : (Y)) + #define MAX(X,Y) ((X) > (Y) ? (X) : (Y)) +#endif + + +OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized +OVR_DISABLE_MSVC_WARNING(4996) // This function or variable may be unsafe + + + + +#if defined(OVR_OS_APPLE) + static OVR::ExceptionHandler* sExceptionHandler = nullptr; + const uint32_t sMachCancelMessageType = 0x0ca9ce11; // This is a made-up value of our own choice. + + extern "C" + { + kern_return_t catch_mach_exception_raise_OVR(mach_port_t /*exceptionPort*/, mach_port_t /*threadSysId*/, + mach_port_t /*machTask*/, exception_type_t /*machExceptionType*/, + mach_exception_data_t /*machExceptionData*/, mach_msg_type_number_t /*machExceptionDataCount*/) + { + return KERN_FAILURE; + } + + kern_return_t catch_mach_exception_raise_state_OVR(mach_port_t /*exceptionPort*/, exception_type_t /*exceptionType*/, + const mach_exception_data_t /*machExceptionData*/, mach_msg_type_number_t /*machExceptionDataCount*/, + int* /*pMachExceptionFlavor*/, const thread_state_t /*threadStatePrev*/, mach_msg_type_number_t /*threaStatePrevCount*/, + thread_state_t /*threadStateNew*/, mach_msg_type_number_t* /*pThreadStateNewCount*/) + { + return KERN_FAILURE; + } + + kern_return_t catch_mach_exception_raise_state_identity_OVR(mach_port_t exceptionPort, mach_port_t threadSysId, mach_port_t machTask, + exception_type_t exceptionType, mach_exception_data_type_t* pMachExceptionData, + mach_msg_type_number_t machExceptionDataCount, int* pMachExceptionFlavor, + thread_state_t threadStatePrev, mach_msg_type_number_t threadStatePrevCount, + thread_state_t threadStateNew, mach_msg_type_number_t* pThreadStateNewCount) + { + return sExceptionHandler->HandleMachException(exceptionPort, threadSysId, machTask, exceptionType, pMachExceptionData, + machExceptionDataCount, pMachExceptionFlavor, threadStatePrev, threadStatePrevCount, + threadStateNew, pThreadStateNewCount); + } + + void* MachHandlerThreadFunctionStatic(void* pExceptionHandlerVoid) + { + return static_cast(pExceptionHandlerVoid)->MachHandlerThreadFunction(); + } + + } // extern "C" +#endif + + +namespace OVR { + + +void GetInstructionPointer(void*& pInstruction) +{ + #if defined(OVR_CC_MSVC) + pInstruction = _ReturnAddress(); + #else // GCC, clang + pInstruction = __builtin_return_address(0); + #endif +} + + +// addressStrCapacity should be at least 2+16+1 = 19 characters. +static size_t SprintfAddress(char* addressStr, size_t addressStrCapacity, const void* pAddress) +{ + #if defined(OVR_CC_MSVC) + #if (OVR_PTR_SIZE >= 8) + return OVR_snprintf(addressStr, addressStrCapacity, "0x%016I64x", pAddress); // e.g. 0x0123456789abcdef + #else + return OVR_snprintf(addressStr, addressStrCapacity, "0x%08x", pAddress); // e.g. 0x89abcdef + #endif + #else + #if (OVR_PTR_SIZE >= 8) + return OVR_snprintf(addressStr, addressStrCapacity, "%016llx", pAddress); // e.g. 0x0123456789abcdef + #else + return OVR_snprintf(addressStr, addressStrCapacity, "%08x", pAddress); // e.g. 0x89abcdef + #endif + #endif +} + + +// threadHandleStrCapacity should be at least 2+16+1 = 19 characters. +static size_t SprintfThreadHandle(char* threadHandleStr, size_t threadHandleStrCapacity, const ThreadHandle& threadHandle) +{ + return SprintfAddress(threadHandleStr, threadHandleStrCapacity, threadHandle); +} + + +// threadSysIdStrCapacity should be at least 20+4+16+2 = 42 characters. +static size_t SprintfThreadSysId(char* threadSysIdStr, size_t threadSysIdStrCapacity, const ThreadSysId& threadSysId) +{ + #if defined(OVR_CC_MSVC) // Somebody could conceivably use VC++ with a different standard library that supports %ll. And VS2012+ also support %ll. + return OVR_snprintf(threadSysIdStr, threadSysIdStrCapacity, "%I64u (0x%I64x)", (uint64_t)threadSysId, (uint64_t)threadSysId); // e.g. 5642 (0x160a) + #else + return OVR_snprintf(threadSysIdStr, threadSysIdStrCapacity, "%llu (0x%llx)", (uint64_t)threadSysId, (uint64_t)threadSysId); + #endif +} + + + + + +void GetThreadStackBounds(void*& pStackBase, void*& pStackLimit, ThreadHandle threadHandle) +{ + #if defined(OVR_OS_WIN64) || defined(OVR_OS_WIN32) + ThreadSysId threadSysIdCurrent = (ThreadSysId)GetCurrentThreadId(); + ThreadSysId threadSysId; + NT_TIB* pTIB = nullptr; + + if(threadHandle == OVR_THREADHANDLE_INVALID) + threadSysId = threadSysIdCurrent; + else + threadSysId = ConvertThreadHandleToThreadSysId(threadHandle); + + if(threadSysId == threadSysIdCurrent) + { + #if (OVR_PTR_SIZE == 4) + // Need to use __asm__("movl %%fs:0x18, %0" : "=r" (pTIB) : : ); under gcc/clang. + __asm { + mov eax, fs:[18h] + mov pTIB, eax + } + #else + pTIB = (NT_TIB*)NtCurrentTeb(); + #endif + } + else + { + #if (OVR_PTR_SIZE == 4) + // It turns out we don't need to suspend the thread when getting SegFs/SegGS, as that's + // constant per thread and doesn't require the thread to be suspended. + //SuspendThread((HANDLE)threadHandle); + CONTEXT context; + memset(&context, 0, sizeof(context)); + context.ContextFlags = CONTEXT_SEGMENTS; + GetThreadContext((HANDLE)threadHandle, &context); // Requires THREAD_QUERY_INFORMATION privileges. + + LDT_ENTRY ldtEntry; + if(GetThreadSelectorEntry(threadHandle, context.SegFs, &ldtEntry)) // Requires THREAD_QUERY_INFORMATION + pTIB = (NT_TIB*)((ldtEntry.HighWord.Bits.BaseHi << 24 ) | (ldtEntry.HighWord.Bits.BaseMid << 16) | ldtEntry.BaseLow); + + //ResumeThread((HANDLE)threadHandle); + #else + // We cannot use GetThreadSelectorEntry or Wow64GetThreadSelectorEntry on Win64. + // We need to read the SegGs qword at offset 0x30. We can't use pTIB = (NT_TIB*)__readgsqword(0x30) because that reads only the current setGs offset. + // mov rax, qword ptr gs:[30h] + // mov qword ptr [pTIB],rax + // In the meantime we rely on the NtQueryInformationThread function. + + static NtQueryInformationThreadFunc spNtQueryInformationThread = nullptr; + + if(!spNtQueryInformationThread) + { + HMODULE hNTDLL = GetModuleHandleA("ntdll.dll"); + spNtQueryInformationThread = (NtQueryInformationThreadFunc)(uintptr_t)GetProcAddress(hNTDLL, "NtQueryInformationThread"); + } + + if(spNtQueryInformationThread) + { + THREAD_BASIC_INFORMATION tbi; + + memset(&tbi, 0, sizeof(tbi)); + LONG result = spNtQueryInformationThread(threadHandle, 0, &tbi, sizeof(tbi), nullptr); // Requires THREAD_QUERY_INFORMATION privileges + if(result == 0) + pTIB = (NT_TIB*)tbi.TebBaseAddress; + } + #endif + } + + if(pTIB) + { + pStackBase = (void*)pTIB->StackBase; + pStackLimit = (void*)pTIB->StackLimit; + } + else + { + pStackBase = nullptr; + pStackLimit = nullptr; + } + + #elif defined(OVR_OS_APPLE) + if(!threadHandle) + threadHandle = pthread_self(); + + pStackBase = pthread_get_stackaddr_np((pthread_t)threadHandle); + size_t stackSize = pthread_get_stacksize_np((pthread_t)threadHandle); + pStackLimit = (void*)((size_t)pStackBase - stackSize); + + #elif defined(OVR_OS_UNIX) + pStackBase = nullptr; + pStackLimit = nullptr; + + pthread_attr_t threadAttr; + pthread_attr_init(&threadAttr); + + #if defined(OVR_OS_LINUX) + int result = pthread_getattr_np((pthread_t)threadHandle, &threadAttr); + #else + int result = pthread_attr_get_np((pthread_t)threadHandle, &threadAttr); + #endif + + if(result == 0) + { + size_t stackSize = 0; + result = pthread_attr_getstack(&threadAttr, &pStackLimit, &stackSize); + + if(result == 0) + pStackBase = (void*)((uintptr_t)pStackLimit + stackSize); // We assume the stack grows downward. + } + + #endif +} + + +bool OVRIsDebuggerPresent() +{ + #if defined(OVR_OS_MS) + return ::IsDebuggerPresent() != 0; + + #elif defined(OVR_OS_APPLE) + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid() }; + struct kinfo_proc info; + size_t size = sizeof(info); + + info.kp_proc.p_flag = 0; + sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0); + + return ((info.kp_proc.p_flag & P_TRACED) != 0); + + #elif defined(PT_TRACE_ME) && !defined(OVR_OS_ANDROID) + return (ptrace(PT_TRACE_ME, 0, 1, 0) < 0); + + #elif (defined(OVR_OS_LINUX) || defined(OVR_OS_BSD)) && !defined(OVR_OS_ANDROID) + // This works better than the PT_TRACE_ME approach, but causes the debugger to get + // confused when executed under a debugger. + // It also presents this problem: + // http://pubs.opengroup.org/onlinepubs/009695399/functions/fork.html + // When the application calls fork() from a signal handler and any of the + // fork handlers registered by pthread_atfork() calls a function that is + // not asynch-signal-safe, the behavior is undefined. + // We may need to provide two pathways within this function, one of which + // doesn't fork and instead uses PT_TRACE_ME. + int pid = fork(); + int status; + bool present = false; + + if (pid == -1) // If fork failed... + { + // perror("fork"); + } + else if (pid == 0) // If we are the child process... + { + int ppid = getppid(); + + #if defined(OVR_OS_LINUX) + if (ptrace(PTRACE_ATTACH, ppid, nullptr, nullptr) == 0) + #else + if (ptrace(PT_ATTACH, ppid, nullptr, nullptr) == 0) + #endif + { + waitpid(ppid, nullptr, 0); + + #if defined(OVR_OS_LINUX) + ptrace(PTRACE_CONT, getppid(), nullptr, nullptr); + ptrace(PTRACE_DETACH, getppid(), nullptr, nullptr); + #else + ptrace(PT_CONTINUE, getppid(), nullptr, nullptr); + ptrace(PT_DETACH, getppid(), nullptr, nullptr); + #endif + } + else + { + // ptrace failed so the debugger is present. + present = true; + } + + exit(present ? 1 : 0); // The WEXITSTATUS call below will read this exit value. + } + else // Else we are the original process. + { + waitpid(pid, &status, 0); + present = WEXITSTATUS(status) ? true : false; // Read the exit value from the child's call to exit. + } + + return present; + + #else + return false; + #endif +} + + +// Exits the process with the given exit code. +void ExitProcess(intptr_t processReturnValue) +{ + exit((int)processReturnValue); +} + + +// Note that we can't just return sizeof(void*) == 8, as we may have the case of a +// 32 bit app running on a 64 bit operating system. +static bool Is64BitOS() +{ + #if (OVR_PTR_SIZE >= 8) + return true; + + #elif defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + BOOL is64BitOS = FALSE; + bool IsWow64ProcessPresent = (GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process") != nullptr); + return (IsWow64ProcessPresent && IsWow64Process(GetCurrentProcess(), &is64BitOS) && is64BitOS); + + #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) + utsname utsName; + memset(&utsName, 0, sizeof(utsName)); + return (uname(&utsName) == 0) && (strcmp(utsName.machine, "x86_64") == 0); + + #else + return false; + #endif +} + + +// The output will always be 0-terminated. +// Returns the required strlen of the output. +// Returns (size_t)-1 on failure. +size_t SpawnShellCommand(const char* shellCommand, char* output, size_t outputCapacity) +{ + #if defined(OVR_OS_UNIX) || defined(OVR_OS_APPLE) + FILE* pFile = popen(shellCommand, "r"); + + if(pFile) + { + size_t requiredLength = 0; + char buffer[256]; + + while(fgets(buffer, sizeof(buffer), pFile)) // fgets 0-terminates the buffer. + { + size_t length = OVR_strlen(buffer); + requiredLength += length; + + if(outputCapacity) + { + OVR_strlcpy(output, buffer, outputCapacity); + length = MIN(outputCapacity, length); + } + + output += length; + outputCapacity -= length; + } + + pclose(pFile); + return requiredLength; + } + #else + // To do. Properly solving this on Windows requires a bit of code. + OVR_UNUSED(shellCommand); + OVR_UNUSED(output); + OVR_UNUSED(outputCapacity); + #endif + + return (size_t)-1; +} + +// Retrieves the name of the given thread. +// To do: Move this to OVR_Threads.h +bool GetThreadName(OVR::ThreadHandle threadHandle, char* threadName, size_t threadNameCapacity) +{ + #if (defined(OVR_OS_APPLE) || defined(OVR_OS_LINUX)) && !defined(OVR_OS_ANDROID) + int result = pthread_getname_np((pthread_t)threadHandle, threadName, threadNameCapacity); + if(result == 0) + return true; + #else + // This is not currently possible on Windows, as only the debugger stores the thread name. We could potentially use a vectored + // exception handler to catch all thread name exceptions (0x406d1388) and record them in a static list at runtime. To detect + // thread exit we could use WMI Win32_ThreadStopTrace. Maintain a list of thread names between these two events. + OVR_UNUSED(threadHandle); + OVR_UNUSED(threadNameCapacity); + #endif + + if(threadNameCapacity) + threadName[0] = 0; + + return false; +} + + +OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle) +{ + #if defined(OVR_OS_WIN64) + return (OVR::ThreadSysId)::GetThreadId(threadHandle); // Requires THREAD_QUERY_INFORMATION privileges. + + #elif defined(OVR_OS_WIN32) + typedef DWORD (WINAPI *GetThreadIdFunc)(HANDLE); + + static volatile bool sInitialized = false; + static GetThreadIdFunc spGetThreadIdFunc = nullptr; + static NtQueryInformationThreadFunc spNtQueryInformationThread = nullptr; + + if(!sInitialized) + { + HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); + if(hKernel32) + spGetThreadIdFunc = (GetThreadIdFunc)(uintptr_t)GetProcAddress(hKernel32, "GetThreadId"); + + if(!spGetThreadIdFunc) + { + HMODULE hNTDLL = GetModuleHandleA("ntdll.dll"); + + if(hNTDLL) + spNtQueryInformationThread = (NtQueryInformationThreadFunc)(uintptr_t)GetProcAddress(hNTDLL, "NtQueryInformationThread"); + } + + sInitialized = true; + } + + if(spGetThreadIdFunc) + return (OVR::ThreadSysId)spGetThreadIdFunc(threadHandle); + + if(spNtQueryInformationThread) + { + THREAD_BASIC_INFORMATION tbi; + + if(spNtQueryInformationThread(threadHandle, 0, &tbi, sizeof(tbi), nullptr) == 0) + return (OVR::ThreadSysId)tbi.UniqueThreadId; + } + + return OVR_THREADSYSID_INVALID; + + #elif defined(OVR_OS_APPLE) + mach_port_t threadSysId = pthread_mach_thread_np((pthread_t)threadHandle); // OS 10.4 and later. + return (ThreadSysId)threadSysId; + + #elif defined(OVR_OS_LINUX) + + // I believe we can usually (though not portably) intepret the pthread_t as a pointer to a struct whose first member is a lwp id. + OVR_UNUSED(threadHandle); + return OVR_THREADSYSID_INVALID; + + #else + OVR_UNUSED(threadHandle); + return OVR_THREADSYSID_INVALID; + #endif +} + + +OVR::ThreadHandle ConvertThreadSysIdToThreadHandle(OVR::ThreadSysId threadSysId) +{ + #if defined(OVR_OS_MS) + // We currently request the given rights because that's what users of this function typically need it for. Ideally there would + // be a way to specify the requested rights in order to avoid the problem if we need only a subset of them but can't get it. + // The solution we use below to try opening with successively reduced rights will work for our uses here but isn't a good general solution to this. + OVR::ThreadHandle threadHandle = ::OpenThread(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); + + if(threadHandle == OVR_THREADHANDLE_INVALID) + { + threadHandle = ::OpenThread(THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); + + if(threadHandle == OVR_THREADHANDLE_INVALID) + threadHandle = ::OpenThread(THREAD_QUERY_INFORMATION, TRUE, (DWORD)threadSysId); + } + + return threadHandle; + #elif defined(OVR_OS_MAC) + return (ThreadHandle)pthread_from_mach_thread_np((mach_port_t)threadSysId); + #else + return (ThreadHandle)threadSysId; + #endif +} + + +void FreeThreadHandle(OVR::ThreadHandle threadHandle) +{ + #if defined(OVR_OS_MS) + if(threadHandle != OVR_THREADHANDLE_INVALID) + ::CloseHandle(threadHandle); + #else + OVR_UNUSED(threadHandle); + #endif +} + + +OVR::ThreadSysId GetCurrentThreadSysId() +{ + #if defined(OVR_OS_MS) + return ::GetCurrentThreadId(); + #elif defined(OVR_OS_APPLE) + return (ThreadSysId)mach_thread_self(); + #else + return (ThreadSysId)pthread_self(); + #endif +} + + + +static void GetCurrentProcessFilePath(char* appPath, size_t appPathCapacity) +{ + appPath[0] = 0; + + #if defined(OVR_OS_MS) + wchar_t pathW[OVR_MAX_PATH]; + GetModuleFileNameW(0, pathW, (DWORD)OVR_ARRAY_COUNT(pathW)); + + size_t requiredUTF8Length = (size_t)OVR::UTF8Util::GetEncodeStringSize(pathW); // Returns required strlen. + + if(requiredUTF8Length < appPathCapacity) + { + OVR::UTF8Util::EncodeString(appPath, pathW, -1); + } + else + { + appPath[0] = 0; + } + + #elif defined(OVR_OS_APPLE) + struct BunderFolder + { + // Returns true if pStr ends with pFind, case insensitively. + // To do: Move OVR_striend to OVRKernel/Std.h + static bool OVR_striend(const char* pStr, const char* pFind, size_t strLength = (size_t)-1, size_t findLength = (size_t)-1) + { + if(strLength == (size_t)-1) + strLength = OVR_strlen(pStr); + if(findLength == (size_t)-1) + findLength = OVR_strlen(pFind); + if(strLength >= findLength) + return (OVR_stricmp(pStr + strLength - findLength, pFind) == 0); + return false; + } + + static bool IsBundleFolder(const char* filePath) + { + // https://developer.apple.com/library/mac/documentation/CoreFoundation/Conceptual/CFBundles/AboutBundles/AboutBundles.html#//apple_ref/doc/uid/10000123i-CH100-SW1 + static const char* extensionArray[] = { ".app", ".bundle", ".framework", ".plugin", ".kext" }; + + for(size_t i = 0; i < OVR_ARRAY_COUNT(extensionArray); i++) + { + if(OVR_striend(filePath, extensionArray[i])) + return true; + } + + return false; + } + }; + + char appPathTemp[PATH_MAX]; + uint32_t appPathTempCapacity32 = PATH_MAX; + size_t requiredStrlen = appPathCapacity; + + if(_NSGetExecutablePath(appPathTemp, &appPathTempCapacity32) == 0) + { + char appPathTempReal[PATH_MAX]; + + if(realpath(appPathTemp, appPathTempReal)) // If the path is a symbolic link, this converts it to the real path. + { + // To consider: Enable reading the internal bundle executable path. An application on Mac may in + // fact be within a file bundle, which is an private file system within a file. With Objective C + // we could use: [[NSWorkspace sharedWorkspace] isFilePackageAtPath:fullPath]; + bool shouldReadTheBunderPath = false; + + if(shouldReadTheBunderPath) + { + // We recursively call dirname() until we find .app/.bundle/.plugin as a directory name. + OVR_strlcpy(appPathTemp, appPathTempReal, OVR_ARRAY_COUNT(appPathTemp)); + bool found = BunderFolder::IsBundleFolder(appPathTemp); + + while(!found && OVR_strcmp(appPathTemp, ".") && OVR_strcmp(appPathTemp, "/")) + { + OVR_strlcpy(appPathTemp, dirname(appPathTemp), OVR_ARRAY_COUNT(appPathTemp)); + found = BunderFolder::IsBundleFolder(appPathTemp); + } + + if(found) // If somewhere above we found a parent bundle container... + requiredStrlen = OVR_strlcpy(appPath, appPathTemp, appPathCapacity); + else + requiredStrlen = OVR_strlcpy(appPath, appPathTempReal, appPathCapacity); + } + else + { + requiredStrlen = OVR_strlcpy(appPath, appPathTempReal, appPathCapacity); + } + } + } + + if(requiredStrlen >= appPathCapacity) + appPath[0] = '\0'; + + #elif defined(OVR_OS_LINUX) + ssize_t length = readlink("/proc/self/exe", appPath, appPathCapacity); + + if((length != -1) && ((size_t)length < (appPathCapacity - 1))) + { + appPath[length] = '\0'; + } + #endif +} + + +static const char* GetFileNameFromPath(const char* filePath) +{ + const char* lastPathSeparator = strrchr(filePath, '/'); + + #if defined(OVR_OS_MS) + // Microsoft APIs are inconsistent with respect to allowing / as a path separator. + const char* candidate = strrchr(filePath, '\\'); + + if(candidate > lastPathSeparator) + { + lastPathSeparator = candidate; + } + #endif + + if(lastPathSeparator) + return lastPathSeparator + 1; + + return filePath; +} + + + +static void FormatDateTime(char* buffer, size_t bufferCapacity, time_t timeValue, bool getDate, bool getTime, bool localDateTime, bool fileNameSafeCharacters = false) +{ + char temp[128]; + const tm* pTime = localDateTime ? localtime(&timeValue) : gmtime(&timeValue); + + if(bufferCapacity) + buffer[0] = 0; + + if(getDate) + { + const char* format = fileNameSafeCharacters ? "%Y-%m-%d" : "%Y/%m/%d"; + strftime(temp, OVR_ARRAY_COUNT(temp), format, pTime); + OVR::OVR_strlcpy(buffer, temp, bufferCapacity); + } + + if(getTime) + { + const char* format = fileNameSafeCharacters ? " %H.%M.%S" : " %H:%M:%S"; + strftime(temp, OVR_ARRAY_COUNT(temp), (getDate ? format : format + 1), pTime); + OVR::OVR_strlcat(buffer, temp, bufferCapacity); + } +} + + +static void GetOSVersionName(char* versionName, size_t versionNameCapacity) +{ + #if defined(OVR_OS_MS) + const char* name = "unknown"; + + OSVERSIONINFOEXW vi; + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(vi); + + if(GetVersionExW((LPOSVERSIONINFOW)&vi)) + { + if(vi.dwMajorVersion >= 7) + { + // Unknown recent version. + } + if(vi.dwMajorVersion >= 6) + { + if(vi.dwMinorVersion >= 4) + name = "Windows 10"; + else if(vi.dwMinorVersion >= 3) + { + if(vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 8.1"; + else + name = "Windows Server 2012 R2"; + } + else if(vi.dwMinorVersion >= 2) + { + if(vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 8"; + else + name = "Windows Server 2012"; + } + else if(vi.dwMinorVersion >= 1) + { + if(vi.wProductType == VER_NT_WORKSTATION) + name = "Windows 7"; + else + name = "Windows Server 2008 R2"; + } + else + { + if(vi.wProductType == VER_NT_WORKSTATION) + name = "Windows Vista"; + else + name = "Windows Server 2008"; + } + } + else if(vi.dwMajorVersion >= 5) + { + if(vi.dwMinorVersion == 0) + name = "Windows 2000"; + else if(vi.dwMinorVersion == 1) + name = "Windows XP"; + else // vi.dwMinorVersion == 2 + { + if(GetSystemMetrics(SM_SERVERR2) != 0) + name = "Windows Server 2003 R2"; + else if(vi.wSuiteMask & VER_SUITE_WH_SERVER) + name = "Windows Home Server"; + if(GetSystemMetrics(SM_SERVERR2) == 0) + name = "Windows Server 2003"; + else + name = "Windows XP Professional x64 Edition"; + } + } + else + name = "Windows 98 or earlier"; + } + + OVR_strlcpy(versionName, name, versionNameCapacity); + + #elif defined(OVR_OS_UNIX) || defined(OVR_OS_APPLE) + utsname utsName; + memset(&utsName, 0, sizeof(utsName)); + + if(uname(&utsName) == 0) + OVR_snprintf(versionName, versionNameCapacity, "%s %s %s %s", utsName.sysname, utsName.release, utsName.version, utsName.machine); + else + OVR_snprintf(versionName, versionNameCapacity, "Unix"); + #endif +} + + + + +void CreateException(CreateExceptionType exceptionType) +{ + char buffer[1024] = {}; + + switch(exceptionType) + { + case kCETAccessViolation: + { + int* pNullPtr = reinterpret_cast((rand() / 2) / RAND_MAX); + pNullPtr[0] = 0; // This line should generate an exception. + sprintf(buffer, "%p", pNullPtr); + break; + } + + case kCETDivideByZero: + { + int smallValue = 1; + int largeValue = (1000 * exceptionType); + int divByZero = (smallValue / largeValue); // This line should generate a div/0 exception. + sprintf(buffer, "%d", divByZero); + break; + } + + case kCETIllegalInstruction: + { + #if defined(OVR_CPU_X86) || (defined(OVR_CPU_X86_64) && !defined(OVR_CC_MSVC)) // (if x86) or (if x64 and any computer but VC++)... + #if defined(OVR_CC_MSVC) + __asm ud2 + #else // e.g. GCC + asm volatile("ud2"); + #endif + + #elif defined(OVR_CPU_X86_64) && (defined(OVR_OS_MS) && defined(PAGE_EXECUTE_READWRITE)) + // VC++ for x64 doesn't support inline asm. + void* pVoid = _AddressOfReturnAddress(); + void** ppVoid = reinterpret_cast(pVoid); + void* pReturnAddress = *ppVoid; + DWORD dwProtectPrev = 0; + + if(VirtualProtect(pReturnAddress, 2, PAGE_EXECUTE_READWRITE, &dwProtectPrev)) // If we can set the memory to be executable... + { + // Modify the code we return to. + uint8_t asm_ud2[] = { 0x0f, 0x0b }; + memcpy(pReturnAddress, asm_ud2, sizeof(asm_ud2)); + VirtualProtect(pReturnAddress, 2, dwProtectPrev, &dwProtectPrev); + } + else + { + // To do: Fix this. + } + + #else + // To do: Fix this. + #endif + + break; + } + + case kCETStackCorruption: + { + size_t size = (sizeof(buffer) * 16) - (rand() % 16); + char* pOutsizeStack = buffer - ((sizeof(buffer) * 16) + (rand() % 16)); + + memset(buffer, 0, size); + memset(pOutsizeStack, 0, size); // This line should generate an exception, or an exception will be generated upon return from this function. + break; + } + + case kCETStackOverflow: + { + CreateException(exceptionType); // Call ourselves recursively. This line should generate a div/0 exception. + sprintf(buffer, "%d", exceptionType); + break; + } + + case kCETAlignment: + { + // Not all platforms generate alignment exceptions. Some internally handle it. + void* pAligned = malloc(16); + char* pMisaligned = (char*)pAligned + 1; + uint64_t* pMisaligned64 = reinterpret_cast(pMisaligned); + + *pMisaligned64 = 0; // This line should generate an exception. + free(pAligned); + break; + } + + case kCETFPU: + // Platforms usually have FPU exceptions disabled. In order to test FPU exceptions we will need to at least + // temporarily disable them before executing code here to generate such exceptions. + // To do. + break; + + case kCETTrap: + // To do. This is hardware-specific. + break; + } +} + + +//----------------------------------------------------------------------------- +// SymbolLookup + +#if defined(OVR_OS_MS) + #if defined(OVR_CC_MSVC) + // The Lock below is one that we want to keep around as long as possible, as there may be application code that + // needs to do symbol lookups during process teardown after main has returned. The init_seg(lib) statement + // below makes it so that this module's globals are initialized right after the C standard library has initialized, + // and are destroyed right before the C standard library is destroyed (after after all other app globals are destroyed). + #pragma warning(disable: 4073) // warning C4073: initializers put in library initialization area. + #pragma warning(disable: 4075) // warning C4075: initializers put in unrecognized initialization area. + #pragma init_seg(lib) + #endif + + typedef BOOL (WINAPI * StackWalk64Type)(DWORD MachineType, HANDLE hProcess, HANDLE hThread, LPSTACKFRAME64 StackFrame, PVOID ContextRecord, PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress); + typedef PVOID (WINAPI * SymFunctionTableAccess64Type)(HANDLE hProcess, DWORD64 dwAddr); + typedef DWORD64 (WINAPI * SymGetModuleBase64Type)(HANDLE hProcess, DWORD64 dwAddr); + typedef DWORD (WINAPI * SymSetOptionsType)(DWORD SymOptions); + typedef BOOL (WINAPI * SymInitializeWType)(HANDLE hProcess, PCWSTR UserSearchPath, BOOL fInvadeProcess); + typedef BOOL (WINAPI * SymCleanupType)(HANDLE hProcess); + typedef DWORD64 (WINAPI * SymLoadModule64Type)(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll); + typedef BOOL (WINAPI * SymFromAddrType)(HANDLE hProcess, DWORD64 Address, PDWORD64 Displacement, PSYMBOL_INFO Symbol); + typedef BOOL (WINAPI * SymGetLineFromAddr64Type)(HANDLE hProcess, DWORD64 qwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line64); + + static StackWalk64Type pStackWalk64 = nullptr; + static SymFunctionTableAccess64Type pSymFunctionTableAccess64 = nullptr; + static SymGetModuleBase64Type pSymGetModuleBase64 = nullptr; + static SymSetOptionsType pSymSetOptions = nullptr; + static SymInitializeWType pSymInitializeW = nullptr; + static SymCleanupType pSymCleanup = nullptr; + static SymLoadModule64Type pSymLoadModule64 = nullptr; + static SymFromAddrType pSymFromAddr = nullptr; + static SymGetLineFromAddr64Type pSymGetLineFromAddr64 = nullptr; + static int32_t sSymUsageCount = 0; + static HMODULE sDbgHelp = nullptr; + static OVR::Lock sDbgHelpLock; + + bool SymbolLookup::Initialize() + { + OVR::Lock::Locker autoLock(&sDbgHelpLock); + + if (++sSymUsageCount > 1) + { + OVR_ASSERT(pSymInitializeW != nullptr); // If it was already initialized then the pointers should be valid. + return true; + } + + // http://msdn.microsoft.com/en-us/library/windows/desktop/ms679294%28v=vs.85%29.aspx + sDbgHelp = LoadLibraryW(L"DbgHelp.dll"); // It's best if the application supplies a recent version of this. + + if (sDbgHelp) + { + pStackWalk64 = (StackWalk64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "StackWalk64"); + pSymFunctionTableAccess64 = (SymFunctionTableAccess64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "SymFunctionTableAccess64"); + pSymGetModuleBase64 = (SymGetModuleBase64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "SymGetModuleBase64"); + pSymSetOptions = (SymSetOptionsType)(uintptr_t)::GetProcAddress(sDbgHelp, "SymSetOptions"); + pSymInitializeW = (SymInitializeWType)(uintptr_t)::GetProcAddress(sDbgHelp, "SymInitializeW"); + pSymCleanup = (SymCleanupType)(uintptr_t)::GetProcAddress(sDbgHelp, "SymCleanup"); + pSymLoadModule64 = (SymLoadModule64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "SymLoadModule64"); + pSymFromAddr = (SymFromAddrType)(uintptr_t)::GetProcAddress(sDbgHelp, "SymFromAddr"); + pSymGetLineFromAddr64 = (SymGetLineFromAddr64Type)(uintptr_t)::GetProcAddress(sDbgHelp, "SymGetLineFromAddr64"); + + // To consider: Use a manually created search path: + // wchar_t searchPathW[4096]; // Semicolon-separated strings. + // The current working directory of the application. + // The directory of the application itself (GetModuleFileName). + // The _NT_SYMBOL_PATH environment variable. + // The _NT_ALTERNATE_SYMBOL_PATH environment variable. + + if (pSymInitializeW) + { + if (pSymInitializeW(GetCurrentProcess(), nullptr /*searchPathW*/, FALSE)) + { + if (pSymSetOptions) + { + pSymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS); + } + + return true; + } + } + } + + return false; + } + + bool SymbolLookup::IsInitialized() + { + // Note that it's possible that another thread could change the state of this right after the return. + OVR::Lock::Locker autoLock(&sDbgHelpLock); + return (sSymUsageCount != 0); + } + + void SymbolLookup::Shutdown() + { + OVR::Lock::Locker autoLock(&sDbgHelpLock); + + if (sSymUsageCount > 0 && + --sSymUsageCount <= 0) + { + pSymCleanup(GetCurrentProcess()); + + pStackWalk64 = nullptr; + pSymFunctionTableAccess64 = nullptr; + pSymGetModuleBase64 = nullptr; + pSymSetOptions = nullptr; + pSymInitializeW = nullptr; + pSymCleanup = nullptr; + pSymLoadModule64 = nullptr; + pSymFromAddr = nullptr; + pSymGetLineFromAddr64 = nullptr; + + FreeLibrary(sDbgHelp); + sDbgHelp = nullptr; + } + } +#else + bool SymbolLookup::Initialize() + { + return true; + } + + bool SymbolLookup::IsInitialized() + { + return true; + } + + void SymbolLookup::Shutdown() + { + } +#endif + +SymbolLookup::SymbolLookup() : + AllowMemoryAllocation(true), + ModuleListUpdated(false), + ModuleInfoArray(), + ModuleInfoArraySize(0) +{ +} + +SymbolLookup::~SymbolLookup() +{ +} + +void SymbolLookup::AddSourceCodeDirectory(const char* pDirectory) +{ + OVR_UNUSED(pDirectory); +} + +void SymbolLookup::EnableMemoryAllocation(bool enabled) +{ + AllowMemoryAllocation = enabled; +} + + +bool SymbolLookup::Refresh() +{ + ModuleListUpdated = false; + return RefreshModuleList(); +} + + +OVR_DISABLE_MSVC_WARNING(4740) // flow in or out of inline asm code suppresses global optimization +OVR_DISABLE_MSVC_WARNING(4748) // /GS can not protect parameters and local variables from local buffer overrun because optimizations are disabled in function + + +size_t SymbolLookup::GetBacktrace(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, void* platformThreadContext, OVR::ThreadSysId threadSysIdHelp) +{ + #if defined(OVR_OS_WIN64) + OVR_UNUSED(threadSysIdHelp); + + // The DbgHelp library must be loaded already. + OVR_ASSERT(sSymUsageCount > 0); + + if(platformThreadContext == nullptr) + return RtlCaptureStackBackTrace((DWORD)skipCount, (ULONG)addressArrayCapacity, addressArray, nullptr); + + // We need to get the call stack of another thread. + size_t frameIndex = 0; + CONTEXT context; + PRUNTIME_FUNCTION pRuntimeFunction; + ULONG64 imageBase = 0; + ULONG64 imageBasePrev = 0; + + memcpy(&context, (CONTEXT*)platformThreadContext, sizeof(CONTEXT)); + context.ContextFlags = CONTEXT_CONTROL; + + if(context.Rip && (frameIndex < addressArrayCapacity)) + addressArray[frameIndex++] = (void*)(uintptr_t)context.Rip; + + while(context.Rip && (frameIndex < addressArrayCapacity)) + { + imageBasePrev = imageBase; + pRuntimeFunction = (PRUNTIME_FUNCTION)RtlLookupFunctionEntry(context.Rip, &imageBase, nullptr); + + if(pRuntimeFunction) + { + VOID* handlerData = nullptr; + ULONG64 establisherFramePointers[2] = { 0, 0 }; + RtlVirtualUnwind(UNW_FLAG_NHANDLER, imageBase, context.Rip, pRuntimeFunction, &context, &handlerData, establisherFramePointers, nullptr); + } + else + { + context.Rip = (ULONG64)(*(PULONG64)context.Rsp); + context.Rsp += 8; + } + + if(context.Rip && (frameIndex < addressArrayCapacity)) + { + if(skipCount) + --skipCount; + else + addressArray[frameIndex++] = (void*)(uintptr_t)context.Rip; + } + } + + return frameIndex; + + #elif defined(OVR_OS_WIN32) + OVR_UNUSED(threadSysIdHelp); + + OVR::Lock::Locker autoLock(&sDbgHelpLock); + size_t frameIndex = 0; + + if(pStackWalk64) + { + CONTEXT context; + + if(platformThreadContext) + { + memcpy(&context, platformThreadContext, sizeof(context)); + context.ContextFlags = CONTEXT_CONTROL; + } + else + { + memset(&context, 0, sizeof(context)); + context.ContextFlags = CONTEXT_CONTROL; + + __asm { + mov context.Ebp, EBP + mov context.Esp, ESP + call GetEIP + GetEIP: + pop context.Eip + } + } + + STACKFRAME64 sf; + memset(&sf, 0, sizeof(sf)); + sf.AddrPC.Offset = context.Eip; + sf.AddrPC.Mode = AddrModeFlat; + sf.AddrStack.Offset = context.Esp; + sf.AddrStack.Mode = AddrModeFlat; + sf.AddrFrame.Offset = context.Ebp; + sf.AddrFrame.Mode = AddrModeFlat; + + const HANDLE hCurrentProcess = ::GetCurrentProcess(); + const HANDLE hCurrentThread = ::GetCurrentThread(); + + if(!platformThreadContext) // If we are reading the current thread's call stack then we ignore this current function. + skipCount++; + + while(frameIndex < addressArrayCapacity) + { + if(!pStackWalk64(IMAGE_FILE_MACHINE_I386, hCurrentProcess, hCurrentThread, &sf, &context, nullptr, pSymFunctionTableAccess64, pSymGetModuleBase64, nullptr)) + break; + + if(sf.AddrFrame.Offset == 0) + break; + + if(skipCount) + --skipCount; + else + addressArray[frameIndex++] = ((void*)(uintptr_t)sf.AddrPC.Offset); + } + } + + return frameIndex; + + #elif defined(OVR_OS_APPLE) + struct StackFrame + { + StackFrame* pParentStackFrame; + void* pReturnPC; + }; + + void* pInstruction; + StackFrame* pStackFrame; + size_t frameIndex = 0; + + if(platformThreadContext) + { + #if defined(OVR_CPU_ARM) + arm_thread_state_t* pThreadState = (arm_thread_state_t*)platformThreadContext; + pStackFrame = (StackFrame*)pThreadState->__fp; + pInstruction = (void*) pThreadState->__pc; + #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0x1) == 0) + #elif defined(OVR_CPU_X86_64) + x86_thread_state_t* pThreadState = (x86_thread_state_t*)platformThreadContext; + pInstruction = (void*) pThreadState->uts.ts64.__rip; + pStackFrame = (StackFrame*)pThreadState->uts.ts64.__rbp; + #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0xf) == 0) + #elif defined(OVR_CPU_X86) + x86_thread_state_t* pThreadState = (x86_thread_state_t*)platformThreadContext; + pInstruction = (void*) pThreadState->uts.ts32.__eip; + pStackFrame = (StackFrame*)pThreadState->uts.ts32.__ebp; + #define FrameIsAligned(pStackFrame) ((((uintptr_t)pStackFrame) & 0xf) == 8) + #endif + + if(frameIndex < addressArrayCapacity) + addressArray[frameIndex++] = pInstruction; + } + else // Else get the current values... + { + pStackFrame = (StackFrame*)__builtin_frame_address(0); + GetInstructionPointer(pInstruction); + } + + pthread_t threadSelf = pthread_self(); + void* pCurrentStackBase = pthread_get_stackaddr_np(threadSelf); + void* pCurrentStackLimit = (void*)((uintptr_t)pCurrentStackBase - pthread_get_stacksize_np(threadSelf)); + bool threadIsCurrent = (platformThreadContext == nullptr) || (((void*)pStackFrame > pCurrentStackLimit) && ((void*)pStackFrame <= pCurrentStackBase)); + StackFrame* pStackBase; + StackFrame* pStackLimit; + + if(threadIsCurrent) + { + pStackBase = (StackFrame*)pCurrentStackBase; + pStackLimit = (StackFrame*)pCurrentStackLimit; + } + else if(threadSysIdHelp) + { + pthread_t threadHandle = pthread_from_mach_thread_np((mach_port_t)threadSysIdHelp); + pStackBase = (StackFrame*)pthread_get_stackaddr_np(threadHandle); + pStackLimit = (StackFrame*)((uintptr_t)pStackBase - pthread_get_stacksize_np(threadHandle)); + } + else + { // We guess what the limits are. + pStackBase = pStackFrame + ((384 * 1024) / sizeof(StackFrame)); + pStackLimit = pStackFrame - ((384 * 1024) / sizeof(StackFrame)); + } + + if((frameIndex < addressArrayCapacity) && pStackFrame && FrameIsAligned(pStackFrame)) + { + addressArray[frameIndex++] = pStackFrame->pReturnPC; + + while(pStackFrame && pStackFrame->pReturnPC && (frameIndex < addressArrayCapacity)) + { + pStackFrame = pStackFrame->pParentStackFrame; + + if(pStackFrame && FrameIsAligned(pStackFrame) && pStackFrame->pReturnPC && (pStackFrame > pStackLimit) && (pStackFrame < pStackBase)) + { + if(skipCount) + --skipCount; + else + addressArray[frameIndex++] = pStackFrame->pReturnPC; + } + else + break; + } + } + + return frameIndex; + + #elif defined(OVR_OS_LINUX) && (defined( __LIBUNWIND__) || defined(LIBUNWIND_AVAIL)) + // Libunwind-based solution. Requires installation of libunwind package. + // Libunwind isn't always safe for threads that are in signal handlers. + // An approach to get the callstack of another thread is to use signal injection into the target thread. + + OVR_UNUSED(platformThreadContext); + OVR_UNUSED(threadSysIdHelp); + + size_t frameIndex = 0; + unw_cursor_t cursor; + unw_context_t uc; + unw_word_t ip, sp; + + unw_getcontext(&uc); // This gets the current thread's context. We could alternatively initialize another thread's context with it. + unw_init_local(&cursor, &uc); + + while((unw_step(&cursor) > 0) && (frameIndex < addressArrayCapacity)) + { + // We can get the function name here too on some platforms with unw_get_proc_info() and unw_get_proc_name(). + + if(skipCount) + --skipCount; + else + { + unw_get_reg(&cursor, UNW_REG_IP, &ip); + addressArray[frameIndex++] = (void*)ip; + } + } + + return frameIndex; + #else + OVR_UNUSED(addressArray); + OVR_UNUSED(addressArrayCapacity); + OVR_UNUSED(skipCount); + OVR_UNUSED(platformThreadContext); + OVR_UNUSED(threadSysIdHelp); + + return 0; + #endif +} + + +size_t SymbolLookup::GetBacktraceFromThreadHandle(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, OVR::ThreadHandle threadHandle) +{ + #if defined(OVR_OS_MS) + size_t count = 0; + DWORD threadSysId = (DWORD)ConvertThreadHandleToThreadSysId(threadHandle); + + // Compare to 0, compare to the self 'pseudohandle' and compare to the self id. + if((threadHandle == OVR_THREADHANDLE_INVALID) || (threadHandle == ::GetCurrentThread()) || (threadSysId == ::GetCurrentThreadId())) // If threadSysId refers to the current thread... + return GetBacktrace(addressArray, addressArrayCapacity, skipCount, nullptr); + + // We are working with another thread. We need to suspend it and get its CONTEXT. + // Suspending other threads is risky, as they may be in some state that cannot be safely blocked. + BOOL result = false; + DWORD suspendResult = ::SuspendThread(threadHandle); // Requires that the handle have THREAD_SUSPEND_RESUME rights. + + if(suspendResult != (DWORD)-1) // Returns previous suspend count, or -1 if failed. + { + CONTEXT context; + context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; // Requires that the handle have THREAD_GET_CONTEXT rights. + result = ::GetThreadContext(threadHandle, &context); + count = GetBacktrace(addressArray, addressArrayCapacity, skipCount, &context); + suspendResult = ::ResumeThread(threadHandle); + OVR_ASSERT_AND_UNUSED(suspendResult != (DWORD)-1, suspendResult); + } + + return count; + + #elif defined(OVR_OS_APPLE) + mach_port_t threadSysID = pthread_mach_thread_np((pthread_t)threadHandle); // Convert pthread_t to mach thread id. + return GetBacktraceFromThreadSysId(addressArray, addressArrayCapacity, skipCount, (OVR::ThreadSysId)threadSysID); + + #elif defined(OVR_OS_LINUX) + // To do. + OVR_UNUSED(addressArray); + OVR_UNUSED(addressArrayCapacity); + OVR_UNUSED(skipCount); + OVR_UNUSED(threadHandle); + return 0; + #endif +} + + +size_t SymbolLookup::GetBacktraceFromThreadSysId(void* addressArray[], size_t addressArrayCapacity, size_t skipCount, OVR::ThreadSysId threadSysId) +{ + #if defined(OVR_OS_MS) + OVR::ThreadHandle threadHandle = ConvertThreadSysIdToThreadHandle(threadSysId); + if(threadHandle) + { + size_t count = GetBacktraceFromThreadHandle(addressArray, addressArrayCapacity, skipCount, threadHandle); + FreeThreadHandle(threadHandle); + return count; + } + return 0; + + #elif defined(OVR_OS_APPLE) + mach_port_t threadCurrent = pthread_mach_thread_np(pthread_self()); + mach_port_t thread = (mach_port_t)threadSysId; + + if(thread == threadCurrent) + { + return GetBacktrace(addressArray, addressArrayCapacity, skipCount, nullptr); + } + else + { + kern_return_t result = thread_suspend(thread); // Do we need to do this if it's an thread who exception is being handled? + size_t count = 0; + + if(result == KERN_SUCCESS) + { + #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) + x86_thread_state_t threadState; + #elif defined(OVR_CPU_ARM) + arm_thread_state_t threadState; + #endif + mach_msg_type_number_t stateCount = MACHINE_THREAD_STATE_COUNT; + + result = thread_get_state(thread, MACHINE_THREAD_STATE, (natural_t*)(uintptr_t)&threadState, &stateCount); + + if(result == KERN_SUCCESS) + count = GetBacktrace(addressArray, addressArrayCapacity, skipCount, &threadState, threadSysId); + + thread_resume(thread); + + return count; + } + } + + return 0; + + #elif defined(OVR_OS_LINUX) + // To do. + OVR_UNUSED(addressArray); + OVR_UNUSED(addressArrayCapacity); + OVR_UNUSED(skipCount); + OVR_UNUSED(threadSysId); + return 0; + #endif +} + + +// We need to return the required moduleInfoArrayCapacity. +size_t SymbolLookup::GetModuleInfoArray(ModuleInfo* pModuleInfoArray, size_t moduleInfoArrayCapacity) +{ + #if defined(OVR_OS_MS) + size_t moduleCountRequired = 0; // The count we would copy to pModuleInfoArray if moduleInfoArrayCapacity was enough. + size_t moduleCount = 0; // The count we actually copy to pModuleInfoArray. Will be <= moduleInfoArrayCapacity. + HANDLE hProcess = GetCurrentProcess(); + HMODULE hModuleArray[200]; + DWORD cbNeeded = 0; + MODULEINFO mi; + + if(EnumProcessModules(hProcess, hModuleArray, sizeof(hModuleArray), &cbNeeded)) + { + moduleCountRequired = ((cbNeeded / sizeof(HMODULE)) < OVR_ARRAY_COUNT(hModuleArray)) ? (cbNeeded / sizeof(HMODULE)) : OVR_ARRAY_COUNT(hModuleArray); + moduleCount = MIN(moduleCountRequired, OVR_ARRAY_COUNT(hModuleArray)); + moduleCount = MIN(moduleCount, moduleInfoArrayCapacity); + + for(size_t i = 0; i < moduleCount; i++) + { + ModuleInfo& moduleInfo = pModuleInfoArray[i]; + + memset(&mi, 0, sizeof(mi)); + BOOL result = GetModuleInformation(hProcess, hModuleArray[i], &mi, sizeof(mi)); + + if(result) + { + wchar_t pathW[OVR_MAX_PATH]; + char pathA[OVR_MAX_PATH * 3]; // *3 to handle UTF8 multibyte encoding. + + moduleInfo.handle = hModuleArray[i]; + moduleInfo.baseAddress = (uintptr_t)mi.lpBaseOfDll; + moduleInfo.size = mi.SizeOfImage; + + GetModuleFileNameW(hModuleArray[i], pathW, OVR_ARRAY_COUNT(pathW)); + OVR::UTF8Util::EncodeString(pathA, pathW, -1); // Problem: DecodeString provides no way to specify the destination capacity. + OVR::OVR_strlcpy(moduleInfo.filePath, pathA, OVR_ARRAY_COUNT(moduleInfo.filePath)); + + const char* fileName = GetFileNameFromPath(pathA); + OVR::OVR_strlcpy(moduleInfo.name, fileName, OVR_ARRAY_COUNT(moduleInfo.name)); + } + else + { + moduleInfo.handle = 0; + moduleInfo.baseAddress = 0; + moduleInfo.size = 0; + moduleInfo.filePath[0] = 0; + moduleInfo.name[0] = 0; + } + } + } + + return moduleCountRequired; + + #elif defined(OVR_OS_MAC) + size_t moduleCountRequired = 0; + size_t moduleCount = 0; + + struct MacModuleInfo // This struct exists solely so we can have a local function within this function.. + { + static void AddMacModuleInfo(ModuleInfo* pModuleInfoArrayL, size_t& moduleCountRequiredL, size_t& moduleCountL, size_t moduleInfoArrayCapacityL, + const char* pTypeFilterL, const char* pModulePath, uintptr_t currentSegmentPos, const MachHeader* pMachHeader, uint64_t offset) + { + for(size_t i = 0; i < pMachHeader->ncmds; i++) + { + const SegmentCommand* pSegmentCommand = reinterpret_cast(currentSegmentPos); + + if(pSegmentCommand->cmd == kLCSegment) + { + const size_t segnameSize = (sizeof(pSegmentCommand->segname) + 1); // +1 so we can have a trailing '\0'. + char segname[segnameSize]; + + memcpy(segname, pSegmentCommand->segname, sizeof(pSegmentCommand->segname)); + segname[segnameSize - 1] = '\0'; + + if(!pTypeFilterL || OVR_strncmp(segname, pTypeFilterL, sizeof(segname))) + { + moduleCountRequiredL++; + + if(moduleCountL < moduleInfoArrayCapacityL) + { + ModuleInfo& info = pModuleInfoArrayL[moduleCountL++]; + + info.baseAddress = (uint64_t)(pSegmentCommand->vmaddr + offset); + info.handle = reinterpret_cast((uintptr_t)info.baseAddress); + info.size = (uint64_t)pSegmentCommand->vmsize; + OVR_strlcpy(info.filePath, pModulePath, OVR_ARRAY_COUNT(info.filePath)); + OVR_strlcpy(info.name, GetFileNameFromPath(pModulePath), OVR_ARRAY_COUNT(info.name)); + + info.permissions[0] = (pSegmentCommand->initprot & VM_PROT_READ) ? 'r' : '-'; + info.permissions[1] = (pSegmentCommand->initprot & VM_PROT_WRITE) ? 'w' : '-'; + info.permissions[2] = (pSegmentCommand->initprot & VM_PROT_EXECUTE) ? 'x' : '-'; + info.permissions[3] = '/'; + info.permissions[4] = (pSegmentCommand->maxprot & VM_PROT_READ) ? 'r' : '-'; + info.permissions[5] = (pSegmentCommand->maxprot & VM_PROT_WRITE) ? 'w' : '-'; + info.permissions[6] = (pSegmentCommand->maxprot & VM_PROT_EXECUTE) ? 'x' : '-'; + info.permissions[7] = '\0'; + + OVR_strlcpy(info.type, pSegmentCommand->segname, OVR_ARRAY_COUNT(info.type)); + } + } + } + + currentSegmentPos += pSegmentCommand->cmdsize; + } + } + }; + + // Iterate dyld_all_image_infos->infoArray + const struct dyld_all_image_infos* pAllImageInfos = _dyld_get_all_image_infos(); + + for(uint32_t i = 0; i < pAllImageInfos->infoArrayCount; i++) + { + const char* pModulePath = pAllImageInfos->infoArray[i].imageFilePath; + + if(pModulePath && *pModulePath) + { + uintptr_t currentSegmentPos = (uintptr_t)pAllImageInfos->infoArray[i].imageLoadAddress; + const MachHeader* pMachHeader = reinterpret_cast(currentSegmentPos); + uint64_t offset = (uint64_t)_dyld_get_image_vmaddr_slide(i); + + currentSegmentPos += sizeof(*pMachHeader); + + MacModuleInfo::AddMacModuleInfo(pModuleInfoArray, moduleCountRequired, moduleCount, moduleInfoArrayCapacity, + nullptr /*"__TEXT"*/, pModulePath, currentSegmentPos, pMachHeader, offset); + } + } + + // In addition to iterating dyld_all_image_infos->infoArray we need to also iterate /usr/lib/dyld entries. + const MachHeader* pMachHeader = (const MachHeader*)pAllImageInfos->dyldImageLoadAddress; + uintptr_t currentSegmentPos = (uintptr_t)pMachHeader + sizeof(*pMachHeader); + char modulePath[OVR_MAX_PATH] = ""; + pid_t pid = getpid(); + int filenameLen = proc_regionfilename((int)pid, currentSegmentPos, modulePath, (uint32_t)sizeof(modulePath)); + + if(filenameLen > 0) + MacModuleInfo::AddMacModuleInfo(pModuleInfoArray, moduleCountRequired, moduleCount, moduleInfoArrayCapacity, + "__TEXT", modulePath, currentSegmentPos, pMachHeader, 0); + + return moduleCountRequired; + + #elif defined(OVR_OS_LINUX) + // One approach is to read /proc/self/maps, which is supported by Linux (though not BSD). + // Linux glibc dladdr() can tell us what module an arbitrary function address comes from, but can't tell us the list of modules. + OVR_UNUSED(pModuleInfoArray); + OVR_UNUSED(moduleInfoArrayCapacity); + return 0; + + #else + OVR_UNUSED(pModuleInfoArray); + OVR_UNUSED(moduleInfoArrayCapacity); + return 0; + #endif +} + + +size_t SymbolLookup::GetThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCapacity) +{ + size_t countRequired = 0; + size_t count = 0; + + #if defined(OVR_OS_MS) + // Print a list of threads. + DWORD currentProcessId = GetCurrentProcessId(); + HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, currentProcessId); // ICreateToolhelp32Snapshot actually ignores currentProcessId. + + if(hThreadSnap != INVALID_HANDLE_VALUE) + { + THREADENTRY32 te32; + te32.dwSize = sizeof(THREADENTRY32); + + if(Thread32First(hThreadSnap, &te32)) + { + do + { + if(te32.th32OwnerProcessID == currentProcessId) + { + HANDLE hThread = ConvertThreadSysIdToThreadHandle(te32.th32ThreadID); + + if(hThread) + { + ++countRequired; + + if((threadHandleArray || threadSysIdArray) && (count < threadArrayCapacity)) + { + if(threadHandleArray) + threadHandleArray[count] = hThread; // The caller must call CloseHandle on this thread, or call DoneThreadList on the returned array. + if(threadSysIdArray) + threadSysIdArray[count] = ConvertThreadHandleToThreadSysId(hThread); + ++count; + } + + if(!threadHandleArray) // If we aren't giving this back to the user... + FreeThreadHandle(hThread); + } + } + } while(Thread32Next(hThreadSnap, &te32)); + } + + CloseHandle(hThreadSnap); + } + + #elif defined(OVR_OS_APPLE) + mach_port_t taskSelf = mach_task_self(); + thread_act_port_array_t threadArray; + mach_msg_type_number_t threadCount; + + kern_return_t result = task_threads(taskSelf, &threadArray, &threadCount); + + if(result == KERN_SUCCESS) + { + for(mach_msg_type_number_t i = 0; i < threadCount; i++) + { + ++countRequired; + + if((threadHandleArray || threadSysIdArray) && (count < threadArrayCapacity)) + { + if(threadHandleArray) + threadHandleArray[count] = pthread_from_mach_thread_np(threadArray[i]); + if(threadSysIdArray) + threadSysIdArray[count] = threadArray[i]; + ++count; + } + } + + vm_deallocate(taskSelf, (vm_address_t)threadArray, threadCount * sizeof(thread_act_t)); + } + + #elif defined(OVR_OS_LINUX) + // To do. + OVR_UNUSED(count); + OVR_UNUSED(threadHandleArray); + OVR_UNUSED(threadSysIdArray); + OVR_UNUSED(threadArrayCapacity); + #endif + + return countRequired; +} + + +void SymbolLookup::DoneThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCount) +{ + #if defined(OVR_OS_MS) + for(size_t i = 0; i != threadArrayCount; ++i) + { + if(threadHandleArray[i]) + { + CloseHandle(threadHandleArray[i]); + threadHandleArray[i] = OVR_THREADHANDLE_INVALID; + } + } + + OVR_UNUSED(threadSysIdArray); + #else + OVR_UNUSED(threadHandleArray); + OVR_UNUSED(threadSysIdArray); + OVR_UNUSED(threadArrayCount); + #endif +} + + +// Writes a given thread's callstack wity symbols to the given output. +// It may not be safe to call this from an exception handler, as sOutput allocates memory. +bool SymbolLookup::ReportThreadCallstack(OVR::String& sOutput, size_t skipCount, ThreadSysId threadSysId) +{ + sOutput.Clear(); + + if(!threadSysId) + threadSysId = GetCurrentThreadSysId(); + + void* addressArray[64]; + size_t addressCount = GetBacktraceFromThreadSysId(addressArray, OVR_ARRAY_COUNT(addressArray), skipCount, threadSysId); + + // Print the header + char headerBuffer[256]; + char threadName[32]; + char threadHandleStr[24]; + char threadSysIdStr[48]; + char stackBaseStr[24]; + char stackLimitStr[24]; + void* pStackBase; + void* pStackLimit; + //void* pStackCurrent; // Current stack pointer. To do: support reporting this. + ThreadHandle threadHandle = ConvertThreadSysIdToThreadHandle(threadSysId); + OVR::GetThreadStackBounds(pStackBase, pStackLimit, threadHandle); + + Thread::GetThreadName(threadName, OVR_ARRAY_COUNT(threadName), threadName); + SprintfThreadHandle(threadHandleStr, OVR_ARRAY_COUNT(threadHandleStr), threadHandle); + SprintfThreadSysId(threadSysIdStr, OVR_ARRAY_COUNT(threadSysIdStr), threadSysId); + SprintfAddress(stackBaseStr, OVR_ARRAY_COUNT(stackBaseStr), pStackBase); + SprintfAddress(stackLimitStr, OVR_ARRAY_COUNT(stackLimitStr), pStackLimit); + + if(threadName[0]) + OVR_snprintf(headerBuffer, OVR_ARRAY_COUNT(headerBuffer), "Thread \"%s\" handle: %s, id: %s, stack base: %s, stack limit: %s\n", threadName, threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr); + else + OVR_snprintf(headerBuffer, OVR_ARRAY_COUNT(headerBuffer), "Thread handle: %s, id: %s, stack base: %s, stack limit: %s\n", threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr); + + sOutput += headerBuffer; + + // Print the backtrace info + char backtraceBuffer[1024]; // Sometimes function symbol names are very long. + SymbolInfo symbolInfo; + const char* pModuleName; + + if(addressCount == 0) + { + sOutput += "\n"; + } + else + { + for(size_t i = 0; i < addressCount; ++i) + { + LookupSymbol((uint64_t)addressArray[i], symbolInfo); + + if(symbolInfo.pModuleInfo && symbolInfo.pModuleInfo->name[0]) + pModuleName = symbolInfo.pModuleInfo->name; + else + pModuleName = "(unknown module)"; + + char addressStr[24]; + SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), addressArray[i]); + + if(symbolInfo.filePath[0]) + OVR_snprintf(backtraceBuffer, OVR_ARRAY_COUNT(backtraceBuffer), "%-2u %-24s %s %s+%d %s:%d\n", (unsigned)i, pModuleName, addressStr, symbolInfo.function, symbolInfo.functionOffset, symbolInfo.filePath, symbolInfo.fileLineNumber); + else + OVR_snprintf(backtraceBuffer, OVR_ARRAY_COUNT(backtraceBuffer), "%-2u %-24s %s %s+%d\n", (unsigned)i, pModuleName, addressStr, symbolInfo.function, symbolInfo.functionOffset); + + sOutput += backtraceBuffer; + } + } + + FreeThreadHandle(threadHandle); + + return (addressCount > 0); +} + + +// Writes all thread's callstacks with symbols to the given output. +// It may not be safe to call this from an exception handler, as sOutput allocates memory. +bool SymbolLookup::ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount) +{ + sOutput.Clear(); + + ThreadSysId threadSysIdArray[64]; + size_t threadSysIdCount = GetThreadList(nullptr, threadSysIdArray, OVR_ARRAY_COUNT(threadSysIdArray)); + + if (threadSysIdCount > OVR_ARRAY_COUNT(threadSysIdArray)) + threadSysIdCount = OVR_ARRAY_COUNT(threadSysIdArray); + + for (size_t i = 0; i < threadSysIdCount; i++) + { + String sTemp; + ReportThreadCallstack(sTemp, skipCount, threadSysIdArray[i]); + if(i > 0) + sOutput += "\n"; + sOutput += sTemp; + } + + return (threadSysIdCount > 0); +} + +bool SymbolLookup::ReportModuleInformation(OVR::String& sOutput) +{ + sOutput.Clear(); + + RefreshModuleList(); + + char backtraceBuffer[1024]; + + for (size_t i = 0; i < ModuleInfoArraySize; ++i) + { + OVR_snprintf(backtraceBuffer, OVR_ARRAY_COUNT(backtraceBuffer), "Base: 0x%llx Size: 0x%llx Name: '%s' Path: '%s'\n", + ModuleInfoArray[i].baseAddress, ModuleInfoArray[i].size, ModuleInfoArray[i].name, ModuleInfoArray[i].filePath); + sOutput += backtraceBuffer; + } + + return true; +} + +bool SymbolLookup::RefreshModuleList() +{ + if(!ModuleListUpdated) + { + #if defined(OVR_OS_MS) + OVR::Lock::Locker autoLock(&sDbgHelpLock); + + // We can't rely on SymRefreshModuleList because it's present in DbgHelp 6.5, + // which doesn't distribute with Windows 7. + + // Currently we support only refreshing the list once ever. With a little effort we could revise this code to + // support re-refreshing the list at runtime to account for the possibility that modules have recently been + // added or removed. + if(pSymLoadModule64) + { + const size_t requiredCount = GetModuleInfoArray(ModuleInfoArray, OVR_ARRAY_COUNT(ModuleInfoArray)); + ModuleInfoArraySize = MIN(requiredCount, OVR_ARRAY_COUNT(ModuleInfoArray)); + + HANDLE hProcess = GetCurrentProcess(); + + for(size_t i = 0; i < ModuleInfoArraySize; i++) + pSymLoadModule64(hProcess, nullptr, ModuleInfoArray[i].filePath, nullptr, ModuleInfoArray[i].baseAddress, (DWORD)ModuleInfoArray[i].size); + + ModuleListUpdated = true; + } + #else + const size_t requiredCount = GetModuleInfoArray(ModuleInfoArray, OVR_ARRAY_COUNT(ModuleInfoArray)); + ModuleInfoArraySize = MIN(requiredCount, OVR_ARRAY_COUNT(ModuleInfoArray)); + ModuleListUpdated = true; + #endif + } + + return true; +} + + +bool SymbolLookup::LookupSymbol(uint64_t address, SymbolInfo& symbolInfo) +{ + return LookupSymbols(&address, &symbolInfo, 1); +} + + +bool SymbolLookup::LookupSymbols(uint64_t* addressArray, SymbolInfo* pSymbolInfoArray, size_t arraySize) +{ + bool success = false; + + if(!ModuleListUpdated) + { + RefreshModuleList(); + } + + #if defined(OVR_OS_MS) + OVR::Lock::Locker autoLock(&sDbgHelpLock); + + union SYMBOL_INFO_UNION + { + SYMBOL_INFO msSymbolInfo; + char suffixPadding[sizeof(SYMBOL_INFO) + 1024]; + }; + + for(size_t i = 0; i < arraySize; i++) + { + uint64_t& address = addressArray[i]; + SymbolInfo& symbolInfo = pSymbolInfoArray[i]; + + // Copy the address and ModuleInfo + symbolInfo.address = addressArray[i]; + symbolInfo.pModuleInfo = GetModuleInfoForAddress(address); // We could also use siu.msSymbolInfo.ModBase to get the module slightly faster. + + // Get the function/offset. + SYMBOL_INFO_UNION siu; + memset(&siu, 0, sizeof(siu)); + siu.msSymbolInfo.SizeOfStruct = sizeof(siu.msSymbolInfo); + siu.msSymbolInfo.MaxNameLen = sizeof(siu.suffixPadding) - sizeof(SYMBOL_INFO) + 1; // +1 because SYMBOL_INFO itself has Name[1]. + + HANDLE hProcess = GetCurrentProcess(); + DWORD64 displacement64 = 0; + bool bResult = (pSymFromAddr != nullptr) && (pSymFromAddr(hProcess, address, &displacement64, &siu.msSymbolInfo) != FALSE); + + if(bResult) + { + success = true; + symbolInfo.size = siu.msSymbolInfo.Size; + OVR_strlcpy(symbolInfo.function, siu.msSymbolInfo.Name, OVR_ARRAY_COUNT(symbolInfo.function)); + symbolInfo.functionOffset = (int32_t)displacement64; + } + else + { + symbolInfo.size = kMISizeInvalid; + symbolInfo.function[0] = 0; + symbolInfo.functionOffset = kMIFunctionOffsetInvalid; + } + + // Get the file/line + IMAGEHLP_LINE64 iLine64; + DWORD displacement = 0; + memset(&iLine64, 0, sizeof(iLine64)); + iLine64.SizeOfStruct = sizeof(iLine64); + + bResult = (pSymGetLineFromAddr64 != nullptr) && (pSymGetLineFromAddr64(hProcess, address, &displacement, &iLine64) != FALSE); + + if(bResult) + { + success = true; + OVR_strlcpy(symbolInfo.filePath, iLine64.FileName, OVR_ARRAY_COUNT(symbolInfo.filePath)); + symbolInfo.fileLineNumber = (int32_t)iLine64.LineNumber; + } + else + { + symbolInfo.filePath[0] = 0; + symbolInfo.fileLineNumber = kMILineNumberInvalid; + } + + // To do: get the source code when possible. We need to use the user-registered directory paths and the symbolInfo.filePath + // and find the given file in the tree(s), then open the file and find the symbolInfo.fileLineNumber line (and surrounding lines). + // symbolInfo.sourceCode[1024] + symbolInfo.sourceCode[0] = '\0'; + } + + #elif defined(OVR_OS_APPLE) + // Apple has an internal CoreSymbolication library which could help with this. + // Third party implementations of the CoreSymbolication header are available and could be used + // to get file/line info better than other means. It used Objective C, so we'll need a .m or .mm file. + + memset(pSymbolInfoArray, 0, arraySize * sizeof(SymbolInfo)); + + for(size_t i = 0; i < arraySize; i++) + { + pSymbolInfoArray[i].address = addressArray[i]; + pSymbolInfoArray[i].pModuleInfo = GetModuleInfoForAddress(addressArray[i]); + } + + // Problem: backtrace_symbols allocates memory from malloc. If you got into a SIGSEGV due to + // malloc arena corruption (quite common) you will likely fault in backtrace_symbols. + // To do: Use allowMemoryAllocation here. + + #if (OVR_PTR_SIZE == 4) + // backtrace_symbols takes a void* array, but we have a uint64_t array. So for 32 bit we + // need to convert the 64 bit array to 32 bit temporarily for the backtrace_symbols call. + void* ptr32Array[256]; // To do: Remove this limit. + for(size_t i = 0, iEnd = MIN(arraySize, OVR_ARRAY_COUNT(ptr32Array)); i < iEnd; i++) + ptr32Array[i] = reinterpret_cast(addressArray[i]); + char** symbolArray = backtrace_symbols(reinterpret_cast(ptr32Array), (int)arraySize); + #else + char** symbolArray = backtrace_symbols(reinterpret_cast(addressArray), (int)arraySize); + #endif + + if(symbolArray) + { + success = true; + + for(size_t i = 0; i < arraySize; i++) + { + // Generates a string like this: "0 OculusWorldDemo 0x000000010000cfd5 _ZN18OculusWorldDemoApp9OnStartupEiPPKc + 213" + static_assert(OVR_ARRAY_COUNT(pSymbolInfoArray[i].function) == 128, "Need to change the string format size below"); + + sscanf(symbolArray[i], "%*d %*s %*x %128s + %d", pSymbolInfoArray[i].function, &pSymbolInfoArray[i].functionOffset); + + if(AllowMemoryAllocation) + { + int status = 0; + char* strDemangled = abi::__cxa_demangle(pSymbolInfoArray[i].function, nullptr, nullptr, &status); + + if(strDemangled) + { + OVR_strlcpy(pSymbolInfoArray[i].function, strDemangled, OVR_ARRAY_COUNT(pSymbolInfoArray[i].function)); + free(strDemangled); + } + } + } + + free(symbolArray); + } + + // To consider: use CoreSybolication to get file/line info instead. atos is a bit slow and cumbersome. + // https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/atos.1.html + // atos -p ... + // atos -o -l ... + // Generates output like this: "OVR::CreateException(OVR::CreateExceptionType) (in OculusWorldDemo) (ExceptionHandler.cpp:598)" + for(size_t i = 0; i < arraySize; i++) + { + struct stat statStruct; + + if(pSymbolInfoArray[i].pModuleInfo && pSymbolInfoArray[i].pModuleInfo->filePath[0] && (stat(pSymbolInfoArray[i].pModuleInfo->filePath, &statStruct) == 0)) + { + char command[PATH_MAX * 2]; // Problem: We can't unilaterally use pSymbolInfoArray[0] for all addresses. We need to match addresses to the corresponding modules. + OVR_snprintf(command, OVR_ARRAY_COUNT(command), "atos -o %s -l 0x%llx 0x%llx", + pSymbolInfoArray[i].pModuleInfo->filePath, (int64_t)pSymbolInfoArray[i].pModuleInfo->baseAddress, (int64_t)pSymbolInfoArray[i].address); + + char output[512]; + if(SpawnShellCommand(command, output, OVR_ARRAY_COUNT(output)) != (size_t)-1) + { + char* pLastOpenParen = strrchr(output, '('); + char* pColon = strrchr(output, ':'); + + if(pLastOpenParen && (pColon > pLastOpenParen)) + { + *pColon = '\0'; + OVR_strlcpy(pSymbolInfoArray[i].filePath, pLastOpenParen + 1, OVR_ARRAY_COUNT(pSymbolInfoArray[i].filePath)); + } + } + } + } + + #elif defined(OVR_OS_LINUX) + // We can use libunwind's unw_get_proc_name to try to get function name info. It can work regardless of relocation. + // Use backtrace_symbols and addr2line. Need to watch out for module load-time relocation. + // Ned to pass the -rdynamic flag to the linker. It will cause the linker to out in the link + // tables the name of all the none static functions in your code, not just the exported ones. + OVR_UNUSED(addressArray); + OVR_UNUSED(pSymbolInfoArray); + OVR_UNUSED(arraySize); + #endif + + return success; +} + + +const ModuleInfo* SymbolLookup::GetModuleInfoForAddress(uint64_t address) +{ + // This is a linear seach. To consider: it would be significantly faster to search by + // address if we ordered it by base address and did a binary search. + for(size_t i = 0; i < ModuleInfoArraySize; ++i) + { + const ModuleInfo& mi = ModuleInfoArray[i]; + + if((mi.baseAddress <= address) && (address < (mi.baseAddress + mi.size))) + return &mi; + } + + return nullptr; +} + + + + +ExceptionInfo::ExceptionInfo() + : time() + , timeVal(0) + , backtrace() + , backtraceCount(0) + , threadHandle(OVR_THREADHANDLE_INVALID) + , threadSysId(OVR_THREADSYSID_INVALID) + , threadName() + , pExceptionInstructionAddress(nullptr) + , pExceptionMemoryAddress(nullptr) + , cpuContext() + , exceptionDescription() + , symbolInfo() + #if defined(OVR_OS_MS) + , exceptionRecord() + #elif defined(OVR_OS_APPLE) + , exceptionType(0) + , cpuExceptionId(0) + , cpuExceptionIdError(0) + , machExceptionData() + , machExceptionDataCount(0) + #endif +{ +} + + + +ExceptionHandler::ExceptionHandler() + : enabled(false) + , pauseCount(0) + , reportPrivacyEnabled(true) + , exceptionResponse(kERHandle) + , exceptionListener(nullptr) + , exceptionListenerUserValue(0) + , appDescription() + , codeBasePathArray() + , reportFilePath() + , miniDumpFlags(0) + , miniDumpFilePath() + , file(nullptr) + , scratchBuffer() + , exceptionOccurred(false) + , handlingBusy(0) + , reportFilePathActual() + , minidumpFilePathActual() + , terminateReturnValue(0) + , exceptionInfo() + #if defined(OVR_OS_MS) + , vectoredHandle(nullptr) + , previousFilter(nullptr) + , pExceptionPointers(nullptr) + #elif defined(OVR_OS_MAC) + , machHandlerInitialized(false) + , machExceptionPort(0) + , machExceptionPortsSaved() + , machThreadShouldContinue(false) + , machThreadExecuting(false) + , machThread((pthread_t)OVR_THREADHANDLE_INVALID) + #endif +{ + SetExceptionPaths("default", "default"); +} + +void ExceptionHandler::SetPathsFromNames(const char* organizationName, const char* ApplicationName, const char* exceptionFormat, const char* minidumpFormat) +{ + char exceptionPath[OVR_MAX_PATH]; + char miniDumpPath[OVR_MAX_PATH]; + GetCrashDumpDirectory(exceptionPath, OVR_MAX_PATH); + OVR_strlcat(exceptionPath, organizationName, OVR_MAX_PATH); + + //make the organization folder if necessary + #ifdef OVR_OS_MS + WCHAR wpath[128]; + OVR::UTF8Util::DecodeString(wpath, exceptionPath); + CreateDirectoryW(wpath,NULL); + #else + mkdir(exceptionPath,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + #endif + + #ifdef OVR_OS_MS + const char* separator = "\\"; + #else + const char* separator = "/"; + #endif + OVR_strlcat(exceptionPath, separator, OVR_MAX_PATH); + OVR_strlcat(exceptionPath, ApplicationName, OVR_MAX_PATH); + #ifdef OVR_OS_MS + OVR::UTF8Util::DecodeString(wpath, exceptionPath); + CreateDirectoryW(wpath, NULL); + #else + mkdir(exceptionPath,S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + #endif + OVR_strlcat(exceptionPath, separator, OVR_MAX_PATH); + OVR_strcpy(miniDumpPath, OVR_MAX_PATH, exceptionPath); + + OVR::OVR_strlcat(exceptionPath, exceptionFormat, OVR_MAX_PATH); + OVR::OVR_strlcat(miniDumpPath, minidumpFormat, OVR_MAX_PATH); + + SetExceptionPaths(exceptionPath, miniDumpPath); +} + +ExceptionHandler::~ExceptionHandler() +{ + if(enabled) + { + Enable(false); + } +} + +size_t ExceptionHandler::GetCrashDumpDirectory(char* directoryPath, size_t directoryPathCapacity) +{ + #if defined(OVR_OS_MS) + wchar_t pathW[OVR_MAX_PATH + 1]; // +1 because we append a path separator. + HRESULT hr = SHGetFolderPathW(nullptr, CSIDL_APPDATA | CSIDL_FLAG_CREATE, nullptr, SHGFP_TYPE_CURRENT, pathW); + + if (SUCCEEDED(hr)) + { + intptr_t requiredUTF8Length = OVR::UTF8Util::GetEncodeStringSize(pathW); // Returns required strlen. + if (requiredUTF8Length < OVR_MAX_PATH) // We need space for a trailing path separator. + { + OVR::UTF8Util::EncodeString(directoryPath, pathW, -1); + OVR::OVR_strlcat(directoryPath, "\\", directoryPathCapacity); + } + + return (requiredUTF8Length + 1); + } + + #elif defined(OVR_OS_MAC) + // This is the same location that Apple puts its OS-generated .crash files. + const char* home = getenv("HOME"); + size_t requiredStrlen = OVR::OVR_snprintf(directoryPath, directoryPathCapacity, "%s/Library/Logs/DiagnosticReports/", home ? home : "/Users/Shared/Logs/DiagnosticReports/"); + // To do: create the directory if it doesn't already exist. + return requiredStrlen; + + #elif defined(OVR_OS_UNIX) + const char* home = getenv("HOME"); + size_t requiredStrlen = OVR::OVR_snprintf(directoryPath, directoryPathCapacity, "%s/Library/", home ? home : "/Users/Shared/"); + // To do: create the directory if it doesn't already exist. + return requiredStrlen; + #endif + + return 0; +} + + +#if defined(OVR_OS_MS) + +static ExceptionHandler* sExceptionHandler = nullptr; + + unsigned WINAPI ExceptionHandler::ExceptionHandlerThreadExec(void * callingHandler) + { + ExceptionHandler* caller = reinterpret_cast(callingHandler); + if (caller->miniDumpFilePath[0]) + caller->WriteMiniDump(); + + if (caller->reportFilePath[0]) + caller->WriteReport(); + + if (caller->exceptionListener) + caller->exceptionListener->HandleException(caller->exceptionListenerUserValue, caller, &caller->exceptionInfo, caller->reportFilePathActual); + return 1; + } + + LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers) + { + if(sExceptionHandler) + return (LONG)sExceptionHandler->ExceptionFilter(pExceptionPointers); + return EXCEPTION_CONTINUE_SEARCH; + } + + LONG ExceptionHandler::ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers) + { + if(pauseCount) + return EXCEPTION_CONTINUE_SEARCH; + + // Exception codes < 0x80000000 are not true exceptions but rather are debugger notifications. They include DBG_TERMINATE_THREAD, + // DBG_TERMINATE_PROCESS, DBG_CONTROL_BREAK, DBG_COMMAND_EXCEPTION, DBG_CONTROL_C, DBG_PRINTEXCEPTION_C, DBG_RIPEXCEPTION, + // and 0x406d1388 (thread named, http://blogs.msdn.com/b/stevejs/archive/2005/12/19/505815.aspx). + + if(pExceptionPointers->ExceptionRecord->ExceptionCode < 0x80000000) + return EXCEPTION_CONTINUE_SEARCH; + + // VC++ C++ exceptions use code 0xe06d7363 ('Emsc') + // http://support.microsoft.com/kb/185294 + // http://blogs.msdn.com/b/oldnewthing/archive/2010/07/30/10044061.aspx + if(pExceptionPointers->ExceptionRecord->ExceptionCode == 0xe06d7363) + return EXCEPTION_CONTINUE_SEARCH; + + if(handlingBusy.CompareAndSet_Acquire(0, 1)) // If we can successfully change it from 0 to 1. + { + exceptionOccurred = true; + + SymbolLookup::Initialize(); + + this->pExceptionPointers = pExceptionPointers; + + // Disable the handler while we do this processing. + ULONG result = RemoveVectoredExceptionHandler(vectoredHandle); + OVR_ASSERT_AND_UNUSED(result != 0, result); + + // Time + exceptionInfo.timeVal = time(nullptr); + exceptionInfo.time = *gmtime(&exceptionInfo.timeVal); + + // Thread id + // This is the thread id of the current thread and not the exception thread. + if(!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &exceptionInfo.threadHandle, 0, true, DUPLICATE_SAME_ACCESS)) + exceptionInfo.threadHandle = 0; + exceptionInfo.threadSysId = ConvertThreadHandleToThreadSysId(exceptionInfo.threadHandle); + + OVR::GetThreadName(exceptionInfo.threadHandle, exceptionInfo.threadName, OVR_ARRAY_COUNT(exceptionInfo.threadName)); + + // Backtraces + exceptionInfo.backtraceCount = symbolLookup.GetBacktrace(exceptionInfo.backtrace, OVR_ARRAY_COUNT(exceptionInfo.backtrace)); + + // Context + exceptionInfo.cpuContext = *pExceptionPointers->ContextRecord; + exceptionInfo.exceptionRecord = *pExceptionPointers->ExceptionRecord; + exceptionInfo.pExceptionInstructionAddress = exceptionInfo.exceptionRecord.ExceptionAddress; + if((exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) || (exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_IN_PAGE_ERROR)) + exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.exceptionRecord.ExceptionInformation[1]; // ExceptionInformation[0] indicates if it was a read (0), write (1), or data execution attempt (8). + else + exceptionInfo.pExceptionMemoryAddress = pExceptionPointers->ExceptionRecord->ExceptionAddress; + + WriteExceptionDescription(); + + if (pExceptionPointers->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW){ + unsigned int IdValue; + + void* ThreadHandle = (HANDLE)_beginthreadex(0, (unsigned)128 * 1024, + ExceptionHandlerThreadExec, this, 0, (unsigned*)&IdValue); + WaitForSingleObject(ThreadHandle, INFINITE); + CloseHandle(ThreadHandle); + + } + else + { + if (miniDumpFilePath[0]) + WriteMiniDump(); + + if (reportFilePath[0]) + WriteReport(); + + if (exceptionListener) + exceptionListener->HandleException(exceptionListenerUserValue, this, &exceptionInfo, reportFilePathActual); + } + if(exceptionInfo.threadHandle) + { + CloseHandle(exceptionInfo.threadHandle); + exceptionInfo.threadHandle = 0; + } + + SymbolLookup::Shutdown(); + + // Restore the handler that we temporarily disabled above. + vectoredHandle = AddVectoredExceptionHandler(1, Win32ExceptionFilter); + + handlingBusy.Store_Release(0); + } + + if(exceptionResponse == ExceptionHandler::kERContinue) + return EXCEPTION_CONTINUE_EXECUTION; + else if(exceptionResponse == ExceptionHandler::kERHandle) + return EXCEPTION_EXECUTE_HANDLER; + else if(exceptionResponse == ExceptionHandler::kERTerminate) + { + TerminateProcess(GetCurrentProcess(), (UINT)terminateReturnValue); + return terminateReturnValue; + } + else if(exceptionResponse == ExceptionHandler::kERThrow) + return EXCEPTION_CONTINUE_SEARCH; + + // kERDefault + return EXCEPTION_EXECUTE_HANDLER; + } + +#endif // defined(OVR_OS_MS) + + +#if defined(OVR_OS_APPLE) + // http://www.opensource.apple.com/source/xnu/xnu-2050.22.13/ + // http://www.opensource.apple.com/source/xnu/xnu-2050.22.13/osfmk/man/ + // http://www.opensource.apple.com/source/Libc/Libc-825.26/ + // https://mikeash.com/pyblog/friday-qa-2013-01-11-mach-exception-handlers.html + + void* ExceptionHandler::MachHandlerThreadFunction() + { + __Request__mach_exception_raise_state_identity_t msg; + __Reply__mach_exception_raise_state_identity_t reply; + mach_msg_return_t result; + + machThreadExecuting = true; + pthread_setname_np("ExceptionHandler"); + + while(machThreadShouldContinue) + { + mach_msg_option_t options = MACH_RCV_MSG | MACH_RCV_LARGE; + natural_t timeout = 0; // Would be better to support a non-zero time. + + if(timeout) + options |= MACH_RCV_TIMEOUT; + + result = mach_msg(&msg.Head, options, 0, sizeof(msg), machExceptionPort, timeout, MACH_PORT_NULL); + + if(msg.Head.msgh_id != sMachCancelMessageType) + { + if(result == MACH_MSG_SUCCESS) + { + if(mach_exc_server_OVR(&msg.Head, &reply.Head) == 0) //This will call our HandleMachException function. + result = ~MACH_MSG_SUCCESS; + } + + // Send the reply + if(result == MACH_MSG_SUCCESS) + { + result = mach_msg(&reply.Head, MACH_SEND_MSG, reply.Head.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + + if(result != MACH_MSG_SUCCESS) + { + // Failure. + } + } + } + } + + machThreadExecuting = false; + + return nullptr; + } + + + kern_return_t ExceptionHandler::HandleMachException(mach_port_t /*machPort*/, mach_port_t threadSysId, mach_port_t machTask, + exception_type_t machExceptionType, mach_exception_data_type_t* pMachExceptionData, + mach_msg_type_number_t exceptionDataCount, int* /*pMachExceptionFlavor*/, thread_state_t threadStatePrev, + mach_msg_type_number_t /*threadStatePrevCount*/, thread_state_t /*threadStateNew*/, + mach_msg_type_number_t* /*pThreadStateNewCount*/) + { + // We don't want to handle exceptions for other processes. + if(machTask != mach_task_self()) + return ForwardMachException(threadSysId, machTask, machExceptionType, pMachExceptionData, exceptionDataCount); + + if(handlingBusy.CompareAndSet_Acquire(0, 1)) // If we can successfully change it from 0 to 1. + { + exceptionOccurred = true; + + // Disable the handler while we do this processing. + // To do. + + // Time + exceptionInfo.timeVal = time(nullptr); + exceptionInfo.time = *gmtime(&exceptionInfo.timeVal); + + // Thread id + exceptionInfo.threadHandle = pthread_from_mach_thread_np(threadSysId); + exceptionInfo.threadSysId = threadSysId; + pthread_getname_np((pthread_t)exceptionInfo.threadHandle, exceptionInfo.threadName, sizeof(exceptionInfo.threadName)); + + // Backtraces + exceptionInfo.backtraceCount = symbolLookup.GetBacktraceFromThreadSysId(exceptionInfo.backtrace, OVR_ARRAY_COUNT(exceptionInfo.backtrace), 0, threadSysId); + + // Context + #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) + // We can read x86_THREAD_STATE directly fromk threadStatePrev. + exceptionInfo.cpuContext.threadState = *reinterpret_cast(threadStatePrev); + + mach_msg_type_number_t stateCount = x86_FLOAT_STATE_COUNT; + thread_get_state(threadSysId, x86_FLOAT_STATE, (natural_t*)&exceptionInfo.cpuContext.floatState, &stateCount); + + stateCount = x86_DEBUG_STATE_COUNT; + thread_get_state(threadSysId, x86_DEBUG_STATE, (natural_t*)&exceptionInfo.cpuContext.debugState, &stateCount); + + stateCount = x86_AVX_STATE_COUNT; + thread_get_state(threadSysId, x86_AVX_STATE, (natural_t*)&exceptionInfo.cpuContext.avxState, &stateCount); + + stateCount = x86_EXCEPTION_STATE_COUNT; + thread_get_state(threadSysId, x86_EXCEPTION_STATE, (natural_t*)&exceptionInfo.cpuContext.exceptionState, &stateCount); + + #if defined(OVR_CPU_X86) + exceptionInfo.pExceptionInstructionAddress = (void*)exceptionInfo.cpuContext.threadState.uts.ts32.__eip; + exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.cpuContext.exceptionState.ues.es32.__faultvaddr; + exceptionInfo.cpuExceptionId = exceptionInfo.cpuContext.exceptionState.ues.es32.__trapno; + exceptionInfo.cpuExceptionIdError = exceptionInfo.cpuContext.exceptionState.ues.es32.__err; + #else + exceptionInfo.pExceptionInstructionAddress = (void*)exceptionInfo.cpuContext.threadState.uts.ts64.__rip; + exceptionInfo.pExceptionMemoryAddress = (void*)exceptionInfo.cpuContext.exceptionState.ues.es64.__faultvaddr; + exceptionInfo.cpuExceptionId = exceptionInfo.cpuContext.exceptionState.ues.es64.__trapno; + exceptionInfo.cpuExceptionIdError = exceptionInfo.cpuContext.exceptionState.ues.es64.__err; + #endif + #endif + + exceptionInfo.exceptionType = machExceptionType; + + exceptionInfo.machExceptionDataCount = MIN(exceptionDataCount, OVR_ARRAY_COUNT(exceptionInfo.machExceptionData)); + for(int i = 0; i < exceptionInfo.machExceptionDataCount; i++) + exceptionInfo.machExceptionData[i] = pMachExceptionData[i]; + + WriteExceptionDescription(); + + if(reportFilePath[0]) + WriteReport(); + + if(miniDumpFilePath[0]) + WriteMiniDump(); + + if(exceptionListener) + exceptionListener->HandleException(exceptionListenerUserValue, this, &exceptionInfo, reportFilePathActual); + + // Re-restore the handler. + // To do. + + handlingBusy.Store_Release(0); + } + + kern_return_t result = KERN_FAILURE; // By default pass on the exception to another handler after we are done here. + + if(exceptionResponse == ExceptionHandler::kERContinue) + result = KERN_SUCCESS; // This will trigger a re-execution of the function. + else if(exceptionResponse == ExceptionHandler::kERTerminate) + ::exit(terminateReturnValue); + else if(exceptionResponse == ExceptionHandler::kERThrow) + ForwardMachException(threadSysId, machTask, machExceptionType, pMachExceptionData, exceptionDataCount); + else if(exceptionResponse == ExceptionHandler::kERDefault) + ::exit(terminateReturnValue); + + // kERHandle + return result; + } + + + bool ExceptionHandler::InitMachExceptionHandler() + { + if(!machHandlerInitialized) + { + mach_port_t machTaskSelf = mach_task_self(); + kern_return_t result = MACH_MSG_SUCCESS; + exception_mask_t mask = EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_CRASH; + + if(machExceptionPort == MACH_PORT_NULL) + { + result = mach_port_allocate(machTaskSelf, MACH_PORT_RIGHT_RECEIVE, &machExceptionPort); + + if(result == MACH_MSG_SUCCESS) + { + result = mach_port_insert_right(machTaskSelf, machExceptionPort, machExceptionPort, MACH_MSG_TYPE_MAKE_SEND); + + if(result == MACH_MSG_SUCCESS) + result = task_get_exception_ports(machTaskSelf, mask, machExceptionPortsSaved.masks, &machExceptionPortsSaved.count, + machExceptionPortsSaved.ports, machExceptionPortsSaved.behaviors, machExceptionPortsSaved.flavors); + } + } + + if(result == MACH_MSG_SUCCESS) + { + result = task_set_exception_ports(machTaskSelf, mask, machExceptionPort, EXCEPTION_STATE_IDENTITY | MACH_EXCEPTION_CODES, MACHINE_THREAD_STATE); + + if(result == MACH_MSG_SUCCESS) + { + machThreadShouldContinue = true; + + pthread_attr_t attr; + pthread_attr_init(&attr); + + result = pthread_create(&machThread, &attr, MachHandlerThreadFunctionStatic, (void*)this); + pthread_attr_destroy(&attr); + + machHandlerInitialized = (result == 0); + } + } + + if(!machHandlerInitialized) + ShutdownMachExceptionHandler(); + } + + return machHandlerInitialized; + } + + + void ExceptionHandler::ShutdownMachExceptionHandler() + { + if(machThreadExecuting) + { + machThreadShouldContinue = false; // Tell it to stop. + + // Cancel the current exception handler thread (which is probably blocking in a call to mach_msg) by sending it a cencel message. + struct CancelMessage + { + mach_msg_header_t msgHeader; + }; + + CancelMessage msg; + memset(&msg.msgHeader, 0, sizeof(CancelMessage)); + msg.msgHeader.msgh_id = sMachCancelMessageType; + msg.msgHeader.msgh_size = sizeof(CancelMessage); + msg.msgHeader.msgh_bits = MACH_MSGH_BITS_REMOTE(MACH_MSG_TYPE_MAKE_SEND); + msg.msgHeader.msgh_remote_port = machExceptionPort; + msg.msgHeader.msgh_local_port = MACH_PORT_NULL; + + mach_msg_return_t result = mach_msg(&msg.msgHeader, MACH_SEND_MSG, msg.msgHeader.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + + if(result == MACH_MSG_SUCCESS) + { + const time_t secondsLater = time(NULL) + 4; + + while(machThreadExecuting && (time(NULL) < secondsLater)) + { + timespec ts = { 0, 1000000000 }; + nanosleep(&ts, nullptr); + } + } + + void* joinResult = nullptr; + pthread_join(machThread, &joinResult); + machThread = 0; + } + + if(machExceptionPort != MACH_PORT_NULL) + { + // Restore the previous ports + kern_return_t result = KERN_SUCCESS; + mach_port_t machTaskSelf = mach_task_self(); + + for(unsigned i = 0; (i < machExceptionPortsSaved.count) && (result == KERN_SUCCESS); i++) + { + result = task_set_exception_ports(machTaskSelf, machExceptionPortsSaved.masks[i], machExceptionPortsSaved.ports[i], + machExceptionPortsSaved.behaviors[i], machExceptionPortsSaved.flavors[i]); + } + + mach_port_deallocate(machTaskSelf, machExceptionPort); + machExceptionPort = MACH_PORT_NULL; + } + + machHandlerInitialized = false; + } + + + kern_return_t ExceptionHandler::ForwardMachException(mach_port_t thread, mach_port_t task, exception_type_t exceptionType, + mach_exception_data_t pMachExceptionData, mach_msg_type_number_t exceptionDataCount) + { + kern_return_t result = KERN_FAILURE; + mach_msg_type_number_t i; + + for(i = 0; i < machExceptionPortsSaved.count; i++) + { + if(machExceptionPortsSaved.masks[i] & (1 << exceptionType)) + break; + } + + if(i < machExceptionPortsSaved.count) + { + mach_port_t port = machExceptionPortsSaved.ports[i]; + exception_behavior_t behavior = machExceptionPortsSaved.behaviors[i]; + thread_state_flavor_t flavor = machExceptionPortsSaved.flavors[i]; + mach_msg_type_number_t threadStateCount = THREAD_STATE_MAX; + thread_state_data_t threadState; + + if(behavior != EXCEPTION_DEFAULT) + thread_get_state(thread, flavor, threadState, &threadStateCount); + + switch(behavior) + { + case EXCEPTION_DEFAULT: + result = mach_exception_raise_OVR(port, thread, task, exceptionType, pMachExceptionData, exceptionDataCount); + break; + + case EXCEPTION_STATE: + result = mach_exception_raise_state_OVR(port, exceptionType, pMachExceptionData, exceptionDataCount, + &flavor, threadState, threadStateCount, threadState, &threadStateCount); + break; + + case EXCEPTION_STATE_IDENTITY: + result = mach_exception_raise_state_identity_OVR(port, thread, task, exceptionType, pMachExceptionData, + exceptionDataCount, &flavor, threadState, threadStateCount, threadState, &threadStateCount); + break; + + default: + result = KERN_FAILURE; + break; + } + + if(behavior != EXCEPTION_DEFAULT) + result = thread_set_state(thread, flavor, threadState, threadStateCount); + } + + return result; + } + + +#endif // OVR_OS_APPLE + + +bool ExceptionHandler::Enable(bool enable) +{ + #if defined(OVR_OS_MS) + if(enable && !enabled) + { + OVR_ASSERT(vectoredHandle == nullptr); + vectoredHandle = AddVectoredExceptionHandler(1, Win32ExceptionFilter); // Windows call. + enabled = (vectoredHandle != nullptr); + OVR_ASSERT(enabled); + sExceptionHandler = this; + return enabled; + } + else if(!enable && enabled) + { + if(sExceptionHandler == this) + sExceptionHandler = nullptr; + OVR_ASSERT(vectoredHandle != nullptr); + ULONG result = RemoveVectoredExceptionHandler(vectoredHandle); // Windows call. + OVR_ASSERT_AND_UNUSED(result != 0, result); + vectoredHandle = nullptr; + enabled = false; + return true; + } + + #elif defined(OVR_OS_APPLE) + + if(enable && !enabled) + { + enabled = InitMachExceptionHandler(); + OVR_ASSERT(enabled); + sExceptionHandler = this; + return enabled; + } + else if(!enable && enabled) + { + if(sExceptionHandler == this) + sExceptionHandler = nullptr; + ShutdownMachExceptionHandler(); + enabled = false; + return true; + } + #else + OVR_UNUSED(enable); + #endif + + return true; +} + +int ExceptionHandler::PauseHandling(bool pause) +{ + if(pause) + return ++pauseCount; + + OVR_ASSERT(pauseCount > 0); + return --pauseCount; +} + +void ExceptionHandler::EnableReportPrivacy(bool enable) +{ + reportPrivacyEnabled = enable; +} + +void ExceptionHandler::WriteExceptionDescription() +{ + #if defined(OVR_OS_MS) + // There is some extra information available for AV exception. + if(exceptionInfo.exceptionRecord.ExceptionCode == EXCEPTION_ACCESS_VIOLATION) + { + const char* error = (exceptionInfo.exceptionRecord.ExceptionInformation[0] == 0) ? "reading" : + ((exceptionInfo.exceptionRecord.ExceptionInformation[0] == 1) ? "writing" : "executing"); + + char addressStr[24]; + SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionMemoryAddress); + OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), "ACCESS_VIOLATION %s address %s", error, addressStr); + } + else + { + exceptionInfo.exceptionDescription[0] = 0; + + // Process "standard" exceptions, other than 'access violation' + #define FORMAT_EXCEPTION(x) \ + case EXCEPTION_##x: \ + OVR::OVR_strlcpy(exceptionInfo.exceptionDescription, #x, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); \ + break; + + switch(exceptionInfo.exceptionRecord.ExceptionCode) + { + //FORMAT_EXCEPTION(ACCESS_VIOLATION) Already handled above. + FORMAT_EXCEPTION(DATATYPE_MISALIGNMENT) + FORMAT_EXCEPTION(BREAKPOINT) + FORMAT_EXCEPTION(SINGLE_STEP) + FORMAT_EXCEPTION(ARRAY_BOUNDS_EXCEEDED) + FORMAT_EXCEPTION(FLT_DENORMAL_OPERAND) + FORMAT_EXCEPTION(FLT_DIVIDE_BY_ZERO) + FORMAT_EXCEPTION(FLT_INEXACT_RESULT) + FORMAT_EXCEPTION(FLT_INVALID_OPERATION) + FORMAT_EXCEPTION(FLT_OVERFLOW) + FORMAT_EXCEPTION(FLT_STACK_CHECK) + FORMAT_EXCEPTION(FLT_UNDERFLOW) + FORMAT_EXCEPTION(INT_DIVIDE_BY_ZERO) + FORMAT_EXCEPTION(INT_OVERFLOW) + FORMAT_EXCEPTION(PRIV_INSTRUCTION) + FORMAT_EXCEPTION(IN_PAGE_ERROR) + FORMAT_EXCEPTION(ILLEGAL_INSTRUCTION) + FORMAT_EXCEPTION(NONCONTINUABLE_EXCEPTION) + FORMAT_EXCEPTION(STACK_OVERFLOW) + FORMAT_EXCEPTION(INVALID_DISPOSITION) + FORMAT_EXCEPTION(GUARD_PAGE) + FORMAT_EXCEPTION(INVALID_HANDLE) + #if defined(EXCEPTION_POSSIBLE_DEADLOCK) && defined(STATUS_POSSIBLE_DEADLOCK) // This type seems to be non-existant in practice. + FORMAT_EXCEPTION(POSSIBLE_DEADLOCK) + #endif + } + + // If not one of the "known" exceptions, try to get the string from NTDLL.DLL's message table. + if(exceptionInfo.exceptionDescription[0] == 0) + { + char addressStr[24]; + SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionMemoryAddress); + + char buffer[384]; + DWORD capacity = OVR_ARRAY_COUNT(buffer); + + const size_t length = (size_t)FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_HMODULE, + GetModuleHandleW(L"NTDLL.DLL"), exceptionInfo.exceptionRecord.ExceptionCode, 0, buffer, capacity, nullptr); + if(length) + OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), + "%s at instruction %s", buffer, addressStr); + + // If everything else failed just show the hex code. + if(exceptionInfo.exceptionDescription[0] == 0) + OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), + "Unknown exception 0x%08x at instruction %s", exceptionInfo.exceptionRecord.ExceptionCode, addressStr); + } + } + + #elif defined(OVR_OS_APPLE) + struct MachExceptionInfo + { + static const char* GetCPUExceptionIdString(uint32_t cpuExceptionId) + { + const char* id; + + #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) + switch (cpuExceptionId) + { + case 0: id = "integer div/0"; break; + case 1: id = "breakpoint fault"; break; + case 2: id = "non-maskable interrupt"; break; + case 3: id = "int 3"; break; + case 4: id = "overflow"; break; + case 5: id = "bounds check failure"; break; + case 6: id = "invalid instruction"; break; + case 7: id = "coprocessor unavailable"; break; + case 8: id = "exception within exception"; break; + case 9: id = "coprocessor segment overrun"; break; + case 10: id = "invalid task switch"; break; + case 11: id = "segment not present"; break; + case 12: id = "stack exception"; break; + case 13: id = "general protection fault"; break; + case 14: id = "page fault"; break; + case 16: id = "coprocessor error"; break; + default: id = ""; break; + } + #else + // To do: Support ARM or others. + #endif + + return id; + } + + static const char* GetMachExceptionTypeString(uint64_t exceptionCause) + { + switch (exceptionCause) + { + case EXC_ARITHMETIC: return "EXC_ARITHMETIC"; + case EXC_BAD_ACCESS: return "EXC_BAD_ACCESS"; + case EXC_BAD_INSTRUCTION: return "EXC_BAD_INSTRUCTION"; + case EXC_BREAKPOINT: return "EXC_BREAKPOINT"; + case EXC_CRASH: return "EXC_CRASH"; + case EXC_EMULATION: return "EXC_EMULATION"; + case EXC_MACH_SYSCALL: return "EXC_MACH_SYSCALL"; + case EXC_RPC_ALERT: return "EXC_RPC_ALERT"; + case EXC_SOFTWARE: return "EXC_SOFTWARE"; + case EXC_SYSCALL: return "EXC_SYSCALL"; + }; + + return "EXC_"; + } + + static const char* GetMachExceptionIdString(uint64_t machExceptionId, uint64_t code0) + { + const char* id = ""; + + #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) + switch (machExceptionId) + { + case EXC_ARITHMETIC: + switch (code0) + { + case EXC_I386_BOUND: id = "EXC_I386_BOUND"; break; + case EXC_I386_DIV: id = "EXC_I386_DIV"; break; + case EXC_I386_EMERR: id = "EXC_I386_EMERR"; break; + case EXC_I386_EXTERR: id = "EXC_I386_EXTERR"; break; + case EXC_I386_EXTOVR: id = "EXC_I386_EXTOVR"; break; + case EXC_I386_INTO: id = "EXC_I386_INTO"; break; + case EXC_I386_NOEXT: id = "EXC_I386_NOEXT"; break; + case EXC_I386_SSEEXTERR: id = "EXC_I386_SSEEXTERR"; break; + } + break; + + case EXC_BAD_INSTRUCTION: + if(code0 == EXC_I386_INVOP) + id = "EXC_I386_INVOP"; + break; + + case EXC_BREAKPOINT: + if(code0 == EXC_I386_BPT) + id = "EXC_I386_BPT"; + else if(code0 == EXC_I386_SGL) + id = "EXC_I386_SGL"; + break; + }; + #else + // To do. + #endif + + return id; + } + }; + + OVR::OVR_snprintf(exceptionInfo.exceptionDescription, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription), + "Mach exception type: %llu (%s)\n", exceptionInfo.exceptionType, MachExceptionInfo::GetMachExceptionTypeString(exceptionInfo.exceptionType)); + + OVR::OVR_snprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), "CPU exception info: exception id: %u (%s), exception id error: %u, fault memory address: %p\n", + exceptionInfo.cpuExceptionId, MachExceptionInfo::GetCPUExceptionIdString(exceptionInfo.cpuExceptionId), exceptionInfo.cpuExceptionIdError, exceptionInfo.pExceptionMemoryAddress); + OVR::OVR_strlcat(exceptionInfo.exceptionDescription, scratchBuffer, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); + + + OVR::OVR_snprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), "Mach exception info: exception id: %llu (%s), 0x%llx (%llu)\n", (uint64_t)exceptionInfo.machExceptionData[0], + MachExceptionInfo::GetMachExceptionIdString(exceptionInfo.exceptionType, exceptionInfo.machExceptionData[0]), + (uint64_t)exceptionInfo.machExceptionData[1], (uint64_t)exceptionInfo.machExceptionData[1]); + OVR::OVR_strlcat(exceptionInfo.exceptionDescription, scratchBuffer, OVR_ARRAY_COUNT(exceptionInfo.exceptionDescription)); + #else + // To do. + exceptionInfo.exceptionDescription[0] = 0; + #endif +} + + +void ExceptionHandler::WriteReportLine(const char* pLine) +{ + fwrite(pLine, strlen(pLine), 1, file); +} + + +void ExceptionHandler::WriteReportLineF(const char* format, ...) +{ + va_list args; + va_start(args, format); + int length = OVR_vsnprintf(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), format, args); + if(length >= (int)OVR_ARRAY_COUNT(scratchBuffer)) // If we didn't have enough space... + length = (OVR_ARRAY_COUNT(scratchBuffer) - 1); // ... use what we have. + va_end(args); + + fwrite(scratchBuffer, length, 1, file); +} + + +// Thread +// 0
: +// 1
: +// . . . +// +void ExceptionHandler::WriteThreadCallstack(ThreadHandle threadHandle, ThreadSysId threadSysId, const char* additionalInfo) +{ + // We intentionally do not directly use the SymbolInfo::ReportThreadCallstack function because that function allocates memory, + // which we cannot do due to possibly being within an exception handler. + + // Print the header + char threadName[32]; + char threadHandleStr[32]; + char threadSysIdStr[32]; + char stackBaseStr[24]; + char stackLimitStr[24]; + char stackCurrentStr[24]; + void* pStackBase; + void* pStackLimit; + bool isExceptionThread = (threadSysId == exceptionInfo.threadSysId); + + #if defined(OVR_OS_MS) && (OVR_PTR_SIZE == 8) + void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.Rsp : nullptr; // We would need to suspend the thread, get its context, resume it, then read the rsp register. It turns out we are already doing that suspend/resume below in the backtrace call. + #elif defined(OVR_OS_MS) + void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.Esp : nullptr; + #elif defined(OVR_OS_MAC) && (OVR_PTR_SIZE == 8) + void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.threadState.uts.ts64.__rsp : nullptr; + #elif defined(OVR_OS_MAC) + void* pStackCurrent = (threadSysId == exceptionInfo.threadSysId) ? (void*)exceptionInfo.cpuContext.threadState.uts.ts32.__esp : nullptr; + #elif defined(OVR_OS_LINUX) + void* pStackCurrent = nullptr; // To do. + #endif + + OVR::GetThreadStackBounds(pStackBase, pStackLimit, threadHandle); + + OVR::Thread::GetThreadName(threadName, OVR_ARRAY_COUNT(threadName), threadName); + SprintfThreadHandle(threadHandleStr, OVR_ARRAY_COUNT(threadHandleStr), threadHandle); + SprintfThreadSysId(threadSysIdStr, OVR_ARRAY_COUNT(threadSysIdStr), threadSysId); + SprintfAddress(stackBaseStr, OVR_ARRAY_COUNT(stackBaseStr), pStackBase); + SprintfAddress(stackLimitStr, OVR_ARRAY_COUNT(stackLimitStr), pStackLimit); + SprintfAddress(stackCurrentStr, OVR_ARRAY_COUNT(stackCurrentStr), pStackCurrent); + + if(threadName[0]) + WriteReportLineF("Thread \"%s\" handle: %s, id: %s, stack base: %s, stack limit: %s, stack current: %s, %s\n", threadName, threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr, stackCurrentStr, additionalInfo ? additionalInfo : ""); + else + WriteReportLineF("Thread handle: %s, id: %s, stack base: %s, stack limit: %s, stack current: %s, %s\n", threadHandleStr, threadSysIdStr, stackBaseStr, stackLimitStr, stackCurrentStr, additionalInfo ? additionalInfo : ""); + + // Print the backtrace info + void* addressArray[64]; + size_t addressCount = symbolLookup.GetBacktraceFromThreadSysId(addressArray, OVR_ARRAY_COUNT(addressArray), 0, threadSysId); + SymbolInfo symbolInfo; + const char* pModuleName; + size_t backtraceSkipCount = 0; + + if(isExceptionThread) + { + // If this thread is the exception thread, skip some frames. + #if defined(OVR_OS_MS) + size_t i, iEnd = MIN(16, addressCount); + + for(i = 0; i < iEnd; i++) + { + symbolLookup.LookupSymbol((uint64_t)addressArray[i], symbolInfo); + if(strstr(symbolInfo.function, "UserExceptionDispatcher") != nullptr) + break; + } + + if(i < iEnd) // If found... + backtraceSkipCount = i; + else if(addressCount >= 9) // Else default to 9, which is coincidentally what works. + backtraceSkipCount = 9; + else + backtraceSkipCount = 0; + + addressArray[backtraceSkipCount] = exceptionInfo.pExceptionInstructionAddress; + #endif + } + + if(addressCount == 0) + { + WriteReportLine("\n\n"); + } + else + { + for(size_t i = backtraceSkipCount; i < addressCount; ++i) + { + symbolLookup.LookupSymbol((uint64_t)addressArray[i], symbolInfo); + + if(symbolInfo.pModuleInfo && symbolInfo.pModuleInfo->name[0]) + pModuleName = symbolInfo.pModuleInfo->name; + else + pModuleName = "(unknown module)"; + + char addressStr[24]; + SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), addressArray[i]); + + if(symbolInfo.filePath[0]) + WriteReportLineF("%-2u %-24s %s %s+%d %s:%d\n%s", (unsigned)i, pModuleName, addressStr, + symbolInfo.function, symbolInfo.functionOffset, symbolInfo.filePath, + symbolInfo.fileLineNumber, (i + 1) == addressCount ? "\n" : ""); + else + WriteReportLineF("%-2u %-24s %s %s+%d\n%s", (unsigned)i, pModuleName, addressStr, + symbolInfo.function, symbolInfo.functionOffset, (i + 1) == addressCount ? "\n" : ""); // If this is the last line, append another \n. + } + } +} + + +void ExceptionHandler::WriteReport() +{ + // It's important that we don't allocate any memory here if we can help it. + using namespace OVR; + + if(strstr(reportFilePath, "%s")) // If the user-specified file path includes a date/time component... + { + char dateTimeBuffer[64]; + FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, true); + OVR_snprintf(reportFilePathActual, OVR_ARRAY_COUNT(reportFilePathActual), reportFilePath, dateTimeBuffer); + } + else + { + OVR_strlcpy(reportFilePathActual, reportFilePath, OVR_ARRAY_COUNT(reportFilePathActual)); + } + + file = fopen(reportFilePathActual, "w"); + OVR_ASSERT(file != nullptr); + if(!file) + return; + + SymbolLookup::Initialize(); + + { + // Exception information + WriteReportLine("Exception Info\n"); + + WriteReportLineF("Exception report file: %s\n", reportFilePathActual); + + #if defined(OVR_OS_MS) + if(miniDumpFilePath[0]) + WriteReportLineF("Exception minidump file: %s\n", minidumpFilePathActual); + #endif + + char dateTimeBuffer[64]; + FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, false); + WriteReportLineF("Time (GMT): %s\n", dateTimeBuffer); + + FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.timeVal, true, true, true, false); + WriteReportLineF("Time (local): %s\n", dateTimeBuffer); + WriteReportLineF("Thread name: %s\n", exceptionInfo.threadName[0] ? exceptionInfo.threadName : "(not available)"); // It's never possible on Windows to get thread names, as they are stored in the debugger at runtime. + + SprintfThreadHandle(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.threadHandle); + OVR_strlcat(scratchBuffer, "\n", OVR_ARRAY_COUNT(scratchBuffer)); + WriteReportLine("Thread handle: "); + WriteReportLine(scratchBuffer); + + SprintfThreadSysId(scratchBuffer, OVR_ARRAY_COUNT(scratchBuffer), exceptionInfo.threadSysId); + OVR_strlcat(scratchBuffer, "\n", OVR_ARRAY_COUNT(scratchBuffer)); + WriteReportLine("Thread sys id: "); + WriteReportLine(scratchBuffer); + + char addressStr[24]; + SprintfAddress(addressStr, OVR_ARRAY_COUNT(addressStr), exceptionInfo.pExceptionInstructionAddress); + WriteReportLineF("Exception instruction address: %s (see callstack below)\n", addressStr); + WriteReportLineF("Exception description: %s\n", exceptionInfo.exceptionDescription); + + if (symbolLookup.LookupSymbol((uint64_t)exceptionInfo.pExceptionInstructionAddress, exceptionInfo.symbolInfo)) + { + if(exceptionInfo.symbolInfo.filePath[0]) + WriteReportLineF("Exception location: %s (%d)\n", exceptionInfo.symbolInfo.filePath, exceptionInfo.symbolInfo.fileLineNumber); + else + WriteReportLineF("Exception location: %s (%d)\n", exceptionInfo.symbolInfo.function, exceptionInfo.symbolInfo.functionOffset); + } + + // To consider: print exceptionInfo.cpuContext registers + } + + #if 0 // Disabled while we move this to the Util module or some other location. + /* + // OVR information + WriteReportLine("\nOVR Info\n"); + WriteReportLineF("OVR time: %f\n", ovr_GetTimeInSeconds()); + WriteReportLineF("OVR version: %s\n", ovr_GetVersionString()); + + // OVR util information + // The following would be useful to use if they didn't allocate memory, which we can't do. + // To do: see if we can have versions of the functions below which don't allocate memory + // or allocate it safely (e.g. use an alternative heap). + // String OVR::GetDisplayDriverVersion(); + // String OVR::GetCameraDriverVersion(); + + // OVR HMD information + WriteReportLine("\nOVR HMD Info\n"); + + // XXX rewrite this to use EnumerateHMDStateList() with a callback... + const OVR::List& hmdStateList = OVR::CAPI::HMDState::GetHMDStateList(); + const OVR::CAPI::HMDState* pHMDState = hmdStateList.GetFirst(); + + if(hmdStateList.IsNull(pHMDState)) + { + WriteReportLine("No HMDs found.\n"); + } + + while(!hmdStateList.IsNull(pHMDState)) + { + if(pHMDState->pProfile) + { + const char* user = pHMDState->pProfile->GetValue(OVR_KEY_USER); + + if(user) + WriteReportLineF("Profile user: %s\n", reportPrivacyEnabled ? "" : user); + else + WriteReportLine("Null profile user\n"); + + float NeckEyeDistance[2]; + float EyeToNoseDistance[2]; + float MaxEyeToPlateDist[2]; + pHMDState->pProfile->GetFloatValues(OVR_KEY_NECK_TO_EYE_DISTANCE, NeckEyeDistance, 2); + pHMDState->pProfile->GetFloatValues(OVR_KEY_EYE_TO_NOSE_DISTANCE, EyeToNoseDistance, 2); + pHMDState->pProfile->GetFloatValues(OVR_KEY_MAX_EYE_TO_PLATE_DISTANCE, MaxEyeToPlateDist, 2); + + WriteReportLineF("Player height: %f, eye height: %f, IPD: %f, Neck eye distance: %f,%f, eye relief dial: %d, eye to nose distance: %f,%f, max eye to plate distance: %f,%f, custom eye render: %s\n", + pHMDState->pProfile->GetFloatValue(OVR_KEY_PLAYER_HEIGHT, 0.f), + pHMDState->pProfile->GetFloatValue(OVR_KEY_EYE_HEIGHT, 0.f), + pHMDState->pProfile->GetFloatValue(OVR_KEY_IPD, 0.f), + NeckEyeDistance[0], NeckEyeDistance[1], + pHMDState->pProfile->GetIntValue(OVR_KEY_EYE_RELIEF_DIAL, 0), + EyeToNoseDistance[0], EyeToNoseDistance[1], + MaxEyeToPlateDist[0], MaxEyeToPlateDist[1], + pHMDState->pProfile->GetBoolValue(OVR_KEY_CUSTOM_EYE_RENDER, false) ? "yes" : "no"); + + // Not currently used: + // OVR_KEY_NAME + // OVR_KEY_GENDER + // OVR_KEY_EYE_CUP + // OVR_KEY_CAMERA_POSITION + } + else + { + WriteReportLine("Null HMD profile\n"); + } + + if(pHMDState->pHmdDesc) // This should usually be true. + { + WriteReportLineF("HMD %d: Type: %u ProductName: %s, Manufacturer: %s VendorId: %d, ProductId: %d, SerialNumber: %s, FirmwareMajor: %d, FirmwareMinor: %d, Resolution: %dx%d, DisplayDeviceName: %s, DisplayId: %d\n", + 0, (unsigned)pHMDState->pHmdDesc->Type, pHMDState->pHmdDesc->ProductName, pHMDState->pHmdDesc->Manufacturer, pHMDState->pHmdDesc->VendorId, + pHMDState->pHmdDesc->ProductId, pHMDState->pHmdDesc->SerialNumber, pHMDState->pHmdDesc->FirmwareMajor, pHMDState->pHmdDesc->FirmwareMinor, + pHMDState->pHmdDesc->Resolution.w, pHMDState->pHmdDesc->Resolution.h, pHMDState->pHmdDesc->DisplayDeviceName, pHMDState->pHmdDesc->DisplayId); + + // HSW display state + ovrHSWDisplayState hswDS; + ovrHmd_GetHSWDisplayState(pHMDState->pHmdDesc, &hswDS); + WriteReportLineF("HSW displayed for hmd: %s\n", hswDS.Displayed ? "yes" : "no"); + } + + char threadIdStr[24]; + SprintfAddress(threadIdStr, OVR_ARRAY_COUNT(threadIdStr), pHMDState->BeginFrameThreadId); + + WriteReportLineF("Hmd Caps: %x, Hmd Service Caps: %x, Latency test active: %s, Last frame time: %f, Last get frame time: %f, Rendering configred: %s, Begin frame called: %s, Begin frame thread id: %s\n", + pHMDState->EnabledHmdCaps, pHMDState->EnabledServiceHmdCaps, pHMDState->LatencyTestActive ? "yes" : "no", pHMDState->LastFrameTimeSeconds, pHMDState->LastGetFrameTimeSeconds, pHMDState->RenderingConfigured ? "yes" : "no", + pHMDState->BeginFrameCalled ? "yes" : "no", threadIdStr); + + if(pHMDState->pLastError) + { + WriteReportLineF("OVR last error for hmd: %s\n", pHMDState->pLastError); + } + + pHMDState = hmdStateList.GetNext(pHMDState); + } + */ + #endif // #if 0 + + #if defined(OVR_OS_WIN32) + { + WriteReportLine("\nApp Info\n"); + + // Print the app path. + char appPath[OVR_MAX_PATH]; + GetCurrentProcessFilePath(appPath, OVR_ARRAY_COUNT(appPath)); + WriteReportLineF("Process path: %s\n", appPath); + + #if (OVR_PTR_SIZE == 4) + WriteReportLine("App format: 32 bit\n"); + #else + WriteReportLine("App format: 64 bit\n"); + #endif + + // Print the app version + wchar_t pathW[OVR_MAX_PATH] = {}; + GetModuleFileNameW(0, pathW, (DWORD)OVR_ARRAY_COUNT(pathW)); + DWORD dwUnused; + DWORD dwSize = GetFileVersionInfoSizeW(pathW, &dwUnused); + scratchBuffer[0] = 0; + + if(dwSize > 0) + { + void* const pVersionData = SafeMMapAlloc(dwSize); + + if(pVersionData) + { + if(GetFileVersionInfoW(pathW, 0, dwSize, pVersionData)) + { + VS_FIXEDFILEINFO* pFFI; + UINT size; + + if(VerQueryValueA(pVersionData, "\\", (void**)&pFFI, &size)) + { + WriteReportLineF("App version: %u.%u.%u.%u\n", + HIWORD(pFFI->dwFileVersionMS), LOWORD(pFFI->dwFileVersionMS), + HIWORD(pFFI->dwFileVersionLS), LOWORD(pFFI->dwFileVersionLS)); + } + } + + SafeMMapFree(pVersionData, dwSize); + } + } + + if(!scratchBuffer[0]) // If version info couldn't be found or read... + WriteReportLine("App version info not present\n"); + } + + { + WriteReportLine("\nSystem Info\n"); + + OSVERSIONINFOEXW vi; + memset(&vi, 0, sizeof(vi)); + vi.dwOSVersionInfoSize = sizeof(vi); + GetVersionExW((LPOSVERSIONINFOW)&vi); // Cast to the older type. + + char osVersionName[256]; + GetOSVersionName(osVersionName, OVR_ARRAY_COUNT(osVersionName)); + WriteReportLineF("OS name: %s, version: %u.%u build %u, %s, platform id: %u, service pack: %ls\n", + osVersionName, vi.dwMajorVersion, vi.dwMinorVersion, vi.dwBuildNumber, Is64BitOS() ? "64 bit" : "32 bit", + vi.dwPlatformId, vi.szCSDVersion[0] ? vi.szCSDVersion : L""); + + WriteReportLineF("Debugger present: %s\n", OVRIsDebuggerPresent() ? "yes" : "no"); + + // System info + SYSTEM_INFO systemInfo; + GetNativeSystemInfo(&systemInfo); + + WriteReportLineF("Processor count: %u\n", systemInfo.dwNumberOfProcessors); + + // Windows Vista and later: + // BOOL WINAPI GetLogicalProcessorInformation(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, PDWORD ReturnLength); + + if(systemInfo.wProcessorArchitecture == 0) + WriteReportLineF("Processor type: x86\n"); + else if(systemInfo.wProcessorArchitecture == 9) + WriteReportLineF("Processor type: x86-64\n"); + else if(systemInfo.wProcessorArchitecture == 10) + WriteReportLineF("Processor type: x86 on x86-64\n"); + + WriteReportLineF("Processor level: %u\n", systemInfo.wProcessorLevel); + WriteReportLineF("Processor revision: %u\n", systemInfo.wProcessorRevision); + + // Memory information + MEMORYSTATUSEX memoryStatusEx; + memset(&memoryStatusEx, 0, sizeof(memoryStatusEx)); + memoryStatusEx.dwLength = sizeof(memoryStatusEx); + GlobalMemoryStatusEx(&memoryStatusEx); + + WriteReportLineF("Memory load: %d%%\n", memoryStatusEx.dwMemoryLoad); + WriteReportLineF("Total physical memory: %I64d MiB\n", memoryStatusEx.ullTotalPhys / (1024 * 1024)); // Or are Mebibytes equal to (1024 * 1000) + WriteReportLineF("Available physical memory: %I64d MiB\n", memoryStatusEx.ullAvailPhys / (1024 * 1024)); + WriteReportLineF("Total page file memory: %I64d MiB\n", memoryStatusEx.ullTotalPageFile / (1024 * 1024)); + WriteReportLineF("Available page file memory: %I64d MiB\n", memoryStatusEx.ullAvailPageFile / (1024 * 1024)); + WriteReportLineF("Total virtual memory: %I64d MiB\n", memoryStatusEx.ullTotalVirtual / (1024 * 1024)); + WriteReportLineF("Free virtual memory: %I64d MiB\n", memoryStatusEx.ullAvailVirtual / (1024 * 1024)); + + DISPLAY_DEVICEW dd; + memset(&dd, 0, sizeof(DISPLAY_DEVICE)); + dd.cb = sizeof(DISPLAY_DEVICE); + + for(int i = 0; EnumDisplayDevicesW(nullptr, (DWORD)i, &dd, EDD_GET_DEVICE_INTERFACE_NAME); ++i) + { + WriteReportLineF("Display Device %d name: %ls, context: %ls, primary: %s, mirroring: %s\n", + i, dd.DeviceName, dd.DeviceString, (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) ? "yes" : "no", (dd.StateFlags & DISPLAY_DEVICE_MIRRORING_DRIVER) ? "yes" : "no"); + } + } + + // Print video card information + // http://msdn.microsoft.com/en-us/library/aa394512%28v=vs.85%29.aspx + { + IWbemLocator* pIWbemLocator = nullptr; + BSTR bstrServer = nullptr; + IWbemServices* pIWbemServices = nullptr; + BSTR bstrWQL = nullptr; + BSTR bstrPath = nullptr; + IEnumWbemClassObject* pEnum = nullptr; + + CoInitializeEx(nullptr, COINIT_MULTITHREADED); + + HRESULT hr = CoCreateInstance(__uuidof(WbemLocator), nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator); + if(FAILED(hr)) + goto End; + + bstrServer = SysAllocString(L"\\\\.\\root\\cimv2"); + hr = pIWbemLocator->ConnectServer(bstrServer, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &pIWbemServices); + if(FAILED(hr)) + goto End; + + hr = CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, + RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_DEFAULT); + if(FAILED(hr)) + goto End; + + bstrWQL = SysAllocString(L"WQL"); + bstrPath = SysAllocString(L"select * from Win32_VideoController"); + hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, nullptr, &pEnum); + if(FAILED(hr)) + goto End; + + ULONG uReturned; + IWbemClassObject* pObj = nullptr; + hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned); + if(FAILED(hr)) + goto End; + + WriteReportLine("\nDisplay adapter list\n"); + + for(unsigned i = 0; SUCCEEDED(hr) && uReturned; i++) + { + char sString[256]; + VARIANT var; + + if(i > 0) + WriteReportLine("\n"); + + WriteReportLineF("Info for display adapter %u\n", i); + + hr = pObj->Get(L"Name", 0, &var, nullptr, nullptr); + if(SUCCEEDED(hr)) + { + WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter Name: %s\n", sString); + } + + hr = pObj->Get(L"AdapterRAM", 0, &var, nullptr, nullptr); + if(SUCCEEDED(hr)) + { + WriteReportLineF("Display Adapter RAM: %u %s\n", + ((uint32_t)var.lVal > (1024*1024*1024) ? (uint32_t)var.lVal/(1024*1024*1024) : (uint32_t)var.lVal/(1024*1024)), ((uint32_t)var.lVal > (1024*1024*1024) ? "GiB" : "MiB")); + } + + hr = pObj->Get(L"DeviceID", 0, &var, nullptr, nullptr); + if(SUCCEEDED(hr)) + { + WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter DeviceID: %s\n", sString); + } + + hr = pObj->Get(L"DriverVersion", 0, &var, nullptr, nullptr); + if(SUCCEEDED(hr)) + { + WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter DriverVersion: %s\n", sString); + } + + hr = pObj->Get(L"DriverDate", 0, &var, nullptr, nullptr); + if(SUCCEEDED(hr)) + { + // http://technet.microsoft.com/en-us/library/ee156576.aspx + wchar_t year[5] = { var.bstrVal[0], var.bstrVal[1], var.bstrVal[2], var.bstrVal[3], 0 }; + wchar_t month[3] = { var.bstrVal[4], var.bstrVal[5], 0 }; + wchar_t monthDay[3] = { var.bstrVal[6], var.bstrVal[7], 0 }; + + WriteReportLineF("Display Adapter DriverDate (US format): %ls/%ls/%ls\n", month, monthDay, year); + } + + // VideoProcessor + hr = pObj->Get(L"VideoProcessor", 0, &var, nullptr, nullptr); + if(SUCCEEDED(hr)) + { + WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter VideoProcessor %s\n", sString); + } + + hr = pObj->Get(L"VideoModeDescription", 0, &var, nullptr, nullptr); + if(SUCCEEDED(hr)) + { + WideCharToMultiByte(CP_ACP, 0, var.bstrVal, -1, sString, sizeof(sString), nullptr, nullptr); + WriteReportLineF("Display Adapter VideoModeDescription: %s\n", sString); + } + + pObj->Release(); + + hr = pEnum->Next(WBEM_INFINITE, 1, &pObj, &uReturned); + } + + End: + if(pEnum) + pEnum->Release(); + if(bstrPath) + SysFreeString(bstrPath); + if(bstrWQL) + SysFreeString(bstrWQL); + if(pIWbemServices) + pIWbemServices->Release(); + if(bstrServer) + SysFreeString(bstrServer); + if(pIWbemLocator) + pIWbemLocator->Release(); + + CoUninitialize(); + } + + { + // Print a list of threads. + DWORD currentProcessId = GetCurrentProcessId(); + HANDLE hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, currentProcessId); // ICreateToolhelp32Snapshot actually ignores currentProcessId. + + if(hThreadSnap != INVALID_HANDLE_VALUE) + { + THREADENTRY32 te32; + te32.dwSize = sizeof(THREADENTRY32); + + if(Thread32First(hThreadSnap, &te32)) + { + WriteReportLine("\nThread list\n"); + + do { + if(te32.th32OwnerProcessID == currentProcessId) + { + HANDLE hThread = ConvertThreadSysIdToThreadHandle(te32.th32ThreadID); + + if(hThread) + { + char buffer[96]; // Can't use scratchBuffer, because it's used by WriteThreadCallstack. + OVR_snprintf(buffer, OVR_ARRAY_COUNT(buffer), "base priority: %ld, delta priority: %ld", te32.tpBasePri, te32.tpDeltaPri); + + bool threadIsExceptionThread = (te32.th32ThreadID == (DWORD)exceptionInfo.threadSysId); + if(threadIsExceptionThread) + OVR_strlcat(buffer, ", exception thread", OVR_ARRAY_COUNT(buffer)); + + WriteThreadCallstack(hThread, (OVR::ThreadSysId)te32.th32ThreadID, buffer); + FreeThreadHandle(hThread); + } + } + } while(Thread32Next(hThreadSnap, &te32)); + } + + CloseHandle(hThreadSnap); + } + } + + { + // Print a list of the current modules within this process. + // DbgHelp.dll also provides a EnumerateLoadedModules64 function. + // To do: Convert the code below to use the GetModuleInfoArray function which we now have. + HMODULE hModule = LoadLibraryW(L"psapi.dll"); + + if(hModule) + { + typedef BOOL (WINAPI * ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE* phModule, DWORD cb, LPDWORD lpcbNeeded); + typedef DWORD (WINAPI * GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); + typedef DWORD (WINAPI * GETMODULEFILENAMEEX) (HANDLE hProcess, HMODULE hModule, LPWSTR lpFilename, DWORD nSize); + typedef BOOL (WINAPI * GETMODULEINFORMATION)(HANDLE hProcess, HMODULE hModule, MODULEINFO* pmi, DWORD nSize); + + ENUMPROCESSMODULES pEnumProcessModules = (ENUMPROCESSMODULES) (uintptr_t)GetProcAddress(hModule, "EnumProcessModules"); + GETMODULEBASENAME pGetModuleBaseName = (GETMODULEBASENAME) (uintptr_t)GetProcAddress(hModule, "GetModuleBaseNameW"); + GETMODULEFILENAMEEX pGetModuleFileNameEx = (GETMODULEFILENAMEEX) (uintptr_t)GetProcAddress(hModule, "GetModuleFileNameExW"); + GETMODULEINFORMATION pGetModuleInformation = (GETMODULEINFORMATION)(uintptr_t)GetProcAddress(hModule, "GetModuleInformation"); + + HANDLE hProcess = GetCurrentProcess(); + HMODULE hModuleArray[200]; + DWORD cbNeeded; + + if(pEnumProcessModules(hProcess, hModuleArray, sizeof(hModuleArray), &cbNeeded)) + { + size_t actualModuleCount = (cbNeeded / sizeof(HMODULE)); + + if(actualModuleCount > OVR_ARRAY_COUNT(hModuleArray)) //If hModuleArray's capacity was not enough... + actualModuleCount = OVR_ARRAY_COUNT(hModuleArray); + + // Print a header + WriteReportLine("\nModule list\n"); + + #if (OVR_PTR_SIZE == 4) + WriteReportLine("Base Size Entrypoint Name Path\n"); + #else + WriteReportLine("Base Size Entrypoint Name Path\n"); + #endif + + // And go through the list one by one + for(size_t i = 0; i < actualModuleCount; i++) + { + MODULEINFO mi; + size_t length; + + if(!pGetModuleInformation(hProcess, hModuleArray[i], &mi, sizeof(mi))) + { + mi.EntryPoint = nullptr; + mi.lpBaseOfDll = nullptr; + mi.SizeOfImage = 0; + } + + // Write the base name. + wchar_t name[OVR_MAX_PATH + 3]; + name[0] = '"'; + if(pGetModuleBaseName(hProcess, hModuleArray[i], name + 1, OVR_MAX_PATH)) + length = wcslen(name); + else + { + wcscpy(name + 1, L"(unknown)"); + length = 10; + } + + name[length] = '"'; + name[length + 1] = '\0'; + + // Write the path + wchar_t path[OVR_MAX_PATH + 3]; + path[0] = '"'; + if(pGetModuleFileNameEx(hProcess, hModuleArray[i], path + 1, OVR_MAX_PATH)) + length = wcslen(path); + else + { + wcscpy(path + 1, L"(unknown)"); + length = 10; + } + path[length] = '"'; + path[length + 1] = '\0'; + + #if (OVR_PTR_SIZE == 4) + WriteReportLineF("0x%08x, 0x%08x 0x%08x %-24ls %ls\n", (uint32_t)mi.lpBaseOfDll, (uint32_t)mi.SizeOfImage, (uint32_t)mi.EntryPoint, name, path); + #else + WriteReportLineF("0x%016I64x 0x%016I64x 0x%016I64x %-24ls %ls\n", (uint64_t)mi.lpBaseOfDll, (uint64_t)mi.SizeOfImage, (uint64_t)mi.EntryPoint, name, path); + #endif + } + } + } + } + + { + // Print a list of processes. + // DbgHelp.dll provides a SymEnumProcesses function, but it's available with DbgHelp.dll v6.2 which doesn't ship with Windows until Windows 8. + WriteReportLine("\nProcess list\n"); + + if(reportPrivacyEnabled) + WriteReportLine("Disabled by report privacy settings\n"); + else + { + HANDLE hProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if(hProcessSnapshot != INVALID_HANDLE_VALUE) + { + PROCESSENTRY32W pe32; + memset(&pe32, 0, sizeof(pe32)); + pe32.dwSize = sizeof(pe32); + + if(Process32FirstW(hProcessSnapshot, &pe32)) + { + WriteReportLine("Process Id File\n"); + + do { + // Try to get the full path to the process, as pe32.szExeFile holds only the process file name. + // This will typically fail with a privilege error unless this process has debug privileges: http://support.microsoft.com/kb/131065/en-us + wchar_t filePathW[OVR_MAX_PATH]; + const wchar_t* pFilePathW = pe32.szExeFile; + HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pe32.th32ProcessID); // With Windows Vista+ we can use PROCESS_QUERY_LIMITED_INFORMATION. + if(hProcess) + { + if(GetProcessImageFileNameW(hProcess, filePathW, (DWORD)OVR_ARRAY_COUNT(filePathW))) + pFilePathW = filePathW; + } + + WriteReportLineF("0x%08x %ls\n", pe32.th32ProcessID, pFilePathW); + } while(Process32NextW(hProcessSnapshot, &pe32)); + } + + CloseHandle(hProcessSnapshot); + } + else + { + WriteReportLine("Unable to read process list\n"); + } + } + } + + #elif defined(OVR_OS_APPLE) + + WriteReportLine("\nApp Info\n"); + + // App path + const pid_t processId = getpid(); + WriteReportLineF("Process id: ", "%lld (0x%llx)\n", (int64_t)processId, (int64_t)processId); + + char appPath[PATH_MAX]; + GetCurrentProcessFilePath(appPath, OVR_ARRAY_COUNT(appPath)); + WriteReportLineF("Process path: %s\n", appPath); + + #if (OVR_PTR_SIZE == 4) + WriteReportLine("App format: 32 bit\n"); + #else + WriteReportLine("App format: 64 bit\n"); + #endif + + // App version + // To do. + + // System Info + WriteReportLine("\nSystem Info\n"); + + char osVersionName[256]; + GetOSVersionName(osVersionName, OVR_ARRAY_COUNT(osVersionName)); + WriteReportLineF("OS name: %s, %s\n", osVersionName, Is64BitOS() ? "64 bit" : "32 bit"); + + int name[2]; + int intValue; + size_t length; + char tempBuffer[256]; + + name[0] = CTL_KERN; + name[1] = KERN_OSTYPE; + length = sizeof(tempBuffer); + tempBuffer[0] = 0; + if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) + { + WriteReportLineF("KERN_OSTYPE: %s\n", tempBuffer); + } + + name[0] = CTL_KERN; + name[1] = KERN_OSREV; + length = sizeof(intValue); + intValue = 0; + if(sysctl(name, 2, &intValue, &length, nullptr, 0) == 0) + { + WriteReportLineF("KERN_OSREV: %d\n", intValue); + } + + name[0] = CTL_KERN; + name[1] = KERN_OSRELEASE; + length = sizeof(tempBuffer); + tempBuffer[0] = 0; + if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) + WriteReportLineF("KERN_OSRELEASE: %s\n", tempBuffer); + + name[0] = CTL_HW; + name[1] = HW_MACHINE; + length = sizeof(tempBuffer); + tempBuffer[0] = 0; + if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) + WriteReportLineF("HW_MACHINE: %s\n", tempBuffer); + + name[0] = CTL_HW; + name[1] = HW_MODEL; + length = sizeof(tempBuffer); + tempBuffer[0] = 0; + if(sysctl(name, 2, tempBuffer, &length, nullptr, 0) == 0) + WriteReportLineF("sHW_MODEL: %s\n", tempBuffer); + + name[0] = CTL_HW; + name[1] = HW_NCPU; + length = sizeof(intValue); + intValue = 0; + if(sysctl(name, 2, &intValue, &length, nullptr, 0) == 0) + WriteReportLineF("HW_NCPU: %d\n", intValue); + + length = sizeof(tempBuffer); + tempBuffer[0] = 0; + if(sysctlbyname("machdep.cpu.brand_string", &tempBuffer, &length, nullptr, 0) == 0) + WriteReportLineF("machdep.cpu.brand_string: %s\n", tempBuffer); + + length = sizeof(tempBuffer); + tempBuffer[0] = 0; + if(sysctlbyname("hw.acpi.thermal.tz0.temperature", &tempBuffer, &length, nullptr, 0) == 0) + WriteReportLineF("hw.acpi.thermal.tz0.temperature: %s\n", tempBuffer); + + host_basic_info_data_t hostinfo; + mach_msg_type_number_t count = HOST_BASIC_INFO_COUNT; + kern_return_t kr = host_info(mach_host_self(), HOST_BASIC_INFO, (host_info_t)&hostinfo, &count); + + if(kr == KERN_SUCCESS) + { + const uint64_t memoryMib = (uint64_t)hostinfo.max_mem / (1024 * 1024); + WriteReportLineF("System memory: %lld Mib (%.1f Gib)\n", memoryMib, (double)memoryMib / 1024); + } + + // Video card info + // To do. + + // Thread list + mach_port_t taskSelf = mach_task_self(); + thread_act_port_array_t threadArray; + mach_msg_type_number_t threadCount; + + kern_return_t result = task_threads(taskSelf, &threadArray, &threadCount); + + if(result == KERN_SUCCESS) + { + WriteReportLine("\nThread list\n"); + + for(mach_msg_type_number_t i = 0; i < threadCount; i++) + { + union TBIUnion{ + natural_t words[THREAD_INFO_MAX]; + thread_basic_info tbi; + }; + + TBIUnion tbiUnion; + mach_port_t thread = threadArray[i]; + pthread_t pthread = pthread_from_mach_thread_np(thread); // We assume the thread was created through pthreads. + + char threadState[32] = "unknown"; + mach_msg_type_number_t threadInfoCount = THREAD_INFO_MAX; + result = thread_info(thread, THREAD_BASIC_INFO, (thread_info_t)&tbiUnion, &threadInfoCount); + + if(result == KERN_SUCCESS) + { + const char* state; + + switch (tbiUnion.tbi.run_state) + { + case TH_STATE_HALTED: state = "halted"; break; + case TH_STATE_RUNNING: state = "running"; break; + case TH_STATE_STOPPED: state = "stopped"; break; + case TH_STATE_UNINTERRUPTIBLE: state = "uninterruptible"; break; + case TH_STATE_WAITING: state = "waiting"; break; + default: state = ""; break; + } + + OVR_snprintf(threadState, OVR_ARRAY_COUNT(threadState), "%s", state); + if(tbiUnion.tbi.flags & TH_FLAGS_IDLE) + OVR_strlcat(threadState, ", idle", sizeof(threadState)); + if(tbiUnion.tbi.flags & TH_FLAGS_SWAPPED) + OVR_strlcat(threadState, ", swapped", sizeof(threadState)); + } + + thread_identifier_info threadIdentifierInfo; + memset(&threadIdentifierInfo, 0, sizeof(threadIdentifierInfo)); + + mach_msg_type_number_t threadIdentifierInfoCount = THREAD_IDENTIFIER_INFO_COUNT; + thread_info(thread, THREAD_IDENTIFIER_INFO, (thread_info_t)&threadIdentifierInfo, &threadIdentifierInfoCount); + + proc_threadinfo procThreadInfo; + memset(&procThreadInfo, 0, sizeof(procThreadInfo)); + result = proc_pidinfo(processId, PROC_PIDTHREADINFO, threadIdentifierInfo.thread_handle, &procThreadInfo, sizeof(procThreadInfo)); + OVR_UNUSED(result); + + char buffer[256]; // Can't use scratchBuffer, because it's used by WriteThreadCallstack. + OVR_snprintf(buffer, OVR_ARRAY_COUNT(buffer), "state: %s, suspend count: %d, kernel priority: %d", threadState, (int)tbiUnion.tbi.suspend_count, (int)procThreadInfo.pth_curpri); + + bool threadIsExceptionThread = (thread == exceptionInfo.threadSysId); + if(threadIsExceptionThread) + OVR_strlcat(buffer, ", exception thread", OVR_ARRAY_COUNT(buffer)); + + WriteThreadCallstack(pthread, thread, buffer); + } + + vm_deallocate(taskSelf, (vm_address_t)threadArray, threadCount * sizeof(thread_act_t)); + } + + + WriteReportLine("\nModule list\n"); + + const size_t mifCapacity = 256; + const size_t mifAllocSize = mifCapacity * sizeof(ModuleInfo); + ModuleInfo* moduleInfoArray = (ModuleInfo*)SafeMMapAlloc(mifAllocSize); + + if(moduleInfoArray) + { + #if (OVR_PTR_SIZE == 4) + WriteReportLine("Base Size Name Path\n"); + #else + WriteReportLine("Base Size Name Path\n"); + #endif + + size_t moduleCount = symbolLookup.GetModuleInfoArray(moduleInfoArray, mifCapacity); + if(moduleCount > mifCapacity) + moduleCount = mifCapacity; + + for(size_t i = 0; i < moduleCount; i++) + { + const ModuleInfo& mi = moduleInfoArray[i]; + + #if (OVR_PTR_SIZE == 4) + WriteReportLineF("0x%08x, 0x%08x %-24s %s\n", (uint32_t)mi.baseAddress, (uint32_t)mi.size, mi.name, mi.filePath); + #else + WriteReportLineF("0x%016llx 0x%016llx %-24s %s\n", (uint64_t)mi.baseAddress, (uint64_t)mi.size, mi.name, mi.filePath); + #endif + } + + SafeMMapFree(moduleInfoArray, mifAllocSize); + } + + + WriteReportLine("\nProcess list\n"); + + if(reportPrivacyEnabled) + WriteReportLine("Disabled by report privacy settings\n"); + else + { + WriteReportLine("Process Id File\n"); + + pid_t pidArray[1024]; + int processCount = proc_listpids(PROC_ALL_PIDS, 0, pidArray, sizeof(pidArray)); // Important that we use sizeof not OVR_ARRAY_COUNT. + char processFilePath[PATH_MAX]; + + for(int i = 0; i < processCount; i++) + { + if(proc_pidpath(pidArray[i], processFilePath, sizeof(processFilePath)) > 0) + WriteReportLineF("%-10d %s\n", pidArray[i], processFilePath); + } + + if(!processCount) + WriteReportLine("Unable to read process list\n"); + } + + #elif defined(OVR_OS_UNIX) + Is64BitOS(); + GetCurrentProcessFilePath(nullptr, 0); + GetFileNameFromPath(nullptr); + GetOSVersionName(nullptr, 0); + + #endif // OVR_OS_MS + + SymbolLookup::Shutdown(); + + fclose(file); + file = nullptr; +} + + +void ExceptionHandler::WriteMiniDump() +{ + if(strstr(miniDumpFilePath, "%s")) // If the user-specified file path includes a date/time component... + { + char dateTimeBuffer[64]; + FormatDateTime(dateTimeBuffer, OVR_ARRAY_COUNT(dateTimeBuffer), exceptionInfo.timeVal, true, true, false, true); + OVR_snprintf(minidumpFilePathActual, OVR_ARRAY_COUNT(minidumpFilePathActual), miniDumpFilePath, dateTimeBuffer); + } + else + { + OVR_strlcpy(minidumpFilePathActual, miniDumpFilePath, OVR_ARRAY_COUNT(minidumpFilePathActual)); + } + + #if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + typedef BOOL (WINAPI * MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE dumpType, CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); + HMODULE hModuleDbgHelp = LoadLibraryW(L"DbgHelp.dll"); + + MINIDUMPWRITEDUMP pMiniDumpWriteDump = hModuleDbgHelp ? (MINIDUMPWRITEDUMP)(void*)GetProcAddress(hModuleDbgHelp, "MiniDumpWriteDump") : nullptr; + + if(pMiniDumpWriteDump) + { + wchar_t miniDumpFilePathW[OVR_MAX_PATH]; + OVR::UTF8Util::DecodeString(miniDumpFilePathW, minidumpFilePathActual, -1); // Problem: DecodeString provides no way to specify the destination capacity. + + HANDLE hFile = CreateFileW(miniDumpFilePathW, GENERIC_READ | GENERIC_WRITE, 0, 0, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, 0); + + if(hFile != INVALID_HANDLE_VALUE) + { + MINIDUMP_EXCEPTION_INFORMATION minidumpExceptionInfo = { ::GetCurrentThreadId(), pExceptionPointers, TRUE }; + + BOOL result = pMiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, + (MINIDUMP_TYPE)miniDumpFlags, &minidumpExceptionInfo, + (CONST PMINIDUMP_USER_STREAM_INFORMATION)nullptr, (CONST PMINIDUMP_CALLBACK_INFORMATION)nullptr); + + OVR_ASSERT_AND_UNUSED(result, result); + CloseHandle(hFile); + hFile = 0; + } + else + { + OVR_ASSERT(pMiniDumpWriteDump); // OVR_FAIL_F(("ExceptionHandler::WriteMiniDump: Failed to create minidump file at %s", minidumpFilePathActual)); + } + } + + FreeLibrary(hModuleDbgHelp); + #else + // Some platforms support various forms or exception reports and core dumps which are automatically generated upon us + // returning from our own exception handling. We might want to put something here if we are using a custom version of + // this, such as Google Breakpad. + #endif +} + + +void ExceptionHandler::SetExceptionListener(ExceptionListener* pExceptionListener, uintptr_t userValue) +{ + exceptionListener = pExceptionListener; + exceptionListenerUserValue = userValue; +} + + +void ExceptionHandler::SetAppDescription(const char* pAppDescription) +{ + appDescription = pAppDescription; +} + + +void ExceptionHandler::SetExceptionPaths(const char* exceptionReportPath, const char* exceptionMiniDumpFilePath) +{ + char tempPath[OVR_MAX_PATH]; + + if(exceptionReportPath) + { + if(OVR_stricmp(exceptionReportPath, "default") == 0) + { + GetCrashDumpDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); + OVR::OVR_strlcat(tempPath, "Exception Report (%s).txt", OVR_ARRAY_COUNT(tempPath)); + exceptionReportPath = tempPath; + } + + OVR_strlcpy(reportFilePath, exceptionReportPath, OVR_ARRAY_COUNT(reportFilePath)); + } + else + { + reportFilePath[0] = '\0'; + } + + if(exceptionMiniDumpFilePath) + { + if(OVR_stricmp(exceptionMiniDumpFilePath, "default") == 0) + { + GetCrashDumpDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); + OVR::OVR_strlcat(tempPath, "Exception Minidump (%s).mdmp", OVR_ARRAY_COUNT(tempPath)); + exceptionMiniDumpFilePath = tempPath; + } + + OVR_strlcpy(miniDumpFilePath, exceptionMiniDumpFilePath, OVR_ARRAY_COUNT(miniDumpFilePath)); + } + else + { + miniDumpFilePath[0] = '\0'; + } +} + + +void ExceptionHandler::SetCodeBaseDirectoryPaths(const char* codeBaseDirectoryPathArray[], size_t codeBaseDirectoryPathCount) +{ + for(size_t i = 0, iCount = OVR::Alg::Min(codeBaseDirectoryPathCount, OVR_ARRAY_COUNT(codeBasePathArray)); i != iCount; ++i) + { + codeBasePathArray[i] = codeBaseDirectoryPathArray[i]; + } +} + +const char* ExceptionHandler::GetExceptionUIText(const char* exceptionReportPath) +{ + char* uiText = nullptr; + OVR::SysFile file(exceptionReportPath, SysFile::Open_Read, SysFile::Mode_ReadWrite); + + if(file.IsValid()) + { + size_t length = (size_t)file.GetLength(); + uiText = (char*)OVR::SafeMMapAlloc(length + 1); + + if(uiText) + { + file.Read((uint8_t*)uiText, (int)length); + uiText[length] = '\0'; + file.Close(); + + // Currently on Mac our message box implementation is unable to display arbitrarily large amounts of text. + // So we reduce its size to a more summary version before presenting. + #if defined(OVR_OS_MAC) + struct Find { static char* PreviousChar(char* p, char c){ while(*p != c) p--; return p; } }; // Assumes the given c is present prior to p. + + // Print that the full report is at + // Exception Info section + // Exception thread callstack. + char empty[] = ""; + char* pExceptionInfoBegin = strstr(uiText, "Exception Info") ? strstr(uiText, "Exception Info") : empty; + char* pExceptionInfoEnd = (pExceptionInfoBegin == empty) ? (empty + 1) : strstr(uiText, "\n\n"); + char* pExceptionThreadArea = strstr(uiText, ", exception thread"); + char* pExceptionThreadBegin = pExceptionThreadArea ? Find::PreviousChar(pExceptionThreadArea, '\n') + 1 : empty; + char* pExceptionThreadEnd = (pExceptionThreadBegin == empty) ? (empty + 1) : strstr(pExceptionThreadArea, "\n\n"); + + if(!pExceptionInfoEnd) + pExceptionInfoEnd = pExceptionInfoBegin; + *pExceptionInfoEnd = '\0'; + + if(!pExceptionThreadEnd) + pExceptionThreadEnd = pExceptionThreadBegin; + *pExceptionThreadEnd = '\0'; + + size_t uiTextBriefLength = OVR_snprintf(nullptr, 0, "Full report:%s\n\nSummary report:\n%s\n\n%s", exceptionReportPath, pExceptionInfoBegin, pExceptionThreadBegin); + char* uiTextBrief = (char*)OVR::SafeMMapAlloc(uiTextBriefLength + 1); + + if(uiTextBrief) + { + OVR_snprintf(uiTextBrief, uiTextBriefLength + 1, "Full report:%s\n\nSummary report:\n%s\n\n%s", exceptionReportPath, pExceptionInfoBegin, pExceptionThreadBegin); + OVR::SafeMMapFree(uiText, length); + uiText = uiTextBrief; + } + #endif + } + } + + return uiText; +} + +void ExceptionHandler::FreeExceptionUIText(const char* messageBoxText) +{ + OVR::SafeMMapFree(messageBoxText, OVR_strlen(messageBoxText)); +} + +void ExceptionHandler::ReportDeadlock(const char* threadName, + const char* organizationName, + const char* applicationName) +{ + ExceptionHandler handler; + + if (!organizationName || !organizationName[0] || + !applicationName || !applicationName[0]) + { + char tempPath[OVR_MAX_PATH]; + GetCrashDumpDirectory(tempPath, OVR_ARRAY_COUNT(tempPath)); + OVR_strlcat(tempPath, "Deadlock Report (%s).txt", OVR_ARRAY_COUNT(tempPath)); + handler.SetExceptionPaths(tempPath); + } + else + { + handler.SetPathsFromNames(organizationName, applicationName, "Deadlock Report (%s).txt"); + } + + OVR_snprintf(handler.exceptionInfo.exceptionDescription, + sizeof(handler.exceptionInfo.exceptionDescription), + "Deadlock in thread '%s'", threadName ? threadName : "(null)"); + + handler.exceptionInfo.timeVal = time(nullptr); + handler.exceptionInfo.time = *gmtime(&handler.exceptionInfo.timeVal); + handler.WriteReport(); +} + + +//----------------------------------------------------------------------------- +// GUI Exception Listener + +GUIExceptionListener::GUIExceptionListener() : + Handler() +{ +} + +int GUIExceptionListener::HandleException(uintptr_t userValue, + ExceptionHandler* pExceptionHandler, + ExceptionInfo* pExceptionInfo, + const char* reportFilePath) +{ + OVR_UNUSED3(userValue, pExceptionHandler, pExceptionInfo); + + // If debugger is not present, + if (!OVRIsDebuggerPresent()) + { + const char* uiText = ExceptionHandler::GetExceptionUIText(reportFilePath); + if (uiText) + { + OVR::Util::DisplayMessageBox("Exception occurred", uiText); + ExceptionHandler::FreeExceptionUIText(uiText); + } + } + return 0; +} + + +} // namespace OVR + + +OVR_RESTORE_MSVC_WARNING() diff --git a/LibOVRKernel/Src/Kernel/OVR_DebugHelp.h b/LibOVRKernel/Src/Kernel/OVR_DebugHelp.h new file mode 100644 index 0000000..be104d7 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_DebugHelp.h @@ -0,0 +1,510 @@ +/************************************************************************************ + +Filename : OVR_DebugHelp.h +Content : Platform-independent exception handling interface +Created : October 6, 2014 + +Copyright : Copyright 2014 Oculus VR, LLC. All Rights reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_ExceptionHandler_h +#define OVR_ExceptionHandler_h + +#include "OVR_Types.h" +#include "OVR_String.h" +#include "OVR_Threads.h" +#include "OVR_Atomic.h" +#include "OVR_Nullptr.h" +#include "OVR_System.h" + +#include +#include + +#if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) + #include "OVR_Win32_IncludeWindows.h" +#elif defined(OVR_OS_APPLE) + #include + #include + #include + + extern "C" void* MachHandlerThreadFunctionStatic(void*); + extern "C" int catch_mach_exception_raise_state_identity_OVR(mach_port_t, mach_port_t, mach_port_t, exception_type_t, mach_exception_data_type_t*, + mach_msg_type_number_t, int*, thread_state_t, mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t*); +#elif defined(OVR_OS_LINUX) + #include +#endif + + +OVR_DISABLE_MSVC_WARNING(4351) // new behavior: elements of array will be default initialized + +namespace OVR { + + // Thread identifiers + //typedef void* ThreadHandle; // Already defined by OVR Threads. Same as Windows thread handle, Unix pthread_t. + //typedef void* ThreadId; // Already defined by OVR Threads. Used by Windows as DWORD thread id, by Unix as pthread_t. + typedef uintptr_t ThreadSysId; // System thread identifier. Used by Windows the same as ThreadId (DWORD), thread_act_t on Mac/BSD, lwp id on Linux. + + // Thread constants + // To do: Move to OVR Threads + #define OVR_THREADHANDLE_INVALID ((ThreadHandle*)nullptr) + #define OVR_THREADID_INVALID ((ThreadId*)nullptr) + #define OVR_THREADSYSID_INVALID ((uintptr_t)0) + + OVR::ThreadSysId ConvertThreadHandleToThreadSysId(OVR::ThreadHandle threadHandle); + OVR::ThreadHandle ConvertThreadSysIdToThreadHandle(OVR::ThreadSysId threadSysId); // The returned handle must be freed with FreeThreadHandle. + void FreeThreadHandle(OVR::ThreadHandle threadHandle); // Frees the handle returned by ConvertThreadSysIdToThreadHandle. + OVR::ThreadSysId GetCurrentThreadSysId(); + + // CPUContext + #if defined(OVR_OS_MS) + typedef CONTEXT CPUContext; + #elif defined(OVR_OS_MAC) + struct CPUContext + { + x86_thread_state_t threadState; // This works for both x86 and x64. + x86_float_state_t floatState; + x86_debug_state_t debugState; + x86_avx_state_t avxState; + x86_exception_state exceptionState; + + CPUContext() { memset(this, 0, sizeof(CPUContext)); } + }; + #elif defined(OVR_OS_LINUX) + typedef int CPUContext; // To do. + #endif + + + // Tells if the current process appears to be running under a debugger. Does not attempt to + // detect the case of stealth debuggers (malware-related for example). + bool OVRIsDebuggerPresent(); + + // Exits the process with the given exit code. + #if !defined(OVR_NORETURN) + #if defined(OVR_CC_MSVC) + #define OVR_NORETURN __declspec(noreturn) + #else + #define OVR_NORETURN __attribute__((noreturn)) + #endif + #endif + OVR_NORETURN void ExitProcess(intptr_t processReturnValue); + + // Returns the instruction pointer of the caller for the position right after the call. + OVR_NO_INLINE void GetInstructionPointer(void*& pInstruction); + + // Returns the stack base and limit addresses for the given thread, or for the current thread if the threadHandle is default. + // The stack limit is a value less than the stack base on most platforms, as stacks usually grow downward. + // Some platforms (e.g. Microsoft) have dynamically resizing stacks, in which case the stack limit reflects the current limit. + void GetThreadStackBounds(void*& pStackBase, void*& pStackLimit, ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); + + + // OVR_MAX_PATH + // Max file path length (for most uses). + // To do: move this to OVR_File. + #if !defined(OVR_MAX_PATH) + #if defined(OVR_OS_MS) // http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247%28v=vs.85%29.aspx + #define OVR_MAX_PATH 260 // Windows can use paths longer than this in some cases (network paths, UNC paths). + #else + #define OVR_MAX_PATH 1024 // This isn't a strict limit on all Unix-based platforms. + #endif + #endif + + + // ModuleHandle + #if defined(OVR_OS_MS) + typedef void* ModuleHandle; // from LoadLibrary() + #elif defined(OVR_OS_APPLE) || defined(OVR_OS_UNIX) + typedef void* ModuleHandle; // from dlopen() + #endif + + #define OVR_MODULEHANDLE_INVALID ((ModuleHandle*)nullptr) + + // Module info constants + static const ModuleHandle kMIHandleInvalid = OVR_MODULEHANDLE_INVALID; + static const uint64_t kMIAddressInvalid = 0xffffffffffffffffull; + static const uint64_t kMISizeInvalid = 0xffffffffffffffffull; + static const int32_t kMILineNumberInvalid = -1; + static const int32_t kMIFunctionOffsetInvalid = -1; + static const uint64_t kMIBaseAddressInvalid = 0xffffffffffffffffull; + static const uint64_t kMIBaseAddressUnspecified = 0xffffffffffffffffull; + + struct ModuleInfo + { + ModuleHandle handle; + uint64_t baseAddress; // The actual runtime base address of the module. May be different from the base address specified in the debug symbol file. + uint64_t size; + char filePath[OVR_MAX_PATH]; + char name[32]; + char type[8]; // Unix-specific. e.g. __TEXT + char permissions[8]; // Unix specific. e.g. "drwxr-xr-x" + + ModuleInfo() : handle(kMIHandleInvalid), baseAddress(kMIBaseAddressInvalid), size(0), filePath(), name(){} + }; + + + // Refers to symbol info for an instruction address. + // Info includes function name, source code file/line, and source code itself. + struct SymbolInfo + { + uint64_t address; + uint64_t size; + const ModuleInfo* pModuleInfo; + char filePath[OVR_MAX_PATH]; + int32_t fileLineNumber; + char function[128]; // This is a fixed size because we need to use it during application exceptions. + int32_t functionOffset; + char sourceCode[1024]; // This is a string representing the code itself and not a file path to the code. + + SymbolInfo() : address(kMIAddressInvalid), size(kMISizeInvalid), pModuleInfo(nullptr), filePath(), + fileLineNumber(kMILineNumberInvalid), function(), functionOffset(kMIFunctionOffsetInvalid), sourceCode() {} + }; + + + // Implements support for reading thread lists, module lists, backtraces, and backtrace symbols. + class SymbolLookup + { + public: + SymbolLookup(); + ~SymbolLookup(); + + static bool Initialize(); + static bool IsInitialized(); + static void Shutdown(); + + void AddSourceCodeDirectory(const char* pDirectory); + + // Should be disabled when within an exception handler. + void EnableMemoryAllocation(bool enabled); + + // Refresh our view of the symbols and modules present within the current process. + bool Refresh(); + + // Retrieves the backtrace (call stack) of the given thread. There may be some per-platform restrictions on this. + // Returns the number written, which will be <= addressArrayCapacity. + // This may not work on some platforms unless stack frames are enabled. + // For Microsoft platforms the platformThreadContext is CONTEXT*. + // For Apple platforms the platformThreadContext is x86_thread_state_t* or arm_thread_state_t*. + // If threadSysIdHelp is non-zero, it may be used by the implementation to help produce a better backtrace. + size_t GetBacktrace(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, void* platformThreadContext = nullptr, OVR::ThreadSysId threadSysIdHelp = OVR_THREADSYSID_INVALID); + + // Retrieves the backtrace for the given ThreadHandle. + // Returns the number written, which will be <= addressArrayCapacity. + size_t GetBacktraceFromThreadHandle(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, OVR::ThreadHandle threadHandle = OVR_THREADHANDLE_INVALID); + + // Retrieves the backtrace for the given ThreadSysId. + // Returns the number written, which will be <= addressArrayCapacity. + size_t GetBacktraceFromThreadSysId(void* addressArray[], size_t addressArrayCapacity, size_t skipCount = 0, OVR::ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); + + // Gets a list of the modules (e.g. DLLs) present in the current process. + // Writes as many ModuleInfos as possible to pModuleInfoArray. + // Returns the required count of ModuleInfos, which will be > moduleInfoArrayCapacity if the capacity needs to be larger. + size_t GetModuleInfoArray(ModuleInfo* pModuleInfoArray, size_t moduleInfoArrayCapacity); + + // Retrieves a list of the current threads. Unless the process is paused the list is volatile. + // Returns the required capacity, which may be larger than threadArrayCapacity. + // Either array can be NULL to specify that it's not written to. + // For Windows the caller needs to CloseHandle the returned ThreadHandles. This can be done by calling DoneThreadList. + size_t GetThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCapacity); + + // Frees any references to thread handles or ids returned by GetThreadList; + void DoneThreadList(ThreadHandle* threadHandleArray, ThreadSysId* threadSysIdArray, size_t threadArrayCount); + + // Writes a given thread's callstack with symbols to the given output. + // It may not be safe to call this from an exception handler, as sOutput allocates memory. + bool ReportThreadCallstack(OVR::String& sOutput, size_t skipCount = 0, ThreadSysId threadSysId = OVR_THREADSYSID_INVALID); + + // Writes all thread's callstacks with symbols to the given output. + // It may not be safe to call this from an exception handler, as sOutput allocates memory. + bool ReportThreadCallstacks(OVR::String& sOutput, size_t skipCount = 0); + + // Writes all loaded modules to the given output string. + // It may not be safe to call this from an exception handler, as sOutput allocates memory. + bool ReportModuleInformation(OVR::String& sOutput); + + // Retrieves symbol info for the given address. + bool LookupSymbol(uint64_t address, SymbolInfo& symbolInfo); + bool LookupSymbols(uint64_t* addressArray, SymbolInfo* pSymbolInfoArray, size_t arraySize); + + const ModuleInfo* GetModuleInfoForAddress(uint64_t address); // The returned ModuleInfo points to an internal structure. + + protected: + bool RefreshModuleList(); + + protected: + bool AllowMemoryAllocation; // True by default. If true then we allow allocating memory (and as a result provide less information). This is useful for when in an exception handler. + bool ModuleListUpdated; + ModuleInfo ModuleInfoArray[256]; // Cached list of modules we use. This is a fixed size because we need to use it during application exceptions. + size_t ModuleInfoArraySize; + }; + + + + // ExceptionInfo + // We need to be careful to avoid data types that can allocate memory while we are + // handling an exception, as the memory system may be corrupted at that point in time. + struct ExceptionInfo + { + tm time; // GM time. + time_t timeVal; // GM time_t (seconds since 1970). + void* backtrace[64]; + size_t backtraceCount; + ThreadHandle threadHandle; // + ThreadSysId threadSysId; // + char threadName[32]; // Cannot be an allocating String object. + void* pExceptionInstructionAddress; + void* pExceptionMemoryAddress; + CPUContext cpuContext; + char exceptionDescription[1024]; // Cannot be an allocating String object. + SymbolInfo symbolInfo; // SymbolInfo for the exception location. + + #if defined(OVR_OS_MS) + EXCEPTION_RECORD exceptionRecord; // This is a Windows SDK struct. + #elif defined(OVR_OS_APPLE) + uint64_t exceptionType; // e.g. EXC_BAD_INSTRUCTION, EXC_BAD_ACCESS, etc. + uint32_t cpuExceptionId; // The x86/x64 CPU trap id. + uint32_t cpuExceptionIdError; // The x86/x64 CPU trap id extra info. + int64_t machExceptionData[4]; // Kernel exception code info. + int machExceptionDataCount; // Count of valid entries. + #endif + + ExceptionInfo(); + }; + + // Implments support for asynchronous exception handling and basic exception report generation. + // If you are implementing exception handling for a commercial application and want auto-uploading + // functionality you may want to consider using something like Google Breakpad. This exception handler + // is for in-application debug/diagnostic services, though it can write a report that has similar + // information to Breakpad or OS-provided reports such as Apple .crash files. + // + // Example usage: + // ExceptionHandler exceptionHandler; + // + // int main(int, char**) + // { + // exceptionHandler.Enable(true); + // exceptionHandler.SetExceptionListener(pSomeListener, 0); // Optional listener hook. + // } + // + class ExceptionHandler + { + public: + ExceptionHandler(); + ~ExceptionHandler(); + + // Enables or disables handling by installing or uninstalling an exception handler. + // If you merely want to temporarily pause handling then it may be better to cause PauseHandling, + // as that's a lighter weight solution. + bool Enable(bool enable); + + // Pauses handling. Exceptions will be caught but immediately passed on to the next handler + // without taking any action. Pauses are additive and calls to Pause(true) must be eventually + // matched to Pause(false). This function can be called from multiple threads simultaneously. + // Returns the new pause count. + int PauseHandling(bool pause); + + // Some report info can be considered private information of the user, such as the current process list, + // computer name, IP address or other identifying info, etc. We should not report this information for + // external users unless they agree to this. + void EnableReportPrivacy(bool enable); + + struct ExceptionListener + { + virtual ~ExceptionListener(){} + virtual int HandleException(uintptr_t userValue, ExceptionHandler* pExceptionHandler, ExceptionInfo* pExceptionInfo, const char* reportFilePath) = 0; + }; + + void SetExceptionListener(ExceptionListener* pExceptionListener, uintptr_t userValue); + + // What we do after handling the exception. + enum ExceptionResponse + { + kERContinue, // Continue execution. Will result in the exception being re-generated unless the application has fixed the cause. Similar to Windows EXCEPTION_CONTINUE_EXECUTION. + kERHandle, // Causes the OS to handle the exception as it normally would. Similar to Windows EXCEPTION_EXECUTE_HANDLER. + kERTerminate, // Exit the application. + kERThrow, // Re-throw the exception. Other handlers may catch it. Similar to Windows EXCEPTION_CONTINUE_SEARCH. + kERDefault // Usually set to kERTerminate. + }; + + void SetExceptionResponse(ExceptionResponse er) + { exceptionResponse = er; } + + // Allws you to add an arbitrary description of the current application, which will be added to exception reports. + void SetAppDescription(const char* appDescription); + + // If the report path has a "%s" in its name, then assume the path is a sprintf format and write it + // with the %s specified as a date/time string. + // The report path can be "default" to signify that you want to use the default user location. + // Passing NULL for exceptionReportPath or exceptionMinidumpPath causes those files to not be written. + // By default both the exceptionReportPath and exceptionMinidumpPath are NULL. + // Example usage: + // handler.SetExceptionPaths("/Users/Current/Exceptions/Exception %s.txt"); + void SetExceptionPaths(const char* exceptionReportPath, const char* exceptionMinidumpPath = nullptr); + + // Calls SetExceptionPaths in the appropriate convention for each operating system + // Windows: %AppData%\Organization\Application + // Mac: ~/Library/Logs/DiagnosticReports/Organization/Application" + // Linux: ~/Library/Organization/Application + // exceptionFormat and minidumpFormat define the file names in the format above + // with the %s specified as a date/time string. + void SetPathsFromNames(const char* organizationName, const char* ApplicationName, const char* exceptionFormat = "Exception Report (%s).txt", const char* minidumpFormat = "Exception Minidump (%s).mdmp"); + + // Allows you to specify base directories for code paths, which can be used to associate exception addresses to lines + // of code as opposed to just file names and line numbers, or function names plus binary offsets. + void SetCodeBaseDirectoryPaths(const char* codeBaseDirectoryPathArray[], size_t codeBaseDirectoryPathCount); + + // Writes lines into the current report. + void WriteReportLine(const char* pLine); + void WriteReportLineF(const char* format, ...); + + // Retrieves a directory path which ends with a path separator. + // Returns the required strlen of the path. + // Guarantees the presence of the directory upon returning true. + static size_t GetCrashDumpDirectory(char* directoryPath, size_t directoryPathCapacity); + + // Given an exception report at a given file path, returns a string suitable for displaying in a message + // box or similar user interface during the handling of an exception. The returned string must be passed + // to FreeMessageBoxText when complete. + static const char* GetExceptionUIText(const char* exceptionReportPath); + static void FreeExceptionUIText(const char* messageBoxText); + + // Writes a deadlock report similar to an exception report. Since there is no allocation risk, an exception handler is created for this log. + static void ReportDeadlock(const char* threadName, const char* organizationName = nullptr, const char* applicationName = nullptr); + + protected: + void WriteExceptionDescription(); + void WriteReport(); + void WriteThreadCallstack(ThreadHandle threadHandle, ThreadSysId threadSysId, const char* additionalInfo); + void WriteMiniDump(); + // Runtime constants + bool enabled; + OVR::AtomicInt pauseCount; // 0 means unpaused. 1+ means paused. + bool reportPrivacyEnabled; // Defaults to true. + ExceptionResponse exceptionResponse; // Defaults to kERHandle + ExceptionListener* exceptionListener; + uintptr_t exceptionListenerUserValue; + String appDescription; + String codeBasePathArray[6]; // 6 is arbitrary. + char reportFilePath[OVR_MAX_PATH];// May be an encoded path, in that it has "%s" in it or is named "default". See reporFiletPathActual for the runtime actual report path. + int miniDumpFlags; + char miniDumpFilePath[OVR_MAX_PATH]; + FILE* file; // Can/should we use OVR Files for this? + char scratchBuffer[4096]; + + // Runtime variables + bool exceptionOccurred; + OVR::AtomicInt handlingBusy; + char reportFilePathActual[OVR_MAX_PATH]; + char minidumpFilePathActual[OVR_MAX_PATH]; + int terminateReturnValue; + ExceptionInfo exceptionInfo; + SymbolLookup symbolLookup; + + #if defined(OVR_OS_MS) + void* vectoredHandle; + LPTOP_LEVEL_EXCEPTION_FILTER previousFilter; + LPEXCEPTION_POINTERS pExceptionPointers; + + friend LONG WINAPI Win32ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); + LONG ExceptionFilter(LPEXCEPTION_POINTERS pExceptionPointers); + + //handles exception in a new thread, used for stack overflow + static unsigned WINAPI ExceptionHandlerThreadExec(void * callingHandler); + #elif defined(OVR_OS_APPLE) + struct SavedExceptionPorts + { + SavedExceptionPorts() : count(0) { memset(this, 0, sizeof(SavedExceptionPorts)); } + + mach_msg_type_number_t count; + exception_mask_t masks[6]; + exception_handler_t ports[6]; + exception_behavior_t behaviors[6]; + thread_state_flavor_t flavors[6]; + }; + + friend void* ::MachHandlerThreadFunctionStatic(void*); + friend int ::catch_mach_exception_raise_state_identity_OVR(mach_port_t, mach_port_t, mach_port_t, exception_type_t, + mach_exception_data_type_t*, mach_msg_type_number_t, int*, thread_state_t, + mach_msg_type_number_t, thread_state_t, mach_msg_type_number_t*); + + bool InitMachExceptionHandler(); + void ShutdownMachExceptionHandler(); + void* MachHandlerThreadFunction(); + kern_return_t HandleMachException(mach_port_t port, mach_port_t thread, mach_port_t task, exception_type_t exceptionType, + mach_exception_data_type_t* pExceptionDetail, mach_msg_type_number_t exceptionDetailCount, + int* pFlavor, thread_state_t pOldState, mach_msg_type_number_t oldStateCount, thread_state_t pNewState, + mach_msg_type_number_t* pNewStateCount); + kern_return_t ForwardMachException(mach_port_t thread, mach_port_t task, exception_type_t exceptionType, + mach_exception_data_t pExceptionDetail, mach_msg_type_number_t exceptionDetailCount); + + bool machHandlerInitialized; + mach_port_t machExceptionPort; + SavedExceptionPorts machExceptionPortsSaved; + volatile bool machThreadShouldContinue; + volatile bool machThreadExecuting; + pthread_t machThread; + + #elif defined(OVR_OS_LINUX) + // To do. + #endif + }; + + + // Identifies basic exception types for the CreateException function. + enum CreateExceptionType + { + kCETAccessViolation, // Read or write to inaccessable memory. + kCETAlignment, // Misaligned read or write. + kCETDivideByZero, // Integer divide by zero. + kCETFPU, // Floating point / VPU exception. + kCETIllegalInstruction, // Illegal opcode. + kCETStackCorruption, // Stack frame was corrupted. + kCETStackOverflow, // Stack ran out of space, often due to infinite recursion. + kCETTrap // System/OS trap (system call). + }; + + + // Creates an exception of the given type, primarily for testing. + void CreateException(CreateExceptionType exceptionType); + + + //----------------------------------------------------------------------------- + // GUI Exception Listener + // + // When this exception handler is called, it will verify that the application + // is not being debugged at that instant. If not, then it will present a GUI + // to the user containing error information. + // Initially the exception listener is not silenced. + class GUIExceptionListener : public ExceptionHandler::ExceptionListener + { + public: + GUIExceptionListener(); + + virtual int HandleException(uintptr_t userValue, + ExceptionHandler* pExceptionHandler, + ExceptionInfo* pExceptionInfo, + const char* reportFilePath) OVR_OVERRIDE; + + protected: + ExceptionHandler Handler; + }; + + +} // namespace OVR + + +OVR_RESTORE_MSVC_WARNING() + + +#endif // Header include guard diff --git a/LibOVRKernel/Src/Kernel/OVR_Delegates.h b/LibOVRKernel/Src/Kernel/OVR_Delegates.h new file mode 100644 index 0000000..88948b4 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Delegates.h @@ -0,0 +1,541 @@ +/************************************************************************************ + +Filename : OVR_Delegates.h +Content : C++ Delegates +Created : June 15, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +/* + Based on The Impossibly Fast C++ Delegates by Sergey Ryazanov from + http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx (2005) +*/ + +/* + Usage: + + Declare a delegate with a void (int) signature, also known as a + function that returns void and has one parameter that is an int: + typedef Delegate1 MyDelegate; + MyDelegate d; + + Point the delegate to a member function: + d.SetMember(&a); + d = MyDelegate::FromMember(&a); + + Point the delegate to a const member function: + d.SetConstMember(&c); + d = MyDelegate::FromConstMember(&c); + + Point the delegate to a free function: + d.SetFree<&FreeFunctionX>(); + d = MyDelegate::FromFree<&FreeFunctionX>(); + + Invoke the function via the delegate (works for all 3 cases): + d(1000); + + By default the delegates are uninitialized. + To clear an array of delegates quickly just zero the memory. + + This implementation is nicer than FastDelegates in my opinion + because it is simple and easy to read. It is a little slower + for virtual functions, but the size of the delegate is small, + and it will only get better as compilers improve. +*/ + +#ifndef OVR_Delegates_h +#define OVR_Delegates_h + +#include "OVR_Types.h" + +namespace OVR { + + +template +class Delegate0 +{ + typedef ret_type (*StubPointer)(void *); + typedef Delegate0 this_type; + + void *_object; + StubPointer _stub; + + OVR_FORCE_INLINE Delegate0(void *object, StubPointer stub) + { + _object = object; + _stub = stub; + } + + // Stubs + + template + static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/) + { + return (F)(); + } + + template + static OVR_FORCE_INLINE ret_type MemberStub(void *object) + { + T *p = static_cast(object); + return (p->*F)(); + } + + template + static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object) + { + T *p = static_cast(object); + return (p->*F)(); + } + +public: + OVR_FORCE_INLINE Delegate0() : _object(0), _stub(0){} + + // Function invocation + + OVR_FORCE_INLINE ret_type operator()() const + { + return (*_stub)(_object); + } + + // Use stub pointer as a validity flag and equality checker + + OVR_FORCE_INLINE bool operator==(const this_type &rhs) const + { + return _object == rhs._object && _stub == rhs._stub; + } + + OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const + { + return _object != rhs._object || _stub != rhs._stub; + } + + OVR_FORCE_INLINE bool IsValid() const + { + return _stub != 0; + } + + OVR_FORCE_INLINE bool operator!() const + { + return _stub == 0; + } + + OVR_FORCE_INLINE void Invalidate() + { + _stub = 0; + } + + // Delegate creation from a function + + template + static OVR_FORCE_INLINE this_type FromFree() + { + return this_type(0, &FreeStub); + } + + template + static OVR_FORCE_INLINE this_type FromMember(T *object) + { + return this_type(object, &MemberStub); + } + + template + static OVR_FORCE_INLINE this_type FromConstMember(T const *object) + { + return this_type(const_cast( object ), &ConstMemberStub); + } + + // In-place assignment to a different function + + template + OVR_FORCE_INLINE void SetFree() + { + *this = FromFree(); + } + + template + OVR_FORCE_INLINE void SetMember(T *object) + { + *this = FromMember(object); + } + + template + OVR_FORCE_INLINE void SetConstMember(T const *object) + { + *this = FromConstMember(object); + } +}; + + +template +class Delegate1 +{ + typedef ret_type (*StubPointer)(void *, arg1_type); + typedef Delegate1 this_type; + + void *_object; + StubPointer _stub; + + OVR_FORCE_INLINE Delegate1(void *object, StubPointer stub) + { + _object = object; + _stub = stub; + } + + // Stubs + + template + static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1) + { + return (F)(a1); + } + + template + static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1) + { + T *p = static_cast(object); + return (p->*F)(a1); + } + + template + static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1) + { + T *p = static_cast(object); + return (p->*F)(a1); + } + +public: + OVR_FORCE_INLINE Delegate1() : _object(0), _stub(0){} + + // Function invocation + + OVR_FORCE_INLINE ret_type operator()(arg1_type a1) const + { + return (*_stub)(_object, a1); + } + + // Use stub pointer as a validity flag and equality checker + + OVR_FORCE_INLINE bool operator==(const this_type &rhs) const + { + return _object == rhs._object && _stub == rhs._stub; + } + + OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const + { + return _object != rhs._object || _stub != rhs._stub; + } + + OVR_FORCE_INLINE bool IsValid() const + { + return _stub != 0; + } + + OVR_FORCE_INLINE bool operator!() const + { + return _stub == 0; + } + + OVR_FORCE_INLINE void Invalidate() + { + _stub = 0; + } + + // Delegate creation from a function + + template + static OVR_FORCE_INLINE this_type FromFree() + { + return this_type(0, &FreeStub); + } + + template + static OVR_FORCE_INLINE this_type FromMember(T *object) + { + return this_type(object, &MemberStub); + } + + template + static OVR_FORCE_INLINE this_type FromConstMember(T const *object) + { + return this_type(const_cast( object ), &ConstMemberStub); + } + + // In-place assignment to a different function + + template + OVR_FORCE_INLINE void SetFree() + { + *this = FromFree(); + } + + template + OVR_FORCE_INLINE void SetMember(T *object) + { + *this = FromMember(object); + } + + template + OVR_FORCE_INLINE void SetConstMember(T const *object) + { + *this = FromConstMember(object); + } +}; + + +template +class Delegate2 +{ + typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type); + typedef Delegate2 this_type; + + void *_object; + StubPointer _stub; + + OVR_FORCE_INLINE Delegate2(void *object, StubPointer stub) + { + _object = object; + _stub = stub; + } + + // Stubs + + template + static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2) + { + return (F)(a1, a2); + } + + template + static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2) + { + T *p = static_cast(object); + return (p->*F)(a1, a2); + } + + template + static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2) + { + T *p = static_cast(object); + return (p->*F)(a1, a2); + } + +public: + OVR_FORCE_INLINE Delegate2() : _object(0), _stub(0){} + + // Function invocation + + OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2) const + { + return (*_stub)(_object, a1, a2); + } + + // Use stub pointer as a validity flag and equality checker + + OVR_FORCE_INLINE bool operator==(const this_type &rhs) const + { + return _object == rhs._object && _stub == rhs._stub; + } + + OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const + { + return _object != rhs._object || _stub != rhs._stub; + } + + OVR_FORCE_INLINE bool IsValid() const + { + return _stub != 0; + } + + OVR_FORCE_INLINE bool operator!() const + { + return _stub == 0; + } + + OVR_FORCE_INLINE void Invalidate() + { + _stub = 0; + } + + // Delegate creation from a function + + template + static OVR_FORCE_INLINE this_type FromFree() + { + return this_type(0, &FreeStub); + } + + template + static OVR_FORCE_INLINE this_type FromMember(T *object) + { + return this_type(object, &MemberStub); + } + + template + static OVR_FORCE_INLINE this_type FromConstMember(T const *object) + { + return this_type(const_cast( object ), &ConstMemberStub); + } + + // In-place assignment to a different function + + template + OVR_FORCE_INLINE void SetFree() + { + *this = FromFree(); + } + + template + OVR_FORCE_INLINE void SetMember(T *object) + { + *this = FromMember(object); + } + + template + OVR_FORCE_INLINE void SetConstMember(T const *object) + { + *this = FromConstMember(object); + } +}; + + +template +class Delegate3 +{ + typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type, arg3_type); + typedef Delegate3 this_type; + + void *_object; + StubPointer _stub; + + OVR_FORCE_INLINE Delegate3(void *object, StubPointer stub) + { + _object = object; + _stub = stub; + } + + // Stubs + + template + static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2, arg3_type a3) + { + return (F)(a1, a2, a3); + } + + template + static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3) + { + T *p = static_cast(object); + return (p->*F)(a1, a2, a3); + } + + template + static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3) + { + T *p = static_cast(object); + return (p->*F)(a1, a2, a3); + } + +public: + OVR_FORCE_INLINE Delegate3() : _object(0), _stub(0){} + + // Function invocation + + OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2, arg3_type a3) const + { + return (*_stub)(_object, a1, a2, a3); + } + + // Use stub pointer as a validity flag and equality checker + + OVR_FORCE_INLINE bool operator==(const this_type &rhs) const + { + return _object == rhs._object && _stub == rhs._stub; + } + + OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const + { + return _object != rhs._object || _stub != rhs._stub; + } + + OVR_FORCE_INLINE bool IsValid() const + { + return _stub != 0; + } + + OVR_FORCE_INLINE bool operator!() const + { + return _stub == 0; + } + + OVR_FORCE_INLINE void Invalidate() + { + _stub = 0; + } + + // Delegate creation from a function + + template + static OVR_FORCE_INLINE this_type FromFree() + { + return this_type(0, &FreeStub); + } + + template + static OVR_FORCE_INLINE this_type FromMember(T *object) + { + return this_type(object, &MemberStub); + } + + template + static OVR_FORCE_INLINE this_type FromConstMember(T const *object) + { + return this_type(const_cast( object ), &ConstMemberStub); + } + + // In-place assignment to a different function + + template + OVR_FORCE_INLINE void SetFree() + { + *this = FromFree(); + } + + template + OVR_FORCE_INLINE void SetMember(T *object) + { + *this = FromMember(object); + } + + template + OVR_FORCE_INLINE void SetConstMember(T const *object) + { + *this = FromConstMember(object); + } +}; + +// Add more here if needed, but keep in mind that a short, simple interface +// is rewarded by making the delegates faster... + + +} // namespace OVR + +#endif // OVR_Delegates_h diff --git a/LibOVRKernel/Src/Kernel/OVR_Deque.h b/LibOVRKernel/Src/Kernel/OVR_Deque.h new file mode 100644 index 0000000..951ed84 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Deque.h @@ -0,0 +1,316 @@ +/************************************************************************************ + +Filename : OVR_Deque.h +Content : Deque container +Created : Nov. 15, 2013 +Authors : Dov Katz + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Deque_h +#define OVR_Deque_h + +#include "OVR_ContainerAllocator.h" + +namespace OVR{ + +template > +class Deque +{ +public: + enum + { + DefaultCapacity = 500 + }; + + Deque(int capacity = DefaultCapacity); + virtual ~Deque(void); + + virtual void PushBack (const Elem &Item); // Adds Item to the end + virtual void PushFront (const Elem &Item); // Adds Item to the beginning + virtual Elem PopBack (void); // Removes Item from the end + virtual Elem PopFront (void); // Removes Item from the beginning + virtual const Elem& PeekBack (int count = 0) const; // Returns count-th Item from the end + virtual const Elem& PeekFront (int count = 0) const; // Returns count-th Item from the beginning + + virtual inline size_t GetSize (void) const; // Returns Number of Elements + OVR_FORCE_INLINE int GetSizeI (void) const + { + return (int)GetSize(); + } + virtual inline size_t GetCapacity(void) const; // Returns the maximum possible number of elements + virtual void Clear (void); // Remove all elements + virtual inline bool IsEmpty () const; + virtual inline bool IsFull () const; + +protected: + Elem *Data; // The actual Data array + const int Capacity; // Deque capacity + int Beginning; // Index of the first element + int End; // Index of the next after last element + + // Instead of calculating the number of elements, using this variable + // is much more convenient. + int ElemCount; + +private: + OVR_NON_COPYABLE(Deque); +}; + +template > +class InPlaceMutableDeque : public Deque +{ + typedef Deque BaseType; + +public: + InPlaceMutableDeque( int capacity = BaseType::DefaultCapacity ) : BaseType( capacity ) {} + virtual ~InPlaceMutableDeque() {}; + + using BaseType::PeekBack; + using BaseType::PeekFront; + virtual Elem& PeekBack (int count = 0); // Returns count-th Item from the end + virtual Elem& PeekFront (int count = 0); // Returns count-th Item from the beginning +}; + +// Same as Deque, but allows to write more elements than maximum capacity +// Old elements are lost as they are overwritten with the new ones +template > +class CircularBuffer : public InPlaceMutableDeque +{ + typedef InPlaceMutableDeque BaseType; + +public: + CircularBuffer(int MaxSize = BaseType::DefaultCapacity) : BaseType(MaxSize) { }; + virtual ~CircularBuffer(){} + + // The following methods are inline as a workaround for a VS bug causing erroneous C4505 warnings + // See: http://stackoverflow.com/questions/3051992/compiler-warning-at-c-template-base-class + inline virtual void PushBack (const Elem &Item); // Adds Item to the end, overwriting the oldest element at the beginning if necessary + inline virtual void PushFront (const Elem &Item); // Adds Item to the beginning, overwriting the oldest element at the end if necessary +}; + +//---------------------------------------------------------------------------------- + +// Deque Constructor function +template +Deque::Deque(int capacity) : +Capacity( capacity ), Beginning(0), End(0), ElemCount(0) +{ + Data = (Elem*) Allocator::Alloc(Capacity * sizeof(Elem)); +} + +// Deque Destructor function +template +Deque::~Deque(void) +{ + Clear(); + Allocator::Free(Data); +} + +template +void Deque::Clear() +{ + if (!IsEmpty()) + { + if (Beginning < End) + { + // no wrap-around + Allocator::DestructArray(Data + Beginning, End - Beginning); + } + else + { + // wrap-around + Allocator::DestructArray(Data + Beginning, Capacity - Beginning); + Allocator::DestructArray(Data, End); + } + } + + Beginning = 0; + End = 0; + ElemCount = 0; +} + +// Push functions +template +void Deque::PushBack(const Elem &Item) +{ + // Error Check: Make sure we aren't + // exceeding our maximum storage space + OVR_ASSERT( ElemCount < Capacity ); + + Allocator::Construct(Data + End, Item); + ++End; + ++ElemCount; + + // Check for wrap-around + if (End >= Capacity) + End -= Capacity; +} + +template +void Deque::PushFront(const Elem &Item) +{ + // Error Check: Make sure we aren't + // exceeding our maximum storage space + OVR_ASSERT( ElemCount < Capacity ); + + --Beginning; + // Check for wrap-around + if (Beginning < 0) + Beginning += Capacity; + + Allocator::Construct(Data + Beginning, Item); + ++ElemCount; +} + +// Pop functions +template +Elem Deque::PopFront(void) +{ + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT( ElemCount > 0 ); + + Elem ReturnValue = Data[ Beginning ]; + Allocator::Destruct(Data + Beginning); + + ++Beginning; + --ElemCount; + + // Check for wrap-around + if (Beginning >= Capacity) + Beginning -= Capacity; + + return ReturnValue; +} + +template +Elem Deque::PopBack(void) +{ + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT( ElemCount > 0 ); + + --End; + --ElemCount; + + // Check for wrap-around + if (End < 0) + End += Capacity; + + Elem ReturnValue = Data[ End ]; + Allocator::Destruct(Data + End); + + return ReturnValue; +} + +// Peek functions +template +const Elem& Deque::PeekFront(int count) const +{ + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT( ElemCount > count ); + + int idx = Beginning + count; + if (idx >= Capacity) + idx -= Capacity; + return Data[ idx ]; +} + +template +const Elem& Deque::PeekBack(int count) const +{ + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT( ElemCount > count ); + + int idx = End - count - 1; + if (idx < 0) + idx += Capacity; + return Data[ idx ]; +} + +// Mutable Peek functions +template +Elem& InPlaceMutableDeque::PeekFront(int count) +{ + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT( BaseType::ElemCount > count ); + + int idx = BaseType::Beginning + count; + if (idx >= BaseType::Capacity) + idx -= BaseType::Capacity; + return BaseType::Data[ idx ]; +} + +template +Elem& InPlaceMutableDeque::PeekBack(int count) +{ + // Error Check: Make sure we aren't reading from an empty Deque + OVR_ASSERT( BaseType::ElemCount > count ); + + int idx = BaseType::End - count - 1; + if (idx < 0) + idx += BaseType::Capacity; + return BaseType::Data[ idx ]; +} + +template +inline size_t Deque::GetCapacity(void) const +{ + return Capacity; +} + +template +inline size_t Deque::GetSize(void) const +{ + return ElemCount; +} + +template +inline bool Deque::IsEmpty(void) const +{ + return ElemCount == 0; +} + +template +inline bool Deque::IsFull(void) const +{ + return ElemCount == Capacity; +} + +// ******* CircularBuffer ******* +// Push functions +template +void CircularBuffer::PushBack(const Elem &Item) +{ + if (this->IsFull()) + this->PopFront(); + BaseType::PushBack(Item); +} + +template +void CircularBuffer::PushFront(const Elem &Item) +{ + if (this->IsFull()) + this->PopBack(); + BaseType::PushFront(Item); +} + +}; + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_File.cpp b/LibOVRKernel/Src/Kernel/OVR_File.cpp new file mode 100644 index 0000000..c431928 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_File.cpp @@ -0,0 +1,585 @@ +/************************************************************************** + +Filename : OVR_File.cpp +Content : File wrapper class implementation (Win32) + +Created : April 5, 1999 +Authors : Michael Antonov + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +**************************************************************************/ + +#define GFILE_CXX + +// Standard C library (Captain Obvious guarantees!) +#include + +#include "OVR_File.h" + +namespace OVR { + +// Buffered file adds buffering to an existing file +// FILEBUFFER_SIZE defines the size of internal buffer, while +// FILEBUFFER_TOLERANCE controls the amount of data we'll effectively try to buffer +#define FILEBUFFER_SIZE (8192-8) +#define FILEBUFFER_TOLERANCE 4096 + +// ** Constructor/Destructor + +// Hidden constructor +// Not supposed to be used +BufferedFile::BufferedFile() : DelegatedFile(0) +{ + pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); + BufferMode = NoBuffer; + FilePos = 0; + Pos = 0; + DataSize = 0; +} + +// Takes another file as source +BufferedFile::BufferedFile(File *pfile) : DelegatedFile(pfile) +{ + pBuffer = (uint8_t*)OVR_ALLOC(FILEBUFFER_SIZE); + BufferMode = NoBuffer; + FilePos = pfile->LTell(); + Pos = 0; + DataSize = 0; +} + + +// Destructor +BufferedFile::~BufferedFile() +{ + // Flush in case there's data + if (pFile) + FlushBuffer(); + // Get rid of buffer + if (pBuffer) + OVR_FREE(pBuffer); +} + +/* +bool BufferedFile::VCopy(const Object &source) +{ + if (!DelegatedFile::VCopy(source)) + return 0; + + // Data members + BufferedFile *psource = (BufferedFile*)&source; + + // Buffer & the mode it's in + pBuffer = psource->pBuffer; + BufferMode = psource->BufferMode; + Pos = psource->Pos; + DataSize = psource->DataSize; + return 1; +} +*/ + +// Initializes buffering to a certain mode +bool BufferedFile::SetBufferMode(BufferModeType mode) +{ + if (!pBuffer) + return false; + if (mode == BufferMode) + return true; + + FlushBuffer(); + + // Can't set write mode if we can't write + if ((mode==WriteBuffer) && (!pFile || !pFile->IsWritable()) ) + return 0; + + // And SetMode + BufferMode = mode; + Pos = 0; + DataSize = 0; + return 1; +} + +// Flushes buffer +void BufferedFile::FlushBuffer() +{ + switch(BufferMode) + { + case WriteBuffer: + // Write data in buffer + FilePos += pFile->Write(pBuffer,Pos); + Pos = 0; + break; + + case ReadBuffer: + // Seek back & reset buffer data + if ((DataSize-Pos)>0) + FilePos = pFile->LSeek(-(int)(DataSize-Pos), Seek_Cur); + DataSize = 0; + Pos = 0; + break; + default: + // not handled! + break; + } +} + +// Reloads data for ReadBuffer +void BufferedFile::LoadBuffer() +{ + if (BufferMode == ReadBuffer) + { + // We should only reload once all of pre-loaded buffer is consumed. + OVR_ASSERT(Pos == DataSize); + + // WARNING: Right now LoadBuffer() assumes the buffer's empty + int sz = pFile->Read(pBuffer,FILEBUFFER_SIZE); + DataSize = sz<0 ? 0 : (unsigned)sz; + Pos = 0; + FilePos += DataSize; + } +} + + +// ** Overridden functions + +// We override all the functions that can possibly +// require buffer mode switch, flush, or extra calculations + +// Tell() requires buffer adjustment +int BufferedFile::Tell() +{ + if (BufferMode == ReadBuffer) + return int (FilePos - DataSize + Pos); + + int pos = pFile->Tell(); + // Adjust position based on buffer mode & data + if (pos!=-1) + { + OVR_ASSERT(BufferMode != ReadBuffer); + if (BufferMode == WriteBuffer) + pos += Pos; + } + return pos; +} + +int64_t BufferedFile::LTell() +{ + if (BufferMode == ReadBuffer) + return FilePos - DataSize + Pos; + + int64_t pos = pFile->LTell(); + if (pos!=-1) + { + OVR_ASSERT(BufferMode != ReadBuffer); + if (BufferMode == WriteBuffer) + pos += Pos; + } + return pos; +} + +int BufferedFile::GetLength() +{ + int len = pFile->GetLength(); + // If writing through buffer, file length may actually be bigger + if ((len!=-1) && (BufferMode==WriteBuffer)) + { + int currPos = pFile->Tell() + Pos; + if (currPos>len) + len = currPos; + } + return len; +} +int64_t BufferedFile::LGetLength() +{ + int64_t len = pFile->LGetLength(); + // If writing through buffer, file length may actually be bigger + if ((len!=-1) && (BufferMode==WriteBuffer)) + { + int64_t currPos = pFile->LTell() + Pos; + if (currPos>len) + len = currPos; + } + return len; +} + +/* +bool BufferedFile::Stat(FileStats *pfs) +{ + // Have to fix up length is stat + if (pFile->Stat(pfs)) + { + if (BufferMode==WriteBuffer) + { + int64_t currPos = pFile->LTell() + Pos; + if (currPos > pfs->Size) + { + pfs->Size = currPos; + // ?? + pfs->Blocks = (pfs->Size+511) >> 9; + } + } + return 1; + } + return 0; +} +*/ + +int BufferedFile::Write(const uint8_t *psourceBuffer, int numBytes) +{ + if ( (BufferMode==WriteBuffer) || SetBufferMode(WriteBuffer)) + { + // If not data space in buffer, flush + if ((FILEBUFFER_SIZE-(int)Pos)FILEBUFFER_TOLERANCE) + { + int sz = pFile->Write(psourceBuffer,numBytes); + if (sz > 0) + FilePos += sz; + return sz; + } + } + + // Enough space in buffer.. so copy to it + memcpy(pBuffer+Pos, psourceBuffer, numBytes); + Pos += numBytes; + return numBytes; + } + int sz = pFile->Write(psourceBuffer,numBytes); + if (sz > 0) + FilePos += sz; + return sz; +} + +int BufferedFile::Read(uint8_t *pdestBuffer, int numBytes) +{ + if ( (BufferMode==ReadBuffer) || SetBufferMode(ReadBuffer)) + { + // Data in buffer... copy it + if ((int)(DataSize-Pos) >= numBytes) + { + memcpy(pdestBuffer, pBuffer+Pos, numBytes); + Pos += numBytes; + return numBytes; + } + + // Not enough data in buffer, copy buffer + int readBytes = DataSize-Pos; + memcpy(pdestBuffer, pBuffer+Pos, readBytes); + numBytes -= readBytes; + pdestBuffer += readBytes; + Pos = DataSize; + + // Don't reload buffer if more then tolerance + // (No major advantage, and we don't want to write a loop) + if (numBytes>FILEBUFFER_TOLERANCE) + { + numBytes = pFile->Read(pdestBuffer,numBytes); + if (numBytes > 0) + { + FilePos += numBytes; + Pos = DataSize = 0; + } + return readBytes + ((numBytes==-1) ? 0 : numBytes); + } + + // Reload the buffer + // WARNING: Right now LoadBuffer() assumes the buffer's empty + LoadBuffer(); + if ((int)(DataSize-Pos) < numBytes) + numBytes = (int)DataSize-Pos; + + memcpy(pdestBuffer, pBuffer+Pos, numBytes); + Pos += numBytes; + return numBytes + readBytes; + + /* + // Alternative Read implementation. The one above is probably better + // due to FILEBUFFER_TOLERANCE. + int total = 0; + + do { + int bufferBytes = (int)(DataSize-Pos); + int copyBytes = (bufferBytes > numBytes) ? numBytes : bufferBytes; + + memcpy(pdestBuffer, pBuffer+Pos, copyBytes); + numBytes -= copyBytes; + pdestBuffer += copyBytes; + Pos += copyBytes; + total += copyBytes; + + if (numBytes == 0) + break; + LoadBuffer(); + + } while (DataSize > 0); + + return total; + */ + } + int sz = pFile->Read(pdestBuffer,numBytes); + if (sz > 0) + FilePos += sz; + return sz; +} + + +int BufferedFile::SkipBytes(int numBytes) +{ + int skippedBytes = 0; + + // Special case for skipping a little data in read buffer + if (BufferMode==ReadBuffer) + { + skippedBytes = (((int)DataSize-(int)Pos) >= numBytes) ? numBytes : (DataSize-Pos); + Pos += skippedBytes; + numBytes -= skippedBytes; + } + + if (numBytes) + { + numBytes = pFile->SkipBytes(numBytes); + // Make sure we return the actual number skipped, or error + if (numBytes!=-1) + { + skippedBytes += numBytes; + FilePos += numBytes; + Pos = DataSize = 0; + } + else if (skippedBytes <= 0) + skippedBytes = -1; + } + return skippedBytes; +} + +int BufferedFile::BytesAvailable() +{ + int available = pFile->BytesAvailable(); + // Adjust available size based on buffers + switch(BufferMode) + { + case ReadBuffer: + available += DataSize-Pos; + break; + case WriteBuffer: + available -= Pos; + if (available<0) + available= 0; + break; + default: + break; + } + return available; +} + +bool BufferedFile::Flush() +{ + FlushBuffer(); + return pFile->Flush(); +} + +// Seeking could be optimized better.. +int BufferedFile::Seek(int offset, int origin) +{ + if (BufferMode == ReadBuffer) + { + if (origin == Seek_Cur) + { + // Seek can fall either before or after Pos in the buffer, + // but it must be within bounds. + if (((unsigned(offset) + Pos)) <= DataSize) + { + Pos += offset; + return int (FilePos - DataSize + Pos); + } + + // Lightweight buffer "Flush". We do this to avoid an extra seek + // back operation which would take place if we called FlushBuffer directly. + origin = Seek_Set; + OVR_ASSERT(((FilePos - DataSize + Pos) + (uint64_t)offset) < ~(uint64_t)0); + offset = (int)(FilePos - DataSize + Pos) + offset; + Pos = DataSize = 0; + } + else if (origin == Seek_Set) + { + if (((unsigned)offset - (FilePos-DataSize)) <= DataSize) + { + OVR_ASSERT((FilePos-DataSize) < ~(uint64_t)0); + Pos = (unsigned)offset - (unsigned)(FilePos-DataSize); + return offset; + } + Pos = DataSize = 0; + } + else + { + FlushBuffer(); + } + } + else + { + FlushBuffer(); + } + + /* + // Old Seek Logic + if (origin == Seek_Cur && offset + Pos < DataSize) + { + //OVR_ASSERT((FilePos - DataSize) >= (FilePos - DataSize + Pos + offset)); + Pos += offset; + OVR_ASSERT(int (Pos) >= 0); + return int (FilePos - DataSize + Pos); + } + else if (origin == Seek_Set && unsigned(offset) >= FilePos - DataSize && unsigned(offset) < FilePos) + { + Pos = unsigned(offset - FilePos + DataSize); + OVR_ASSERT(int (Pos) >= 0); + return int (FilePos - DataSize + Pos); + } + + FlushBuffer(); + */ + + + FilePos = pFile->Seek(offset,origin); + return int (FilePos); +} + +int64_t BufferedFile::LSeek(int64_t offset, int origin) +{ + if (BufferMode == ReadBuffer) + { + if (origin == Seek_Cur) + { + // Seek can fall either before or after Pos in the buffer, + // but it must be within bounds. + if (((unsigned(offset) + Pos)) <= DataSize) + { + Pos += (unsigned)offset; + return int64_t(FilePos - DataSize + Pos); + } + + // Lightweight buffer "Flush". We do this to avoid an extra seek + // back operation which would take place if we called FlushBuffer directly. + origin = Seek_Set; + offset = (int64_t)(FilePos - DataSize + Pos) + offset; + Pos = DataSize = 0; + } + else if (origin == Seek_Set) + { + if (((uint64_t)offset - (FilePos-DataSize)) <= DataSize) + { + Pos = (unsigned)((uint64_t)offset - (FilePos-DataSize)); + return offset; + } + Pos = DataSize = 0; + } + else + { + FlushBuffer(); + } + } + else + { + FlushBuffer(); + } + +/* + OVR_ASSERT(BufferMode != NoBuffer); + + if (origin == Seek_Cur && offset + Pos < DataSize) + { + Pos += int (offset); + return FilePos - DataSize + Pos; + } + else if (origin == Seek_Set && offset >= int64_t(FilePos - DataSize) && offset < int64_t(FilePos)) + { + Pos = unsigned(offset - FilePos + DataSize); + return FilePos - DataSize + Pos; + } + + FlushBuffer(); + */ + + FilePos = pFile->LSeek(offset,origin); + return FilePos; +} + +int BufferedFile::CopyFromStream(File *pstream, int byteSize) +{ + // We can't rely on overridden Write() + // because delegation doesn't override virtual pointers + // So, just re-implement + uint8_t* buff = new uint8_t[0x4000]; + int count = 0; + int szRequest, szRead, szWritten; + + while(byteSize) + { + szRequest = (byteSize > int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; + + szRead = pstream->Read(buff,szRequest); + szWritten = 0; + if (szRead > 0) + szWritten = Write(buff,szRead); + + count +=szWritten; + byteSize-=szWritten; + if (szWritten < szRequest) + break; + } + + delete[] buff; + + return count; +} + +// Closing files +bool BufferedFile::Close() +{ + switch(BufferMode) + { + case WriteBuffer: + FlushBuffer(); + break; + case ReadBuffer: + // No need to seek back on close + BufferMode = NoBuffer; + break; + default: + break; + } + return pFile->Close(); +} + + +// ***** Global path helpers + +// Find trailing short filename in a path. +const char* OVR_CDECL GetShortFilename(const char* purl) +{ + size_t len = OVR_strlen(purl); + for (size_t i=len; i>0; i--) + if (purl[i]=='\\' || purl[i]=='/') + return purl+i+1; + return purl; +} + +} // OVR + diff --git a/LibOVRKernel/Src/Kernel/OVR_File.h b/LibOVRKernel/Src/Kernel/OVR_File.h new file mode 100644 index 0000000..d9d3b0f --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_File.h @@ -0,0 +1,530 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_File.h +Content : Header for all internal file management - functions and structures + to be inherited by OS specific subclasses. +Created : September 19, 2012 +Notes : + +Notes : errno may not be preserved across use of BaseFile member functions + : Directories cannot be deleted while files opened from them are in use + (For the GetFullName function) + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_File_h +#define OVR_File_h + +#include "OVR_RefCount.h" +#include "OVR_Std.h" +#include "OVR_Alg.h" + +#include +#include "OVR_String.h" + +namespace OVR { + +// ***** Declared classes +class FileConstants; +class File; +class DelegatedFile; +class BufferedFile; + + +// ***** Flags for File & Directory accesses + +class FileConstants +{ +public: + + // *** File open flags + enum OpenFlags + { + Open_Read = 1, + Open_Write = 2, + Open_ReadWrite = 3, + + // Opens file and truncates it to zero length + // - file must have write permission + // - when used with Create, it opens an existing + // file and empties it or creates a new file + Open_Truncate = 4, + + // Creates and opens new file + // - does not erase contents if file already + // exists unless combined with Truncate + Open_Create = 8, + + // Returns an error value if the file already exists + Open_CreateOnly = 24, + + // Open file with buffering + Open_Buffered = 32 + }; + + // *** File Mode flags + enum Modes + { + Mode_Read = 0444, + Mode_Write = 0222, + Mode_Execute = 0111, + + Mode_ReadWrite = 0666 + }; + + // *** Seek operations + enum SeekOps + { + Seek_Set = 0, + Seek_Cur = 1, + Seek_End = 2 + }; + + // *** Errors + enum Errors + { + Error_FileNotFound = 0x1001, + Error_Access = 0x1002, + Error_IOError = 0x1003, + Error_DiskFull = 0x1004 + }; +}; + + +//----------------------------------------------------------------------------------- +// ***** File Class + +// The pure virtual base random-access file +// This is a base class to all files + +class File : public RefCountBase, public FileConstants +{ +public: + File() { } + // ** Location Information + + // Returns a file name path relative to the 'reference' directory + // This is often a path that was used to create a file + // (this is not a global path, global path can be obtained with help of directory) + virtual const char* GetFilePath() = 0; + + + // ** File Information + + // Return 1 if file's usable (open) + virtual bool IsValid() = 0; + // Return 1 if file's writable, otherwise 0 + virtual bool IsWritable() = 0; + + // Return position + virtual int Tell() = 0; + virtual int64_t LTell() = 0; + + // File size + virtual int GetLength() = 0; + virtual int64_t LGetLength() = 0; + + // Returns file stats + // 0 for failure + //virtual bool Stat(FileStats *pfs) = 0; + + // Return errno-based error code + // Useful if any other function failed + virtual int GetErrorCode() = 0; + + + // ** Stream implementation & I/O + + // Blocking write, will write in the given number of bytes to the stream + // Returns : -1 for error + // Otherwise number of bytes read + virtual int Write(const uint8_t *pbufer, int numBytes) = 0; + // Blocking read, will read in the given number of bytes or less from the stream + // Returns : -1 for error + // Otherwise number of bytes read, + // if 0 or < numBytes, no more bytes available; end of file or the other side of stream is closed + virtual int Read(uint8_t *pbufer, int numBytes) = 0; + + // Skips (ignores) a given # of bytes + // Same return values as Read + virtual int SkipBytes(int numBytes) = 0; + + // Returns the number of bytes available to read from a stream without blocking + // For a file, this should generally be number of bytes to the end + virtual int BytesAvailable() = 0; + + // Causes any implementation's buffered data to be delivered to destination + // Return 0 for error + virtual bool Flush() = 0; + + + // Need to provide a more optimized implementation that doe snot necessarily involve a lot of seeking + inline bool IsEOF() { return !BytesAvailable(); } + + + // Seeking + // Returns new position, -1 for error + virtual int Seek(int offset, int origin=Seek_Set) = 0; + virtual int64_t LSeek(int64_t offset, int origin=Seek_Set) = 0; + // Seek simplification + int SeekToBegin() {return Seek(0); } + int SeekToEnd() {return Seek(0,Seek_End); } + int Skip(int numBytes) {return Seek(numBytes,Seek_Cur); } + + + // Appends other file data from a stream + // Return -1 for error, else # of bytes written + virtual int CopyFromStream(File *pstream, int byteSize) = 0; + + // Closes the file + // After close, file cannot be accessed + virtual bool Close() = 0; + + + // ***** Inlines for convenient primitive type serialization + + // Read/Write helpers +private: + uint64_t PRead64() { uint64_t v = 0; Read((uint8_t*)&v, 8); return v; } + uint32_t PRead32() { uint32_t v = 0; Read((uint8_t*)&v, 4); return v; } + uint16_t PRead16() { uint16_t v = 0; Read((uint8_t*)&v, 2); return v; } + uint8_t PRead8() { uint8_t v = 0; Read((uint8_t*)&v, 1); return v; } + void PWrite64(uint64_t v) { Write((uint8_t*)&v, 8); } + void PWrite32(uint32_t v) { Write((uint8_t*)&v, 4); } + void PWrite16(uint16_t v) { Write((uint8_t*)&v, 2); } + void PWrite8(uint8_t v) { Write((uint8_t*)&v, 1); } + +public: + + // Writing primitive types - Little Endian + inline void WriteUByte(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteSByte(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteUInt8(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteSInt8(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteUInt16(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteSInt16(int16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteUInt32(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteSInt32(int32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteUInt64(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteSInt64(int64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToLE(v)); } + inline void WriteFloat(float v) { v = Alg::ByteUtil::SystemToLE(v); Write((uint8_t*)&v, 4); } + inline void WriteDouble(double v) { v = Alg::ByteUtil::SystemToLE(v); Write((uint8_t*)&v, 8); } + // Writing primitive types - Big Endian + inline void WriteUByteBE(uint8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteSByteBE(int8_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteUInt8BE(uint16_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteSInt8BE(int16_t v) { PWrite8((uint8_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteUInt16BE(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteSInt16BE(uint16_t v) { PWrite16((uint16_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteUInt32BE(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteSInt32BE(uint32_t v) { PWrite32((uint32_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteUInt64BE(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteSInt64BE(uint64_t v) { PWrite64((uint64_t)Alg::ByteUtil::SystemToBE(v)); } + inline void WriteFloatBE(float v) { v = Alg::ByteUtil::SystemToBE(v); Write((uint8_t*)&v, 4); } + inline void WriteDoubleBE(double v) { v = Alg::ByteUtil::SystemToBE(v); Write((uint8_t*)&v, 8); } + + // Reading primitive types - Little Endian + inline uint8_t ReadUByte() { return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); } + inline int8_t ReadSByte() { return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); } + inline uint8_t ReadUInt8() { return (uint8_t)Alg::ByteUtil::LEToSystem(PRead8()); } + inline int8_t ReadSInt8() { return (int8_t)Alg::ByteUtil::LEToSystem(PRead8()); } + inline uint16_t ReadUInt16() { return (uint16_t)Alg::ByteUtil::LEToSystem(PRead16()); } + inline int16_t ReadSInt16() { return (int16_t)Alg::ByteUtil::LEToSystem(PRead16()); } + inline uint32_t ReadUInt32() { return (uint32_t)Alg::ByteUtil::LEToSystem(PRead32()); } + inline int32_t ReadSInt32() { return (int32_t)Alg::ByteUtil::LEToSystem(PRead32()); } + inline uint64_t ReadUInt64() { return (uint64_t)Alg::ByteUtil::LEToSystem(PRead64()); } + inline int64_t ReadSInt64() { return (int64_t)Alg::ByteUtil::LEToSystem(PRead64()); } + inline float ReadFloat() { float v = 0.0f; Read((uint8_t*)&v, 4); return Alg::ByteUtil::LEToSystem(v); } + inline double ReadDouble() { double v = 0.0; Read((uint8_t*)&v, 8); return Alg::ByteUtil::LEToSystem(v); } + // Reading primitive types - Big Endian + inline uint8_t ReadUByteBE() { return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); } + inline int8_t ReadSByteBE() { return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); } + inline uint8_t ReadUInt8BE() { return (uint8_t)Alg::ByteUtil::BEToSystem(PRead8()); } + inline int8_t ReadSInt8BE() { return (int8_t)Alg::ByteUtil::BEToSystem(PRead8()); } + inline uint16_t ReadUInt16BE() { return (uint16_t)Alg::ByteUtil::BEToSystem(PRead16()); } + inline int16_t ReadSInt16BE() { return (int16_t)Alg::ByteUtil::BEToSystem(PRead16()); } + inline uint32_t ReadUInt32BE() { return (uint32_t)Alg::ByteUtil::BEToSystem(PRead32()); } + inline int32_t ReadSInt32BE() { return (int32_t)Alg::ByteUtil::BEToSystem(PRead32()); } + inline uint64_t ReadUInt64BE() { return (uint64_t)Alg::ByteUtil::BEToSystem(PRead64()); } + inline int64_t ReadSInt64BE() { return (int64_t)Alg::ByteUtil::BEToSystem(PRead64()); } + inline float ReadFloatBE() { float v = 0.0f; Read((uint8_t*)&v, 4); return Alg::ByteUtil::BEToSystem(v); } + inline double ReadDoubleBE() { double v = 0.0; Read((uint8_t*)&v, 8); return Alg::ByteUtil::BEToSystem(v); } +}; + + +// *** Delegated File + +class DelegatedFile : public File +{ +protected: + // Delegating file pointer + Ptr pFile; + + // Hidden default constructor + DelegatedFile() : pFile(0) { } + DelegatedFile(const DelegatedFile &source) : File() { OVR_UNUSED(source); } +public: + // Constructors + DelegatedFile(File *pfile) : pFile(pfile) { } + + // ** Location Information + virtual const char* GetFilePath() { return pFile->GetFilePath(); } + + // ** File Information + virtual bool IsValid() { return pFile && pFile->IsValid(); } + virtual bool IsWritable() { return pFile->IsWritable(); } +// virtual bool IsRecoverable() { return pFile->IsRecoverable(); } + + virtual int Tell() { return pFile->Tell(); } + virtual int64_t LTell() { return pFile->LTell(); } + + virtual int GetLength() { return pFile->GetLength(); } + virtual int64_t LGetLength() { return pFile->LGetLength(); } + + //virtual bool Stat(FileStats *pfs) { return pFile->Stat(pfs); } + + virtual int GetErrorCode() { return pFile->GetErrorCode(); } + + // ** Stream implementation & I/O + virtual int Write(const uint8_t *pbuffer, int numBytes) { return pFile->Write(pbuffer,numBytes); } + virtual int Read(uint8_t *pbuffer, int numBytes) { return pFile->Read(pbuffer,numBytes); } + + virtual int SkipBytes(int numBytes) { return pFile->SkipBytes(numBytes); } + + virtual int BytesAvailable() { return pFile->BytesAvailable(); } + + virtual bool Flush() { return pFile->Flush(); } + + // Seeking + virtual int Seek(int offset, int origin=Seek_Set) { return pFile->Seek(offset,origin); } + virtual int64_t LSeek(int64_t offset, int origin=Seek_Set) { return pFile->LSeek(offset,origin); } + + virtual int CopyFromStream(File *pstream, int byteSize) { return pFile->CopyFromStream(pstream,byteSize); } + + // Closing the file + virtual bool Close() { return pFile->Close(); } +}; + + +//----------------------------------------------------------------------------------- +// ***** Buffered File + +// This file class adds buffering to an existing file +// Buffered file never fails by itself; if there's not +// enough memory for buffer, no buffer's used + +class BufferedFile : public DelegatedFile +{ +protected: + enum BufferModeType + { + NoBuffer, + ReadBuffer, + WriteBuffer + }; + + // Buffer & the mode it's in + uint8_t* pBuffer; + BufferModeType BufferMode; + // Position in buffer + unsigned Pos; + // Data in buffer if reading + unsigned DataSize; + // Underlying file position + uint64_t FilePos; + + // Initializes buffering to a certain mode + bool SetBufferMode(BufferModeType mode); + // Flushes buffer + // WriteBuffer - write data to disk, ReadBuffer - reset buffer & fix file position + void FlushBuffer(); + // Loads data into ReadBuffer + // WARNING: Right now LoadBuffer() assumes the buffer's empty + void LoadBuffer(); + + // Hidden constructor + BufferedFile(); + BufferedFile(const BufferedFile &) : DelegatedFile(), pBuffer(NULL), BufferMode(NoBuffer), Pos(0), DataSize(0), FilePos(0) { } + +public: + + // Constructor + // - takes another file as source + BufferedFile(File *pfile); + ~BufferedFile(); + + + // ** Overridden functions + + // We override all the functions that can possibly + // require buffer mode switch, flush, or extra calculations + virtual int Tell(); + virtual int64_t LTell(); + + virtual int GetLength(); + virtual int64_t LGetLength(); + +// virtual bool Stat(GFileStats *pfs); + + virtual int Write(const uint8_t *pbufer, int numBytes); + virtual int Read(uint8_t *pbufer, int numBytes); + + virtual int SkipBytes(int numBytes); + + virtual int BytesAvailable(); + + virtual bool Flush(); + + virtual int Seek(int offset, int origin=Seek_Set); + virtual int64_t LSeek(int64_t offset, int origin=Seek_Set); + + virtual int CopyFromStream(File *pstream, int byteSize); + + virtual bool Close(); +}; + + +//----------------------------------------------------------------------------------- +// ***** Memory File + +class MemoryFile : public File +{ +public: + + const char* GetFilePath() { return FilePath.ToCStr(); } + + bool IsValid() { return Valid; } + bool IsWritable() { return false; } + + bool Flush() { return true; } + int GetErrorCode() { return 0; } + + int Tell() { return FileIndex; } + int64_t LTell() { return (int64_t) FileIndex; } + + int GetLength() { return FileSize; } + int64_t LGetLength() { return (int64_t) FileSize; } + + bool Close() + { + Valid = false; + return false; + } + + int CopyFromStream(File *pstream, int byteSize) + { OVR_UNUSED2(pstream, byteSize); + return 0; + } + + int Write(const uint8_t *pbuffer, int numBytes) + { OVR_UNUSED2(pbuffer, numBytes); + return 0; + } + + int Read(uint8_t *pbufer, int numBytes) + { + if (FileIndex + numBytes > FileSize) + { + numBytes = FileSize - FileIndex; + } + + if (numBytes > 0) + { + ::memcpy (pbufer, &FileData [FileIndex], numBytes); + + FileIndex += numBytes; + } + + return numBytes; + } + + int SkipBytes(int numBytes) + { + if (FileIndex + numBytes > FileSize) + { + numBytes = FileSize - FileIndex; + } + + FileIndex += numBytes; + + return numBytes; + } + + int BytesAvailable() + { + return (FileSize - FileIndex); + } + + int Seek(int offset, int origin = Seek_Set) + { + switch (origin) + { + case Seek_Set : FileIndex = offset; break; + case Seek_Cur : FileIndex += offset; break; + case Seek_End : FileIndex = FileSize - offset; break; + } + + return FileIndex; + } + + int64_t LSeek(int64_t offset, int origin = Seek_Set) + { + return (int64_t) Seek((int) offset, origin); + } + +public: + + MemoryFile (const String& fileName, const uint8_t *pBuffer, int buffSize) + : FilePath(fileName) + { + FileData = pBuffer; + FileSize = buffSize; + FileIndex = 0; + Valid = (!fileName.IsEmpty() && pBuffer && buffSize > 0) ? true : false; + } + + // pfileName should be encoded as UTF-8 to support international file names. + MemoryFile (const char* pfileName, const uint8_t *pBuffer, int buffSize) + : FilePath(pfileName) + { + FileData = pBuffer; + FileSize = buffSize; + FileIndex = 0; + Valid = (pfileName && pBuffer && buffSize > 0) ? true : false; + } +private: + + String FilePath; + const uint8_t *FileData; + int FileSize; + int FileIndex; + bool Valid; +}; + + +// ***** Global path helpers + +// Find trailing short filename in a path. +const char* OVR_CDECL GetShortFilename(const char* purl); + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp b/LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp new file mode 100644 index 0000000..2bb2057 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_FileFILE.cpp @@ -0,0 +1,608 @@ +/************************************************************************** + +Filename : OVR_FileFILE.cpp +Content : File wrapper class implementation (Win32) + +Created : April 5, 1999 +Authors : Michael Antonov + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +**************************************************************************/ + +#define GFILE_CXX + +#include "OVR_Types.h" +#include "OVR_Log.h" + +// Standard C library (Captain Obvious guarantees!) +#include +#ifndef OVR_OS_WINCE +#include +#endif + +#include "OVR_SysFile.h" + +#ifndef OVR_OS_WINCE +#include +#endif + +namespace OVR { + +// ***** File interface + +// ***** FILEFile - C streams file + +static int SFerror () +{ + if (errno == ENOENT) + return FileConstants::Error_FileNotFound; + else if (errno == EACCES || errno == EPERM) + return FileConstants::Error_Access; + else if (errno == ENOSPC) + return FileConstants::Error_DiskFull; + else + return FileConstants::Error_IOError; +}; + +#if defined(OVR_OS_WIN32) +#include "OVR_Win32_IncludeWindows.h" +// A simple helper class to disable/enable system error mode, if necessary +// Disabling happens conditionally only if a drive name is involved +class SysErrorModeDisabler +{ + BOOL Disabled; + UINT OldMode; +public: + SysErrorModeDisabler(const char* pfileName) + { + if (pfileName && (pfileName[0]!=0) && pfileName[1]==':') + { + Disabled = TRUE; + OldMode = ::SetErrorMode(SEM_FAILCRITICALERRORS); + } + else + { + Disabled = 0; + OldMode = 0; + } + } + + ~SysErrorModeDisabler() + { + if (Disabled) + ::SetErrorMode(OldMode); + } +}; +#else +class SysErrorModeDisabler +{ +public: + SysErrorModeDisabler(const char* pfileName) { OVR_UNUSED(pfileName); } +}; +#endif // OVR_OS_WIN32 + + +// This macro enables verification of I/O results after seeks against a pre-loaded +// full file buffer copy. This is generally not necessary, but can been used to debug +// memory corruptions; we've seen this fail due to EAX2/DirectSound corrupting memory +// under FMOD with XP64 (32-bit) and Realtek HA Audio driver. +//#define GFILE_VERIFY_SEEK_ERRORS + + +// This is the simplest possible file implementation, it wraps around the descriptor +// This file is delegated to by SysFile. + +class FILEFile : public File +{ +protected: + + // Allocated filename + String FileName; + + // File handle & open mode + bool Opened; + FILE* fs; + int OpenFlags; + // Error code for last request + int ErrorCode; + + int LastOp; + +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + uint8_t* pFileTestBuffer; + unsigned FileTestLength; + unsigned TestPos; // File pointer position during tests. +#endif + +public: + + FILEFile() : + FileName(), + Opened(false), + fs(NULL), + OpenFlags(0), + ErrorCode(0), + LastOp(0) + #ifdef OVR_FILE_VERIFY_SEEK_ERRORS + ,pFileTestBuffer(NULL) + ,FileTestLength(0) + ,TestPos(0) + #endif + { + } + + // Initialize file by opening it + FILEFile(const String& fileName, int flags, int Mode); + + // The 'pfileName' should be encoded as UTF-8 to support international file names. + FILEFile(const char* pfileName, int flags, int Mode); + + ~FILEFile() + { + if (Opened) + Close(); + } + + virtual const char* GetFilePath(); + + // ** File Information + virtual bool IsValid(); + virtual bool IsWritable(); + + // Return position / file size + virtual int Tell(); + virtual int64_t LTell(); + virtual int GetLength(); + virtual int64_t LGetLength(); + +// virtual bool Stat(FileStats *pfs); + virtual int GetErrorCode(); + + // ** Stream implementation & I/O + virtual int Write(const uint8_t *pbuffer, int numBytes); + virtual int Read(uint8_t *pbuffer, int numBytes); + virtual int SkipBytes(int numBytes); + virtual int BytesAvailable(); + virtual bool Flush(); + virtual int Seek(int offset, int origin); + virtual int64_t LSeek(int64_t offset, int origin); + + virtual int CopyFromStream(File *pStream, int byteSize); + virtual bool Close(); +private: + void init(); +}; + + +// Initialize file by opening it +FILEFile::FILEFile(const String& fileName, int flags, int mode) + : FileName(fileName), OpenFlags(flags) +{ + OVR_UNUSED(mode); + init(); +} + +// The 'pfileName' should be encoded as UTF-8 to support international file names. +FILEFile::FILEFile(const char* pfileName, int flags, int mode) + : FileName(pfileName), OpenFlags(flags) +{ + OVR_UNUSED(mode); + init(); +} + +void FILEFile::init() +{ + // Open mode for file's open + const char *omode = "rb"; + + if (OpenFlags & Open_Truncate) + { + if (OpenFlags & Open_Read) + omode = "w+b"; + else + omode = "wb"; + } + else if (OpenFlags & Open_Create) + { + if (OpenFlags & Open_Read) + omode = "a+b"; + else + omode = "ab"; + } + else if (OpenFlags & Open_Write) + omode = "r+b"; + +#if defined(OVR_OS_MS) + SysErrorModeDisabler disabler(FileName.ToCStr()); +#endif + +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + wchar_t womode[16]; + wchar_t *pwFileName = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(FileName.ToCStr())+1) * sizeof(wchar_t)); + UTF8Util::DecodeString(pwFileName, FileName.ToCStr()); + OVR_ASSERT(strlen(omode) < sizeof(womode)/sizeof(womode[0])); + UTF8Util::DecodeString(womode, omode); + _wfopen_s(&fs, pwFileName, womode); + OVR_FREE(pwFileName); +#else + fs = fopen(FileName.ToCStr(), omode); +#endif + if (fs) + rewind (fs); + Opened = (fs != NULL); + // Set error code + if (!Opened) + ErrorCode = SFerror(); + else + { + // If we are testing file seek correctness, pre-load the entire file so + // that we can do comparison tests later. +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + TestPos = 0; + fseek(fs, 0, SEEK_END); + FileTestLength = ftell(fs); + fseek(fs, 0, SEEK_SET); + pFileTestBuffer = (uint8_t*)OVR_ALLOC(FileTestLength); + if (pFileTestBuffer) + { + OVR_ASSERT(FileTestLength == (unsigned)Read(pFileTestBuffer, FileTestLength)); + Seek(0, Seek_Set); + } +#endif + + ErrorCode = 0; + } + LastOp = 0; +} + + +const char* FILEFile::GetFilePath() +{ + return FileName.ToCStr(); +} + + +// ** File Information +bool FILEFile::IsValid() +{ + return Opened; +} +bool FILEFile::IsWritable() +{ + return IsValid() && (OpenFlags&Open_Write); +} +/* +bool FILEFile::IsRecoverable() +{ + return IsValid() && ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC); +} +*/ + +// Return position / file size +int FILEFile::Tell() +{ + int pos = (int)ftell (fs); + if (pos < 0) + ErrorCode = SFerror(); + return pos; +} + +int64_t FILEFile::LTell() +{ + int64_t pos = ftell(fs); + if (pos < 0) + ErrorCode = SFerror(); + return pos; +} + +int FILEFile::GetLength() +{ + int pos = Tell(); + if (pos >= 0) + { + Seek (0, Seek_End); + int size = Tell(); + Seek (pos, Seek_Set); + return size; + } + return -1; +} +int64_t FILEFile::LGetLength() +{ + int64_t pos = LTell(); + if (pos >= 0) + { + LSeek (0, Seek_End); + int64_t size = LTell(); + LSeek (pos, Seek_Set); + return size; + } + return -1; +} + +int FILEFile::GetErrorCode() +{ + return ErrorCode; +} + +// ** Stream implementation & I/O +int FILEFile::Write(const uint8_t *pbuffer, int numBytes) +{ + if (LastOp && LastOp != Open_Write) + fflush(fs); + LastOp = Open_Write; + int written = (int) fwrite(pbuffer, 1, numBytes, fs); + if (written < numBytes) + ErrorCode = SFerror(); + +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + if (written > 0) + TestPos += written; +#endif + + return written; +} + +int FILEFile::Read(uint8_t *pbuffer, int numBytes) +{ + if (LastOp && LastOp != Open_Read) + fflush(fs); + LastOp = Open_Read; + int read = (int) fread(pbuffer, 1, numBytes, fs); + if (read < numBytes) + ErrorCode = SFerror(); + +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + if (read > 0) + { + // Read-in data must match our pre-loaded buffer data! + uint8_t* pcompareBuffer = pFileTestBuffer + TestPos; + for (int i=0; i< read; i++) + { + OVR_ASSERT(pcompareBuffer[i] == pbuffer[i]); + } + + //OVR_ASSERT(!memcmp(pFileTestBuffer + TestPos, pbuffer, read)); + TestPos += read; + OVR_ASSERT(ftell(fs) == (int)TestPos); + } +#endif + + return read; +} + +// Seeks ahead to skip bytes +int FILEFile::SkipBytes(int numBytes) +{ + int64_t pos = LTell(); + int64_t newPos = LSeek(numBytes, Seek_Cur); + + // Return -1 for major error + if ((pos==-1) || (newPos==-1)) + { + return -1; + } + //ErrorCode = ((NewPos-Pos) int(sizeof(buff))) ? int(sizeof(buff)) : byteSize; + + szRead = pstream->Read(buff, szRequest); + szWritten = 0; + if (szRead > 0) + szWritten = Write(buff, szRead); + + count += szWritten; + byteSize -= szWritten; + if (szWritten < szRequest) + break; + } + + delete[] buff; + + return count; +} + + +bool FILEFile::Close() +{ +#ifdef OVR_FILE_VERIFY_SEEK_ERRORS + if (pFileTestBuffer) + { + OVR_FREE(pFileTestBuffer); + pFileTestBuffer = 0; + FileTestLength = 0; + } +#endif + + bool closeRet = !fclose(fs); + + if (!closeRet) + { + ErrorCode = SFerror(); + return 0; + } + else + { + Opened = 0; + fs = 0; + ErrorCode = 0; + } + + // Handle safe truncate + /* + if ((OpenFlags & OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) + { + // Delete original file (if it existed) + DWORD oldAttributes = FileUtilWin32::GetFileAttributes(FileName); + if (oldAttributes!=0xFFFFFFFF) + if (!FileUtilWin32::DeleteFile(FileName)) + { + // Try to remove the readonly attribute + FileUtilWin32::SetFileAttributes(FileName, oldAttributes & (~FILE_ATTRIBUTE_READONLY) ); + // And delete the file again + if (!FileUtilWin32::DeleteFile(FileName)) + return 0; + } + + // Rename temp file to real filename + if (!FileUtilWin32::MoveFile(TempName, FileName)) + { + //ErrorCode = errno; + return 0; + } + } + */ + return 1; +} + +/* +bool FILEFile::CloseCancel() +{ + bool closeRet = (bool)::CloseHandle(fd); + + if (!closeRet) + { + //ErrorCode = errno; + return 0; + } + else + { + Opened = 0; + fd = INVALID_HANDLE_VALUE; + ErrorCode = 0; + } + + // Handle safe truncate (delete tmp file, leave original unchanged) + if ((OpenFlags&OVR_FO_SAFETRUNC) == OVR_FO_SAFETRUNC) + if (!FileUtilWin32::DeleteFile(TempName)) + { + //ErrorCode = errno; + return 0; + } + return 1; +} +*/ + +Ptr FileFILEOpen(const String& path, int flags, int mode) +{ + Ptr result = *new FILEFile(path, flags, mode); + return result; +} + +// Helper function: obtain file information time. +bool SysFile::GetFileStat(FileStat* pfileStat, const String& path) +{ +#if defined(OVR_OS_MS) + // 64-bit implementation on Windows. + struct __stat64 fileStat; + // Stat returns 0 for success. + wchar_t *pwpath = (wchar_t*)OVR_ALLOC((UTF8Util::GetLength(path.ToCStr())+1)*sizeof(wchar_t)); + UTF8Util::DecodeString(pwpath, path.ToCStr()); + + int ret = _wstat64(pwpath, &fileStat); + OVR_FREE(pwpath); + if (ret) return false; +#else + struct stat fileStat; + // Stat returns 0 for success. + if (stat(path, &fileStat) != 0) + return false; +#endif + pfileStat->AccessTime = fileStat.st_atime; + pfileStat->ModifyTime = fileStat.st_mtime; + pfileStat->FileSize = fileStat.st_size; + return true; +} + +} // Namespace OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_Hash.h b/LibOVRKernel/Src/Kernel/OVR_Hash.h new file mode 100644 index 0000000..06d0add --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Hash.h @@ -0,0 +1,1306 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_Hash.h +Content : Template hash-table/set implementation +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Hash_h +#define OVR_Hash_h + +#include "OVR_ContainerAllocator.h" +#include "OVR_Alg.h" + +// 'new' operator is redefined/used in this file. +#undef new + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** Hash Table Implementation + +// HastSet and Hash. +// +// Hash table, linear probing, internal chaining. One interesting/nice thing +// about this implementation is that the table itself is a flat chunk of memory +// containing no pointers, only relative indices. If the key and value types +// of the Hash contain no pointers, then the Hash can be serialized using raw IO. +// +// Never shrinks, unless you explicitly Clear() it. Expands on +// demand, though. For best results, if you know roughly how big your +// table will be, default it to that size when you create it. +// +// Key usability feature: +// +// 1. Allows node hash values to either be cached or not. +// +// 2. Allows for alternative keys with methods such as GetAlt(). Handy +// if you need to search nodes by their components; no need to create +// temporary nodes. +// + + +// *** Hash functors: +// +// IdentityHash - use when the key is already a good hash +// HFixedSizeHash - general hash based on object's in-memory representation. + + +// Hash is just the input value; can use this for integer-indexed hash tables. +template +class IdentityHash +{ +public: + size_t operator()(const C& data) const + { return (size_t) data; } +}; + +// Computes a hash of an object's representation. +template +class FixedSizeHash +{ +public: + // Alternative: "sdbm" hash function, suggested at same web page + // above, http::/www.cs.yorku.ca/~oz/hash.html + // This is somewhat slower then Bernstein, but it works way better than the above + // hash function for hashing large numbers of 32-bit ints. + static OVR_FORCE_INLINE size_t SDBM_Hash(const void* data_in, size_t size, size_t seed = 5381) + { + const uint8_t* data = (const uint8_t*) data_in; + size_t h = seed; + while (size > 0) + { + --size; + #ifndef __clang_analyzer__ // It mistakenly thinks data is garbage. + h = (h << 16) + (h << 6) - h + (size_t)data[size]; + #endif + } + return h; + } + + size_t operator()(const C& data) const + { + const unsigned char* p = (const unsigned char*) &data; + const size_t size = sizeof(C); + + return SDBM_Hash(p, size); + } +}; + + + +// *** HashsetEntry Entry types. + +// Compact hash table Entry type that re-computes hash keys during hash traversal. +// Good to use if the hash function is cheap or the hash value is already cached in C. +template +class HashsetEntry +{ +public: + // Internal chaining for collisions. + intptr_t NextInChain; + C Value; + + HashsetEntry() + : NextInChain(-2) { } + HashsetEntry(const HashsetEntry& e) + : NextInChain(e.NextInChain), Value(e.Value) { } + HashsetEntry(const C& key, intptr_t next) + : NextInChain(next), Value(key) { } + + bool IsEmpty() const { return NextInChain == -2; } + bool IsEndOfChain() const { return NextInChain == -1; } + + // Cached hash value access - can be optimized bu storing hash locally. + // Mask value only needs to be used if SetCachedHash is not implemented. + size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; } + void SetCachedHash(size_t) {} + + void Clear() + { + Value.~C(); // placement delete + NextInChain = -2; + } + // Free is only used from dtor of hash; Clear is used during regular operations: + // assignment, hash reallocations, value reassignments, so on. + void Free() { Clear(); } +}; + +// Hash table Entry type that caches the Entry hash value for nodes, so that it +// does not need to be re-computed during access. +template +class HashsetCachedEntry +{ +public: + // Internal chaining for collisions. + intptr_t NextInChain; + size_t HashValue; + C Value; + + HashsetCachedEntry() + : NextInChain(-2) { } + HashsetCachedEntry(const HashsetCachedEntry& e) + : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { } + HashsetCachedEntry(const C& key, intptr_t next) + : NextInChain(next), Value(key) { } + + bool IsEmpty() const { return NextInChain == -2; } + bool IsEndOfChain() const { return NextInChain == -1; } + + // Cached hash value access - can be optimized bu storing hash locally. + // Mask value only needs to be used if SetCachedHash is not implemented. + size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; } + void SetCachedHash(size_t hashValue) { HashValue = hashValue; } + + void Clear() + { + Value.~C(); + NextInChain = -2; + } + // Free is only used from dtor of hash; Clear is used during regular operations: + // assignment, hash reallocations, value reassignments, so on. + void Free() { Clear(); } +}; + + +//----------------------------------------------------------------------------------- +// *** HashSet implementation - relies on either cached or regular entries. +// +// Use: Entry = HashsetCachedEntry if hashes are expensive to +// compute and thus need caching in entries. +// Entry = HashsetEntry if hashes are already externally cached. +// +template, + class AltHashF = HashF, + class Allocator = ContainerAllocator, + class Entry = HashsetCachedEntry > +class HashSetBase +{ + enum { HashMinSize = 8 }; + +public: + OVR_MEMORY_REDEFINE_NEW(HashSetBase) + + typedef HashSetBase SelfType; + + HashSetBase() : pTable(NULL) { } + HashSetBase(int sizeHint) : pTable(NULL) { SetCapacity(sizeHint); } + HashSetBase(const SelfType& src) : pTable(NULL) { Assign(src); } + + ~HashSetBase() + { + if (pTable) + { + // Delete the entries. + for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) + { + Entry* e = &E(i); + if (!e->IsEmpty()) + e->Free(); + } + + Allocator::Free(pTable); + pTable = NULL; + } + } + + + void Assign(const SelfType& src) + { + Clear(); + if (src.IsEmpty() == false) + { + SetCapacity(src.GetSize()); + + for (ConstIterator it = src.Begin(); it != src.End(); ++it) + { + Add(*it); + } + } + } + + + // Remove all entries from the HashSet table. + void Clear() + { + if (pTable) + { + // Delete the entries. + for (size_t i = 0, n = pTable->SizeMask; i <= n; i++) + { + Entry* e = &E(i); + if (!e->IsEmpty()) + e->Clear(); + } + + Allocator::Free(pTable); + pTable = NULL; + } + } + + // Returns true if the HashSet is empty. + bool IsEmpty() const + { + return pTable == NULL || pTable->EntryCount == 0; + } + + + // Set a new or existing value under the key, to the value. + // Pass a different class of 'key' so that assignment reference object + // can be passed instead of the actual object. + template + void Set(const CRef& key) + { + size_t hashValue = HashF()(key); + intptr_t index = (intptr_t)-1; + + if (pTable != NULL) + index = findIndexCore(key, hashValue & pTable->SizeMask); + + if (index >= 0) + { + E(index).Value = key; + } + else + { + // Entry under key doesn't exist. + add(key, hashValue); + } + } + + template + inline void Add(const CRef& key) + { + size_t hashValue = HashF()(key); + add(key, hashValue); + } + + // Remove by alternative key. + template + void RemoveAlt(const K& key) + { + if (pTable == NULL) + return; + + size_t hashValue = AltHashF()(key); + intptr_t index = hashValue & pTable->SizeMask; + + Entry* e = &E(index); + + // If empty node or occupied by collider, we have nothing to remove. + if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != (size_t)index)) + return; + + // Save index + intptr_t naturalIndex = index; + intptr_t prevIndex = -1; + + while ((e->GetCachedHash(pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) + { + // Keep looking through the chain. + prevIndex = index; + index = e->NextInChain; + if (index == -1) + return; // End of chain, item not found + e = &E(index); + } + + // Found it - our item is at index + if (naturalIndex == index) + { + // If we have a follower, move it to us + if (!e->IsEndOfChain()) + { + Entry* enext = &E(e->NextInChain); + e->Clear(); + new (e) Entry(*enext); + // Point us to the follower's cell that will be cleared + e = enext; + } + } + else + { + // We are not at natural index, so deal with the prev items next index + E(prevIndex).NextInChain = e->NextInChain; + } + + // Clear us, of the follower cell that was moved. + e->Clear(); + pTable->EntryCount --; + // Should we check the size to condense hash? ... + } + + // Remove by main key. + template + void Remove(const CRef& key) + { + RemoveAlt(key); + } + + // Retrieve the pointer to a value under the given key. + // - If there's no value under the key, then return NULL. + // - If there is a value, return the pointer. + template + C* Get(const K& key) + { + intptr_t index = findIndex(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template + const C* Get(const K& key) const + { + intptr_t index = findIndex(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + // Alternative key versions of Get. Used by Hash. + template + const C* GetAlt(const K& key) const + { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template + C* GetAlt(const K& key) + { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return &E(index).Value; + return 0; + } + + template + bool GetAlt(const K& key, C* pval) const + { + intptr_t index = findIndexAlt(key); + if (index >= 0) + { + if (pval) + *pval = E(index).Value; + return true; + } + return false; + } + + + size_t GetSize() const + { + return pTable == NULL ? 0 : (size_t)pTable->EntryCount; + } + int GetSizeI() const { return (int)GetSize(); } + + + // Resize the HashSet table to fit one more Entry. Often this + // doesn't involve any action. + void CheckExpand() + { + if (pTable == NULL) + { + // Initial creation of table. Make a minimum-sized table. + setRawCapacity(HashMinSize); + } + else if (pTable->EntryCount * 5 > (pTable->SizeMask + 1) * 4) + { + // pTable is more than 5/4 ths full. Expand. + setRawCapacity((pTable->SizeMask + 1) * 2); + } + } + + // Hint the bucket count to >= n. + void Resize(size_t n) + { + // Not really sure what this means in relation to + // STLport's hash_map... they say they "increase the + // bucket count to at least n" -- but does that mean + // their real capacity after Resize(n) is more like + // n*2 (since they do linked-list chaining within + // buckets?). + SetCapacity(n); + } + + // Size the HashSet so that it can comfortably contain the given + // number of elements. If the HashSet already contains more + // elements than newSize, then this may be a no-op. + void SetCapacity(size_t newSize) + { + size_t newRawSize = (newSize * 5) / 4; + if (newRawSize <= GetSize()) + return; + setRawCapacity(newRawSize); + } + + // Disable inappropriate 'operator ->' warning on MSVC6. +#ifdef OVR_CC_MSVC +#if (OVR_CC_MSVC < 1300) +# pragma warning(disable : 4284) +#endif +#endif + + // Iterator API, like STL. + struct ConstIterator + { + const C& operator * () const + { + OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); + return pHash->E(Index).Value; + } + + const C* operator -> () const + { + OVR_ASSERT(Index >= 0 && Index <= (intptr_t)pHash->pTable->SizeMask); + return &pHash->E(Index).Value; + } + + void operator ++ () + { + // Find next non-empty Entry. + if (Index <= (intptr_t)pHash->pTable->SizeMask) + { + Index++; + while ((size_t)Index <= pHash->pTable->SizeMask && + pHash->E(Index).IsEmpty()) + { + Index++; + } + } + } + + bool operator == (const ConstIterator& it) const + { + if (IsEnd() && it.IsEnd()) + { + return true; + } + else + { + return (pHash == it.pHash) && (Index == it.Index); + } + } + + bool operator != (const ConstIterator& it) const + { + return ! (*this == it); + } + + + bool IsEnd() const + { + return (pHash == NULL) || + (pHash->pTable == NULL) || + (Index > (intptr_t)pHash->pTable->SizeMask); + } + + ConstIterator() + : pHash(NULL), Index(0) + { } + + public: + // Constructor was intentionally made public to allow create + // iterator with arbitrary index. + ConstIterator(const SelfType* h, intptr_t index) + : pHash(h), Index(index) + { } + + const SelfType* GetContainer() const + { + return pHash; + } + intptr_t GetIndex() const + { + return Index; + } + + protected: + friend class HashSetBase; + + const SelfType* pHash; + intptr_t Index; + }; + + friend struct ConstIterator; + + + // Non-const Iterator; Get most of it from ConstIterator. + struct Iterator : public ConstIterator + { + // Allow non-const access to entries. + C& operator*() const + { + OVR_ASSERT((ConstIterator::pHash) && ConstIterator::pHash->pTable && (ConstIterator::Index >= 0) && (ConstIterator::Index <= (intptr_t)ConstIterator::pHash->pTable->SizeMask)); + return const_cast(ConstIterator::pHash)->E(ConstIterator::Index).Value; + } + + C* operator->() const + { + return &(operator*()); + } + + Iterator() + : ConstIterator(NULL, 0) + { } + + // Removes current element from Hash + void Remove() + { + RemoveAlt(operator*()); + } + + template + void RemoveAlt(const K& key) + { + SelfType* phash = const_cast(ConstIterator::pHash); + //Entry* ee = &phash->E(ConstIterator::Index); + //const C& key = ee->Value; + + size_t hashValue = AltHashF()(key); + intptr_t index = hashValue & phash->pTable->SizeMask; + + Entry* e = &phash->E(index); + + // If empty node or occupied by collider, we have nothing to remove. + if (e->IsEmpty() || (e->GetCachedHash(phash->pTable->SizeMask) != (size_t)index)) + return; + + // Save index + intptr_t naturalIndex = index; + intptr_t prevIndex = -1; + + while ((e->GetCachedHash(phash->pTable->SizeMask) != (size_t)naturalIndex) || !(e->Value == key)) + { + // Keep looking through the chain. + prevIndex = index; + index = e->NextInChain; + if (index == -1) + return; // End of chain, item not found + e = &phash->E(index); + } + + if (index == (intptr_t)ConstIterator::Index) + { + // Found it - our item is at index + if (naturalIndex == index) + { + // If we have a follower, move it to us + if (!e->IsEndOfChain()) + { + Entry* enext = &phash->E(e->NextInChain); + e->Clear(); + new (e) Entry(*enext); + // Point us to the follower's cell that will be cleared + e = enext; + --ConstIterator::Index; + } + } + else + { + // We are not at natural index, so deal with the prev items next index + phash->E(prevIndex).NextInChain = e->NextInChain; + } + + // Clear us, of the follower cell that was moved. + e->Clear(); + phash->pTable->EntryCount --; + } + else + OVR_ASSERT(0); //? + } + + private: + friend class HashSetBase; + + Iterator(SelfType* h, intptr_t i0) + : ConstIterator(h, i0) + { } + }; + + friend struct Iterator; + + Iterator Begin() + { + if (pTable == 0) + return Iterator(NULL, 0); + + // Scan till we hit the First valid Entry. + size_t i0 = 0; + while (i0 <= pTable->SizeMask && E(i0).IsEmpty()) + { + i0++; + } + return Iterator(this, i0); + } + Iterator End() { return Iterator(NULL, 0); } + + ConstIterator Begin() const { return const_cast(this)->Begin(); } + ConstIterator End() const { return const_cast(this)->End(); } + + template + Iterator Find(const K& key) + { + intptr_t index = findIndex(key); + if (index >= 0) + return Iterator(this, index); + return Iterator(NULL, 0); + } + + template + Iterator FindAlt(const K& key) + { + intptr_t index = findIndexAlt(key); + if (index >= 0) + return Iterator(this, index); + return Iterator(NULL, 0); + } + + template + ConstIterator Find(const K& key) const { return const_cast(this)->Find(key); } + + template + ConstIterator FindAlt(const K& key) const { return const_cast(this)->FindAlt(key); } + +private: + // Find the index of the matching Entry. If no match, then return -1. + template + intptr_t findIndex(const K& key) const + { + if (pTable == NULL) + return -1; + size_t hashValue = HashF()(key) & pTable->SizeMask; + return findIndexCore(key, hashValue); + } + + template + intptr_t findIndexAlt(const K& key) const + { + if (pTable == NULL) + return -1; + size_t hashValue = AltHashF()(key) & pTable->SizeMask; + return findIndexCore(key, hashValue); + } + + // Find the index of the matching Entry. If no match, then return -1. + template + intptr_t findIndexCore(const K& key, size_t hashValue) const + { + // Table must exist. + OVR_ASSERT(pTable != 0); + // Hash key must be 'and-ed' by the caller. + OVR_ASSERT((hashValue & ~pTable->SizeMask) == 0); + + size_t index = hashValue; + const Entry* e = &E(index); + + // If empty or occupied by a collider, not found. + if (e->IsEmpty() || (e->GetCachedHash(pTable->SizeMask) != index)) + return -1; + + while(1) + { + OVR_ASSERT(e->GetCachedHash(pTable->SizeMask) == hashValue); + + if (e->GetCachedHash(pTable->SizeMask) == hashValue && e->Value == key) + { + // Found it. + return index; + } + // Values can not be equal at this point. + // That would mean that the hash key for the same value differs. + OVR_ASSERT(!(e->Value == key)); + + // Keep looking through the chain. + index = e->NextInChain; + if (index == (size_t)-1) + break; // end of chain + + e = &E(index); + OVR_ASSERT(!e->IsEmpty()); + } + return -1; + } + + + // Add a new value to the HashSet table, under the specified key. + template + void add(const CRef& key, size_t hashValue) + { + CheckExpand(); + hashValue &= pTable->SizeMask; + + pTable->EntryCount++; + + intptr_t index = hashValue; + Entry* naturalEntry = &(E(index)); + + if (naturalEntry->IsEmpty()) + { + // Put the new Entry in. + new (naturalEntry) Entry(key, -1); + } + else + { + // Find a blank spot. + intptr_t blankIndex = index; + do { + blankIndex = (blankIndex + 1) & pTable->SizeMask; + } while(!E(blankIndex).IsEmpty()); + + Entry* blankEntry = &E(blankIndex); + + if (naturalEntry->GetCachedHash(pTable->SizeMask) == (size_t)index) + { + // Collision. Link into this chain. + + // Move existing list head. + new (blankEntry) Entry(*naturalEntry); // placement new, copy ctor + + // Put the new info in the natural Entry. + naturalEntry->Value = key; + naturalEntry->NextInChain = blankIndex; + } + else + { + // Existing Entry does not naturally + // belong in this slot. Existing + // Entry must be moved. + + // Find natural location of collided element (i.e. root of chain) + intptr_t collidedIndex = naturalEntry->GetCachedHash(pTable->SizeMask); + OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); + for (;;) + { + Entry* e = &E(collidedIndex); + if (e->NextInChain == index) + { + // Here's where we need to splice. + new (blankEntry) Entry(*naturalEntry); + e->NextInChain = blankIndex; + break; + } + collidedIndex = e->NextInChain; + OVR_ASSERT(collidedIndex >= 0 && collidedIndex <= (intptr_t)pTable->SizeMask); + } + + // Put the new data in the natural Entry. + naturalEntry->Value = key; + naturalEntry->NextInChain = -1; + } + } + + // Record hash value: has effect only if cached node is used. + naturalEntry->SetCachedHash(hashValue); + } + + // Index access helpers. + Entry& E(size_t index) + { + // Must have pTable and access needs to be within bounds. + OVR_ASSERT(index <= pTable->SizeMask); + return *(((Entry*) (pTable + 1)) + index); + } + const Entry& E(size_t index) const + { + OVR_ASSERT(index <= pTable->SizeMask); + return *(((Entry*) (pTable + 1)) + index); + } + + + // Resize the HashSet table to the given size (Rehash the + // contents of the current table). The arg is the number of + // HashSet table entries, not the number of elements we should + // actually contain (which will be less than this). + void setRawCapacity(size_t newSize) + { + if (newSize == 0) + { + // Special case. + Clear(); + return; + } + + // Minimum size; don't incur rehashing cost when expanding + // very small tables. Not that we perform this check before + // 'log2f' call to avoid fp exception with newSize == 1. + if (newSize < HashMinSize) + newSize = HashMinSize; + else + { + // Force newSize to be a power of two. + int bits = Alg::UpperBit(newSize-1) + 1; // Chop( Log2f((float)(newSize-1)) + 1); + OVR_ASSERT((size_t(1) << bits) >= newSize); + newSize = size_t(1) << bits; + } + + SelfType newHash; + newHash.pTable = (TableType*) + Allocator::Alloc( + sizeof(TableType) + sizeof(Entry) * newSize); + // Need to do something on alloc failure! + OVR_ASSERT(newHash.pTable); + + newHash.pTable->EntryCount = 0; + newHash.pTable->SizeMask = newSize - 1; + size_t i, n; + + // Mark all entries as empty. + for (i = 0; i < newSize; i++) + newHash.E(i).NextInChain = -2; + + // Copy stuff to newHash + if (pTable) + { + for (i = 0, n = pTable->SizeMask; i <= n; i++) + { + Entry* e = &E(i); + if (e->IsEmpty() == false) + { + // Insert old Entry into new HashSet. + newHash.Add(e->Value); + // placement delete of old element + e->Clear(); + } + } + + // Delete our old data buffer. + Allocator::Free(pTable); + } + + // Steal newHash's data. + pTable = newHash.pTable; + newHash.pTable = NULL; + } + + struct TableType + { + size_t EntryCount; + size_t SizeMask; + // Entry array follows this structure + // in memory. + }; + TableType* pTable; +}; + + + +//----------------------------------------------------------------------------------- +template, + class AltHashF = HashF, + class Allocator = ContainerAllocator, + class Entry = HashsetCachedEntry > +class HashSet : public HashSetBase +{ +public: + typedef HashSetBase BaseType; + typedef HashSet SelfType; + + HashSet() { } + HashSet(int sizeHint) : BaseType(sizeHint) { } + HashSet(const SelfType& src) : BaseType(src) { } + ~HashSet() { } + + void operator = (const SelfType& src) { BaseType::Assign(src); } + + // Set a new or existing value under the key, to the value. + // Pass a different class of 'key' so that assignment reference object + // can be passed instead of the actual object. + template + void Set(const CRef& key) + { + BaseType::Set(key); + } + + template + inline void Add(const CRef& key) + { + BaseType::Add(key); + } + + // Hint the bucket count to >= n. + void Resize(size_t n) + { + BaseType::SetCapacity(n); + } + + // Size the HashSet so that it can comfortably contain the given + // number of elements. If the HashSet already contains more + // elements than newSize, then this may be a no-op. + void SetCapacity(size_t newSize) + { + BaseType::SetCapacity(newSize); + } + +}; + +// HashSet with uncached hash code; declared for convenience. +template, + class AltHashF = HashF, + class Allocator = ContainerAllocator > +class HashSetUncached : public HashSet > +{ +public: + + typedef HashSetUncached SelfType; + typedef HashSet > BaseType; + + // Delegated constructors. + HashSetUncached() { } + HashSetUncached(int sizeHint) : BaseType(sizeHint) { } + HashSetUncached(const SelfType& src) : BaseType(src) { } + ~HashSetUncached() { } + + void operator = (const SelfType& src) + { + BaseType::operator = (src); + } +}; + + +//----------------------------------------------------------------------------------- +// ***** Hash hash table implementation + +// Node for Hash - necessary so that Hash can delegate its implementation +// to HashSet. +template +struct HashNode +{ + typedef HashNode SelfType; + typedef C FirstType; + typedef U SecondType; + + C First; + U Second; + + // NodeRef is used to allow passing of elements into HashSet + // without using a temporary object. + struct NodeRef + { + const C* pFirst; + const U* pSecond; + + NodeRef(const C& f, const U& s) : pFirst(&f), pSecond(&s) { } + NodeRef(const NodeRef& src) : pFirst(src.pFirst), pSecond(src.pSecond) { } + + // Enable computation of ghash_node_hashf. + inline size_t GetHash() const { return HashF()(*pFirst); } + // Necessary conversion to allow HashNode::operator == to work. + operator const C& () const { return *pFirst; } + }; + + // Note: No default constructor is necessary. + HashNode(const HashNode& src) : First(src.First), Second(src.Second) { } + HashNode(const NodeRef& src) : First(*src.pFirst), Second(*src.pSecond) { } + void operator = (const NodeRef& src) { First = *src.pFirst; Second = *src.pSecond; } + + template + bool operator == (const K& src) const { return (First == src); } + + template + static size_t CalcHash(const K& data) { return HashF()(data); } + inline size_t GetHash() const { return HashF()(First); } + + // Hash functors used with this node. A separate functor is used for alternative + // key lookup so that it does not need to access the '.First' element. + struct NodeHashF + { + template + size_t operator()(const K& data) const { return data.GetHash(); } + }; + struct NodeAltHashF + { + template + size_t operator()(const K& data) const { return HashNode::CalcHash(data); } + }; +}; + + + +// **** Extra hashset_entry types to allow NodeRef construction. + +// The big difference between the below types and the ones used in hash_set is that +// these allow initializing the node with 'typename C::NodeRef& keyRef', which +// is critical to avoid temporary node allocation on stack when using placement new. + +// Compact hash table Entry type that re-computes hash keys during hash traversal. +// Good to use if the hash function is cheap or the hash value is already cached in C. +template +class HashsetNodeEntry +{ +public: + // Internal chaining for collisions. + intptr_t NextInChain; + C Value; + + HashsetNodeEntry() + : NextInChain(-2) { } + HashsetNodeEntry(const HashsetNodeEntry& e) + : NextInChain(e.NextInChain), Value(e.Value) { } + HashsetNodeEntry(const C& key, intptr_t next) + : NextInChain(next), Value(key) { } + HashsetNodeEntry(const typename C::NodeRef& keyRef, intptr_t next) + : NextInChain(next), Value(keyRef) { } + + bool IsEmpty() const { return NextInChain == -2; } + bool IsEndOfChain() const { return NextInChain == -1; } + size_t GetCachedHash(size_t maskValue) const { return HashF()(Value) & maskValue; } + void SetCachedHash(size_t hashValue) { OVR_UNUSED(hashValue); } + + void Clear() + { + Value.~C(); // placement delete + NextInChain = -2; + } + // Free is only used from dtor of hash; Clear is used during regular operations: + // assignment, hash reallocations, value reassignments, so on. + void Free() { Clear(); } +}; + +// Hash table Entry type that caches the Entry hash value for nodes, so that it +// does not need to be re-computed during access. +template +class HashsetCachedNodeEntry +{ +public: + // Internal chaining for collisions. + intptr_t NextInChain; + size_t HashValue; + C Value; + + HashsetCachedNodeEntry() + : NextInChain(-2) { } + HashsetCachedNodeEntry(const HashsetCachedNodeEntry& e) + : NextInChain(e.NextInChain), HashValue(e.HashValue), Value(e.Value) { } + HashsetCachedNodeEntry(const C& key, intptr_t next) + : NextInChain(next), Value(key) { } + HashsetCachedNodeEntry(const typename C::NodeRef& keyRef, intptr_t next) + : NextInChain(next), Value(keyRef) { } + + bool IsEmpty() const { return NextInChain == -2; } + bool IsEndOfChain() const { return NextInChain == -1; } + size_t GetCachedHash(size_t maskValue) const { OVR_UNUSED(maskValue); return HashValue; } + void SetCachedHash(size_t hashValue) { HashValue = hashValue; } + + void Clear() + { + Value.~C(); + NextInChain = -2; + } + // Free is only used from dtor of hash; Clear is used during regular operations: + // assignment, hash reallocations, value reassignments, so on. + void Free() { Clear(); } +}; + + +//----------------------------------------------------------------------------------- +template, + class Allocator = ContainerAllocator, + class HashNode = OVR::HashNode, + class Entry = HashsetCachedNodeEntry, + class Container = HashSet > +class Hash +{ +public: + OVR_MEMORY_REDEFINE_NEW(Hash) + + // Types used for hash_set. + typedef U ValueType; + typedef Hash SelfType; + + // Actual hash table itself, implemented as hash_set. + Container mHash; + +public: + Hash() { } + Hash(int sizeHint) : mHash(sizeHint) { } + Hash(const SelfType& src) : mHash(src.mHash) { } + ~Hash() { } + + void operator = (const SelfType& src) { mHash = src.mHash; } + + // Remove all entries from the Hash table. + inline void Clear() { mHash.Clear(); } + // Returns true if the Hash is empty. + inline bool IsEmpty() const { return mHash.IsEmpty(); } + + // Access (set). + inline void Set(const C& key, const U& value) + { + typename HashNode::NodeRef e(key, value); + mHash.Set(e); + } + inline void Add(const C& key, const U& value) + { + typename HashNode::NodeRef e(key, value); + mHash.Add(e); + } + + // Removes an element by clearing its Entry. + inline void Remove(const C& key) + { + mHash.RemoveAlt(key); + } + template + inline void RemoveAlt(const K& key) + { + mHash.RemoveAlt(key); + } + + // Retrieve the value under the given key. + // - If there's no value under the key, then return false and leave *pvalue alone. + // - If there is a value, return true, and Set *Pvalue to the Entry's value. + // - If value == NULL, return true or false according to the presence of the key. + bool Get(const C& key, U* pvalue) const + { + const HashNode* p = mHash.GetAlt(key); + if (p) + { + if (pvalue) + *pvalue = p->Second; + return true; + } + return false; + } + + template + bool GetAlt(const K& key, U* pvalue) const + { + const HashNode* p = mHash.GetAlt(key); + if (p) + { + if (pvalue) + *pvalue = p->Second; + return true; + } + return false; + } + + // Retrieve the pointer to a value under the given key. + // - If there's no value under the key, then return NULL. + // - If there is a value, return the pointer. + inline U* Get(const C& key) + { + HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + inline const U* Get(const C& key) const + { + const HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + + template + inline U* GetAlt(const K& key) + { + HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + template + inline const U* GetAlt(const K& key) const + { + const HashNode* p = mHash.GetAlt(key); + return p ? &p->Second : 0; + } + + // Sizing methods - delegate to Hash. + inline size_t GetSize() const { return mHash.GetSize(); } + inline int GetSizeI() const { return (int)GetSize(); } + inline void Resize(size_t n) { mHash.Resize(n); } + inline void SetCapacity(size_t newSize) { mHash.SetCapacity(newSize); } + + // Iterator API, like STL. + typedef typename Container::ConstIterator ConstIterator; + typedef typename Container::Iterator Iterator; + + inline Iterator Begin() { return mHash.Begin(); } + inline Iterator End() { return mHash.End(); } + inline ConstIterator Begin() const { return mHash.Begin(); } + inline ConstIterator End() const { return mHash.End(); } + + Iterator Find(const C& key) { return mHash.FindAlt(key); } + ConstIterator Find(const C& key) const { return mHash.FindAlt(key); } + + template + Iterator FindAlt(const K& key) { return mHash.FindAlt(key); } + template + ConstIterator FindAlt(const K& key) const { return mHash.FindAlt(key); } +}; + + + +// Hash with uncached hash code; declared for convenience. +template, class Allocator = ContainerAllocator > +class HashUncached + : public Hash, + HashsetNodeEntry, typename HashNode::NodeHashF> > +{ +public: + typedef HashUncached SelfType; + typedef Hash, + HashsetNodeEntry, + typename HashNode::NodeHashF> > BaseType; + + // Delegated constructors. + HashUncached() { } + HashUncached(int sizeHint) : BaseType(sizeHint) { } + HashUncached(const SelfType& src) : BaseType(src) { } + ~HashUncached() { } + void operator = (const SelfType& src) { BaseType::operator = (src); } +}; + + + +// And identity hash in which keys serve as hash value. Can be uncached, +// since hash computation is assumed cheap. +template, class HashF = IdentityHash > +class HashIdentity + : public HashUncached +{ +public: + typedef HashIdentity SelfType; + typedef HashUncached BaseType; + + // Delegated constructors. + HashIdentity() { } + HashIdentity(int sizeHint) : BaseType(sizeHint) { } + HashIdentity(const SelfType& src) : BaseType(src) { } + ~HashIdentity() { } + void operator = (const SelfType& src) { BaseType::operator = (src); } +}; + + +} // OVR + + +#ifdef OVR_DEFINE_NEW +#define new OVR_DEFINE_NEW +#endif + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_JSON.cpp b/LibOVRKernel/Src/Kernel/OVR_JSON.cpp new file mode 100644 index 0000000..b0ae183 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_JSON.cpp @@ -0,0 +1,1332 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_JSON.h +Content : JSON format reader and writer +Created : April 9, 2013 +Author : Brant Lewis +Notes : + The code is a derivative of the cJSON library written by Dave Gamble and subject + to the following permissive copyright. + + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include "OVR_JSON.h" +#include "OVR_SysFile.h" +#include "OVR_Log.h" + + +namespace OVR { + + +//----------------------------------------------------------------------------- +// Create a new copy of a string +static char* JSON_strdup(const char* str) +{ + size_t len = OVR_strlen(str) + 1; + char* copy = (char*)OVR_ALLOC(len); + if (!copy) + return 0; + memcpy(copy, str, len); + return copy; +} + + +//----------------------------------------------------------------------------- +// Render the number from the given item into a string. +static char* PrintInt(int valueint) +{ + char *str; + str = (char*)OVR_ALLOC(21); // 2^64+1 can be represented in 21 chars. + if (str) + { + OVR_sprintf(str, 21, "%d", valueint); + } + return str; +} + + +//----------------------------------------------------------------------------- +// Render the number from the given item into a string. +static char* PrintNumber(double d) +{ + char *str; + int valueint = (int)d; + + if ((fabs(((double)valueint)-d) <= DBL_EPSILON) && (d <= INT_MAX) && (d >= INT_MIN)) + { + return PrintInt(valueint); + } + else + { + const size_t kCapacity = 64; + + str=(char*)OVR_ALLOC(kCapacity); // This is a nice tradeoff. + if (str) + { + // The JSON Standard, section 7.8.3, specifies that decimals are always expressed with '.' and + // not some locale-specific decimal such as ',' or ' '. However, since we are using the C standard + // library below to write a floating point number, we need to make sure that it's writing a '.' + // and not something else. We can't change the locale (even temporarily) here, as it will affect + // the whole process by default. That are compiler-specific ways to change this per-thread, but + // below we implement the simple solution of simply fixing the decimal after the string was written. + + if ((fabs(floor(d)-d) <= DBL_EPSILON) && (fabs(d) < 1.0e60)) + OVR_sprintf(str, kCapacity, "%.0f", d); + else if ((fabs(d) < 1.0e-6) || (fabs(d) > 1.0e9)) + OVR_sprintf(str, kCapacity, "%e", d); + else + OVR_sprintf(str, kCapacity, "%f", d); + + // Convert any found ',' or ''' char to '.'. This will happen only if the locale was set to write a ',' + // instead of a '.' for the decimal point. Decimal points are represented only by one of these + // three characters in practice. + for(char* p = str; *p; p++) + { + if((*p == ',') || (*p == '\'')) + { + *p = '.'; + break; + } + } + } + } + return str; +} + + +// Parse the input text into an un-escaped cstring, and populate item. +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + +// Helper to assign error sting and return 0. +const char* AssignError(const char** perror, const char *errorMessage) +{ + if (perror) + *perror = errorMessage; + return 0; +} + +//----------------------------------------------------------------------------- +// ***** JSON Node class + +JSON::JSON(JSONItemType itemType) : + Type(itemType), dValue(0.) +{ +} + +JSON::~JSON() +{ + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child)) + { + child->RemoveNode(); + child->Release(); + child = Children.GetFirst(); + } +} + +//----------------------------------------------------------------------------- +// Parse the input text to generate a number, and populate the result into item +// Returns the text position after the parsed number +const char* JSON::parseNumber(const char *num) +{ + const char* num_start = num; + double n=0, scale=0; + int subscale = 0, + signsubscale = 1; + bool positiveSign = true; + const char decimalSeparator = '.'; // The JSON standard specifies that numbers use '.' regardless of locale. + + // Could use sscanf for this? + if (*num == '-') + { + positiveSign = false; + num++; // Has sign? + } + if (*num == '0') + { + num++; // is zero + } + + if (*num>='1' && *num<='9') + { + do + { + n = (n*10.0) + (*num++ - '0'); + } + while (*num>='0' && *num<='9'); // Number? + } + + if ((*num=='.' || *num==decimalSeparator) && num[1]>='0' && num[1]<='9') + { + num++; + do + { + n=(n*10.0)+(*num++ -'0'); + scale--; + } + while (*num>='0' && *num<='9'); // Fractional part? + } + + if (*num=='e' || *num=='E') // Exponent? + { + num++; + if (*num == '+') + { + num++; + } + else if (*num=='-') + { + signsubscale=-1; + num++; // With sign? + } + + while (*num >= '0' && *num <= '9') + { + subscale = (subscale * 10) + (*num++ - '0'); // Number? + } + } + + // Number = +/- number.fraction * 10^+/- exponent + n *= pow(10.0, (scale + subscale*signsubscale)); + + if (!positiveSign) + { + n = -n; + } + + // Assign parsed value. + Type = JSON_Number; + dValue = n; + Value.AssignString(num_start, num - num_start); + + return num; +} + +// Parses a hex string up to the specified number of digits. +// Returns the first character after the string. +const char* ParseHex(unsigned* val, unsigned digits, const char* str) +{ + *val = 0; + + for(unsigned digitCount = 0; digitCount < digits; digitCount++, str++) + { + unsigned v = *str; + + if ((v >= '0') && (v <= '9')) + v -= '0'; + else if ((v >= 'a') && (v <= 'f')) + v = 10 + v - 'a'; + else if ((v >= 'A') && (v <= 'F')) + v = 10 + v - 'A'; + else + break; + + *val = *val * 16 + v; + } + + return str; +} + +//----------------------------------------------------------------------------- +// Parses the input text into a string item and returns the text position after +// the parsed string +const char* JSON::parseString(const char* str, const char** perror) +{ + const char* ptr = str+1; + const char* p; + char* ptr2; + char* out; + int len=0; + unsigned uc, uc2; + + if (*str!='\"') + { + return AssignError(perror, "Syntax Error: Missing quote"); + } + + while (*ptr!='\"' && *ptr && ++len) + { + if (*ptr++ == '\\') ptr++; // Skip escaped quotes. + } + + // This is how long we need for the string, roughly. + out=(char*)OVR_ALLOC(len+1); + if (!out) + return 0; + + ptr = str+1; + ptr2= out; + + while (*ptr!='\"' && *ptr) + { + if (*ptr!='\\') + { + *ptr2++ = *ptr++; + } + else + { + ptr++; + switch (*ptr) + { + case 'b': *ptr2++ = '\b'; break; + case 'f': *ptr2++ = '\f'; break; + case 'n': *ptr2++ = '\n'; break; + case 'r': *ptr2++ = '\r'; break; + case 't': *ptr2++ = '\t'; break; + + // Transcode utf16 to utf8. + case 'u': + + // Get the unicode char. + p = ParseHex(&uc, 4, ptr + 1); + if (ptr != p) + ptr = p - 1; + + if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) + break; // Check for invalid. + + // UTF16 surrogate pairs. + if (uc>=0xD800 && uc<=0xDBFF) + { + if (ptr[1]!='\\' || ptr[2]!='u') + break; // Missing second-half of surrogate. + + p= ParseHex(&uc2, 4, ptr + 3); + if (ptr != p) + ptr = p - 1; + + if (uc2<0xDC00 || uc2>0xDFFF) + break; // Invalid second-half of surrogate. + + uc = 0x10000 + (((uc&0x3FF)<<10) | (uc2&0x3FF)); + } + + len=4; + + if (uc<0x80) + len=1; + else if (uc<0x800) + len=2; + else if (uc<0x10000) + len=3; + + ptr2+=len; + + switch (len) + { + case 4: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + //no break, fall through + case 3: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + //no break + case 2: *--ptr2 =((uc | 0x80) & 0xBF); uc >>= 6; + //no break + case 1: *--ptr2 = (char)(uc | firstByteMark[len]); + //no break + } + ptr2+=len; + break; + + default: + *ptr2++ = *ptr; + break; + } + ptr++; + } + } + + *ptr2 = 0; + if (*ptr=='\"') + ptr++; + + // Make a copy of the string + Value=out; + OVR_FREE(out); + Type=JSON_String; + + return ptr; +} + +//----------------------------------------------------------------------------- +// Render the string provided to an escaped version that can be printed. +char* PrintString(const char* str) +{ + const char *ptr; + char *ptr2,*out; + int len=0; + unsigned char token; + + if (!str) + return JSON_strdup(""); + ptr=str; + + token=*ptr; + while (token && ++len)\ + { + if (strchr("\"\\\b\f\n\r\t",token)) + len++; + else if (token<32) + len+=5; + ptr++; + token=*ptr; + } + + int buff_size = len+3; + out=(char*)OVR_ALLOC(buff_size); + if (!out) + return 0; + + ptr2 = out; + ptr = str; + *ptr2++ = '\"'; + + while (*ptr) + { + if ((unsigned char)*ptr>31 && *ptr!='\"' && *ptr!='\\') + *ptr2++=*ptr++; + else + { + *ptr2++='\\'; + switch (token=*ptr++) + { + case '\\': *ptr2++='\\'; break; + case '\"': *ptr2++='\"'; break; + case '\b': *ptr2++='b'; break; + case '\f': *ptr2++='f'; break; + case '\n': *ptr2++='n'; break; + case '\r': *ptr2++='r'; break; + case '\t': *ptr2++='t'; break; + default: + OVR_sprintf(ptr2, buff_size - (ptr2-out), "u%04x",token); + ptr2+=5; + break; // Escape and print. + } + } + } + *ptr2++='\"'; + *ptr2++=0; + return out; +} + +//----------------------------------------------------------------------------- +// Utility to jump whitespace and cr/lf +static const char* skip(const char* in) +{ + while (in && *in && (unsigned char)*in<=' ') + in++; + return in; +} + +//----------------------------------------------------------------------------- +// Parses the supplied buffer of JSON text and returns a JSON object tree +// The returned object must be Released after use +JSON* JSON::Parse(const char* buff, const char** perror) +{ + const char* end = 0; + JSON* json = new JSON(); + + if (!json) + { + AssignError(perror, "Error: Failed to allocate memory"); + return 0; + } + + end = json->parseValue(skip(buff), perror); + if (!end) + { + json->Release(); + return NULL; + } // parse failure. ep is set. + + return json; +} + +//----------------------------------------------------------------------------- +// This version works for buffers that are not null terminated strings. +JSON* JSON::ParseBuffer(const char *buff, int len, const char** perror) +{ + // Our JSON parser does not support length-based parsing, + // so ensure it is null-terminated. + char *termStr = new char[len + 1]; + memcpy(termStr, buff, len); + termStr[len] = '\0'; + + JSON *objJson = Parse(termStr, perror); + + delete[]termStr; + + return objJson; +} + +//----------------------------------------------------------------------------- +// Parser core - when encountering text, process appropriately. +const char* JSON::parseValue(const char* buff, const char** perror) +{ + if (perror) + *perror = 0; + + if (!buff) + return NULL; // Fail on null. + + if (!OVR_strncmp(buff, "null", 4)) + { + Type = JSON_Null; + return buff + 4; + } + if (!OVR_strncmp(buff, "false", 5)) + { + Type = JSON_Bool; + Value = "false"; + dValue = 0.; + return buff + 5; + } + if (!OVR_strncmp(buff, "true", 4)) + { + Type = JSON_Bool; + Value = "true"; + dValue = 1.; + return buff + 4; + } + if (*buff=='\"') + { + return parseString(buff, perror); + } + if (*buff=='-' || (*buff>='0' && *buff<='9')) + { + return parseNumber(buff); + } + if (*buff=='[') + { + return parseArray(buff, perror); + } + if (*buff=='{') + { + return parseObject(buff, perror); + } + + return AssignError(perror, "Syntax Error: Invalid syntax"); +} + +//----------------------------------------------------------------------------- +// Render a value to text. +char* JSON::PrintValue(int depth, bool fmt) +{ + char *out=0; + + switch (Type) + { + case JSON_Null: out = JSON_strdup("null"); break; + case JSON_Bool: + if ((int)dValue == 0) + out = JSON_strdup("false"); + else + out = JSON_strdup("true"); + break; + case JSON_Number: out = PrintNumber(dValue); break; + case JSON_String: out = PrintString(Value); break; + case JSON_Array: out = PrintArray(depth, fmt); break; + case JSON_Object: out = PrintObject(depth, fmt); break; + case JSON_None: OVR_ASSERT_LOG(false, ("Bad JSON type.")); break; + } + return out; +} + +//----------------------------------------------------------------------------- +// Build an array object from input text and returns the text position after +// the parsed array +const char* JSON::parseArray(const char* buff, const char** perror) +{ + JSON *child; + if (*buff!='[') + { + return AssignError(perror, "Syntax Error: Missing opening bracket"); + } + + Type=JSON_Array; + buff=skip(buff+1); + + if (*buff==']') + return buff+1; // empty array. + + child = new JSON(); + if (!child) + return 0; // memory fail + Children.PushBack(child); + + buff=skip(child->parseValue(skip(buff), perror)); // skip any spacing, get the buff. + if (!buff) + return 0; + + while (*buff==',') + { + JSON *new_item = new JSON(); + if (!new_item) + return AssignError(perror, "Error: Failed to allocate memory"); + + Children.PushBack(new_item); + + buff=skip(new_item->parseValue(skip(buff+1), perror)); + if (!buff) + return AssignError(perror, "Error: Failed to allocate memory"); + } + + if (*buff==']') + return buff+1; // end of array + + return AssignError(perror, "Syntax Error: Missing ending bracket"); +} + +//----------------------------------------------------------------------------- +// Render an array to text. The returned text must be freed +char* JSON::PrintArray(int depth, bool fmt) +{ + char ** entries; + char * out = 0, *ptr,*ret; + intptr_t len = 5; + + bool fail = false; + + // How many entries in the array? + int numentries = GetItemCount(); + if (!numentries) + { + out=(char*)OVR_ALLOC(3); + if (out) + OVR_strcpy(out, 3, "[]"); + return out; + } + // Allocate an array to hold the values for each + entries=(char**)OVR_ALLOC(numentries*sizeof(char*)); + if (!entries) + return 0; + memset(entries,0,numentries*sizeof(char*)); + + //// Retrieve all the results: + JSON* child = Children.GetFirst(); + for (int i=0; iPrintValue(depth+1, fmt); + entries[i]=ret; + if (ret) + len+=OVR_strlen(ret)+2+(fmt?1:0); + else + { + fail = true; + break; + } + child = Children.GetNext(child); + } + + // If we didn't fail, try to malloc the output string + if (!fail) + out=(char*)OVR_ALLOC(len); + // If that fails, we fail. + if (!out) + fail = true; + + // Handle failure. + if (fail) + { + for (int i=0; iparseString(skip(buff), perror)); + if (!buff) + return 0; + child->Name = child->Value; + child->Value.Clear(); + + if (*buff!=':') + { + return AssignError(perror, "Syntax Error: Missing colon"); + } + + buff=skip(child->parseValue(skip(buff+1), perror)); // skip any spacing, get the value. + if (!buff) + return 0; + + while (*buff==',') + { + child = new JSON(); + if (!child) + return 0; // memory fail + + Children.PushBack(child); + + buff=skip(child->parseString(skip(buff+1), perror)); + if (!buff) + return 0; + + child->Name=child->Value; + child->Value.Clear(); + + if (*buff!=':') + { + return AssignError(perror, "Syntax Error: Missing colon"); + } // fail! + + // Skip any spacing, get the value. + buff=skip(child->parseValue(skip(buff+1), perror)); + if (!buff) + return 0; + } + + if (*buff=='}') + return buff+1; // end of array + + return AssignError(perror, "Syntax Error: Missing closing brace"); +} + +//----------------------------------------------------------------------------- +// Render an object to text. The returned string must be freed +char* JSON::PrintObject(int depth, bool fmt) +{ + char** entries = 0, **names = 0; + char* out = 0; + char* ptr, *ret, *str; + intptr_t len = 7, i = 0, j; + bool fail = false; + + // Count the number of entries. + int numentries = GetItemCount(); + + // Explicitly handle empty object case + if (numentries == 0) + { + out=(char*)OVR_ALLOC(fmt?depth+4:4); + if (!out) + return 0; + ptr=out; + *ptr++='{'; + + if (fmt) + { + *ptr++='\n'; + for (i=0;iName); + entries[i++] = ret = child->PrintValue(depth, fmt); + + if (str && ret) + { + len += OVR_strlen(ret)+OVR_strlen(str)+2+(fmt?3+depth:0); + } + else + { + fail = true; + break; + } + + child = Children.GetNext(child); + } + + // Try to allocate the output string + if (!fail) + out=(char*)OVR_ALLOC(len); + if (!out) + fail=true; + + // Handle failure + if (fail) + { + for (i=0;iGetNext(); + i++; + } + } + + return child; +} + +// Returns the child item with the given name or NULL if not found +JSON* JSON::GetItemByName(const char* name) +{ + JSON* child = 0; + + if (!Children.IsEmpty()) + { + child = Children.GetFirst(); + + while (OVR_strcmp(child->Name, name) != 0) + { + if (Children.IsLast(child)) + { + child = 0; + break; + } + child = child->GetNext(); + } + } + + return child; +} + +//----------------------------------------------------------------------------- +// Adds a new item to the end of the child list +void JSON::AddItem(const char *string, JSON *item) +{ + if (item) + { + item->Name = string; + Children.PushBack(item); + } +} + +/* + +// Removes and frees the items at the given index +void JSON::DeleteItem(unsigned int index) +{ + unsigned int num_items = 0; + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child) && num_items < index) + { + num_items++; + child = Children.GetNext(child); + } + + if (!Children.IsNull(child)) + + child->RemoveNode(); + child->Release(); + } +} + +// Replaces and frees the item at the give index with the new item +void JSON::ReplaceItem(unsigned int index, JSON* new_item) +{ + unsigned int num_items = 0; + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child) && num_items < index) + { + num_items++; + child = Children.GetNext(child); + } + + if (!Children.IsNull(child)) + { + child->ReplaceNodeWith(new_item); + child->Release(); + } +} +*/ + +// Removes and frees the last child item +void JSON::RemoveLast() +{ + JSON* child = Children.GetLast(); + if (!Children.IsNull(child)) + { + child->RemoveNode(); + child->Release(); + } +} + +JSON* JSON::CreateBool(bool b) +{ + JSON *item = new JSON(JSON_Bool); + if (item) + { + item->dValue = b ? 1. : 0.; + item->Value = b ? "true" : "false"; + } + return item; +} + +JSON* JSON::CreateNumber(double num) +{ + JSON *item = new JSON(JSON_Number); + if (item) + { + item->dValue = num; + } + return item; +} + +JSON* JSON::CreateInt(int num) +{ + JSON *item = new JSON(JSON_Number); + if (item) + { + item->dValue = num; + } + return item; +} + +JSON* JSON::CreateString(const char *s) +{ + JSON *item = new JSON(JSON_String); + if (item && s) + { + item->Value = s; + } + return item; +} + + +//----------------------------------------------------------------------------- +// Get elements by name +double JSON::GetNumberByName(const char *name, double defValue) +{ + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Number) + { + return defValue; + } + else + { + return item->dValue; + } +} + +int JSON::GetIntByName(const char *name, int defValue) +{ + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Number) + { + return defValue; + } + else + { + return (int)item->dValue; + } +} + +bool JSON::GetBoolByName(const char *name, bool defValue) +{ + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_Bool) + { + return defValue; + } + else + { + return (int)item->dValue != 0; + } +} + +String JSON::GetStringByName(const char *name, const String &defValue) +{ + JSON* item = GetItemByName(name); + if (!item || item->Type != JSON_String) + { + return defValue; + } + else + { + return item->Value; + } +} + + +int JSON::GetArrayByName(const char *name, double values[], int count) +{ + JSON* array = GetItemByName(name); + if (!array || array->Type != JSON_Array) + return 0; + + int i = 0; + for (JSON* child = array->Children.GetFirst(); !array->Children.IsNull(child); child = array->Children.GetNext(child)) + { + if (i >= count) + break; + values[i++] = child->dValue; + } + + OVR_ASSERT(i <= count); + return i; +} + + +//----------------------------------------------------------------------------- +// Adds an element to an array object type +void JSON::AddArrayElement(JSON *item) +{ + if (item) + { + Children.PushBack(item); + } +} + +// Inserts an element into a valid array position +void JSON::InsertArrayElement(int index, JSON *item) +{ + if (!item) + { + return; + } + + if (index == 0) + { + Children.PushFront(item); + return; + } + + JSON* iter = Children.GetFirst(); + int i=0; + while (iter && iInsertNodeBefore(item); + else + Children.PushBack(item); +} + +// Returns the size of an array +int JSON::GetArraySize() +{ + if (Type == JSON_Array) + { + return GetItemCount(); + } + + return 0; +} + +// Returns the number value an the give array index +double JSON::GetArrayNumber(int index) +{ + if (Type == JSON_Array) + { + JSON* number = GetItemByIndex(index); + return number ? number->dValue : 0.0; + } + + return 0; +} + +// Returns the string value at the given array index +const char* JSON::GetArrayString(int index) +{ + if (Type == JSON_Array) + { + JSON* number = GetItemByIndex(index); + return number ? number->Value : 0; + } + + return 0; +} + +JSON* JSON::Copy() +{ + JSON* copy = new JSON(Type); + copy->Name = Name; + copy->Value = Value; + copy->dValue = dValue; + + JSON* child = Children.GetFirst(); + while (!Children.IsNull(child)) + { + copy->Children.PushBack(child->Copy()); + child = Children.GetNext(child); + } + + return copy; +} + +char* JSON::PrintValue(bool fmt) +{ + return PrintValue(0, fmt); +} + +//----------------------------------------------------------------------------- +// Loads and parses the given JSON file pathname and returns a JSON object tree. +// The returned object must be Released after use. +JSON* JSON::Load(const char* path, const char** perror) +{ + SysFile f; + if (!f.Open(path, File::Open_Read, File::Mode_Read)) + { + AssignError(perror, "Failed to open file"); + return NULL; + } + + int len = f.GetLength(); + uint8_t* buff = (uint8_t*)OVR_ALLOC(len + 1); + int bytes = f.Read(buff, len); + f.Close(); + + if (bytes == 0 || bytes != len) + { + OVR_FREE(buff); + return NULL; + } + + // Ensure the result is null-terminated since Parse() expects null-terminated input. + buff[len] = '\0'; + + JSON* json = JSON::Parse((char*)buff, perror); + OVR_FREE(buff); + return json; +} + +//----------------------------------------------------------------------------- +// Serializes the JSON object and writes to the give file path +bool JSON::Save(const char* path) +{ + SysFile f; + if (!f.Open(path, File::Open_Write | File::Open_Create | File::Open_Truncate, File::Mode_Write)) + return false; + + char* text = PrintValue(0, true); + if (text) + { + intptr_t len = OVR_strlen(text); + OVR_ASSERT(len <= (intptr_t)(int)len); + + int bytes = f.Write((uint8_t*)text, (int)len); + f.Close(); + OVR_FREE(text); + return (bytes == len); + } + else + { + return false; + } +} + +//----------------------------------------------------------------------------- +// Serializes the JSON object to a String +String JSON::Stringify(bool fmt) +{ + char* text = PrintValue(0, fmt); + String copy(text); + OVR_FREE(text); + return copy; +} + + +} // namespace OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_JSON.h b/LibOVRKernel/Src/Kernel/OVR_JSON.h new file mode 100644 index 0000000..e5e715e --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_JSON.h @@ -0,0 +1,171 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_JSON.h +Content : JSON format reader and writer +Created : April 9, 2013 +Author : Brant Lewis +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_JSON_h +#define OVR_JSON_h + +#include "OVR_RefCount.h" +#include "OVR_String.h" +#include "OVR_List.h" + +namespace OVR { + +// JSONItemType describes the type of JSON item, specifying the type of +// data that can be obtained from it. +enum JSONItemType +{ + JSON_None = 0, + JSON_Null = 1, + JSON_Bool = 2, + JSON_Number = 3, + JSON_String = 4, + JSON_Array = 5, + JSON_Object = 6 +}; + +//----------------------------------------------------------------------------- +// ***** JSON + +// JSON object represents a JSON node that can be either a root of the JSON tree +// or a child item. Every node has a type that describes what is is. +// New JSON trees are typically loaded JSON::Load or created with JSON::Parse. + +class JSON : public RefCountBase, public ListNode +{ +protected: + List Children; + +public: + JSONItemType Type; // Type of this JSON node. + String Name; // Name part of the {Name, Value} pair in a parent object. + String Value; + double dValue; + +public: + ~JSON(); + + // *** Creation of NEW JSON objects + + static JSON* CreateObject() { return new JSON(JSON_Object);} + static JSON* CreateNull() { return new JSON(JSON_Null); } + static JSON* CreateArray() { return new JSON(JSON_Array); } + static JSON* CreateBool(bool b); + static JSON* CreateNumber(double num); + static JSON* CreateInt(int num); + static JSON* CreateString(const char *s); + + // Creates a new JSON object from parsing string. + // Returns null pointer and fills in *perror in case of parse error. + static JSON* Parse(const char* buff, const char** perror = 0); + + // This version works for buffers that are not null terminated strings. + static JSON* ParseBuffer(const char *buff, int len, const char** perror = 0); + + // Loads and parses a JSON object from a file. + // Returns 0 and assigns perror with error message on fail. + static JSON* Load(const char* path, const char** perror = 0); + + // Saves a JSON object to a file. + bool Save(const char* path); + + // Return the String representation of a JSON object. + String Stringify(bool fmt); + + // *** Object Member Access + + // These provide access to child items of the list. + bool HasItems() const { return Children.IsEmpty(); } + // Returns first/last child item, or null if child list is empty + JSON* GetFirstItem() { return (!Children.IsEmpty()) ? Children.GetFirst() : 0; } + JSON* GetLastItem() { return (!Children.IsEmpty()) ? Children.GetLast() : 0; } + + // Counts the number of items in the object; these methods are inefficient. + unsigned GetItemCount() const; + JSON* GetItemByIndex(unsigned i); + JSON* GetItemByName(const char* name); + + // Accessors by name + double GetNumberByName(const char *name, double defValue = 0.0); + int GetIntByName(const char *name, int defValue = 0); + bool GetBoolByName(const char *name, bool defValue = false); + String GetStringByName(const char *name, const String &defValue = ""); + int GetArrayByName(const char *name, double values[], int count); + + // Returns next item in a list of children; 0 if no more items exist. + JSON* GetNextItem(JSON* item) { return Children.IsLast (item) ? nullptr : item->GetNext(); } + JSON* GetPrevItem(JSON* item) { return Children.IsFirst(item) ? nullptr : item->GetPrev(); } + + + // Child item access functions + void AddItem(const char *string, JSON* item); + void AddNullItem(const char* name) { AddItem(name, CreateNull()); } + void AddBoolItem(const char* name, bool b) { AddItem(name, CreateBool(b)); } + void AddIntItem(const char* name, int n) { AddItem(name, CreateInt(n)); } + void AddNumberItem(const char* name, double n) { AddItem(name, CreateNumber(n)); } + void AddStringItem(const char* name, const char* s) { AddItem(name, CreateString(s)); } +// void ReplaceItem(unsigned index, JSON* new_item); +// void DeleteItem(unsigned index); + void RemoveLast(); + + // *** Array Element Access + + // Add new elements to the end of array. + void AddArrayElement(JSON *item); + void InsertArrayElement(int index, JSON* item); + void AddArrayNumber(double n) { AddArrayElement(CreateNumber(n)); } + void AddArrayInt(int n) { AddArrayElement(CreateInt(n)); } + void AddArrayString(const char* s) { AddArrayElement(CreateString(s)); } + + // Accessed array elements; currently inefficient. + int GetArraySize(); + double GetArrayNumber(int index); + const char* GetArrayString(int index); + + JSON* Copy(); // Create a copy of this object + + // Return text value of JSON. Use OVR_FREE when done with return value + char* PrintValue(bool fmt); +protected: + JSON(JSONItemType itemType = JSON_Object); + + // JSON Parsing helper functions. + const char* parseValue(const char *buff, const char** perror); + const char* parseNumber(const char *num); + const char* parseArray(const char* value, const char** perror); + const char* parseObject(const char* value, const char** perror); + const char* parseString(const char* str, const char** perror); + + char* PrintValue(int depth, bool fmt); + char* PrintObject(int depth, bool fmt); + char* PrintArray(int depth, bool fmt); +}; + + +} + +#endif // OVR_JSON_h diff --git a/LibOVRKernel/Src/Kernel/OVR_KeyCodes.h b/LibOVRKernel/Src/Kernel/OVR_KeyCodes.h new file mode 100644 index 0000000..12b66a9 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_KeyCodes.h @@ -0,0 +1,255 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_KeyCodes.h +Content : Common keyboard constants +Created : September 19, 2012 + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_KeyCodes_h +#define OVR_KeyCodes_h + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** KeyCode + +// KeyCode enumeration defines platform-independent keyboard key constants. +// Note that Key_A through Key_Z are mapped to capital ascii constants. + +enum KeyCode +{ + // Key_None indicates that no key was specified. + Key_None = 0, + + // A through Z and numbers 0 through 9. + Key_A = 65, + Key_B, + Key_C, + Key_D, + Key_E, + Key_F, + Key_G, + Key_H, + Key_I, + Key_J, + Key_K, + Key_L, + Key_M, + Key_N, + Key_O, + Key_P, + Key_Q, + Key_R, + Key_S, + Key_T, + Key_U, + Key_V, + Key_W, + Key_X, + Key_Y, + Key_Z, + Key_Num0 = 48, + Key_Num1, + Key_Num2, + Key_Num3, + Key_Num4, + Key_Num5, + Key_Num6, + Key_Num7, + Key_Num8, + Key_Num9, + + // Numeric keypad. + Key_KP_0 = 0xa0, + Key_KP_1, + Key_KP_2, + Key_KP_3, + Key_KP_4, + Key_KP_5, + Key_KP_6, + Key_KP_7, + Key_KP_8, + Key_KP_9, + Key_KP_Multiply, + Key_KP_Add, + Key_KP_Enter, + Key_KP_Subtract, + Key_KP_Decimal, + Key_KP_Divide, + + // Function keys. + Key_F1 = 0xb0, + Key_F2, + Key_F3, + Key_F4, + Key_F5, + Key_F6, + Key_F7, + Key_F8, + Key_F9, + Key_F10, + Key_F11, + Key_F12, + Key_F13, + Key_F14, + Key_F15, + + // Other keys. + Key_Backspace = 8, + Key_Tab, + Key_Clear = 12, + Key_Return, + Key_Shift = 16, + Key_Control, + Key_Alt, + Key_Pause, + Key_CapsLock = 20, // Toggle + Key_Escape = 27, + Key_Space = 32, + Key_Quote = 39, + Key_PageUp = 0xc0, + Key_PageDown, + Key_End, + Key_Home, + Key_Left, + Key_Up, + Key_Right, + Key_Down, + Key_Insert, + Key_Delete, + Key_Help, + + // Synthetic mouse wheel state + Key_MouseWheelAwayFromUser, // "forwards" or "up" + Key_MouseWheelTowardUser, // "backwards" or "down" + + Key_Comma = 44, + Key_Minus, + Key_Slash = 47, + Key_Period, + Key_NumLock = 144, // Toggle + Key_ScrollLock = 145, // Toggle + + Key_Semicolon = 59, + Key_Equal = 61, + Key_Backtick = 96, // ` and tilda~ when shifted (US keyboard) + Key_BracketLeft = 91, + Key_Backslash, + Key_BracketRight, + + Key_OEM_AX = 0xE1, // 'AX' key on Japanese AX keyboard + Key_OEM_102 = 0xE2, // "<>" or "\|" on RT 102-key keyboard. + Key_ICO_HELP = 0xE3, // Help key on ICO + Key_ICO_00 = 0xE4, // 00 key on ICO + + Key_Meta, + + // Total number of keys. + Key_CodeCount +}; + + +//----------------------------------------------------------------------------------- + +class KeyModifiers +{ +public: + enum + { + Key_ShiftPressed = 0x01, + Key_CtrlPressed = 0x02, + Key_AltPressed = 0x04, + Key_MetaPressed = 0x08, + Key_CapsToggled = 0x10, + Key_NumToggled = 0x20, + Key_ScrollToggled = 0x40, + + Initialized_Bit = 0x80, + Initialized_Mask = 0xFF + }; + unsigned char States; + + KeyModifiers() : States(0) { } + KeyModifiers(unsigned char st) : States((unsigned char)(st | Initialized_Bit)) { } + + void Reset() { States = 0; } + + bool IsShiftPressed() const { return (States & Key_ShiftPressed) != 0; } + bool IsCtrlPressed() const { return (States & Key_CtrlPressed) != 0; } + bool IsAltPressed() const { return (States & Key_AltPressed) != 0; } + bool IsMetaPressed() const { return (States & Key_MetaPressed) != 0; } + bool IsCapsToggled() const { return (States & Key_CapsToggled) != 0; } + bool IsNumToggled() const { return (States & Key_NumToggled) != 0; } + bool IsScrollToggled() const{ return (States & Key_ScrollToggled) != 0; } + + void SetShiftPressed(bool v = true) { (v) ? States |= Key_ShiftPressed : States &= ~Key_ShiftPressed; } + void SetCtrlPressed(bool v = true) { (v) ? States |= Key_CtrlPressed : States &= ~Key_CtrlPressed; } + void SetAltPressed(bool v = true) { (v) ? States |= Key_AltPressed : States &= ~Key_AltPressed; } + void SetMetaPressed(bool v = true) { (v) ? States |= Key_MetaPressed : States &= ~Key_MetaPressed; } + void SetCapsToggled(bool v = true) { (v) ? States |= Key_CapsToggled : States &= ~Key_CapsToggled; } + void SetNumToggled(bool v = true) { (v) ? States |= Key_NumToggled : States &= ~Key_NumToggled; } + void SetScrollToggled(bool v = true) { (v) ? States |= Key_ScrollToggled: States &= ~Key_ScrollToggled; } + + bool IsInitialized() const { return (States & Initialized_Mask) != 0; } +}; + + +//----------------------------------------------------------------------------------- + +/* +enum PadKeyCode +{ + Pad_None, // Indicates absence of key code. + Pad_Back, + Pad_Start, + Pad_A, + Pad_B, + Pad_X, + Pad_Y, + Pad_R1, // RightShoulder; + Pad_L1, // LeftShoulder; + Pad_R2, // RightTrigger; + Pad_L2, // LeftTrigger; + Pad_Up, + Pad_Down, + Pad_Right, + Pad_Left, + Pad_Plus, + Pad_Minus, + Pad_1, + Pad_2, + Pad_H, + Pad_C, + Pad_Z, + Pad_O, + Pad_T, + Pad_S, + Pad_Select, + Pad_Home, + Pad_RT, // RightThumb; + Pad_LT // LeftThumb; +}; +*/ + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_List.h b/LibOVRKernel/Src/Kernel/OVR_List.h new file mode 100644 index 0000000..70027db --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_List.h @@ -0,0 +1,365 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_List.h +Content : Template implementation for doubly-connected linked List +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_List_h +#define OVR_List_h + +#include "OVR_Types.h" + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** ListNode +// +// Base class for the elements of the intrusive linked list. +// To store elements in the List do: +// +// class MyData : ListNode +// { +// . . . +// }; + +template +class ListNode +{ +private: + ListNode* pPrev; + ListNode* pNext; + + template friend class List; + +public: + T* GetPrev() const { return (T*)(pPrev); } + T* GetNext() const { return (T*)(pNext); } + + ListNode() + { + pPrev = nullptr; + pNext = nullptr; + } + + bool IsInList() + { + return (pNext != nullptr); + } + + void RemoveNode() + { + pPrev->pNext = pNext; + pNext->pPrev = pPrev; + pPrev = nullptr; + pNext = nullptr; + } + + // Removes us from the list and inserts pnew there instead. + void ReplaceNodeWith(T* pnew) + { + pPrev->pNext = pnew; + pNext->pPrev = pnew; + pnew->pPrev = pPrev; + pnew->pNext = pNext; + pPrev = nullptr; + pNext = nullptr; + } + + // Inserts the argument linked list node after us in the list. + void InsertNodeAfter(T* p) + { + p->pPrev = pNext->pPrev; // this + p->pNext = pNext; + pNext->pPrev = p; + pNext = p; + } + // Inserts the argument linked list node before us in the list. + void InsertNodeBefore(T* p) + { + p->pNext = pNext->pPrev; // this + p->pPrev = pPrev; + pPrev->pNext = p; + pPrev = p; + } + + void Alloc_MoveTo(ListNode* pdest) + { + pdest->pNext = pNext; + pdest->pPrev = pPrev; + pPrev->pNext = pdest; + pNext->pPrev = pdest; + pPrev = nullptr; + pNext = nullptr; + } +}; + +//------------------------------------------------------------------------ +// ***** List +// +// Doubly linked intrusive list. +// The data type must be derived from ListNode. +// +// Adding: PushFront(), PushBack(). +// Removing: Remove() - the element must be in the list! +// Moving: BringToFront(), SendToBack() - the element must be in the list! +// +// Iterating: +// MyData* data = MyList.GetFirst(); +// while (!MyList.IsNull(data)) +// { +// . . . +// data = MyList.GetNext(data); +// } +// +// Removing: +// MyData* data = MyList.GetFirst(); +// while (!MyList.IsNull(data)) +// { +// MyData* next = MyList.GetNext(data); +// if (ToBeRemoved(data)) +// MyList.Remove(data); +// data = next; +// } +// + +// List<> represents a doubly-linked list of T, where each T must derive +// from ListNode. B specifies the base class that was directly +// derived from ListNode, and is only necessary if there is an intermediate +// inheritance chain. + +template class List +{ +public: + typedef T ValueType; + + List() + { + Root.pNext = Root.pPrev = &Root; + } + + void Clear() + { + Root.pNext = Root.pPrev = &Root; + } + + size_t GetSize() const + { + size_t n = 0; + + for(const ListNode* pNode = Root.pNext; pNode != &Root; pNode = pNode->pNext) + ++n; + + return n; + } + + const ValueType* GetFirst() const { return IsEmpty() ? nullptr : (const ValueType*)Root.pNext; } + const ValueType* GetLast () const { return IsEmpty() ? nullptr : (const ValueType*)Root.pPrev; } + ValueType* GetFirst() { return IsEmpty() ? nullptr : (ValueType*)Root.pNext; } + ValueType* GetLast () { return IsEmpty() ? nullptr : (ValueType*)Root.pPrev; } + + // Determine if list is empty (i.e.) points to itself. + // Go through void* access to avoid issues with strict-aliasing optimizing out the + // access after RemoveNode(), etc. + bool IsEmpty() const { return Root.pNext == &Root; } + bool IsFirst(const ValueType* p) const { return p == Root.pNext; } + bool IsLast (const ValueType* p) const { return p == Root.pPrev; } + bool IsNull (const ListNode* p) const { return p == nullptr || p == &Root; } + + inline const ValueType* GetPrev(const ValueType* p) const { return IsNull(p->pPrev) ? nullptr : (const ValueType*)p->pPrev; } + inline const ValueType* GetNext(const ValueType* p) const { return IsNull(p->pNext) ? nullptr : (const ValueType*)p->pNext; } + inline ValueType* GetPrev( ValueType* p) { return IsNull(p->pPrev) ? nullptr : (ValueType*)p->pPrev; } + inline ValueType* GetNext( ValueType* p) { return IsNull(p->pNext) ? nullptr : (ValueType*)p->pNext; } + + void PushFront(ValueType* p) + { + p->pNext = Root.pNext; + p->pPrev = &Root; + Root.pNext->pPrev = p; + Root.pNext = p; + } + + void PushBack(ValueType* p) + { + p->pPrev = Root.pPrev; + p->pNext = &Root; + Root.pPrev->pNext = p; + Root.pPrev = p; + } + + static void Remove(ValueType* p) + { + p->pPrev->pNext = p->pNext; + p->pNext->pPrev = p->pPrev; + p->pPrev = nullptr; + p->pNext = nullptr; + } + + void BringToFront(ValueType* p) + { + Remove(p); + PushFront(p); + } + + void SendToBack(ValueType* p) + { + Remove(p); + PushBack(p); + } + + // Appends the contents of the argument list to the front of this list; + // items are removed from the argument list. + void PushListToFront(List& src) + { + if (!src.IsEmpty()) + { + ValueType* pfirst = src.GetFirst(); + ValueType* plast = src.GetLast(); + src.Clear(); + plast->pNext = Root.pNext; + pfirst->pPrev = &Root; + Root.pNext->pPrev = plast; + Root.pNext = pfirst; + } + } + + void PushListToBack(List& src) + { + if (!src.IsEmpty()) + { + ValueType* pfirst = src.GetFirst(); + ValueType* plast = src.GetLast(); + src.Clear(); + plast->pNext = &Root; + pfirst->pPrev = Root.pPrev; + Root.pPrev->pNext = pfirst; + Root.pPrev = plast; + } + } + + // Removes all source list items after (and including) the 'pfirst' node from the + // source list and adds them to out list. + void PushFollowingListItemsToFront(List& src, ValueType *pfirst) + { + if (pfirst != &src.Root) + { + ValueType *plast = src.Root.pPrev; + + // Remove list remainder from source. + pfirst->pPrev->pNext = &src.Root; + src.Root.pPrev = pfirst->pPrev; + // Add the rest of the items to list. + plast->pNext = Root.pNext; + pfirst->pPrev = &Root; + Root.pNext->pPrev = plast; + Root.pNext = pfirst; + } + } + + // Removes all source list items up to but NOT including the 'pend' node from the + // source list and adds them to out list. + void PushPrecedingListItemsToFront(List& src, ValueType *ptail) + { + if (src.GetFirst() != ptail) + { + ValueType *pfirst = src.Root.pNext; + ValueType *plast = ptail->pPrev; + + // Remove list remainder from source. + ptail->pPrev = &src.Root; + src.Root.pNext = ptail; + + // Add the rest of the items to list. + plast->pNext = Root.pNext; + pfirst->pPrev = &Root; + Root.pNext->pPrev = plast; + Root.pNext = pfirst; + } + } + + + // Removes a range of source list items starting at 'pfirst' and up to, but not including 'pend', + // and adds them to out list. Note that source items MUST already be in the list. + void PushListItemsToFront(ValueType *pfirst, ValueType *pend) + { + if (pfirst != pend) + { + ValueType *plast = pend->pPrev; + + // Remove list remainder from source. + pfirst->pPrev->pNext = pend; + pend->pPrev = pfirst->pPrev; + // Add the rest of the items to list. + plast->pNext = Root.pNext; + pfirst->pPrev = &Root; + Root.pNext->pPrev = plast; + Root.pNext = pfirst; + } + } + + + void Alloc_MoveTo(List* pdest) + { + if (IsEmpty()) + pdest->Clear(); + else + { + pdest->Root.pNext = Root.pNext; + pdest->Root.pPrev = Root.pPrev; + + Root.pNext->pPrev = &pdest->Root; + Root.pPrev->pNext = &pdest->Root; + } + } + + +private: + // Copying is prohibited + List(const List&); + const List& operator = (const List&); + + ListNode Root; +}; + + +//------------------------------------------------------------------------ +// ***** FreeListElements +// +// Remove all elements in the list and free them in the allocator + +template +void FreeListElements(List& list, Allocator& allocator) +{ + typename List::ValueType* self = list.GetFirst(); + while(!list.IsNull(self)) + { + typename List::ValueType* next = list.GetNext(self); + allocator.Free(self); + self = next; + } + list.Clear(); +} + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Lockless.cpp b/LibOVRKernel/Src/Kernel/OVR_Lockless.cpp new file mode 100644 index 0000000..6a5ec6b --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Lockless.cpp @@ -0,0 +1,225 @@ +/************************************************************************************ + +Filename : OVR_Lockless.cpp +Content : Test logic for lock-less classes +Created : December 27, 2013 +Authors : Michael Antonov + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "OVR_Lockless.h" + +#ifdef OVR_LOCKLESS_TEST + +#include "OVR_Threads.h" +#include "OVR_Timer.h" +#include "OVR_Log.h" + +namespace OVR { namespace LocklessTest { + + +const int TestIterations = 10000000; + +// Use volatile dummies to force compiler to do spinning. +volatile int Dummy1; +int Unused1[32]; +volatile int Dummy2; +int Unused2[32]; +volatile int Dummy3; +int Unused3[32]; + + +// Data block out of 20 consecutive integers, should be internally consistent. +struct TestData +{ + enum { ItemCount = 20 }; + + int Data[ItemCount]; + + + void Set(int val) + { + for (int i=0; i TestDataUpdater; + +// Use this lock to verify that testing algorithm is otherwise correct... +Lock TestLock; + + +//------------------------------------------------------------------------------------- + +// Consumer thread reads values from TestDataUpdater and +// ensures that each one is internally consistent. + +class Consumer : public Thread +{ + virtual int Run() + { + LogText("LocklessTest::Consumer::Run started.\n"); + + while (!FirstItemWritten) + { + // spin until producer wrote first value... + } + + TestData d; + int oldValue = 0; + int newValue; + + do + { + { + //Lock::Locker scope(&TestLock); + d = TestDataUpdater.GetState(); + } + + newValue = d.ReadAndCheckConsistency(oldValue); + + // Values should increase or stay the same! + if (newValue < oldValue) + { + LogText("LocklessTest Fail - %d after %d; delta = %d\n", + newValue, oldValue, newValue - oldValue); + // OVR_ASSERT(0); + } + + + if (oldValue != newValue) + { + oldValue = newValue; + + if (oldValue % (TestIterations/30) == 0) + { + LogText("LocklessTest::Consumer - %5.2f%% done\n", + 100.0f * (float)oldValue/(float)TestIterations); + } + } + + // Spin a while + for (int j = 0; j< 300; j++) + { + Dummy3 = j; + } + + + } while (oldValue < (TestIterations * 99 / 100)); + + LogText("LocklessTest::Consumer::Run exiting.\n"); + return 0; + } + +}; + + +//------------------------------------------------------------------------------------- + +class Producer : public Thread +{ + + virtual int Run() + { + LogText("LocklessTest::Producer::Run started.\n"); + + for (int testVal = 0; testVal < TestIterations; testVal++) + { + TestData d; + d.Set(testVal); + + { + //Lock::Locker scope(&TestLock); + TestDataUpdater.SetState(d); + } + + FirstItemWritten = true; + + // Spin a bit + for(int j = 0; j < 1000; j++) + { + Dummy2 = j; + } + + if (testVal % (TestIterations/30) == 0) + { + LogText("LocklessTest::Producer - %5.2f%% done\n", + 100.0f * (float)testVal/(float)TestIterations); + } + } + + LogText("LocklessTest::Producer::Run exiting.\n"); + return 0; + } +}; + + +} // namespace LocklessTest + + + +void StartLocklessTest() +{ + // These threads will release themselves once done + Ptr producerThread = *new LocklessTest::Producer; + Ptr consumerThread = *new LocklessTest::Consumer; + + producerThread->Start(); + consumerThread->Start(); + + while (!producerThread->IsFinished() && consumerThread->IsFinished()) + { + Thread::MSleep(500); + } +} + + +} // namespace OVR + +#endif // OVR_LOCKLESS_TEST diff --git a/LibOVRKernel/Src/Kernel/OVR_Lockless.h b/LibOVRKernel/Src/Kernel/OVR_Lockless.h new file mode 100644 index 0000000..f9043a9 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Lockless.h @@ -0,0 +1,117 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Lockless.h +Content : Lock-less classes for producer/consumer communication +Created : November 9, 2013 +Authors : John Carmack + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Lockless_h +#define OVR_Lockless_h + +#include "OVR_Atomic.h" + +// Define this to compile-in Lockless test logic +//#define OVR_LOCKLESS_TEST + +namespace OVR { + + +// ***** LocklessUpdater + +// For single producer cases where you only care about the most recent update, not +// necessarily getting every one that happens (vsync timing, SensorFusion updates). +// +// This is multiple consumer safe, but is currently only used with a single consumer. +// +// The SlotType can be the same as T, but should probably be a larger fixed size. +// This allows for forward compatibility when the updater is shared between processes. + +// FIXME: ExchangeAdd_Sync() should be replaced with a portable read-only primitive, +// so that the lockless pose state can be read-only on remote processes and to reduce +// false sharing between processes and improve performance. + +template +class LocklessUpdater +{ +public: + LocklessUpdater() : UpdateBegin( 0 ), UpdateEnd( 0 ) + { + OVR_COMPILER_ASSERT(sizeof(T) <= sizeof(SlotType)); + } + + T GetState() const + { + // Copy the state out, then retry with the alternate slot + // if we determine that our copy may have been partially + // stepped on by a new update. + T state; + int begin, end, final; + + for(;;) + { + // We are adding 0, only using these as atomic memory barriers, so it + // is ok to cast off the const, allowing GetState() to remain const. + end = UpdateEnd.Load_Acquire(); + state = Slots[ end & 1 ]; + begin = UpdateBegin.Load_Acquire(); + if ( begin == end ) { + break; + } + + // The producer is potentially blocked while only having partially + // written the update, so copy out the other slot. + state = Slots[ (begin & 1) ^ 1 ]; + final = UpdateBegin.Load_Acquire(); + if ( final == begin ) { + break; + } + + // The producer completed the last update and started a new one before + // we got it copied out, so try fetching the current buffer again. + } + return state; + } + + void SetState( const T& state ) + { + const int slot = UpdateBegin.ExchangeAdd_Sync(1) & 1; + // Write to (slot ^ 1) because ExchangeAdd returns 'previous' value before add. + Slots[slot ^ 1] = state; + UpdateEnd.ExchangeAdd_Sync(1); + } + + AtomicInt UpdateBegin; + AtomicInt UpdateEnd; + SlotType Slots[2]; +}; + + +#ifdef OVR_LOCKLESS_TEST +void StartLocklessTest(); +#endif + + +} // namespace OVR + +#endif // OVR_Lockless_h + diff --git a/LibOVRKernel/Src/Kernel/OVR_Log.cpp b/LibOVRKernel/Src/Kernel/OVR_Log.cpp new file mode 100644 index 0000000..4f8fc53 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Log.cpp @@ -0,0 +1,504 @@ +/************************************************************************************ + +Filename : OVR_Log.cpp +Content : Logging support +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Log.h" +#include "OVR_Std.h" +#include +#include +#include +#include "OVR_System.h" +#include "OVR_DebugHelp.h" +#include +#include + +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) +#include "OVR_Win32_IncludeWindows.h" +#elif defined(OVR_OS_ANDROID) +#include +#elif defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) +#include +#endif + + +//----------------------------------------------------------------------------------- +// ***** LogSubject + +static bool LogSubject_IsReady = false; + +class LogSubject : public OVR::SystemSingletonBase +{ + OVR_DECLARE_SINGLETON(LogSubject); + +public: + void AddListener(OVR::CallbackListener *listener) + { + OVR::Lock::Locker locker(&SubjectLock); + Subject.AddListener(listener); + } + + void Call(const char* message, OVR::LogMessageType type) + { + OVR::Lock::Locker locker(&SubjectLock); + Subject.Call(message, type); + } + +protected: + virtual void OnThreadDestroy(); // Listen to thread shutdown event + + OVR::CallbackEmitter Subject; + + // This lock is needed because AddListener() and Call() can happen on different + // threads but CallbackEmitter is not thread-safe. + OVR::Lock SubjectLock; +}; + +LogSubject::LogSubject() +{ + LogSubject_IsReady = true; + + // Must be at end of function + PushDestroyCallbacks(); +} + +LogSubject::~LogSubject() +{ +} + +void LogSubject::OnThreadDestroy() +{ + LogSubject_IsReady = false; +} + +void LogSubject::OnSystemDestroy() +{ + delete this; +} + +OVR_DEFINE_SINGLETON(LogSubject); + + +namespace OVR { + + +// Global Log pointer. +Log* OVR_GlobalLog = nullptr; +Log::CAPICallback OVR_CAPICallback = nullptr; + + +//----------------------------------------------------------------------------------- +// ***** Log Implementation + +Log::Log(unsigned logMask) : + LoggingMask(logMask) +{ +#ifdef OVR_OS_WIN32 + hEventSource = RegisterEventSourceA(NULL, "OculusVR"); + OVR_ASSERT(hEventSource != NULL); +#endif +} + +Log::~Log() +{ +#ifdef OVR_OS_WIN32 + if (hEventSource) + { + DeregisterEventSource(hEventSource); + } +#endif + + // Clear out global log + if (this == OVR_GlobalLog) + { + // TBD: perhaps we should ASSERT if this happens before system shutdown? + OVR_GlobalLog = 0; + } +} + +void Log::SetCAPICallback(CAPICallback callback) +{ + if (!OVR::System::IsInitialized()) + { + OVR_CAPICallback = callback; + } +} + +void Log::AddLogObserver(CallbackListener* listener) +{ + if (OVR::System::IsInitialized() && LogSubject_IsReady) + { + LogSubject::GetInstance()->AddListener(listener); + } +} + +static void RouteLogOutput(const char* message, LogMessageType messageType) +{ + int level = int(LogLevel_Debug); + if (Log::IsDebugMessage(messageType)) + { + TraceLogDebug(message); + } + else if (messageType == OVR::Log_Error) + { + level = int(LogLevel_Error); + TraceLogError(message); + } + else + { + level = int(LogLevel_Info); + TraceLogInfo(message); + } + + if (OVR_CAPICallback) + OVR_CAPICallback(level, message); + + LogSubject::GetInstance()->Call(message, messageType); +} + +void Log::LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList) +{ + if (OVR::System::IsInitialized()) + { + // Invoke subject + char buffer[MaxLogBufferMessageSize]; + char* pBuffer = buffer; + char* pAllocated = NULL; + + #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. + va_list argListSaved; + va_copy(argListSaved, argList); + #endif + + int result = FormatLog(pBuffer, MaxLogBufferMessageSize, Log_Text, fmt, argList); + + if(result >= MaxLogBufferMessageSize) // If there was insufficient capacity... + { + // We assume C++ exceptions are disabled. + // FormatLog will handle the case that pAllocated is NULL. + pAllocated = new char [result + 1]; + // We cannot use OVR_ALLOC() for this allocation because the logging subsystem exists + // outside of the rest of LibOVR so that it can be used to log events from anywhere. + pBuffer = pAllocated; + + #if !defined(OVR_CC_MSVC) + va_end(argList); // The caller owns argList and will call va_end on it. + va_copy(argList, argListSaved); + #endif + + FormatLog(pBuffer, (size_t)result + 1, Log_Text, fmt, argList); + } + + RouteLogOutput(pBuffer, messageType); + + delete[] pAllocated; + } +} + +void Log::LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList) +{ + if ((messageType & LoggingMask) == 0) + return; +#ifndef OVR_BUILD_DEBUG + if (IsDebugMessage(messageType)) + return; +#endif + + char buffer[MaxLogBufferMessageSize]; + char* pBuffer = buffer; + char* pAllocated = NULL; + + #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. + va_list argListSaved; + va_copy(argListSaved, argList); + #endif + + int result = FormatLog(pBuffer, MaxLogBufferMessageSize, messageType, fmt, argList); + + if(result >= MaxLogBufferMessageSize) // If there was insufficient capacity... + { + // We assume C++ exceptions are disabled. + // FormatLog will handle the case that pAllocated is NULL. + pAllocated = new char [result + 1]; + // We cannot use OVR_ALLOC() for this allocation because the logging subsystem exists + // outside of the rest of LibOVR so that it can be used to log events from anywhere. + pBuffer = pAllocated; + + #if !defined(OVR_CC_MSVC) + va_end(argList); // The caller owns argList and will call va_end on it. + va_copy(argList, argListSaved); + #endif + + FormatLog(pBuffer, (size_t)result + 1, messageType, fmt, argList); + } + + DefaultLogOutput(pBuffer, messageType, result); + delete[] pAllocated; +} + +void OVR::Log::LogMessage(LogMessageType messageType, const char* pfmt, ...) +{ + va_list argList; + va_start(argList, pfmt); + LogMessageVarg(messageType, pfmt, argList); + va_end(argList); +} + + +// Return behavior is the same as ISO C vsnprintf: returns the required strlen of buffer (which will +// be >= bufferSize if bufferSize is insufficient) or returns a negative value because the input was bad. +int Log::FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType, + const char* fmt, va_list argList) +{ + OVR_ASSERT(buffer && (bufferSize >= 10)); // Need to be able to at least print "Assert: \n" to it. + if(!buffer || (bufferSize < 10)) + return -1; + + int addNewline = 1; + int prefixLength = 0; + + switch(messageType) + { + case Log_Error: OVR_strcpy(buffer, bufferSize, "Error: "); prefixLength = 7; break; + case Log_Debug: OVR_strcpy(buffer, bufferSize, "Debug: "); prefixLength = 7; break; + case Log_Assert: OVR_strcpy(buffer, bufferSize, "Assert: "); prefixLength = 8; break; + case Log_Text: buffer[0] = 0; addNewline = 0; break; + case Log_DebugText: buffer[0] = 0; addNewline = 0; break; + default: buffer[0] = 0; addNewline = 0; break; + } + + char* buffer2 = buffer + prefixLength; + size_t size2 = bufferSize - (size_t)prefixLength; + int messageLength = OVR_vsnprintf(buffer2, size2, fmt, argList); + + if (addNewline) + { + if (messageLength < 0) // If there was a format error... + { + // To consider: append to the buffer here. + buffer2[0] = '\n'; // We are guaranteed to have capacity for this. + buffer2[1] = '\0'; + } + else + { + // If the printed string used all of the capacity or required more than the capacity, + // Chop the output by one character so we can append the \n safely. + int messageEnd = (messageLength >= (int)(size2 - 1)) ? (int)(size2 - 2) : messageLength; + buffer2[messageEnd + 0] = '\n'; + buffer2[messageEnd + 1] = '\0'; + } + } + + if (messageLength >= 0) // If the format was OK... + return prefixLength + messageLength + addNewline; // Return the required strlen of buffer. + + return messageLength; // Else we cannot know what the required strlen is and return the error to the caller. +} + +void Log::DefaultLogOutput(const char* formattedText, LogMessageType messageType, int bufferSize) +{ + OVR_UNUSED2(bufferSize, formattedText); + +#if defined(OVR_OS_WIN32) + + ::OutputDebugStringA(formattedText); + fputs(formattedText, stdout); + +#elif defined(OVR_OS_MS) // Any other Microsoft OSs + + ::OutputDebugStringA(formattedText); + +#elif defined(OVR_OS_ANDROID) + // To do: use bufferSize to deal with the case that Android has a limited output length. + __android_log_write(ANDROID_LOG_INFO, "OVR", formattedText); + +#else + fputs(formattedText, stdout); + +#endif + + if (messageType == Log_Error) + { +#if defined(OVR_OS_WIN32) + if (!ReportEventA(hEventSource, EVENTLOG_ERROR_TYPE, 0, 0, NULL, 1, 0, &formattedText, NULL)) + { + OVR_ASSERT(false); + } +#elif defined(OVR_OS_MS) // Any other Microsoft OSs + // TBD +#elif defined(OVR_OS_ANDROID) + // TBD +#elif defined(OVR_OS_MAC) || defined(OVR_OS_LINUX) + syslog(LOG_ERR, "%s", formattedText); +#else + // TBD +#endif + } +} + + +//static +void Log::SetGlobalLog(Log *log) +{ + OVR_GlobalLog = log; +} +//static +Log* Log::GetGlobalLog() +{ +// No global log by default? +// if (!OVR_GlobalLog) +// OVR_GlobalLog = GetDefaultLog(); + return OVR_GlobalLog; +} + +//static +Log* Log::GetDefaultLog() +{ + // Create default log pointer statically so that it can be used + // even during startup. + static Log defaultLog; + return &defaultLog; +} + + +//----------------------------------------------------------------------------------- +// ***** Global Logging functions + +#if !defined(OVR_CC_MSVC) +// The reason for va_copy is because you can't use va_start twice on Linux +#define OVR_LOG_FUNCTION_IMPL(Name) \ + void Log##Name(const char* fmt, ...) \ + { \ + if (OVR_GlobalLog) \ + { \ + va_list argList1; \ + va_start(argList1, fmt); \ + va_list argList2; \ + va_copy(argList2, argList1); \ + OVR_GlobalLog->LogMessageVargInt(Log_##Name, fmt, argList2); \ + va_end(argList2); \ + OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList1); \ + va_end(argList1); \ + } \ + } +#else +#define OVR_LOG_FUNCTION_IMPL(Name) \ + void Log##Name(const char* fmt, ...) \ + { \ + if (OVR_GlobalLog) \ + { \ + va_list argList1; \ + va_start(argList1, fmt); \ + OVR_GlobalLog->LogMessageVargInt(Log_##Name, fmt, argList1); \ + OVR_GlobalLog->LogMessageVarg(Log_##Name, fmt, argList1); \ + va_end(argList1); \ + } \ + } +#endif // #if !defined(OVR_OS_WIN32) + +OVR_LOG_FUNCTION_IMPL(Text) +OVR_LOG_FUNCTION_IMPL(Error) + +#ifdef OVR_BUILD_DEBUG +OVR_LOG_FUNCTION_IMPL(DebugText) +OVR_LOG_FUNCTION_IMPL(Debug) +OVR_LOG_FUNCTION_IMPL(Assert) +#endif + + + +// Assertion handler support +// To consider: Move this to an OVR_Types.cpp or OVR_Assert.cpp source file. + +static OVRAssertionHandler sOVRAssertionHandler = OVR::DefaultAssertionHandler; +static intptr_t sOVRAssertionHandlerUserParameter = 0; + +OVRAssertionHandler GetAssertionHandler(intptr_t* userParameter) +{ + if(userParameter) + *userParameter = sOVRAssertionHandlerUserParameter; + return sOVRAssertionHandler; +} + +void SetAssertionHandler(OVRAssertionHandler assertionHandler, intptr_t userParameter) +{ + sOVRAssertionHandler = assertionHandler; + sOVRAssertionHandlerUserParameter = userParameter; +} + +intptr_t DefaultAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message) +{ + if(OVRIsDebuggerPresent()) + { + OVR_DEBUG_BREAK; + } + else + { + OVR_UNUSED(title); + OVR_UNUSED(message); + + #if defined(OVR_BUILD_DEBUG) + if(Allocator::GetInstance()) // The code below currently depends on having a valid Allocator. + { + // Print a stack trace of all threads. + OVR::String s; + OVR::String threadListOutput; + static OVR::SymbolLookup symbolLookup; + + s = "Failure: "; + s += message; + + if(symbolLookup.Initialize() && symbolLookup.ReportThreadCallstack(threadListOutput, 4)) // This '4' is there to skip our internal handling and retrieve starting at the assertion location (our caller) only. + { + // threadListOutput has newlines that are merely \n, whereas Windows MessageBox wants \r\n newlines. So we insert \r in front of all \n. + for(size_t i = 0, iEnd = threadListOutput.GetSize(); i < iEnd; i++) + { + if(threadListOutput[i] == '\n') + { + threadListOutput.Insert("\r", i, 1); + ++i; + ++iEnd; + } + } + + s += "\r\n\r\n"; + s += threadListOutput; + } + + OVR::Util::DisplayMessageBox(title, s.ToCStr()); + } + else + { + OVR::Util::DisplayMessageBox(title, message); + } + #else + OVR::Util::DisplayMessageBox(title, message); + #endif + } + + return 0; +} + + +} // OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_Log.h b/LibOVRKernel/Src/Kernel/OVR_Log.h new file mode 100644 index 0000000..9d38457 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Log.h @@ -0,0 +1,240 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_Log.h +Content : Logging support +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Log_h +#define OVR_Log_h + +#include "OVR_Types.h" +#include "OVR_Delegates.h" +#include "OVR_Callbacks.h" +#include + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** Logging Constants + +// LogMaskConstants defined bit mask constants that describe what log messages +// should be displayed. +enum LogMaskConstants +{ + LogMask_Regular = 0x100, + LogMask_Debug = 0x200, + LogMask_None = 0, + LogMask_All = LogMask_Regular|LogMask_Debug +}; + +// LogLevel should match the CAPI ovrLogLevel enum, values are passed back to ovrLogCallback +enum LogLevel +{ + LogLevel_Debug = 0, + LogLevel_Info = 1, + LogLevel_Error = 2 +}; + +// LogMessageType describes the type of the log message, controls when it is +// displayed and what prefix/suffix is given to it. Messages are subdivided into +// regular and debug logging types. Debug logging is only generated in debug builds. +// +// Log_Text - General output text displayed without prefix or new-line. +// Used in OVR libraries for general log flow messages +// such as "Device Initialized". +// +// Log_Error - Error message output with "Error: %s\n", intended for +// application/sample-level use only, in cases where an expected +// operation failed. OVR libraries should not use this internally, +// reporting status codes instead. +// +// Log_DebugText - Message without prefix or new lines; output in Debug build only. +// +// Log_Debug - Debug-build only message, formatted with "Debug: %s\n". +// Intended to comment on incorrect API usage that doesn't lead +// to crashes but can be avoided with proper use. +// There is no Debug Error on purpose, since real errors should +// be handled by API user. +// +// Log_Assert - Debug-build only message, formatted with "Assert: %s\n". +// Intended for severe unrecoverable conditions in library +// source code. Generated though OVR_ASSERT_MSG(c, "Text"). + +enum LogMessageType +{ + // General Logging + Log_Text = LogMask_Regular | 0, + Log_Error = LogMask_Regular | 1, // "Error: %s\n". + + // Debug-only messages (not generated in release build) + Log_DebugText = LogMask_Debug | 0, + Log_Debug = LogMask_Debug | 1, // "Debug: %s\n". + Log_Assert = LogMask_Debug | 2, // "Assert: %s\n". +}; + + +// LOG_VAARG_ATTRIBUTE macro, enforces printf-style formatting for message types +#ifdef __GNUC__ +# define OVR_LOG_VAARG_ATTRIBUTE(a,b) __attribute__((format (printf, a, b))) +#else +# define OVR_LOG_VAARG_ATTRIBUTE(a,b) +#endif + +//----------------------------------------------------------------------------------- +// ***** Log + +// Log defines a base class interface that can be implemented to catch both +// debug and runtime messages. +// Debug logging can be overridden by calling Log::SetGlobalLog. + +class Log +{ + friend class System; + +#ifdef OVR_OS_WIN32 + void* hEventSource; +#endif + +public: + Log(unsigned logMask = LogMask_Debug); + virtual ~Log(); + + typedef Delegate2 LogHandler; + + // The following is deprecated, as there is no longer a max log buffer message size. + enum { MaxLogBufferMessageSize = 4096 }; + + unsigned GetLoggingMask() const { return LoggingMask; } + void SetLoggingMask(unsigned logMask) { LoggingMask = logMask; } + + static void AddLogObserver(CallbackListener* listener); + + // This is the same callback signature as in the CAPI. + typedef void (*CAPICallback)(int level, const char* message); + + // This function should be called before OVR::Initialize() + static void SetCAPICallback(CAPICallback callback); + + // Internal + // Invokes observers, then calls LogMessageVarg() + static void LogMessageVargInt(LogMessageType messageType, const char* fmt, va_list argList); + + // This virtual function receives all the messages, + // developers should override this function in order to do custom logging + virtual void LogMessageVarg(LogMessageType messageType, const char* fmt, va_list argList); + + // Call the logging function with specific message type, with no type filtering. + void LogMessage(LogMessageType messageType, + const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(3,4); + + + // Helper used by LogMessageVarg to format the log message, writing the resulting + // string into buffer. It formats text based on fmt and appends prefix/new line + // based on LogMessageType. Return behavior is the same as ISO C vsnprintf: returns the + // required strlen of buffer (which will be >= bufferSize if bufferSize is insufficient) + // or returns a negative value because the input was bad. + static int FormatLog(char* buffer, size_t bufferSize, LogMessageType messageType, + const char* fmt, va_list argList); + + // Default log output implementation used by by LogMessageVarg. + // Debug flag may be used to re-direct output on some platforms, but doesn't + // necessarily disable it in release builds; that is the job of the called. + void DefaultLogOutput(const char* textBuffer, LogMessageType messageType, int bufferSize = -1); + + // Determines if the specified message type is for debugging only. + static bool IsDebugMessage(LogMessageType messageType) + { + return (messageType & LogMask_Debug) != 0; + } + + // *** Global APIs + + // Global Log registration APIs. + // - Global log is used for OVR_DEBUG messages. Set global log to null (0) + // to disable all logging. + static void SetGlobalLog(Log *log); + static Log* GetGlobalLog(); + + // Returns default log singleton instance. + static Log* GetDefaultLog(); + + // Applies logMask to the default log and returns a pointer to it. + // By default, only Debug logging is enabled, so to avoid SDK generating console + // messages in user app (those are always disabled in release build, + // even if the flag is set). This function is useful in System constructor. + static Log* ConfigureDefaultLog(unsigned logMask = LogMask_Debug) + { + Log* log = GetDefaultLog(); + log->SetLoggingMask(logMask); + return log; + } + +private: + // Logging mask described by LogMaskConstants. + unsigned LoggingMask; +}; + + +//----------------------------------------------------------------------------------- +// ***** Global Logging Functions and Debug Macros + +// These functions will output text to global log with semantics described by +// their LogMessageType. +void LogText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); +void LogError(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); + +#ifdef OVR_BUILD_DEBUG + + // Debug build only logging. + void LogDebugText(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); + void LogDebug(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); + void LogAssert(const char* fmt, ...) OVR_LOG_VAARG_ATTRIBUTE(1,2); + + // Macro to do debug logging, printf-style. + // An extra set of set of parenthesis must be used around arguments, + // as in: OVR_DEBUG_LOG(("Value %d", 2)). + #define OVR_DEBUG_LOG(args) do { OVR::LogDebug args; } while(0) + #define OVR_DEBUG_LOG_TEXT(args) do { OVR::LogDebugText args; } while(0) + + // Conditional logging. It logs when the condition 'c' is true. + #define OVR_DEBUG_LOG_COND(c, args) do { if ((c)) { OVR::LogDebug args; } } while(0) + #define OVR_DEBUG_LOG_TEXT_COND(c, args) do { if ((c)) { OVR::LogDebugText args; } } while(0) + + // Conditional logging & asserting. It asserts/logs when the condition 'c' is NOT true. + #define OVR_ASSERT_LOG(c, args) do { if (!(c)) { OVR::LogAssert args; OVR_DEBUG_BREAK; } } while(0) + +#else + + // If not in debug build, macros do nothing. + #define OVR_DEBUG_LOG(args) ((void)0) + #define OVR_DEBUG_LOG_TEXT(args) ((void)0) + #define OVR_DEBUG_LOG_COND(c, args) ((void)0) + #define OVR_DEBUG_LOG_TEXT_COND(args) ((void)0) + #define OVR_ASSERT_LOG(c, args) ((void)0) + +#endif + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Nullptr.h b/LibOVRKernel/Src/Kernel/OVR_Nullptr.h new file mode 100644 index 0000000..a09f446 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Nullptr.h @@ -0,0 +1,150 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Nullptr.h +Content : Implements C++11 nullptr for the case that the compiler doesn't. +Created : June 19, 2014 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Nullptr_h +#define OVR_Nullptr_h + +#pragma once + +#include "OVR_Types.h" + + +//----------------------------------------------------------------------------------- +// ***** OVR_HAVE_std_nullptr_t +// +// Identifies if includes std::nullptr_t. +// +#if !defined(OVR_HAVE_std_nullptr_t) && defined(OVR_CPP11_ENABLED) + #if defined(OVR_STDLIB_LIBCPP) + #define OVR_HAVE_std_nullptr_t 1 + #elif defined(OVR_STDLIB_LIBSTDCPP) + #if (__GLIBCXX__ >= 20110325) && (__GLIBCXX__ != 20110428) && (__GLIBCXX__ != 20120702) + #define OVR_HAVE_std_nullptr_t 1 + #endif + #elif defined(_MSC_VER) && (_MSC_VER >= 1600) // VS2010+ + #define OVR_HAVE_std_nullptr_t 1 + #elif defined(__clang__) + #define OVR_HAVE_std_nullptr_t 1 + #elif defined(OVR_CPP_GNUC) && (OVR_CC_VERSION >= 406) // GCC 4.6+ + #define OVR_HAVE_std_nullptr_t 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** nullptr / std::nullptr_t +// +// Declares and defines nullptr and related types. +// +#if defined(OVR_CPP_NO_NULLPTR) + namespace std + { + class nullptr_t + { + public: + template + operator T*() const + { return 0; } + + template + operator T C::*() const + { return 0; } + + #if OVR_CPP_NO_EXPLICIT_CONVERSION_OPERATORS + typedef void* (nullptr_t::*bool_)() const; // 4.12,p1. We can't portably use operator bool(){ return false; } because bool + operator bool_() const // is convertable to int which breaks other required functionality. + { return false; } + #else + operator bool() const + { return false; } + #endif + + private: + void operator&() const; // 5.2.10,p9 + }; + + inline nullptr_t nullptr_get() + { + nullptr_t n = { }; + return n; + } + + #if !defined(nullptr) + #define nullptr nullptr_get() + #endif + + } // namespace std + + + // 5.9,p2 p4 + // 13.6, p13 + template + inline bool operator==(T* pT, const std::nullptr_t) + { return pT == 0; } + + template + inline bool operator==(const std::nullptr_t, T* pT) + { return pT == 0; } + + template + inline bool operator==(const std::nullptr_t, T U::* pU) + { return pU == 0; } + + template + inline bool operator==(T U::* pTU, const std::nullptr_t) + { return pTU == 0; } + + inline bool operator==(const std::nullptr_t, const std::nullptr_t) + { return true; } + + inline bool operator!=(const std::nullptr_t, const std::nullptr_t) + { return false; } + + inline bool operator<(const std::nullptr_t, const std::nullptr_t) + { return false; } + + inline bool operator<=(const std::nullptr_t, const std::nullptr_t) + { return true; } + + inline bool operator>(const std::nullptr_t, const std::nullptr_t) + { return false; } + + inline bool operator>=(const std::nullptr_t, const std::nullptr_t) + { return true; } + + using std::nullptr_t; + using std::nullptr_get; + +// Some compilers natively support C++11 nullptr but the standard library being used +// doesn't declare std::nullptr_t, in which case we provide one ourselves. +#elif !defined(OVR_HAVE_std_nullptr_t) && !defined(OVR_CPP_NO_DECLTYPE) + namespace std { typedef decltype(nullptr) nullptr_t; } +#endif + + +#endif + diff --git a/LibOVRKernel/Src/Kernel/OVR_Rand.cpp b/LibOVRKernel/Src/Kernel/OVR_Rand.cpp new file mode 100644 index 0000000..3d6f50e --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Rand.cpp @@ -0,0 +1,79 @@ +/************************************************************************** + +Filename : OVR_Rand.cpp +Content : Random number generator +Created : Aug 28, 2014 +Author : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Rand.h" +#include "OVR_Timer.h" + +namespace OVR { + + +void RandomNumberGenerator::SeedRandom() +{ + uint64_t seed = Timer::GetTicksNanos(); + + uint32_t x = (uint32_t)seed, y = (uint32_t)(seed >> 32); + + Seed(x, y); +} + +void RandomNumberGenerator::Seed(uint32_t x, uint32_t y) +{ + // Based on the mixing functions of MurmurHash3 + static const uint64_t C1 = 0xff51afd7ed558ccdULL; + static const uint64_t C2 = 0xc4ceb9fe1a85ec53ULL; + + x += y; + y += x; + + uint64_t seed_x = 0x9368e53c2f6af274ULL ^ x; + uint64_t seed_y = 0x586dcd208f7cd3fdULL ^ y; + + seed_x *= C1; + seed_x ^= seed_x >> 33; + seed_x *= C2; + seed_x ^= seed_x >> 33; + + seed_y *= C1; + seed_y ^= seed_y >> 33; + seed_y *= C2; + seed_y ^= seed_y >> 33; + + Rx = seed_x; + Ry = seed_y; + + // Inlined Next(): Discard first output + + Rx = (uint64_t)0xfffd21a7 * (uint32_t)Rx + (uint32_t)(Rx >> 32); + Ry = (uint64_t)0xfffd1361 * (uint32_t)Ry + (uint32_t)(Ry >> 32); + + // Throw away any saved RandN() state + HaveRandN = false; + + Seeded = true; +} + + +} // namespace OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_Rand.h b/LibOVRKernel/Src/Kernel/OVR_Rand.h new file mode 100644 index 0000000..14897c0 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Rand.h @@ -0,0 +1,201 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Rand.h +Content : Random number generator +Created : Aug 28, 2014 +Author : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Rand_h +#define OVR_Rand_h + +#include "OVR_Types.h" +#include + +namespace OVR { + + +/* + This is designed to generate up to 2^^32 numbers per seed. + + Its period is about 2^^126 and passes all BigCrush tests. + It is the fastest simple generator that passes all tests. + + It has a few advantages over the stdlib RNG, including that + all bits of the output are equally good in quality. + Furthermore, the input seeds are hashed to avoid linear + relationships between the input seeds and the low bits of + the first few outputs. +*/ +class RandomNumberGenerator +{ +protected: + uint64_t Rx; + uint64_t Ry; + double NextRandN; + bool Seeded; + bool HaveRandN; + +public: + RandomNumberGenerator() : + Seeded(false), + HaveRandN(false) + // Other members left uninitialized + { + } + + bool IsSeeded() const + { + return Seeded; + } + + // Seed with a random state + void SeedRandom(); + + // Start with a specific seed + void Seed(uint32_t x, uint32_t y); + + // Returns an unsigned uint32_t uniformly distributed in interval [0..2^32-1] + OVR_FORCE_INLINE uint32_t Next() + { + // If it is not Seeded yet, + if (!IsSeeded()) + { + SeedRandom(); + } + + // Sum of two long-period MWC generators + Rx = (uint64_t)0xfffd21a7 * (uint32_t)Rx + (uint32_t)(Rx >> 32); + Ry = (uint64_t)0xfffd1361 * (uint32_t)Ry + (uint32_t)(Ry >> 32); + return (((uint32_t)Rx << 7) | ((uint32_t)Rx >> (32 - 7))) + (uint32_t)Ry; // ROL(x, 7) + y + } + + // The following functions are inspired by the Matlab functions rand(), randi(), and randn() + + // Uniform distribution over open interval (0..2^32) + // (i.e. closed interval [1..2^32-1], not including 0) + OVR_FORCE_INLINE uint32_t NextNonZero() + { + uint32_t n; + do + { + n = Next(); + } while (n == 0); + return n; + } + + // Double uniformly distributed over open interval (0..1) + OVR_FORCE_INLINE double Rand() + { + return NextNonZero() * (1.0 / 4294967296.0); // 2^32 + } + + // Double uniformly distributed over open interval (dmin..dmax) + OVR_FORCE_INLINE double Rand(double dmin, double dmax) + { + return dmin + (dmax - dmin) * (1.0 / 4294967296.0) * NextNonZero(); // 2^32 + } + + // Integer uniformly distributed over closed interval [0..imax-1] + // (NOTE: Matalb randi(imax) returns 1..imax) + OVR_FORCE_INLINE int RandI(int imax) + { + return (int)(Next() % imax); + } + + // Integer uniformly distributed over closed interval [imin..imax-1] + // (NOTE: Matlab randi() returns imin..imax) + OVR_FORCE_INLINE int RandI(int imin, int imax) + { + return imin + (int)(Next() % (imax - imin)); + } + + // Coordinate (x,y) uniformly distributed inside unit circle. + // Returns magnitude squared of (x,y) + OVR_FORCE_INLINE double RandInUnitCircle(double& x, double& y) + { + double r2; + do + { + x = Rand(-1.0, 1.0); + y = Rand(-1.0, 1.0); + r2 = x*x + y*y; + } while (r2 >= 1.0); + return r2; + } + + // Standard normal (gaussian) distribution: mean 0.0, stdev 1.0 + double RandN() + { + if (HaveRandN) + { + HaveRandN = false; + return NextRandN; + } + else + { + double x, y; + double r2 = RandInUnitCircle(x, y); + // Box-Muller transform + double f = sqrt(-2 * log(r2) / r2); + + // Return first, save second for next call + NextRandN = y * f; + HaveRandN = true; + + return x * f; + } + } + + // Uniform coordinate (c,s) ON unit circle. + // This function computes cos(theta), sin(theta) + // of rotation uniform in (0..2*pi). + // [ c s] is a random 2D rotation matrix. + // [-s c] + // Reference: Numerical Recipes in C++, chap. 21 + OVR_FORCE_INLINE void RandOnUnitCircle(double& c, double& s) + { + double r2 = RandInUnitCircle(c, s); + double normalize = 1.0 / sqrt(r2); + c *= normalize; + s *= normalize; + } + + // Uniform coordinate (x,y,z,w) on surface of 4D hypersphere. + // This is a quaternion rotation uniformly distributed across all rotations + // Reference: Numerical Recipes in C++, chap. 21 + OVR_FORCE_INLINE void RandOnUnitSphere4(double& x, double& y, double& z, double& w) + { + double r2xy = RandInUnitCircle(x, y); + + double u, v; + double r2uv = RandInUnitCircle(u, v); + + double f = sqrt((1.0 - r2xy) / r2uv); + z = u * f; + w = v * f; + } +}; + +} // namespace OVR + +#endif // OVR_Rand_h diff --git a/LibOVRKernel/Src/Kernel/OVR_RefCount.cpp b/LibOVRKernel/Src/Kernel/OVR_RefCount.cpp new file mode 100644 index 0000000..b04ad29 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_RefCount.cpp @@ -0,0 +1,105 @@ +/************************************************************************************ + +Filename : OVR_RefCount.cpp +Content : Reference counting implementation +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_RefCount.h" +#include "OVR_Atomic.h" +#include "OVR_Log.h" + +namespace OVR { + + +// ***** Reference Count Base implementation + +RefCountImplCore::~RefCountImplCore() +{ + // RefCount can be either 1 or 0 here. + // 0 if Release() was properly called. + // 1 if the object was declared on stack or as an aggregate. + OVR_ASSERT(RefCount <= 1); +} + +#ifdef OVR_BUILD_DEBUG +void RefCountImplCore::reportInvalidDelete(void *pmem) +{ + OVR_DEBUG_LOG( + ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); + OVR_ASSERT(0); +} +#endif + +RefCountNTSImplCore::~RefCountNTSImplCore() +{ + // RefCount can be either 1 or 0 here. + // 0 if Release() was properly called. + // 1 if the object was declared on stack or as an aggregate. + OVR_ASSERT(RefCount <= 1); +} + +#ifdef OVR_BUILD_DEBUG +void RefCountNTSImplCore::reportInvalidDelete(void *pmem) +{ + OVR_DEBUG_LOG( + ("Invalid delete call on ref-counted object at %p. Please use Release()", pmem)); + OVR_ASSERT(0); +} +#endif + + +// *** Thread-Safe RefCountImpl + +void RefCountImpl::AddRef() +{ + AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); +} +void RefCountImpl::Release() +{ + if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) + delete this; +} + +// *** Thread-Safe RefCountVImpl w/virtual AddRef/Release + +void RefCountVImpl::AddRef() +{ + AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); +} +void RefCountVImpl::Release() +{ + if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) + delete this; +} + +// *** NON-Thread-Safe RefCountImpl + +void RefCountNTSImpl::Release() const +{ + RefCount--; + if (RefCount == 0) + delete this; +} + + +} // OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_RefCount.h b/LibOVRKernel/Src/Kernel/OVR_RefCount.h new file mode 100644 index 0000000..68c2633 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_RefCount.h @@ -0,0 +1,512 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_RefCount.h +Content : Reference counting implementation headers +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_RefCount_h +#define OVR_RefCount_h + +#include "OVR_Types.h" +#include "OVR_Allocator.h" + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** Reference Counting + +// There are three types of reference counting base classes: +// +// RefCountBase - Provides thread-safe reference counting (Default). +// RefCountBaseNTS - Non Thread Safe version of reference counting. + + +// ***** Declared classes + +template +class RefCountBase; +template +class RefCountBaseNTS; + +class RefCountImpl; +class RefCountNTSImpl; + + +//----------------------------------------------------------------------------------- +// ***** Implementation For Reference Counting + +// RefCountImplCore holds RefCount value and defines a few utility +// functions shared by all implementations. + +class RefCountImplCore +{ +protected: + volatile int RefCount; + +public: + // RefCountImpl constructor always initializes RefCount to 1 by default. + OVR_FORCE_INLINE RefCountImplCore() : RefCount(1) { } + + // Need virtual destructor + // This: 1. Makes sure the right destructor's called. + // 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem() + virtual ~RefCountImplCore(); + + // Debug method only. + int GetRefCount() const { return RefCount; } + + // This logic is used to detect invalid 'delete' calls of reference counted + // objects. Direct delete calls are not allowed on them unless they come in + // internally from Release. +#ifdef OVR_BUILD_DEBUG + static void OVR_CDECL reportInvalidDelete(void *pmem); + inline static void checkInvalidDelete(RefCountImplCore *pmem) + { + if (pmem->RefCount != 0) + reportInvalidDelete(pmem); + } +#else + inline static void checkInvalidDelete(RefCountImplCore *) { } +#endif + + // Base class ref-count content should not be copied. + void operator = (const RefCountImplCore &) { } +}; + +class RefCountNTSImplCore +{ +protected: + mutable int RefCount; + +public: + // RefCountImpl constructor always initializes RefCount to 1 by default. + OVR_FORCE_INLINE RefCountNTSImplCore() : RefCount(1) { } + + // Need virtual destructor + // This: 1. Makes sure the right destructor's called. + // 2. Makes us have VTable, necessary if we are going to have format needed by InitNewMem() + virtual ~RefCountNTSImplCore(); + + // Debug method only. + int GetRefCount() const + { + return RefCount; + } + + // This logic is used to detect invalid 'delete' calls of reference counted + // objects. Direct delete calls are not allowed on them unless they come in + // internally from Release. +#ifdef OVR_BUILD_DEBUG + static void OVR_CDECL reportInvalidDelete(void *pmem); + OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *pmem) + { + if (pmem->RefCount != 0) + reportInvalidDelete(pmem); + } +#else + OVR_FORCE_INLINE static void checkInvalidDelete(RefCountNTSImplCore *) { } +#endif + + // Base class ref-count content should not be copied. + void operator = (const RefCountNTSImplCore &) { } +}; + + + +// RefCountImpl provides Thread-Safe implementation of reference counting, so +// it should be used by default in most places. + +class RefCountImpl : public RefCountImplCore +{ +public: + // Thread-Safe Ref-Count Implementation. + void AddRef(); + void Release(); +}; + +// RefCountVImpl provides Thread-Safe implementation of reference counting, plus, +// virtual AddRef and Release. + +class RefCountVImpl : virtual public RefCountImplCore +{ +public: + // Thread-Safe Ref-Count Implementation. + virtual void AddRef(); + virtual void Release(); +}; + + +// RefCountImplNTS provides Non-Thread-Safe implementation of reference counting, +// which is slightly more efficient since it doesn't use atomics. + +class RefCountNTSImpl : public RefCountNTSImplCore +{ +public: + OVR_FORCE_INLINE void AddRef() const + { + RefCount++; + } + + void Release() const; +}; + + + +// RefCountBaseStatImpl<> is a common class that adds new/delete override with Stat tracking +// to the reference counting implementation. Base must be one of the RefCountImpl classes. + +template +class RefCountBaseStatImpl : public Base +{ +public: + RefCountBaseStatImpl() { } + + // *** Override New and Delete + + // DOM-IGNORE-BEGIN + // Undef new temporarily if it is being redefined +#ifdef OVR_DEFINE_NEW +#undef new +#endif + +#ifdef OVR_BUILD_DEBUG + // Custom check used to detect incorrect calls of 'delete' on ref-counted objects. + #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) \ + do {if (p) Base::checkInvalidDelete((class_name*)p); } while(0) +#else + #define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) +#endif + + // Redefine all new & delete operators. + OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE) + +#undef OVR_REFCOUNTALLOC_CHECK_DELETE + +#ifdef OVR_DEFINE_NEW +#define new OVR_DEFINE_NEW +#endif + // OVR_BUILD_DEFINE_NEW + // DOM-IGNORE-END +}; + + +template +class RefCountBaseStatVImpl : virtual public Base +{ +public: + RefCountBaseStatVImpl() { } + + // *** Override New and Delete + + // DOM-IGNORE-BEGIN + // Undef new temporarily if it is being redefined +#ifdef OVR_DEFINE_NEW +#undef new +#endif + +#define OVR_REFCOUNTALLOC_CHECK_DELETE(class_name, p) + + // Redefine all new & delete operators. + OVR_MEMORY_REDEFINE_NEW_IMPL(Base, OVR_REFCOUNTALLOC_CHECK_DELETE) + +#undef OVR_REFCOUNTALLOC_CHECK_DELETE + +#ifdef OVR_DEFINE_NEW +#define new OVR_DEFINE_NEW +#endif + // OVR_BUILD_DEFINE_NEW + // DOM-IGNORE-END +}; + + + +//----------------------------------------------------------------------------------- +// *** End user RefCountBase<> classes + + +// RefCountBase is a base class for classes that require thread-safe reference +// counting; it also overrides the new and delete operators to use MemoryHeap. +// +// Reference counted objects start out with RefCount value of 1. Further lifetime +// management is done through the AddRef() and Release() methods, typically +// hidden by Ptr<>. + +template +class RefCountBase : public RefCountBaseStatImpl +{ +public: + // Constructor. + OVR_FORCE_INLINE RefCountBase() : RefCountBaseStatImpl() { } +}; + +// RefCountBaseV is the same as RefCountBase but with virtual AddRef/Release + +template +class RefCountBaseV : virtual public RefCountBaseStatVImpl +{ +public: + // Constructor. + OVR_FORCE_INLINE RefCountBaseV() : RefCountBaseStatVImpl() { } +}; + + +// RefCountBaseNTS is a base class for classes that require Non-Thread-Safe reference +// counting; it also overrides the new and delete operators to use MemoryHeap. +// This class should only be used if all pointers to it are known to be assigned, +// destroyed and manipulated within one thread. +// +// Reference counted objects start out with RefCount value of 1. Further lifetime +// management is done through the AddRef() and Release() methods, typically +// hidden by Ptr<>. + +template +class RefCountBaseNTS : public RefCountBaseStatImpl +{ +public: + // Constructor. + OVR_FORCE_INLINE RefCountBaseNTS() : RefCountBaseStatImpl() { } +}; + + + + +//----------------------------------------------------------------------------------- +// ***** Ref-Counted template pointer +// +// Automatically AddRefs and Releases interfaces +// +// Note: Some of the member functions take C& as opposed to C* arguments: +// Ptr(C&) +// const Ptr& operator= (C&) +// Ptr& SetPtr(C&) +// These functions do not AddRef the assigned C& value, unlike the C* assignment +// functions. Thus the purpose of these functions is for the Ptr instance to +// assume ownership of a C reference count. Example usage: +// Ptr w = *new Widget; // Calls the Ptr(C&) constructor. Note that the Widget constructor sets initial refcount to 1. +// + +template +class Ptr +{ +protected: + C *pObject; + +public: + + // Constructors + OVR_FORCE_INLINE Ptr() + : pObject(0) + { } + + // This constructor adopts the object's existing reference count rather than increment it. + OVR_FORCE_INLINE Ptr(C &robj) + : pObject(&robj) + { } + + OVR_FORCE_INLINE Ptr(C *pobj) + { + if (pobj) + pobj->AddRef(); + pObject = pobj; + } + + OVR_FORCE_INLINE Ptr(const Ptr &src) + { + if (src.pObject) + src.pObject->AddRef(); + pObject = src.pObject; + } + + template + OVR_FORCE_INLINE Ptr(Ptr &src) + { + if (src) + src->AddRef(); + pObject = src; + } + + // Destructor + OVR_FORCE_INLINE ~Ptr() + { + if (pObject) + pObject->Release(); + } + + // Compares + OVR_FORCE_INLINE bool operator == (const Ptr &other) const + { + return pObject == other.pObject; + } + + OVR_FORCE_INLINE bool operator != (const Ptr &other) const + { + return pObject != other.pObject; + } + + OVR_FORCE_INLINE bool operator == (C *pother) const + { + return pObject == pother; + } + + OVR_FORCE_INLINE bool operator != (C *pother) const + { + return pObject != pother; + } + + OVR_FORCE_INLINE bool operator < (const Ptr &other) const + { + return pObject < other.pObject; + } + + // Assignment + template + OVR_FORCE_INLINE const Ptr& operator = (const Ptr &src) + { + // By design we don't check for src == pObject, as we don't expect that to be the case the large majority of the time. + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + + // Specialization + OVR_FORCE_INLINE const Ptr& operator = (const Ptr &src) + { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + + OVR_FORCE_INLINE const Ptr& operator = (C *psrc) + { + if (psrc) + psrc->AddRef(); + if (pObject) + pObject->Release(); + pObject = psrc; + return *this; + } + + // This operator adopts the object's existing reference count rather than increment it. + OVR_FORCE_INLINE const Ptr& operator = (C &src) + { + if (pObject) + pObject->Release(); + pObject = &src; + return *this; + } + + // Set Assignment + template + OVR_FORCE_INLINE Ptr& SetPtr(const Ptr &src) + { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + // Specialization + OVR_FORCE_INLINE Ptr& SetPtr(const Ptr &src) + { + if (src) + src->AddRef(); + if (pObject) + pObject->Release(); + pObject = src; + return *this; + } + + OVR_FORCE_INLINE Ptr& SetPtr(C *psrc) + { + if (psrc) + psrc->AddRef(); + if (pObject) + pObject->Release(); + pObject = psrc; + return *this; + } + + // This function adopts the object's existing reference count rather than increment it. + OVR_FORCE_INLINE Ptr& SetPtr(C &src) + { + if (pObject) + pObject->Release(); + pObject = &src; + return *this; + } + + // Nulls ref-counted pointer without decrement + OVR_FORCE_INLINE void NullWithoutRelease() + { + pObject = 0; + } + + // Clears the pointer to the object + OVR_FORCE_INLINE void Clear() + { + if (pObject) + pObject->Release(); + pObject = 0; + } + + // Obtain pointer reference directly, for D3D interfaces + OVR_FORCE_INLINE C*& GetRawRef() + { + return pObject; + } + + // Access Operators + OVR_FORCE_INLINE C* GetPtr() const + { + return pObject; + } + + OVR_FORCE_INLINE C& operator * () const + { + return *pObject; + } + + OVR_FORCE_INLINE C* operator -> () const + { + return pObject; + } + + // Conversion + OVR_FORCE_INLINE operator C* () const + { + return pObject; + } + +}; + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp b/LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp new file mode 100644 index 0000000..cb5c1e2 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_SharedMemory.cpp @@ -0,0 +1,742 @@ +/************************************************************************************ + +Filename : OVR_SharedMemory.cpp +Content : Inter-process shared memory subsystem +Created : June 1, 2014 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_SharedMemory.h" +#include "OVR_Atomic.h" +#include "OVR_Log.h" +#include "OVR_String.h" +#include "OVR_Array.h" + +#if defined(OVR_OS_WIN32) +#include // ConvertStringSecurityDescriptorToSecurityDescriptor +#endif // OVR_OS_WIN32 + +#if defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +#include // shm_open(), mmap() +#include // error results for mmap +#include // mode constants +#include // O_ constants +#include // close() +#endif // OVR_OS_LINUX + +OVR_DEFINE_SINGLETON(OVR::SharedMemoryFactory); + +namespace OVR { + + +//----------------------------------------------------------------------------- +// SharedMemoryInternalBase + +class SharedMemoryInternalBase : public NewOverrideBase +{ +public: + SharedMemoryInternalBase() + { + } + virtual ~SharedMemoryInternalBase() + { + } + + virtual void* GetFileView() = 0; +}; + + +//----------------------------------------------------------------------------- +// FakeMemoryBlock + +class FakeMemoryBlock : public RefCountBase +{ + String Name; + char* Data; + int SizeBytes; + int References; + +public: + FakeMemoryBlock(const String& name, int size) : + Name(name), + Data(NULL), + SizeBytes(size), + References(1) + { + Data = new char[SizeBytes]; + } + ~FakeMemoryBlock() + { + delete[] Data; + } + + bool IsNamed(const String& name) + { + return Name.CompareNoCase(name) == 0; + } + void* GetData() + { + return Data; + } + int GetSizeI() + { + return SizeBytes; + } + void IncrementReferences() + { + ++References; + } + bool DecrementReferences() + { + return --References <= 0; + } +}; + +class FakeMemoryInternal : public SharedMemoryInternalBase +{ +public: + void* FileView; + Ptr Block; + + FakeMemoryInternal(FakeMemoryBlock* block); + ~FakeMemoryInternal(); + + virtual void* GetFileView() OVR_OVERRIDE + { + return FileView; + } +}; + + +//----------------------------------------------------------------------------- +// FakeMemoryManager + +class FakeMemoryManager : public NewOverrideBase, public SystemSingletonBase +{ + OVR_DECLARE_SINGLETON(FakeMemoryManager); + + Lock FakeLock; + Array< Ptr > FakeArray; + +public: + FakeMemoryInternal* Open(const char *name, int bytes, bool openOnly) + { + Lock::Locker locker(&FakeLock); + + const int count = FakeArray.GetSizeI(); + for (int ii = 0; ii < count; ++ii) + { + if (FakeArray[ii]->IsNamed(name)) + { + FakeArray[ii]->IncrementReferences(); + return new FakeMemoryInternal(FakeArray[ii]); + } + } + + if (openOnly) + { + return NULL; + } + + Ptr data = *new FakeMemoryBlock(name, bytes); + FakeArray.PushBack(data); + return new FakeMemoryInternal(data); + } + + void Free(FakeMemoryBlock* block) + { + Lock::Locker locker(&FakeLock); + + const int count = FakeArray.GetSizeI(); + for (int ii = 0; ii < count; ++ii) + { + if (FakeArray[ii].GetPtr() == block) + { + // If the reference count hit zero, + if (FakeArray[ii]->DecrementReferences()) + { + // Toast + FakeArray.RemoveAtUnordered(ii); + } + break; + } + } + } +}; + +FakeMemoryManager::FakeMemoryManager() +{ + PushDestroyCallbacks(); +} + +FakeMemoryManager::~FakeMemoryManager() +{ + // If this assertion trips it is because we have not cleanly released shared memory resources. + OVR_ASSERT(FakeArray.GetSizeI() == 0); +} + +void FakeMemoryManager::OnSystemDestroy() +{ + delete this; +} + +FakeMemoryInternal::FakeMemoryInternal(FakeMemoryBlock* block) : + Block(block) +{ + FileView = Block->GetData(); +} + +FakeMemoryInternal::~FakeMemoryInternal() +{ + FakeMemoryManager::GetInstance()->Free(Block); + Block.Clear(); +} + + +} // namespace OVR + +OVR_DEFINE_SINGLETON(FakeMemoryManager); + +namespace OVR { + + +static SharedMemoryInternalBase* CreateFakeSharedMemory(const SharedMemory::OpenParameters& params) +{ + return FakeMemoryManager::GetInstance()->Open(params.globalName, params.minSizeBytes, params.openMode == SharedMemory::OpenMode_OpenOnly); +} + + +//// Windows version + +#if defined(OVR_OS_WIN32) + +#pragma comment(lib, "advapi32.lib") + +// Hidden implementation class for OS-specific behavior +class SharedMemoryInternal : public SharedMemoryInternalBase +{ +public: + HANDLE FileMapping; + void* FileView; + + SharedMemoryInternal(HANDLE fileMapping, void* fileView) : + FileMapping(fileMapping), + FileView(fileView) + { + } + + ~SharedMemoryInternal() + { + // If file view is set, + if (FileView) + { + UnmapViewOfFile(FileView); + FileView = NULL; + } + + // If file mapping is set, + if (FileMapping != NULL) + { + CloseHandle(FileMapping); + FileMapping = NULL; + } + } + + virtual void* GetFileView() OVR_OVERRIDE + { + return FileView; + } +}; + +static SharedMemoryInternal* DoFileMap(HANDLE hFileMapping, const char* fileName, bool openReadOnly, int minSize) +{ + // Interpret the access mode as a map desired access code + DWORD mapDesiredAccess = openReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE; + + // Map view of the file to this process + void* pFileView = MapViewOfFile(hFileMapping, mapDesiredAccess, 0, 0, minSize); + + // If mapping could not be created, + if (!pFileView) + { + CloseHandle(hFileMapping); + + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to map view of file for %s error code = %d", fileName, GetLastError())); + OVR_UNUSED(fileName); + return NULL; + } + + // Create internal representation + SharedMemoryInternal* pimple = new SharedMemoryInternal(hFileMapping, pFileView); + + // If memory allocation fails, + if (!pimple) + { + UnmapViewOfFile(pFileView); + CloseHandle(hFileMapping); + + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Out of memory")); + return NULL; + } + + return pimple; +} + +static SharedMemoryInternal* AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly) +{ + // Interpret the access mode as a map desired access code + DWORD mapDesiredAccess = openReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE; + + // Open file mapping + HANDLE hFileMapping = OpenFileMappingA(mapDesiredAccess, TRUE, fileName); + + // If file was mapped unsuccessfully, + if (NULL == hFileMapping) + { + //OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to open file mapping for %s error code = %d (not necessarily bad)", fileName, GetLastError())); + return NULL; + } + + // Map the file + return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); +} + +static SharedMemoryInternal* AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite) +{ + // Prepare a SECURITY_ATTRIBUTES object + SECURITY_ATTRIBUTES security; + ZeroMemory(&security, sizeof(security)); + security.nLength = sizeof(security); + + // Security descriptor by DACL strings: + // ACE strings grant Allow(A), Object/Contains Inheritance (OICI) of: + // + Grant All (GA) to System (SY) + // + Grant All (GA) to Built-in Administrators (BA) + // + Grant Read-Only (GR) or Read-Write (GWGR) to Interactive Users (IU) - ie. games + static const char* DACLString_ReadOnly = "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GR;;;IU)"; + static const char* DACLString_ReadWrite = "D:P(A;OICI;GA;;;SY)(A;OICI;GA;;;BA)(A;OICI;GWGR;;;IU)"; + + // Select the remote process access mode + const char* remoteAccessString = + allowRemoteWrite ? DACLString_ReadWrite : DACLString_ReadOnly; + + // Attempt to convert access string to security attributes + // Note: This will allocate the security descriptor with LocalAlloc() and must be freed later + BOOL bConvertOkay = ConvertStringSecurityDescriptorToSecurityDescriptorA( + remoteAccessString, SDDL_REVISION_1, &security.lpSecurityDescriptor, NULL); + + // If conversion fails, + if (!bConvertOkay) + { + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to convert access string, error code = %d", GetLastError())); + return NULL; + } + + // Interpret the access mode as a page protection code + int pageProtectCode = openReadOnly ? PAGE_READONLY : PAGE_READWRITE; + + // Attempt to create a file mapping + HANDLE hFileMapping = CreateFileMappingA(INVALID_HANDLE_VALUE, // From page file + &security, // Security attributes + pageProtectCode, // Read-only? + 0, // High word for size = 0 + minSize, // Low word for size + fileName); // Name of global shared memory file + + // Free the security descriptor buffer + LocalFree(security.lpSecurityDescriptor); + + // If mapping could not be created, + if (NULL == hFileMapping) + { + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to create file mapping for %s error code = %d", fileName, GetLastError())); + return NULL; + } + +#ifndef OVR_ALLOW_CREATE_FILE_MAPPING_IF_EXISTS + // If the file mapping already exists, + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + CloseHandle(hFileMapping); + + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: File mapping at %s already exists", fileName)); + return NULL; + } +#endif + + // Map the file + return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); +} + +static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params) +{ + SharedMemoryInternal* retval = NULL; + + // Construct the file mapping name in a Windows-specific way + OVR::String fileMappingName = params.globalName; + const char *fileName = fileMappingName.ToCStr(); + + // Is being opened read-only? + const bool openReadOnly = (params.accessMode == SharedMemory::AccessMode_ReadOnly); + + // Try up to 3 times to reduce low-probability failures: + static const int ATTEMPTS_MAX = 3; + for (int attempts = 0; attempts < ATTEMPTS_MAX; ++attempts) + { + // If opening should be attempted first, + if (params.openMode != SharedMemory::OpenMode_CreateOnly) + { + // Attempt to open a shared memory map + retval = AttemptOpenSharedMemory(fileName, params.minSizeBytes, openReadOnly); + + // If successful, + if (retval) + { + // Done! + break; + } + } + + // If creating the shared memory is also acceptable, + if (params.openMode != SharedMemory::OpenMode_OpenOnly) + { + // Interpret create mode + const bool allowRemoteWrite = (params.remoteMode == SharedMemory::RemoteMode_ReadWrite); + + // Attempt to create a shared memory map + retval = AttemptCreateSharedMemory(fileName, params.minSizeBytes, openReadOnly, allowRemoteWrite); + + // If successful, + if (retval) + { + // Done! + break; + } + } + } // Re-attempt create/open + + // Note: On Windows the initial contents of the region are guaranteed to be zero. + return retval; +} + +#endif // OVR_OS_WIN32 + + +#if (defined(OVR_OS_LINUX) || defined(OVR_OS_MAC)) + +// Hidden implementation class for OS-specific behavior +class SharedMemoryInternal : public SharedMemoryInternalBase +{ +public: + int FileMapping; + void* FileView; + int FileSize; + + SharedMemoryInternal(int fileMapping, void* fileView, int fileSize) : + FileMapping(fileMapping), + FileView(fileView), + FileSize(fileSize) + { + } + + virtual ~SharedMemoryInternal() + { + // If file view is set, + if (FileView) + { + munmap(FileView, FileSize); + FileView = MAP_FAILED; + } + + // If file mapping is set, + if (FileMapping >= 0) + { + close(FileMapping); + FileMapping = -1; + } + } + + virtual void* GetFileView() OVR_OVERRIDE + { + return FileView; + } +}; + +static SharedMemoryInternal* DoFileMap(int hFileMapping, const char* fileName, bool openReadOnly, int minSize) +{ + // Calculate the required flags based on read/write mode + int prot = openReadOnly ? PROT_READ : (PROT_READ|PROT_WRITE); + + // Map the file view + void* pFileView = mmap(NULL, minSize, prot, MAP_SHARED, hFileMapping, 0); + + if (pFileView == MAP_FAILED) + { + close(hFileMapping); + + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to map view of file for %s error code = %d", fileName, errno)); + OVR_UNUSED(fileName); + return NULL; + } + + // Create internal representation + SharedMemoryInternal* pimple = new SharedMemoryInternal(hFileMapping, pFileView, minSize); + + // If memory allocation fails, + if (!pimple) + { + munmap(pFileView, minSize); + close(hFileMapping); + + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Out of memory")); + return NULL; + } + + return pimple; +} + +static SharedMemoryInternal* AttemptOpenSharedMemory(const char* fileName, int minSize, bool openReadOnly) +{ + // Calculate permissions and flags based on read/write mode + int flags = openReadOnly ? O_RDONLY : O_RDWR; + int perms = openReadOnly ? S_IRUSR : (S_IRUSR | S_IWUSR); + + // Attempt to open the shared memory file + int hFileMapping = shm_open(fileName, flags, perms); + + // If file was not opened successfully, + if (hFileMapping < 0) + { + OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to open file mapping for %s error code = %d (not necessarily bad)", fileName, errno)); + return NULL; + } + + // Map the file + return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); +} + +static SharedMemoryInternal* AttemptCreateSharedMemory(const char* fileName, int minSize, bool openReadOnly, bool allowRemoteWrite) +{ + // Create mode + // Note: Cannot create the shared memory file read-only because then ftruncate() will fail. + int flags = O_CREAT | O_RDWR; + +#ifndef OVR_ALLOW_CREATE_FILE_MAPPING_IF_EXISTS + // Require exclusive access when creating (seems like a good idea without trying it yet..) + if (shm_unlink(fileName) < 0) + { + OVR_DEBUG_LOG(("[SharedMemory] WARNING: Unable to unlink shared memory file %s error code = %d", fileName, errno)); + } + flags |= O_EXCL; +#endif + + // Set own read/write permissions + int perms = openReadOnly ? S_IRUSR : (S_IRUSR|S_IWUSR); + + // Allow other users to read/write the shared memory file + perms |= allowRemoteWrite ? (S_IWGRP|S_IWOTH|S_IRGRP|S_IROTH) : (S_IRGRP|S_IROTH); + + // Attempt to open the shared memory file + int hFileMapping = shm_open(fileName, flags, perms); + + // If file was not opened successfully, + if (hFileMapping < 0) + { + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to create file mapping for %s error code = %d", fileName, errno)); + return NULL; + } + + int truncRes = ftruncate(hFileMapping, minSize); + + // If file was not opened successfully, + if (truncRes < 0) + { + close(hFileMapping); + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Unable to truncate file for %s to %d error code = %d", fileName, minSize, errno)); + return NULL; + } + + // Map the file + return DoFileMap(hFileMapping, fileName, openReadOnly, minSize); +} + +static SharedMemoryInternal* CreateSharedMemory(const SharedMemory::OpenParameters& params) +{ + SharedMemoryInternal* retval = NULL; + + // Construct the file mapping name in a Linux-specific way + OVR::String fileMappingName = "/"; + fileMappingName += params.globalName; + const char *fileName = fileMappingName.ToCStr(); + + // Is being opened read-only? + const bool openReadOnly = (params.accessMode == SharedMemory::AccessMode_ReadOnly); + + // Try up to 3 times to reduce low-probability failures: + static const int ATTEMPTS_MAX = 3; + for (int attempts = 0; attempts < ATTEMPTS_MAX; ++attempts) + { + // If opening should be attempted first, + if (params.openMode != SharedMemory::OpenMode_CreateOnly) + { + // Attempt to open a shared memory map + retval = AttemptOpenSharedMemory(fileName, params.minSizeBytes, openReadOnly); + + // If successful, + if (retval) + { + // Done! + break; + } + } + + // If creating the shared memory is also acceptable, + if (params.openMode != SharedMemory::OpenMode_OpenOnly) + { + // Interpret create mode + const bool allowRemoteWrite = (params.remoteMode == SharedMemory::RemoteMode_ReadWrite); + + // Attempt to create a shared memory map + retval = AttemptCreateSharedMemory(fileName, params.minSizeBytes, openReadOnly, allowRemoteWrite); + + // If successful, + if (retval) + { + // Done! + break; + } + } + } // Re-attempt create/open + + // Note: On Windows the initial contents of the region are guaranteed to be zero. + return retval; +} + +#endif // OVR_OS_LINUX + + +//----------------------------------------------------------------------------- +// SharedMemory + +static bool FakingSharedMemory = false; + +void SharedMemory::SetFakeSharedMemory(bool enabled) +{ + FakingSharedMemory = enabled; +} + +bool SharedMemory::IsFakingSharedMemory() +{ + return FakingSharedMemory; +} + +SharedMemory::SharedMemory(int size, void* data, const String& name, SharedMemoryInternalBase* pInternal) : + Size(size), + Data(data), + Name(name), + Internal(pInternal) +{ +} + +SharedMemory::~SharedMemory() +{ + // Call close when it goes out of scope + Close(); + delete Internal; +} + +void SharedMemory::Close() +{ + if (Internal) + { + delete Internal; + Internal = NULL; + } +} + + +//----------------------------------------------------------------------------- +// SharedMemoryFactory + +Ptr SharedMemoryFactory::Open(const SharedMemory::OpenParameters& params) +{ + Ptr retval; + + // If no name specified or no size requested, + if (!params.globalName || (params.minSizeBytes <= 0)) + { + OVR_DEBUG_LOG(("[SharedMemory] FAILURE: Invalid parameters to Create()")); + return NULL; + } + +#ifdef OVR_BUILD_DEBUG + const char* OpType = "{Unknown}"; + switch (params.openMode) + { + case SharedMemory::OpenMode_CreateOnly: OpType = "Creating"; break; + case SharedMemory::OpenMode_CreateOrOpen: OpType = "Creating/Opening"; break; + case SharedMemory::OpenMode_OpenOnly: OpType = "Opening"; break; + default: OVR_ASSERT(false); break; + } + + OVR_DEBUG_LOG(("[SharedMemory] %s shared memory region: %s > %d bytes", + OpType, params.globalName, params.minSizeBytes)); +#endif + + // Attempt to create a shared memory region from the parameters + SharedMemoryInternalBase* pInternal; + if (SharedMemory::IsFakingSharedMemory()) + { + pInternal = CreateFakeSharedMemory(params); + } + else + { + pInternal = CreateSharedMemory(params); + } + + if (pInternal) + { + // Create the wrapper object + retval = *new SharedMemory(params.minSizeBytes, pInternal->GetFileView(), params.globalName, pInternal); + } + + return retval; +} + +SharedMemoryFactory::SharedMemoryFactory() +{ + OVR_DEBUG_LOG(("[SharedMemory] Creating factory")); + + PushDestroyCallbacks(); +} + +SharedMemoryFactory::~SharedMemoryFactory() +{ + OVR_DEBUG_LOG(("[SharedMemory] Destroying factory")); +} + +void SharedMemoryFactory::OnSystemDestroy() +{ + delete this; +} + + +} // namespace OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_SharedMemory.h b/LibOVRKernel/Src/Kernel/OVR_SharedMemory.h new file mode 100644 index 0000000..dd155f7 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_SharedMemory.h @@ -0,0 +1,254 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_SharedMemory.h +Content : Inter-process shared memory subsystem +Created : June 1, 2014 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_SharedMemory_h +#define OVR_SharedMemory_h + +#include "OVR_Types.h" +#include "OVR_RefCount.h" +#include "OVR_Allocator.h" +#include "OVR_System.h" +#include "OVR_String.h" + + +namespace OVR { + +class SharedMemoryInternalBase; // Opaque + + +// SharedMemory +// Note: Safe when used between 32-bit and 64-bit processes +class SharedMemory : public RefCountBase +{ + friend class SharedMemoryFactory; + + OVR_NON_COPYABLE(SharedMemory); + +public: + // Only constructed by the SharedMemory Factory + SharedMemory(int size, void* data, const String& name, SharedMemoryInternalBase* pInternal); + // Call close when it goes out of scope + ~SharedMemory(); + + // Modes for opening a new shared memory region + enum OpenMode + { + // Note: On Windows, Create* requires Administrator priviledges or running as a Service. + OpenMode_CreateOnly, // Must not already exist + OpenMode_OpenOnly, // Must already exist + OpenMode_CreateOrOpen // May exist or not + }; + + // Local access restrictions + enum AccessMode + { + AccessMode_ReadOnly, // Acquire read-only access + AccessMode_ReadWrite, // Acquire read or write access + }; + + // Remote access restrictions + enum RemoteMode + { + RemoteMode_ReadOnly, // Other processes will need to open in read-only mode + RemoteMode_ReadWrite // Other processes can open in read-write mode + }; + + // Modes for opening a new shared memory region + struct OpenParameters + { + OpenParameters() : + globalName(NULL), + minSizeBytes(0), + openMode(SharedMemory::OpenMode_CreateOrOpen), + remoteMode(SharedMemory::RemoteMode_ReadWrite), + accessMode(SharedMemory::AccessMode_ReadWrite) + { + } + + // Creation parameters + const char* globalName; // Name of the shared memory region + int minSizeBytes; // Minimum number of bytes to request + SharedMemory::OpenMode openMode; // Creating the file or opening the file? + SharedMemory::RemoteMode remoteMode; // When creating, what access should other processes get? + SharedMemory::AccessMode accessMode; // When opening/creating, what access should this process get? + }; + +public: + // Returns the size of the shared memory region + int GetSizeI() const + { + return Size; + } + + // Returns the process-local pointer to the shared memory region + // Note: This may be different on different processes + void* GetData() const + { + return Data; + } + + // Returns the name of the shared memory region + String GetName() + { + return Name; + } + +protected: + int Size; // How many shared bytes are shared at the pointer address? + void* Data; // Pointer to the shared memory region. + String Name; // Name that can be used to access this region + + // Hidden implementation class for OS-specific behavior + SharedMemoryInternalBase* Internal; + + // Close and cleanup the shared memory region + // Note: This is called on destruction + void Close(); + +public: + static void SetFakeSharedMemory(bool enabled); + static bool IsFakingSharedMemory(); +}; + + +// SharedMemoryFactory +class SharedMemoryFactory : public NewOverrideBase, public SystemSingletonBase +{ + OVR_DECLARE_SINGLETON(SharedMemoryFactory); + +public: + // Construct a SharedMemory object. + // Note: The new object is reference-counted so it should be stored with Ptr<>. Initial reference count is 1. + Ptr Open(const SharedMemory::OpenParameters&); +}; + + +// A shared object +// Its constructor will be called when creating a writer +// Its destructor will not be called +template +class ISharedObject : public RefCountBase > +{ +public: + static const int RegionSize = (int)sizeof(SharedType); + +protected: + Ptr pSharedMemory; + + bool Open(const char* name, bool readOnly) + { + // Configure open parameters based on read-only mode + SharedMemory::OpenParameters params; + + // FIXME: This is a hack. We currently need to allow clients to open this for read-write even + // though they only need read-only access. This is because in the first 0.4 release the + // LocklessUpdater class technically writes to it (increments by 0) to read from the space. + // This was quickly corrected in 0.4.1 and we are waiting for the right time to disallow write + // access when everyone upgrades to 0.4.1+. + //params.remoteMode = SharedMemory::RemoteMode_ReadOnly; + params.remoteMode = SharedMemory::RemoteMode_ReadWrite; + params.globalName = name; + params.accessMode = readOnly ? SharedMemory::AccessMode_ReadOnly : SharedMemory::AccessMode_ReadWrite; + params.minSizeBytes = RegionSize; + params.openMode = readOnly ? SharedMemory::OpenMode_OpenOnly : SharedMemory::OpenMode_CreateOrOpen; + + // Attempt to open the shared memory file + pSharedMemory = SharedMemoryFactory::GetInstance()->Open(params); + + // If it was not able to be opened, + if (pSharedMemory && pSharedMemory->GetSizeI() >= RegionSize && pSharedMemory->GetData()) + { + // If writing, + if (!readOnly) + { + // Construct the object also + Construct(pSharedMemory->GetData()); + } + + return true; + } + + return false; + } + + SharedType* Get() const + { + if (!pSharedMemory) + { + return NULL; + } + + void* data = pSharedMemory->GetData(); + if (!data) + { + return NULL; + } + + return reinterpret_cast(data); + } + +public: + String GetName() const + { + return pSharedMemory ? pSharedMemory->GetName() : ""; + } +}; + +// Writer specialized shared object: Ctor will be called on Open() +template +class SharedObjectWriter : public ISharedObject +{ +public: + OVR_FORCE_INLINE bool Open(const char* name) + { + return ISharedObject::Open(name, false); + } + OVR_FORCE_INLINE SharedType* Get() + { + return ISharedObject::Get(); + } +}; + +// Reader specialized shared object: Ctor will not be called +template +class SharedObjectReader : public ISharedObject +{ +public: + OVR_FORCE_INLINE bool Open(const char* name) + { + return ISharedObject::Open(name, true); + } + OVR_FORCE_INLINE const SharedType* Get() const + { + return ISharedObject::Get(); + } +}; + + +} // namespace OVR + +#endif // OVR_SharedMemory_h diff --git a/LibOVRKernel/Src/Kernel/OVR_Std.cpp b/LibOVRKernel/Src/Kernel/OVR_Std.cpp new file mode 100644 index 0000000..fc5ad04 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Std.cpp @@ -0,0 +1,1097 @@ +/************************************************************************************ + +Filename : OVR_Std.cpp +Content : Standard C function implementation +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Std.h" +#include "OVR_Alg.h" + +// localeconv() call in OVR_strtod() +#include + +namespace OVR { + +// Source for functions not available on all platforms is included here. + +size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize) +{ + const char* s = src; + size_t n = destsize; + + if(n && --n) + { + do{ + if((*dest++ = *s++) == 0) + break; + } while(--n); + } + + if(!n) + { + if(destsize) + *dest = 0; + while(*s++) + { } + } + + return (size_t)((s - src) - 1); +} + + +size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize) +{ + const size_t d = destsize ? OVR_strlen(dest) : 0; + const size_t s = OVR_strlen(src); + const size_t t = s + d; + + OVR_ASSERT((destsize == 0) || (d < destsize)); + + if(t < destsize) + memcpy(dest + d, src, (s + 1) * sizeof(*src)); + else + { + if(destsize) + { + memcpy(dest + d, src, ((destsize - d) - 1) * sizeof(*src)); + dest[destsize - 1] = 0; + } + } + + return t; +} + + +// Case insensitive compare implemented in platform-specific way. +int OVR_CDECL OVR_stricmp(const char* a, const char* b) +{ +#if defined(OVR_OS_MS) + #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_stricmp(a, b); + #else + return ::stricmp(a, b); + #endif + +#else + return strcasecmp(a, b); +#endif +} + +int OVR_CDECL OVR_strnicmp(const char* a, const char* b, size_t count) +{ +#if defined(OVR_OS_MS) + #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_strnicmp(a, b, count); + #else + return ::strnicmp(a, b, count); + #endif + +#else + return strncasecmp(a, b, count); +#endif +} + +wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src) +{ +#if defined(OVR_MSVC_SAFESTRING) + wcscpy_s(dest, destsize, src); + return dest; +#elif defined(OVR_OS_MS) + OVR_UNUSED(destsize); + wcscpy(dest, src); + return dest; +#else + size_t l = OVR_wcslen(src) + 1; // incl term null + l = (l < destsize) ? l : destsize; + memcpy(dest, src, l * sizeof(wchar_t)); + return dest; +#endif +} + +wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count) +{ +#if defined(OVR_MSVC_SAFESTRING) + wcsncpy_s(dest, destsize, src, count); + return dest; +#else + size_t srclen = OVR_wcslen(src); + size_t l = Alg::Min(srclen, count); + l = (l < destsize) ? l : destsize; + memcpy(dest, src, l * sizeof(wchar_t)); + if (count > srclen) + { + size_t remLen = Alg::Min(destsize - l, (count - srclen)); + memset(&dest[l], 0, sizeof(wchar_t)*remLen); + } + else if (l < destsize) + dest[l] = 0; + return dest; +#endif +} + + +wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src) +{ +#if defined(OVR_MSVC_SAFESTRING) + wcscat_s(dest, destsize, src); + return dest; +#elif defined(OVR_OS_MS) + OVR_UNUSED(destsize); + wcscat(dest, src); + return dest; +#else + size_t dstlen = OVR_wcslen(dest); // do not incl term null + size_t srclen = OVR_wcslen(src) + 1; // incl term null + size_t copylen = (dstlen + srclen < destsize) ? srclen : destsize - dstlen; + memcpy(dest + dstlen, src, copylen * sizeof(wchar_t)); + return dest; +#endif +} + +size_t OVR_CDECL OVR_wcslen(const wchar_t* str) +{ +#if defined(OVR_OS_MS) + return wcslen(str); +#else + size_t i = 0; + while(str[i] != '\0') + ++i; + return i; +#endif +} + +int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b) +{ +#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) + return wcscmp(a, b); +#else + // not supported, use custom implementation + const wchar_t *pa = a, *pb = b; + while (*pa && *pb) + { + wchar_t ca = *pa; + wchar_t cb = *pb; + if (ca < cb) + return -1; + else if (ca > cb) + return 1; + pa++; + pb++; + } + if (*pa) + return 1; + else if (*pb) + return -1; + else + return 0; +#endif +} + +int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b) +{ +#if defined(OVR_OS_MS) + #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_wcsicmp(a, b); + #else + return ::wcsicmp(a, b); + #endif +#elif defined(OVR_OS_MAC) || defined(__CYGWIN__) || defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) + // not supported, use custom implementation + const wchar_t *pa = a, *pb = b; + while (*pa && *pb) + { + wchar_t ca = OVR_towlower(*pa); + wchar_t cb = OVR_towlower(*pb); + if (ca < cb) + return -1; + else if (ca > cb) + return 1; + pa++; + pb++; + } + if (*pa) + return 1; + else if (*pb) + return -1; + else + return 0; +#else + return wcscasecmp(a, b); +#endif +} + +// This function is not inline because of dependency on +double OVR_CDECL OVR_strtod(const char* str, char** tailptr) +{ +#if !defined(OVR_OS_ANDROID) // The Android C library doesn't have localeconv. + const char s = *localeconv()->decimal_point; + + if (s != '.') // If the C library is using a locale that is not using '.' as a decimal point, we convert the input str's '.' chars to the char that the C library expects (e.g. ',' or ' '). + { + char buffer[347 + 1]; + + OVR_strcpy(buffer, sizeof(buffer), str); + + // Ensure null-termination of string + buffer[sizeof(buffer)-1] = '\0'; + + for (char* c = buffer; *c != '\0'; ++c) + { + if (*c == '.') + { + *c = s; + break; + } + } + + char *nextPtr = NULL; + double retval = strtod(buffer, &nextPtr); + + // If a tail pointer is requested, + if (tailptr) + { + // Return a tail pointer that points to the same offset as nextPtr, in the orig string + *tailptr = !nextPtr ? NULL : (char*)str + (int)(nextPtr - buffer); + } + + return retval; + } +#endif + + return strtod(str, tailptr); +} + + +#ifndef OVR_NO_WCTYPE + +//// Use this class to generate Unicode bitsets. For example: +//// +//// UnicodeBitSet bitSet; +//// for(unsigned i = 0; i < 65536; ++i) +//// { +//// if (iswalpha(i)) +//// bitSet.Set(i); +//// } +//// bitSet.Dump(); +//// +////--------------------------------------------------------------- +//class UnicodeBitSet +//{ +//public: +// UnicodeBitSet() +// { +// memset(Offsets, 0, sizeof(Offsets)); +// memset(Bits, 0, sizeof(Bits)); +// } +// +// void Set(unsigned bit) { Bits[bit >> 8][(bit >> 4) & 15] |= 1 << (bit & 15); } +// +// void Dump() +// { +// unsigned i, j; +// unsigned offsetCount = 0; +// for(i = 0; i < 256; ++i) +// { +// if (isNull(i)) Offsets[i] = 0; +// else +// if (isFull(i)) Offsets[i] = 1; +// else Offsets[i] = uint16_t(offsetCount++ * 16 + 256); +// } +// for(i = 0; i < 16; ++i) +// { +// for(j = 0; j < 16; ++j) +// { +// printf("%5u,", Offsets[i*16+j]); +// } +// printf("\n"); +// } +// for(i = 0; i < 256; ++i) +// { +// if (Offsets[i] > 255) +// { +// for(j = 0; j < 16; j++) +// { +// printf("%5u,", Bits[i][j]); +// } +// printf("\n"); +// } +// } +// } +// +//private: +// bool isNull(unsigned n) const +// { +// const uint16_t* p = Bits[n]; +// for(unsigned i = 0; i < 16; ++i) +// if (p[i] != 0) return false; +// return true; +// } +// +// bool isFull(unsigned n) const +// { +// const uint16_t* p = Bits[n]; +// for(unsigned i = 0; i < 16; ++i) +// if (p[i] != 0xFFFF) return false; +// return true; +// } +// +// uint16_t Offsets[256]; +// uint16_t Bits[256][16]; +//}; + + +const uint16_t UnicodeAlnumBits[] = { + 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, + 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, + 640, 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 672, 688, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 704, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, + 1, 1, 1, 1, 736, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 768, 784, 1, 800, 816, 832, + 0, 0, 0, 1023,65534, 2047,65534, 2047, 0, 0, 0, 524,65535,65407,65535,65407, +65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, + 0, 0, 0, 0, 32, 0, 0, 1024,55104,65535,65531,65535,32767,64767,65535, 15, +65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, + 0, 0, 0,65534,65535, 639,65534,65535, 255, 0, 0, 0, 0,65535, 2047, 7, + 0, 0,65534, 2047,65534, 63, 1023,65535,65535,65535,65535,65535,65535, 8175, 8702, 8191, + 0,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, +65518,65535,65535,58367, 8191,65281,65487, 0,40942,65529,65023,50117, 6559,45184,65487, 3, +34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, +40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, +57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, +57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 12, +65534,65535,65535, 2047,32767, 1023, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, + 1, 0, 1023, 0,65279,65535, 2047,65534, 3843,65279,65535, 8191, 0, 0, 0, 0, +65535,65535,63227, 327, 1023, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 127, +65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, +65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, +32767,32573,65535,65535,65407, 2047,65024, 3, 0, 0,65535,65535,65535,65535,65535, 31, +65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, +65535,65535,65535,65535,65535,65535,40959, 127,65534, 2047,65535,65535,65535,65535, 2047, 0, + 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 0, 1023, 0, + 0, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, +65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, + 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, +64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, + 192, 0, 1022, 1792,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 2047, +65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, +65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, +65535,65535,65535,16383, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, + 0, 0, 0, 0, 0, 0, 0,65495,65535,65535,65535,65535,65535,65535,65535, 8191, + 0, 1023,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; + +const uint16_t UnicodeAlphaBits[] = { + 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, + 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, + 640, 656, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 672, 688, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 704, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, + 1, 1, 1, 1, 736, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 768, 784, 1, 800, 816, 832, + 0, 0, 0, 0,65534, 2047,65534, 2047, 0, 0, 0, 0,65535,65407,65535,65407, +65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, + 0, 0, 0, 0, 32, 0, 0, 1024,55104,65535,65531,65535,32767,64767,65535, 15, +65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, + 0, 0, 0,65534,65535, 639,65534,65535, 255, 0, 0, 0, 0,65535, 2047, 7, + 0, 0,65534, 2047,65534, 63, 0,65535,65535,65535,65535,65535,65535, 8175, 8702, 7168, + 0,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, +65518,65535,65535,58367, 8191,65281, 15, 0,40942,65529,65023,50117, 6559,45184, 15, 3, +34788,65529,65023,50029, 6535,24064, 0, 31,45038,65531,65023,58349, 7103, 1, 1, 0, +40942,65529,65023,58317, 6543,45248, 3, 0,51180,54845,50968,50111, 7623, 128, 0, 0, +57326,65533,65023,50159, 7647, 96, 3, 0,57324,65533,65023,50159, 7647,16480, 3, 0, +57324,65533,65023,50175, 7631, 128, 3, 0,65516,64639,65535,12283,32895,65375, 0, 12, +65534,65535,65535, 2047,32767, 0, 0, 0, 9622,65264,60590,15359, 8223,12288, 0, 0, + 1, 0, 0, 0,65279,65535, 2047,65534, 3843,65279,65535, 8191, 0, 0, 0, 0, +65535,65535,63227, 327, 0, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 127, +65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, +65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, +32767,32573,65535,65535,65407, 2047, 0, 0, 0, 0,65535,65535,65535,65535,65535, 31, +65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, +65535,65535,65535,65535,65535,65535,40959, 127,65534, 2047,65535,65535,65535,65535, 2047, 0, + 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 0, 0, 0, + 0, 0,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, +65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, + 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, +64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, + 192, 0, 1022, 1792,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 2047, +65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, +65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, +65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, +65535,65535,65535,16383, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, + 0, 0, 0, 0, 0, 0, 0,65495,65535,65535,65535,65535,65535,65535,65535, 8191, + 0, 0,65534, 2047,65534, 2047,65472,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; + +const uint16_t UnicodeDigitBits[] = { + 256, 0, 0, 0, 0, 0, 272, 0, 0, 288, 304, 320, 336, 352, 368, 384, + 400, 0, 0, 416, 0, 0, 0, 432, 448, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 464, + 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 524, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 1023, + 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, + 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, + 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65408, 0, + 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0,65472, 0, + 0, 0, 0, 0, 0, 0,65472, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 1023, 0, 0, + 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0,65024, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1023, 0, + 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1023, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const uint16_t UnicodeSpaceBits[] = { + 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 288, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +15872, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 4095, 0,33536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +const uint16_t UnicodeXDigitBits[] = { + 256, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 272, + 0, 0, 0, 1023, 126, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1023, 126, 0, 126, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +// Uncomment if necessary +//const uint16_t UnicodeCntrlBits[] = { +// 256, 0, 0, 0, 0, 0, 0, 272, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, +// 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 336, +//65535,65535, 0, 0, 0, 0, 0,32768,65535,65535, 0, 0, 0, 0, 0, 0, +//32768, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +//30720, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +//61440, 0,31744, 0, 0, 0,64512, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,32768, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3584}; +// +//const uint16_t UnicodeGraphBits[] = { +// 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, +// 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, +// 640, 656, 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 688, 704, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 736, +// 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 768, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 784, 800, 1, 816, 832, 848, +// 0, 0,65534,65535,65535,65535,65535,32767, 0, 0,65534,65535,65535,65535,65535,65535, +//65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, +// 0, 0, 0, 0, 32, 0, 0,17408,55232,65535,65531,65535,32767,64767,65535, 15, +//65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, +// 0, 0, 0,65534,65535,65151,65534,65535, 1791, 0, 0,16384, 9,65535, 2047, 31, +// 4096,34816,65534, 2047,65534, 63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191, +//16383,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, +//65518,65535,65535,58367, 8191,65281,65535, 1,40942,65529,65023,50117, 6559,45184,65487, 3, +//34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, +//40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, +//57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, +//57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 28, +//65534,65535,65535, 2047,65535, 4095, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, +//65521, 7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191, 0, 0, 0, 0, +//65535,65535,63227, 327,65535, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 2175, +//65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, +//65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, +//32767,32573,65535,65535,65407, 2047,65534, 3, 0, 0,65535,65535,65535,65535,65535, 31, +//65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, +//65535,65535,65535,65535,65535,65535,65535, 127,65534, 8191,65535,65535,65535,65535,16383, 0, +// 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 6128, 1023, 0, +// 2047, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, +//65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, +// 0,65535, 255,65535,16239, 0, 0,57344,24576, 0, 0, 0, 0, 0, 0, 0, +//64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +//65486,65523, 1022, 1793,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 4095, +//65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, +//65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, +//65535,65535,65535,65535, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, +// 0, 0, 0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535, 8191, +//63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; +// +//const uint16_t UnicodePrintBits[] = { +// 256, 1, 272, 288, 304, 320, 336, 352, 0, 368, 384, 400, 416, 432, 448, 464, +// 480, 496, 512, 528, 544, 1, 560, 576, 592, 0, 0, 0, 0, 0, 608, 624, +// 640, 656, 0, 672, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 688, 704, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 720, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 736, +// 1, 1, 1, 1, 752, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +// 1, 1, 1, 1, 1, 1, 1, 768, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 784, 800, 1, 816, 832, 848, +// 512, 0,65535,65535,65535,65535,65535,32767, 0, 0,65535,65535,65535,65535,65535,65535, +//65535,65535,65532, 15, 0,65535,65535,65535,65535,65535,16383,63999, 3, 0,16415, 0, +// 0, 0, 0, 0, 32, 0, 0,17408,55232,65535,65531,65535,32767,64767,65535, 15, +//65535,65535,65535,65535,65535,65535,65535,65535,61443,65535,65535,65535, 6559,65535,65535, 831, +// 0, 0, 0,65534,65535,65151,65534,65535, 1791, 0, 0,16384, 9,65535, 2047, 31, +// 4096,34816,65534, 2047,65534, 63,16383,65535,65535,65535,65535,65535,65535, 8191, 8702, 8191, +//16383,65535, 8191,65535, 0, 0, 0, 0,65535,65535,65535, 1, 0, 0, 0, 0, +//65518,65535,65535,58367, 8191,65281,65535, 1,40942,65529,65023,50117, 6559,45184,65487, 3, +//34788,65529,65023,50029, 6535,24064,65472, 31,45038,65531,65023,58349, 7103, 1,65473, 0, +//40942,65529,65023,58317, 6543,45248,65475, 0,51180,54845,50968,50111, 7623, 128,65408, 0, +//57326,65533,65023,50159, 7647, 96,65475, 0,57324,65533,65023,50159, 7647,16480,65475, 0, +//57324,65533,65023,50175, 7631, 128,65475, 0,65516,64639,65535,12283,32895,65375, 0, 28, +//65534,65535,65535, 2047,65535, 4095, 0, 0, 9622,65264,60590,15359, 8223,13311, 0, 0, +//65521, 7, 1023,15360,65279,65535, 2047,65534, 3875,65279,65535, 8191, 0, 0, 0, 0, +//65535,65535,63227, 327,65535, 1023, 0, 0, 0, 0,65535,65535, 63,65535,65535, 2175, +//65535,65535,65535,65535,65535,33791,65535,65535,65535,65535,65287,65535,65535,65535,65535, 1023, +//65407,65535,65535,65535,15743,15743,65535,65535,15743,65535,32767,32573,32573,65407,32767,65535, +//32767,32573,65535,65535,65407, 2047,65534, 3, 0, 0,65535,65535,65535,65535,65535, 31, +//65534,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, +//65535,65535,65535,65535,65535,65535,65535, 127,65534, 8191,65535,65535,65535,65535,16383, 0, +// 0, 0, 0, 0, 0, 0, 0, 0,65535,65535,65535,65535, 511, 6128, 1023, 0, +// 2047, 1023,65535,65535,65527,65535,65535, 255,65535,65535, 1023, 0, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535,65535, 4095,65535,65535,65535,65535,65535, 1023, +//65535,16191,65535,65535,16191,43775,65535,16383,65535,65535,65535,24543, 8156, 4047, 8191, 8156, +// 0,65535, 255,65535,16239, 0, 0,57344,24576, 0, 0, 0, 0, 0, 0, 0, +//64644,15919,48464, 1019, 0, 0,65535,65535, 15, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +//65487,65523, 1022, 1793,65534,65535,65535,65535,65535, 31,65534,65535,65535,65535,65535, 4095, +//65504,65535, 8191,65534,65535,65535,65535,65535,32767, 0,65535, 255, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 63, 0, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535, 8191, 0, 0, 0, 0, 0, 0, 0, +//65535,65535,65535,65535,65535,65535,65535,65535,65535,65535, 15, 0, 0, 0, 0, 0, +//65535,65535,16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 127,41208,65023,24447,65499,65535,65535,65535,65535,65535,65535, 3, 0,65528,65535,65535, +//65535,65535,65535,65535, 0,65535,65535,65535,65535,65532,65535,65535, 255, 0, 0, 4095, +// 0, 0, 0,65535,65055,65527, 3339,65495,65535,65535,65535,65535,65535,65535,65535,40959, +//63470,36863,65535,49151,65534,12287,65534,65534,65535,16383,65535,32767,64764, 7420, 0, 0}; +// +//const uint16_t UnicodePunctBits[] = { +// 256, 0, 0, 272, 0, 288, 304, 320, 0, 336, 0, 0, 0, 352, 368, 384, +// 400, 0, 0, 416, 0, 0, 432, 448, 464, 0, 0, 0, 0, 0, 0, 0, +// 480, 0, 0, 496, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 528, 544, 560, +// 0, 0,65534,64512, 1,63488, 1,30720, 0, 0,65534,65535, 0, 128, 0, 128, +// 0, 0, 0, 0, 0, 0, 0,16384, 128, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0,64512, 0, 0, 1536, 0, 0,16384, 9, 0, 0, 24, +// 4096,34816, 0, 0, 0, 0,15360, 0, 0, 0, 0, 0, 0, 16, 0, 0, +//16383, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 48, 1, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, +// 0, 0, 0, 0,32768, 3072, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +//65520, 7, 0,15360, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0,64512, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, +// 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0,24576, 0, 0, 6144, 0, 0, 0, 0,14336, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6128, 0, 0, +// 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0,65535, 255,65535,16239, 0, 0,24576,24576, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 1536, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +//65294,65523, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2048, +// 0, 0, 0,49152, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0,65535,65055,65527, 3339, 0, 0, 0, 0, 0, 0, 0, 0, 0, +//63470,35840, 1,47104, 0,10240, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +// +//const uint16_t UnicodeLowerBits[] = { +// 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 368, +// 384, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 432, +// 0, 0, 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0,32768,65535,65407, +//43690,43690,43690,21930,43861,43690,43690,54442,12585,20004,11562,58961,23392,46421,43690,43565, +//43690,43690,43688, 10, 0,65535,65535,65535,65535,65535,16383, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,61440,65535,32767,43235,43690, 15, +// 0, 0, 0,65535,65535,65535,43690,43690,40962,43690,43690,43690, 4372,43690,43690, 554, +// 0, 0, 0, 0, 0, 0,65534,65535, 255, 0, 0, 0, 0, 0, 0, 0, +//43690,43690,43690,43690,43690,43690,43690,43690,43690, 4074,43690,43690,43690,43690,43690, 682, +// 255, 63, 255, 255, 63, 255, 255,16383,65535,65535,65535,20703, 4316, 207, 255, 4316, +// 0, 0, 0, 0, 0, 0, 0,32768, 0, 0, 0, 0, 0, 0, 0, 0, +//50176, 8,32768, 528, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 127, 248, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +// +//const uint16_t UnicodeUpperBits[] = { +// 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 384, +// 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, +// 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,32639, 0, 0, +//21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53973, 4526,44464,19114,21845,21974, +//21845,21845,21844, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0,55104,65534, 4091, 0, 0,21532,21845, 0, +//65535,65535,65535, 0, 0, 0,21845,21845,20481,21845,21845,21845, 2187,21845,21845, 277, +// 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535,65535, 63, 0, 0, 0, +//21845,21845,21845,21845,21845,21845,21845,21845,21845, 21,21845,21845,21845,21845,21845, 341, +//65280,16128,65280,65280,16128,43520,65280, 0,65280,65280,65280, 7936, 7936, 3840, 7936, 7936, +//14468,15911,15696, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +// 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + +// MA: March 19, 2010 +// Modified ToUpper and ToLower tables to match values expected by AS3 tests. +// ToLower modifications: +// 304 -> 105 +// 1024 -> 1104 * +// 1037 -> 1117 * +// UoUpper modifications: +// 255 -> 376 +// 305 -> 73 +// 383 -> 83 +// 1104 -> 1024 * +// 1117 -> 1037 * +// Entries marked with a '*' don't make complete sense based on Unicode manual, although +// they match AS3. + + +static const uint16_t UnicodeToUpperBits[] = { + 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 352, 368, + 0, 384, 0, 0, 400, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, + 0, 0, 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,65407, +43690,43690,43690,21674,43349,43690,43690,54442, 4392, 516, 8490, 8785,21056,46421,43690,43048, // MA: Modified for AS3. +43690, 170, 0, 0, 0, 2776,33545, 36, 3336, 4, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,61440,65534,32767, 0,43688, 0, + 0, 0, 0,65535,65535,65535,43690,43690, 2,43690,43690,43690, 4372,43690,35498, 554, // MA: Modified for AS3. + 0, 0, 0, 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, +43690,43690,43690,43690,43690,43690,43690,43690,43690, 42,43690,43690,43690,43690,43690, 682, + 255, 63, 255, 255, 63, 170, 255,16383, 0, 0, 0, 3, 0, 3, 35, 0, + 0, 0, 0, 0, 0, 0, 0,65535, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535, 1023, 0, + 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +static const uint16_t UnicodeToLowerBits[] = { + 256, 272, 288, 304, 320, 336, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 352, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 384, + 0, 400, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 432, + 0, 0, 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0,65535,32639, 0, 0, +21845,21845,21845,43605,21674,21845,21845,11093,52950,45531,53909, 4526,42128,19114,21845,21522,// MA: Modidied for AS3. +21845, 85, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0,55104,65534, 4091, 0, 0, 0,21844, 0, +65535,65535,65535, 0, 0, 0,21845,21845, 1,21845,21845,21845, 2186,21845,17749, 277, + 0, 0, 0,65534,65535, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65535,65535, 63, 0, 0, 0, +21845,21845,21845,21845,21845,21845,21845,21845,21845, 21,21845,21845,21845,21845,21845, 341, +65280,16128,65280,65280,16128,43520,65280, 0, 0, 0, 0, 3840, 3840, 3840, 7936, 3840, + 0, 0, 0, 0, 0, 0,65535, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,65472,65535, 0, 0, 0, + 0, 0,65534, 2047, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + +struct GUnicodePairType +{ + uint16_t Key, Value; +}; + +static inline bool CmpUnicodeKey(const GUnicodePairType& a, uint16_t key) +{ + return a.Key < key; +} + +static const GUnicodePairType UnicodeToUpperTable[] = { +{ 97, 65}, { 98, 66}, { 99, 67}, { 100, 68}, { 101, 69}, { 102, 70}, { 103, 71}, +{ 104, 72}, { 105, 73}, { 106, 74}, { 107, 75}, { 108, 76}, { 109, 77}, { 110, 78}, +{ 111, 79}, { 112, 80}, { 113, 81}, { 114, 82}, { 115, 83}, { 116, 84}, { 117, 85}, +{ 118, 86}, { 119, 87}, { 120, 88}, { 121, 89}, { 122, 90}, { 224, 192}, { 225, 193}, +{ 226, 194}, { 227, 195}, { 228, 196}, { 229, 197}, { 230, 198}, { 231, 199}, { 232, 200}, +{ 233, 201}, { 234, 202}, { 235, 203}, { 236, 204}, { 237, 205}, { 238, 206}, { 239, 207}, +{ 240, 208}, { 241, 209}, { 242, 210}, { 243, 211}, { 244, 212}, { 245, 213}, { 246, 214}, +{ 248, 216}, { 249, 217}, { 250, 218}, { 251, 219}, { 252, 220}, { 253, 221}, { 254, 222}, +{ 255, 376}, { 257, 256}, { 259, 258}, { 261, 260}, { 263, 262}, { 265, 264}, { 267, 266}, +{ 269, 268}, { 271, 270}, { 273, 272}, { 275, 274}, { 277, 276}, { 279, 278}, { 281, 280}, +{ 283, 282}, { 285, 284}, { 287, 286}, { 289, 288}, { 291, 290}, { 293, 292}, { 295, 294}, +{ 297, 296}, { 299, 298}, { 301, 300}, { 303, 302}, { 305, 73}, { 307, 306}, { 309, 308}, { 311, 310}, +{ 314, 313}, { 316, 315}, { 318, 317}, { 320, 319}, { 322, 321}, { 324, 323}, { 326, 325}, +{ 328, 327}, { 331, 330}, { 333, 332}, { 335, 334}, { 337, 336}, { 339, 338}, { 341, 340}, +{ 343, 342}, { 345, 344}, { 347, 346}, { 349, 348}, { 351, 350}, { 353, 352}, { 355, 354}, +{ 357, 356}, { 359, 358}, { 361, 360}, { 363, 362}, { 365, 364}, { 367, 366}, { 369, 368}, +{ 371, 370}, { 373, 372}, { 375, 374}, { 378, 377}, { 380, 379}, { 382, 381}, { 383, 83}, { 387, 386}, +{ 389, 388}, { 392, 391}, { 396, 395}, { 402, 401}, { 409, 408}, { 417, 416}, { 419, 418}, +{ 421, 420}, { 424, 423}, { 429, 428}, { 432, 431}, { 436, 435}, { 438, 437}, { 441, 440}, +{ 445, 444}, { 454, 452}, { 457, 455}, { 460, 458}, { 462, 461}, { 464, 463}, { 466, 465}, +{ 468, 467}, { 470, 469}, { 472, 471}, { 474, 473}, { 476, 475}, { 477, 398}, { 479, 478}, +{ 481, 480}, { 483, 482}, { 485, 484}, { 487, 486}, { 489, 488}, { 491, 490}, { 493, 492}, +{ 495, 494}, { 499, 497}, { 501, 500}, { 507, 506}, { 509, 508}, { 511, 510}, { 513, 512}, +{ 515, 514}, { 517, 516}, { 519, 518}, { 521, 520}, { 523, 522}, { 525, 524}, { 527, 526}, +{ 529, 528}, { 531, 530}, { 533, 532}, { 535, 534}, { 595, 385}, { 596, 390}, { 598, 393}, +{ 599, 394}, { 601, 399}, { 603, 400}, { 608, 403}, { 611, 404}, { 616, 407}, { 617, 406}, +{ 623, 412}, { 626, 413}, { 629, 415}, { 643, 425}, { 648, 430}, { 650, 433}, { 651, 434}, +{ 658, 439}, { 940, 902}, { 941, 904}, { 942, 905}, { 943, 906}, { 945, 913}, { 946, 914}, +{ 947, 915}, { 948, 916}, { 949, 917}, { 950, 918}, { 951, 919}, { 952, 920}, { 953, 921}, +{ 954, 922}, { 955, 923}, { 956, 924}, { 957, 925}, { 958, 926}, { 959, 927}, { 960, 928}, +{ 961, 929}, { 962, 931}, { 963, 931}, { 964, 932}, { 965, 933}, { 966, 934}, { 967, 935}, +{ 968, 936}, { 969, 937}, { 970, 938}, { 971, 939}, { 972, 908}, { 973, 910}, { 974, 911}, +{ 995, 994}, { 997, 996}, { 999, 998}, { 1001, 1000}, { 1003, 1002}, { 1005, 1004}, { 1007, 1006}, +{ 1072, 1040}, { 1073, 1041}, { 1074, 1042}, { 1075, 1043}, { 1076, 1044}, { 1077, 1045}, { 1078, 1046}, +{ 1079, 1047}, { 1080, 1048}, { 1081, 1049}, { 1082, 1050}, { 1083, 1051}, { 1084, 1052}, { 1085, 1053}, +{ 1086, 1054}, { 1087, 1055}, { 1088, 1056}, { 1089, 1057}, { 1090, 1058}, { 1091, 1059}, { 1092, 1060}, +{ 1093, 1061}, { 1094, 1062}, { 1095, 1063}, { 1096, 1064}, { 1097, 1065}, { 1098, 1066}, { 1099, 1067}, +{ 1100, 1068}, { 1101, 1069}, { 1102, 1070}, { 1103, 1071}, { 1104, 1024}, { 1105, 1025}, { 1106, 1026}, { 1107, 1027}, +{ 1108, 1028}, { 1109, 1029}, { 1110, 1030}, { 1111, 1031}, { 1112, 1032}, { 1113, 1033}, { 1114, 1034}, +{ 1115, 1035}, { 1116, 1036}, { 1117, 1037}, { 1118, 1038}, { 1119, 1039}, { 1121, 1120}, { 1123, 1122}, { 1125, 1124}, +{ 1127, 1126}, { 1129, 1128}, { 1131, 1130}, { 1133, 1132}, { 1135, 1134}, { 1137, 1136}, { 1139, 1138}, +{ 1141, 1140}, { 1143, 1142}, { 1145, 1144}, { 1147, 1146}, { 1149, 1148}, { 1151, 1150}, { 1153, 1152}, +{ 1169, 1168}, { 1171, 1170}, { 1173, 1172}, { 1175, 1174}, { 1177, 1176}, { 1179, 1178}, { 1181, 1180}, +{ 1183, 1182}, { 1185, 1184}, { 1187, 1186}, { 1189, 1188}, { 1191, 1190}, { 1193, 1192}, { 1195, 1194}, +{ 1197, 1196}, { 1199, 1198}, { 1201, 1200}, { 1203, 1202}, { 1205, 1204}, { 1207, 1206}, { 1209, 1208}, +{ 1211, 1210}, { 1213, 1212}, { 1215, 1214}, { 1218, 1217}, { 1220, 1219}, { 1224, 1223}, { 1228, 1227}, +{ 1233, 1232}, { 1235, 1234}, { 1237, 1236}, { 1239, 1238}, { 1241, 1240}, { 1243, 1242}, { 1245, 1244}, +{ 1247, 1246}, { 1249, 1248}, { 1251, 1250}, { 1253, 1252}, { 1255, 1254}, { 1257, 1256}, { 1259, 1258}, +{ 1263, 1262}, { 1265, 1264}, { 1267, 1266}, { 1269, 1268}, { 1273, 1272}, { 1377, 1329}, { 1378, 1330}, +{ 1379, 1331}, { 1380, 1332}, { 1381, 1333}, { 1382, 1334}, { 1383, 1335}, { 1384, 1336}, { 1385, 1337}, +{ 1386, 1338}, { 1387, 1339}, { 1388, 1340}, { 1389, 1341}, { 1390, 1342}, { 1391, 1343}, { 1392, 1344}, +{ 1393, 1345}, { 1394, 1346}, { 1395, 1347}, { 1396, 1348}, { 1397, 1349}, { 1398, 1350}, { 1399, 1351}, +{ 1400, 1352}, { 1401, 1353}, { 1402, 1354}, { 1403, 1355}, { 1404, 1356}, { 1405, 1357}, { 1406, 1358}, +{ 1407, 1359}, { 1408, 1360}, { 1409, 1361}, { 1410, 1362}, { 1411, 1363}, { 1412, 1364}, { 1413, 1365}, +{ 1414, 1366}, { 7681, 7680}, { 7683, 7682}, { 7685, 7684}, { 7687, 7686}, { 7689, 7688}, { 7691, 7690}, +{ 7693, 7692}, { 7695, 7694}, { 7697, 7696}, { 7699, 7698}, { 7701, 7700}, { 7703, 7702}, { 7705, 7704}, +{ 7707, 7706}, { 7709, 7708}, { 7711, 7710}, { 7713, 7712}, { 7715, 7714}, { 7717, 7716}, { 7719, 7718}, +{ 7721, 7720}, { 7723, 7722}, { 7725, 7724}, { 7727, 7726}, { 7729, 7728}, { 7731, 7730}, { 7733, 7732}, +{ 7735, 7734}, { 7737, 7736}, { 7739, 7738}, { 7741, 7740}, { 7743, 7742}, { 7745, 7744}, { 7747, 7746}, +{ 7749, 7748}, { 7751, 7750}, { 7753, 7752}, { 7755, 7754}, { 7757, 7756}, { 7759, 7758}, { 7761, 7760}, +{ 7763, 7762}, { 7765, 7764}, { 7767, 7766}, { 7769, 7768}, { 7771, 7770}, { 7773, 7772}, { 7775, 7774}, +{ 7777, 7776}, { 7779, 7778}, { 7781, 7780}, { 7783, 7782}, { 7785, 7784}, { 7787, 7786}, { 7789, 7788}, +{ 7791, 7790}, { 7793, 7792}, { 7795, 7794}, { 7797, 7796}, { 7799, 7798}, { 7801, 7800}, { 7803, 7802}, +{ 7805, 7804}, { 7807, 7806}, { 7809, 7808}, { 7811, 7810}, { 7813, 7812}, { 7815, 7814}, { 7817, 7816}, +{ 7819, 7818}, { 7821, 7820}, { 7823, 7822}, { 7825, 7824}, { 7827, 7826}, { 7829, 7828}, { 7841, 7840}, +{ 7843, 7842}, { 7845, 7844}, { 7847, 7846}, { 7849, 7848}, { 7851, 7850}, { 7853, 7852}, { 7855, 7854}, +{ 7857, 7856}, { 7859, 7858}, { 7861, 7860}, { 7863, 7862}, { 7865, 7864}, { 7867, 7866}, { 7869, 7868}, +{ 7871, 7870}, { 7873, 7872}, { 7875, 7874}, { 7877, 7876}, { 7879, 7878}, { 7881, 7880}, { 7883, 7882}, +{ 7885, 7884}, { 7887, 7886}, { 7889, 7888}, { 7891, 7890}, { 7893, 7892}, { 7895, 7894}, { 7897, 7896}, +{ 7899, 7898}, { 7901, 7900}, { 7903, 7902}, { 7905, 7904}, { 7907, 7906}, { 7909, 7908}, { 7911, 7910}, +{ 7913, 7912}, { 7915, 7914}, { 7917, 7916}, { 7919, 7918}, { 7921, 7920}, { 7923, 7922}, { 7925, 7924}, +{ 7927, 7926}, { 7929, 7928}, { 7936, 7944}, { 7937, 7945}, { 7938, 7946}, { 7939, 7947}, { 7940, 7948}, +{ 7941, 7949}, { 7942, 7950}, { 7943, 7951}, { 7952, 7960}, { 7953, 7961}, { 7954, 7962}, { 7955, 7963}, +{ 7956, 7964}, { 7957, 7965}, { 7968, 7976}, { 7969, 7977}, { 7970, 7978}, { 7971, 7979}, { 7972, 7980}, +{ 7973, 7981}, { 7974, 7982}, { 7975, 7983}, { 7984, 7992}, { 7985, 7993}, { 7986, 7994}, { 7987, 7995}, +{ 7988, 7996}, { 7989, 7997}, { 7990, 7998}, { 7991, 7999}, { 8000, 8008}, { 8001, 8009}, { 8002, 8010}, +{ 8003, 8011}, { 8004, 8012}, { 8005, 8013}, { 8017, 8025}, { 8019, 8027}, { 8021, 8029}, { 8023, 8031}, +{ 8032, 8040}, { 8033, 8041}, { 8034, 8042}, { 8035, 8043}, { 8036, 8044}, { 8037, 8045}, { 8038, 8046}, +{ 8039, 8047}, { 8048, 8122}, { 8049, 8123}, { 8050, 8136}, { 8051, 8137}, { 8052, 8138}, { 8053, 8139}, +{ 8054, 8154}, { 8055, 8155}, { 8056, 8184}, { 8057, 8185}, { 8058, 8170}, { 8059, 8171}, { 8060, 8186}, +{ 8061, 8187}, { 8112, 8120}, { 8113, 8121}, { 8144, 8152}, { 8145, 8153}, { 8160, 8168}, { 8161, 8169}, +{ 8165, 8172}, { 8560, 8544}, { 8561, 8545}, { 8562, 8546}, { 8563, 8547}, { 8564, 8548}, { 8565, 8549}, +{ 8566, 8550}, { 8567, 8551}, { 8568, 8552}, { 8569, 8553}, { 8570, 8554}, { 8571, 8555}, { 8572, 8556}, +{ 8573, 8557}, { 8574, 8558}, { 8575, 8559}, { 9424, 9398}, { 9425, 9399}, { 9426, 9400}, { 9427, 9401}, +{ 9428, 9402}, { 9429, 9403}, { 9430, 9404}, { 9431, 9405}, { 9432, 9406}, { 9433, 9407}, { 9434, 9408}, +{ 9435, 9409}, { 9436, 9410}, { 9437, 9411}, { 9438, 9412}, { 9439, 9413}, { 9440, 9414}, { 9441, 9415}, +{ 9442, 9416}, { 9443, 9417}, { 9444, 9418}, { 9445, 9419}, { 9446, 9420}, { 9447, 9421}, { 9448, 9422}, +{ 9449, 9423}, {65345,65313}, {65346,65314}, {65347,65315}, {65348,65316}, {65349,65317}, {65350,65318}, +{65351,65319}, {65352,65320}, {65353,65321}, {65354,65322}, {65355,65323}, {65356,65324}, {65357,65325}, +{65358,65326}, {65359,65327}, {65360,65328}, {65361,65329}, {65362,65330}, {65363,65331}, {65364,65332}, +{65365,65333}, {65366,65334}, {65367,65335}, {65368,65336}, {65369,65337}, {65370,65338}, {65535, 0}}; + +static const GUnicodePairType UnicodeToLowerTable[] = { +{ 65, 97}, { 66, 98}, { 67, 99}, { 68, 100}, { 69, 101}, { 70, 102}, { 71, 103}, +{ 72, 104}, { 73, 105}, { 74, 106}, { 75, 107}, { 76, 108}, { 77, 109}, { 78, 110}, +{ 79, 111}, { 80, 112}, { 81, 113}, { 82, 114}, { 83, 115}, { 84, 116}, { 85, 117}, +{ 86, 118}, { 87, 119}, { 88, 120}, { 89, 121}, { 90, 122}, { 192, 224}, { 193, 225}, +{ 194, 226}, { 195, 227}, { 196, 228}, { 197, 229}, { 198, 230}, { 199, 231}, { 200, 232}, +{ 201, 233}, { 202, 234}, { 203, 235}, { 204, 236}, { 205, 237}, { 206, 238}, { 207, 239}, +{ 208, 240}, { 209, 241}, { 210, 242}, { 211, 243}, { 212, 244}, { 213, 245}, { 214, 246}, +{ 216, 248}, { 217, 249}, { 218, 250}, { 219, 251}, { 220, 252}, { 221, 253}, { 222, 254}, +{ 256, 257}, { 258, 259}, { 260, 261}, { 262, 263}, { 264, 265}, { 266, 267}, { 268, 269}, +{ 270, 271}, { 272, 273}, { 274, 275}, { 276, 277}, { 278, 279}, { 280, 281}, { 282, 283}, +{ 284, 285}, { 286, 287}, { 288, 289}, { 290, 291}, { 292, 293}, { 294, 295}, { 296, 297}, +{ 298, 299}, { 300, 301}, { 302, 303}, { 304, 105}, { 306, 307}, { 308, 309}, { 310, 311}, { 313, 314}, +{ 315, 316}, { 317, 318}, { 319, 320}, { 321, 322}, { 323, 324}, { 325, 326}, { 327, 328}, +{ 330, 331}, { 332, 333}, { 334, 335}, { 336, 337}, { 338, 339}, { 340, 341}, { 342, 343}, +{ 344, 345}, { 346, 347}, { 348, 349}, { 350, 351}, { 352, 353}, { 354, 355}, { 356, 357}, +{ 358, 359}, { 360, 361}, { 362, 363}, { 364, 365}, { 366, 367}, { 368, 369}, { 370, 371}, +{ 372, 373}, { 374, 375}, { 376, 255}, { 377, 378}, { 379, 380}, { 381, 382}, { 385, 595}, +{ 386, 387}, { 388, 389}, { 390, 596}, { 391, 392}, { 393, 598}, { 394, 599}, { 395, 396}, +{ 398, 477}, { 399, 601}, { 400, 603}, { 401, 402}, { 403, 608}, { 404, 611}, { 406, 617}, +{ 407, 616}, { 408, 409}, { 412, 623}, { 413, 626}, { 415, 629}, { 416, 417}, { 418, 419}, +{ 420, 421}, { 423, 424}, { 425, 643}, { 428, 429}, { 430, 648}, { 431, 432}, { 433, 650}, +{ 434, 651}, { 435, 436}, { 437, 438}, { 439, 658}, { 440, 441}, { 444, 445}, { 452, 454}, +{ 455, 457}, { 458, 460}, { 461, 462}, { 463, 464}, { 465, 466}, { 467, 468}, { 469, 470}, +{ 471, 472}, { 473, 474}, { 475, 476}, { 478, 479}, { 480, 481}, { 482, 483}, { 484, 485}, +{ 486, 487}, { 488, 489}, { 490, 491}, { 492, 493}, { 494, 495}, { 497, 499}, { 500, 501}, +{ 506, 507}, { 508, 509}, { 510, 511}, { 512, 513}, { 514, 515}, { 516, 517}, { 518, 519}, +{ 520, 521}, { 522, 523}, { 524, 525}, { 526, 527}, { 528, 529}, { 530, 531}, { 532, 533}, +{ 534, 535}, { 902, 940}, { 904, 941}, { 905, 942}, { 906, 943}, { 908, 972}, { 910, 973}, +{ 911, 974}, { 913, 945}, { 914, 946}, { 915, 947}, { 916, 948}, { 917, 949}, { 918, 950}, +{ 919, 951}, { 920, 952}, { 921, 953}, { 922, 954}, { 923, 955}, { 924, 956}, { 925, 957}, +{ 926, 958}, { 927, 959}, { 928, 960}, { 929, 961}, { 931, 963}, { 932, 964}, { 933, 965}, +{ 934, 966}, { 935, 967}, { 936, 968}, { 937, 969}, { 938, 970}, { 939, 971}, { 994, 995}, +{ 996, 997}, { 998, 999}, { 1000, 1001}, { 1002, 1003}, { 1004, 1005}, { 1006, 1007}, { 1024, 1104}, { 1025, 1105}, +{ 1026, 1106}, { 1027, 1107}, { 1028, 1108}, { 1029, 1109}, { 1030, 1110}, { 1031, 1111}, { 1032, 1112}, +{ 1033, 1113}, { 1034, 1114}, { 1035, 1115}, { 1036, 1116}, { 1037, 1117}, { 1038, 1118}, { 1039, 1119}, { 1040, 1072}, +{ 1041, 1073}, { 1042, 1074}, { 1043, 1075}, { 1044, 1076}, { 1045, 1077}, { 1046, 1078}, { 1047, 1079}, +{ 1048, 1080}, { 1049, 1081}, { 1050, 1082}, { 1051, 1083}, { 1052, 1084}, { 1053, 1085}, { 1054, 1086}, +{ 1055, 1087}, { 1056, 1088}, { 1057, 1089}, { 1058, 1090}, { 1059, 1091}, { 1060, 1092}, { 1061, 1093}, +{ 1062, 1094}, { 1063, 1095}, { 1064, 1096}, { 1065, 1097}, { 1066, 1098}, { 1067, 1099}, { 1068, 1100}, +{ 1069, 1101}, { 1070, 1102}, { 1071, 1103}, { 1120, 1121}, { 1122, 1123}, { 1124, 1125}, { 1126, 1127}, +{ 1128, 1129}, { 1130, 1131}, { 1132, 1133}, { 1134, 1135}, { 1136, 1137}, { 1138, 1139}, { 1140, 1141}, +{ 1142, 1143}, { 1144, 1145}, { 1146, 1147}, { 1148, 1149}, { 1150, 1151}, { 1152, 1153}, { 1168, 1169}, +{ 1170, 1171}, { 1172, 1173}, { 1174, 1175}, { 1176, 1177}, { 1178, 1179}, { 1180, 1181}, { 1182, 1183}, +{ 1184, 1185}, { 1186, 1187}, { 1188, 1189}, { 1190, 1191}, { 1192, 1193}, { 1194, 1195}, { 1196, 1197}, +{ 1198, 1199}, { 1200, 1201}, { 1202, 1203}, { 1204, 1205}, { 1206, 1207}, { 1208, 1209}, { 1210, 1211}, +{ 1212, 1213}, { 1214, 1215}, { 1217, 1218}, { 1219, 1220}, { 1223, 1224}, { 1227, 1228}, { 1232, 1233}, +{ 1234, 1235}, { 1236, 1237}, { 1238, 1239}, { 1240, 1241}, { 1242, 1243}, { 1244, 1245}, { 1246, 1247}, +{ 1248, 1249}, { 1250, 1251}, { 1252, 1253}, { 1254, 1255}, { 1256, 1257}, { 1258, 1259}, { 1262, 1263}, +{ 1264, 1265}, { 1266, 1267}, { 1268, 1269}, { 1272, 1273}, { 1329, 1377}, { 1330, 1378}, { 1331, 1379}, +{ 1332, 1380}, { 1333, 1381}, { 1334, 1382}, { 1335, 1383}, { 1336, 1384}, { 1337, 1385}, { 1338, 1386}, +{ 1339, 1387}, { 1340, 1388}, { 1341, 1389}, { 1342, 1390}, { 1343, 1391}, { 1344, 1392}, { 1345, 1393}, +{ 1346, 1394}, { 1347, 1395}, { 1348, 1396}, { 1349, 1397}, { 1350, 1398}, { 1351, 1399}, { 1352, 1400}, +{ 1353, 1401}, { 1354, 1402}, { 1355, 1403}, { 1356, 1404}, { 1357, 1405}, { 1358, 1406}, { 1359, 1407}, +{ 1360, 1408}, { 1361, 1409}, { 1362, 1410}, { 1363, 1411}, { 1364, 1412}, { 1365, 1413}, { 1366, 1414}, +{ 4256, 4304}, { 4257, 4305}, { 4258, 4306}, { 4259, 4307}, { 4260, 4308}, { 4261, 4309}, { 4262, 4310}, +{ 4263, 4311}, { 4264, 4312}, { 4265, 4313}, { 4266, 4314}, { 4267, 4315}, { 4268, 4316}, { 4269, 4317}, +{ 4270, 4318}, { 4271, 4319}, { 4272, 4320}, { 4273, 4321}, { 4274, 4322}, { 4275, 4323}, { 4276, 4324}, +{ 4277, 4325}, { 4278, 4326}, { 4279, 4327}, { 4280, 4328}, { 4281, 4329}, { 4282, 4330}, { 4283, 4331}, +{ 4284, 4332}, { 4285, 4333}, { 4286, 4334}, { 4287, 4335}, { 4288, 4336}, { 4289, 4337}, { 4290, 4338}, +{ 4291, 4339}, { 4292, 4340}, { 4293, 4341}, { 7680, 7681}, { 7682, 7683}, { 7684, 7685}, { 7686, 7687}, +{ 7688, 7689}, { 7690, 7691}, { 7692, 7693}, { 7694, 7695}, { 7696, 7697}, { 7698, 7699}, { 7700, 7701}, +{ 7702, 7703}, { 7704, 7705}, { 7706, 7707}, { 7708, 7709}, { 7710, 7711}, { 7712, 7713}, { 7714, 7715}, +{ 7716, 7717}, { 7718, 7719}, { 7720, 7721}, { 7722, 7723}, { 7724, 7725}, { 7726, 7727}, { 7728, 7729}, +{ 7730, 7731}, { 7732, 7733}, { 7734, 7735}, { 7736, 7737}, { 7738, 7739}, { 7740, 7741}, { 7742, 7743}, +{ 7744, 7745}, { 7746, 7747}, { 7748, 7749}, { 7750, 7751}, { 7752, 7753}, { 7754, 7755}, { 7756, 7757}, +{ 7758, 7759}, { 7760, 7761}, { 7762, 7763}, { 7764, 7765}, { 7766, 7767}, { 7768, 7769}, { 7770, 7771}, +{ 7772, 7773}, { 7774, 7775}, { 7776, 7777}, { 7778, 7779}, { 7780, 7781}, { 7782, 7783}, { 7784, 7785}, +{ 7786, 7787}, { 7788, 7789}, { 7790, 7791}, { 7792, 7793}, { 7794, 7795}, { 7796, 7797}, { 7798, 7799}, +{ 7800, 7801}, { 7802, 7803}, { 7804, 7805}, { 7806, 7807}, { 7808, 7809}, { 7810, 7811}, { 7812, 7813}, +{ 7814, 7815}, { 7816, 7817}, { 7818, 7819}, { 7820, 7821}, { 7822, 7823}, { 7824, 7825}, { 7826, 7827}, +{ 7828, 7829}, { 7840, 7841}, { 7842, 7843}, { 7844, 7845}, { 7846, 7847}, { 7848, 7849}, { 7850, 7851}, +{ 7852, 7853}, { 7854, 7855}, { 7856, 7857}, { 7858, 7859}, { 7860, 7861}, { 7862, 7863}, { 7864, 7865}, +{ 7866, 7867}, { 7868, 7869}, { 7870, 7871}, { 7872, 7873}, { 7874, 7875}, { 7876, 7877}, { 7878, 7879}, +{ 7880, 7881}, { 7882, 7883}, { 7884, 7885}, { 7886, 7887}, { 7888, 7889}, { 7890, 7891}, { 7892, 7893}, +{ 7894, 7895}, { 7896, 7897}, { 7898, 7899}, { 7900, 7901}, { 7902, 7903}, { 7904, 7905}, { 7906, 7907}, +{ 7908, 7909}, { 7910, 7911}, { 7912, 7913}, { 7914, 7915}, { 7916, 7917}, { 7918, 7919}, { 7920, 7921}, +{ 7922, 7923}, { 7924, 7925}, { 7926, 7927}, { 7928, 7929}, { 7944, 7936}, { 7945, 7937}, { 7946, 7938}, +{ 7947, 7939}, { 7948, 7940}, { 7949, 7941}, { 7950, 7942}, { 7951, 7943}, { 7960, 7952}, { 7961, 7953}, +{ 7962, 7954}, { 7963, 7955}, { 7964, 7956}, { 7965, 7957}, { 7976, 7968}, { 7977, 7969}, { 7978, 7970}, +{ 7979, 7971}, { 7980, 7972}, { 7981, 7973}, { 7982, 7974}, { 7983, 7975}, { 7992, 7984}, { 7993, 7985}, +{ 7994, 7986}, { 7995, 7987}, { 7996, 7988}, { 7997, 7989}, { 7998, 7990}, { 7999, 7991}, { 8008, 8000}, +{ 8009, 8001}, { 8010, 8002}, { 8011, 8003}, { 8012, 8004}, { 8013, 8005}, { 8025, 8017}, { 8027, 8019}, +{ 8029, 8021}, { 8031, 8023}, { 8040, 8032}, { 8041, 8033}, { 8042, 8034}, { 8043, 8035}, { 8044, 8036}, +{ 8045, 8037}, { 8046, 8038}, { 8047, 8039}, { 8120, 8112}, { 8121, 8113}, { 8122, 8048}, { 8123, 8049}, +{ 8136, 8050}, { 8137, 8051}, { 8138, 8052}, { 8139, 8053}, { 8152, 8144}, { 8153, 8145}, { 8154, 8054}, +{ 8155, 8055}, { 8168, 8160}, { 8169, 8161}, { 8170, 8058}, { 8171, 8059}, { 8172, 8165}, { 8184, 8056}, +{ 8185, 8057}, { 8186, 8060}, { 8187, 8061}, { 8544, 8560}, { 8545, 8561}, { 8546, 8562}, { 8547, 8563}, +{ 8548, 8564}, { 8549, 8565}, { 8550, 8566}, { 8551, 8567}, { 8552, 8568}, { 8553, 8569}, { 8554, 8570}, +{ 8555, 8571}, { 8556, 8572}, { 8557, 8573}, { 8558, 8574}, { 8559, 8575}, { 9398, 9424}, { 9399, 9425}, +{ 9400, 9426}, { 9401, 9427}, { 9402, 9428}, { 9403, 9429}, { 9404, 9430}, { 9405, 9431}, { 9406, 9432}, +{ 9407, 9433}, { 9408, 9434}, { 9409, 9435}, { 9410, 9436}, { 9411, 9437}, { 9412, 9438}, { 9413, 9439}, +{ 9414, 9440}, { 9415, 9441}, { 9416, 9442}, { 9417, 9443}, { 9418, 9444}, { 9419, 9445}, { 9420, 9446}, +{ 9421, 9447}, { 9422, 9448}, { 9423, 9449}, {65313,65345}, {65314,65346}, {65315,65347}, {65316,65348}, +{65317,65349}, {65318,65350}, {65319,65351}, {65320,65352}, {65321,65353}, {65322,65354}, {65323,65355}, +{65324,65356}, {65325,65357}, {65326,65358}, {65327,65359}, {65328,65360}, {65329,65361}, {65330,65362}, +{65331,65363}, {65332,65364}, {65333,65365}, {65334,65366}, {65335,65367}, {65336,65368}, {65337,65369}, +{65338,65370}, {65535, 0}}; + +int OVR_CDECL OVR_towupper(wchar_t charCode) +{ + // Don't use UnicodeUpperBits! It differs from UnicodeToUpperBits. + if (UnicodeCharIs(UnicodeToUpperBits, charCode)) + { + // To protect from memory overrun in case the character is not found + // we use one extra fake element in the table {65536, 0}. + size_t idx = Alg::LowerBoundSliced( + UnicodeToUpperTable, + 0, + sizeof(UnicodeToUpperTable) / sizeof(UnicodeToUpperTable[0]) - 1, + (uint16_t)charCode, + CmpUnicodeKey); + return UnicodeToUpperTable[idx].Value; + } + return charCode; +} + +int OVR_CDECL OVR_towlower(wchar_t charCode) +{ + // Don't use UnicodeLowerBits! It differs from UnicodeToLowerBits. + if (UnicodeCharIs(UnicodeToLowerBits, charCode)) + { + // To protect from memory overrun in case the character is not found + // we use one extra fake element in the table {65536, 0}. + size_t idx = Alg::LowerBoundSliced( + UnicodeToLowerTable, + 0, + sizeof(UnicodeToLowerTable) / sizeof(UnicodeToLowerTable[0]) - 1, + (uint16_t)charCode, + CmpUnicodeKey); + return UnicodeToLowerTable[idx].Value; + } + return charCode; +} + +#endif //OVR_NO_WCTYPE + +} // OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_Std.h b/LibOVRKernel/Src/Kernel/OVR_Std.h new file mode 100644 index 0000000..6a14231 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Std.h @@ -0,0 +1,638 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Std.h +Content : Standard C function interface +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Std_h +#define OVR_Std_h + +#include "OVR_Types.h" +#include // for va_list args +#include +#include +#include +#include + +#if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) +#define OVR_MSVC_SAFESTRING +#include +#endif + +// Wide-char funcs +#include +#include + +namespace OVR { + +// Has the same behavior as itoa aside from also having a dest size argument. +// Return value: Pointer to the resulting null-terminated string, same as parameter str. +#if defined(OVR_OS_MS) +inline char* OVR_CDECL OVR_itoa(int val, char *dest, size_t destsize, int radix) +{ +#if defined(OVR_MSVC_SAFESTRING) + _itoa_s(val, dest, destsize, radix); + return dest; +#else + OVR_UNUSED(destsize); + return itoa(val, dest, radix); +#endif +} +#else // OVR_OS_MS +inline char* OVR_itoa(int val, char* dest, size_t len, int radix) +{ + if (val == 0) + { + if (len > 1) + { + dest[0] = '0'; + dest[1] = '\0'; + } + else if(len > 0) + dest[0] = '\0'; + return dest; + } + + // FIXME: Fix the following code to avoid memory write overruns when len is in sufficient. + int cur = val; + size_t i = 0; + size_t sign = 0; + + if (val < 0) + { + val = -val; + sign = 1; + } + + while ((val != 0) && (i < (len - 1 - sign))) + { + cur = val % radix; + val /= radix; + + if (radix == 16) + { + switch(cur) + { + case 10: + dest[i] = 'a'; + break; + case 11: + dest[i] = 'b'; + break; + case 12: + dest[i] = 'c'; + break; + case 13: + dest[i] = 'd'; + break; + case 14: + dest[i] = 'e'; + break; + case 15: + dest[i] = 'f'; + break; + default: + dest[i] = (char)('0' + cur); + break; + } + } + else + { + dest[i] = (char)('0' + cur); + } + ++i; + } + + if (sign) + { + dest[i++] = '-'; + } + + for (size_t j = 0; j < i / 2; ++j) + { + char tmp = dest[j]; + dest[j] = dest[i - 1 - j]; + dest[i - 1 - j] = tmp; + } + dest[i] = '\0'; + + return dest; +} + +#endif + + +// String functions + +inline size_t OVR_CDECL OVR_strlen(const char* str) +{ + return strlen(str); +} + +inline char* OVR_CDECL OVR_strcpy(char* dest, size_t destsize, const char* src) +{ +#if defined(OVR_MSVC_SAFESTRING) + strcpy_s(dest, destsize, src); + return dest; +#else + // FIXME: This should be a safer implementation + OVR_UNUSED(destsize); + return strcpy(dest, src); +#endif +} + + +// Acts the same as the strlcpy function. +// Copies src to dest, 0-terminating even if it involves truncating the write. +// Returns the required strlen of dest (which is one less than the required size of dest). +// strlcpy is a safer alternative to strcpy and strncpy and provides size information. +// However, it still may result in an incomplete copy. +// +// Example usage: +// char buffer[256]; +// if(OVR_strlcpy(buffer, "hello world", sizeof(buffer)) < sizeof(buffer)) +// { there was enough space } +// else +// { need a larger buffer } +// +size_t OVR_CDECL OVR_strlcpy(char* dest, const char* src, size_t destsize); + +// Acts the same as the strlcat function. +// Appends src to dest, 0-terminating even if it involves an incomplete write. +// Doesn't 0-terminate in the case that destsize is 0. +// Returns the required strlen of dest (which is one less than the required size of dest). +// The terminating 0 char of dest is overwritten by the first +// character of src, and a new 0 char is appended to dest. The required capacity +// of the destination is (strlen(src) + strlen(dest) + 1). +// strlcat is a safer alternative to strcat and provides size information. +// However, it still may result in an incomplete copy. +// +// Example usage: +// char buffer[256] = "hello "; +// if(OVR_strlcat(buffer, "world", sizeof(buffer)) < sizeof(buffer)) +// { there was enough space } +// else +// { need a larger buffer } +// +size_t OVR_CDECL OVR_strlcat(char* dest, const char* src, size_t destsize); + + +inline char* OVR_CDECL OVR_strncpy(char* dest, size_t destsize, const char* src, size_t count) +{ +#if defined(OVR_MSVC_SAFESTRING) + strncpy_s(dest, destsize, src, count); + return dest; +#else + // FIXME: This should be a safer implementation + OVR_UNUSED(destsize); + return strncpy(dest, src, count); +#endif +} + +inline char * OVR_CDECL OVR_strcat(char* dest, size_t destsize, const char* src) +{ +#if defined(OVR_MSVC_SAFESTRING) + strcat_s(dest, destsize, src); + return dest; +#else + // FIXME: This should be a safer implementation + OVR_UNUSED(destsize); + return strcat(dest, src); +#endif +} + +inline int OVR_CDECL OVR_strcmp(const char* dest, const char* src) +{ + return strcmp(dest, src); +} + +inline const char* OVR_CDECL OVR_strchr(const char* str, char c) +{ + return strchr(str, c); +} + +inline char* OVR_CDECL OVR_strchr(char* str, char c) +{ + return strchr(str, c); +} + +inline const char* OVR_strrchr(const char* str, char c) +{ + size_t len = OVR_strlen(str); + for (size_t i=len; i>0; i--) + if (str[i]==c) + return str+i; + return 0; +} + +inline const uint8_t* OVR_CDECL OVR_memrchr(const uint8_t* str, size_t size, uint8_t c) +{ + for (intptr_t i = (intptr_t)size - 1; i >= 0; i--) + { + if (str[i] == c) + return str + i; + } + return 0; +} + +inline char* OVR_CDECL OVR_strrchr(char* str, char c) +{ + size_t len = OVR_strlen(str); + for (size_t i=len; i>0; i--) + if (str[i]==c) + return str+i; + return 0; +} + + +double OVR_CDECL OVR_strtod(const char* string, char** tailptr); + +inline long OVR_CDECL OVR_strtol(const char* string, char** tailptr, int radix) +{ + return strtol(string, tailptr, radix); +} + +inline long OVR_CDECL OVR_strtoul(const char* string, char** tailptr, int radix) +{ + return strtoul(string, tailptr, radix); +} + +inline int OVR_CDECL OVR_strncmp(const char* ws1, const char* ws2, size_t size) +{ + return strncmp(ws1, ws2, size); +} + +inline uint64_t OVR_CDECL OVR_strtouq(const char *nptr, char **endptr, int base) +{ +#if defined(OVR_CC_MSVC) + return _strtoui64(nptr, endptr, base); +#else + return strtoull(nptr, endptr, base); +#endif +} + +inline int64_t OVR_CDECL OVR_strtoq(const char *nptr, char **endptr, int base) +{ +#if defined(OVR_CC_MSVC) + return _strtoi64(nptr, endptr, base); +#else + return strtoll(nptr, endptr, base); +#endif +} + + +inline int64_t OVR_CDECL OVR_atoq(const char* string) +{ +#if defined(OVR_CC_MSVC) + return _atoi64(string); +#else + return atoll(string); +#endif +} + +inline uint64_t OVR_CDECL OVR_atouq(const char* string) +{ + return OVR_strtouq(string, NULL, 10); +} + + +// Implemented in OVR_Std.cpp in platform-specific manner. +int OVR_CDECL OVR_stricmp(const char* dest, const char* src); +int OVR_CDECL OVR_strnicmp(const char* dest, const char* src, size_t count); + + +// This is like sprintf but with a destination buffer size argument. However, the behavior is different +// from vsnprintf in that the return value semantics are like sprintf (which returns -1 on capacity overflow) and +// not like snprintf (which returns intended strlen on capacity overflow). +inline size_t OVR_CDECL OVR_sprintf(char *dest, size_t destsize, const char* format, ...) +{ + va_list argList; + va_start(argList,format); + size_t ret; +#if defined(OVR_CC_MSVC) + #if defined(OVR_MSVC_SAFESTRING) + ret = _vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); + OVR_ASSERT(ret != -1); + #else + OVR_UNUSED(destsize); + ret = _vsnprintf(dest, destsize - 1, format, argList); // -1 for space for the null character + OVR_ASSERT(ret != -1); + dest[destsize-1] = 0; + #endif +#else + OVR_UNUSED(destsize); + ret = vsprintf(dest, format, argList); + OVR_ASSERT(ret < destsize); +#endif + va_end(argList); + return ret; +} + + +// This is like vsprintf but with a destination buffer size argument. However, the behavior is different +// from vsnprintf in that the return value semantics are like vsprintf (which returns -1 on capacity overflow) and +// not like vsnprintf (which returns intended strlen on capacity overflow). +// Return value: +// On success, the total number of characters written is returned. +// On failure, a negative number is returned. +inline size_t OVR_CDECL OVR_vsprintf(char *dest, size_t destsize, const char * format, va_list argList) +{ + size_t ret; +#if defined(OVR_CC_MSVC) + #if defined(OVR_MSVC_SAFESTRING) + dest[0] = '\0'; + int rv = vsnprintf_s(dest, destsize, _TRUNCATE, format, argList); + if (rv == -1) + { + dest[destsize - 1] = '\0'; + ret = destsize - 1; + } + else + ret = (size_t)rv; + #else + OVR_UNUSED(destsize); + int rv = _vsnprintf(dest, destsize - 1, format, argList); + OVR_ASSERT(rv != -1); + ret = (size_t)rv; + dest[destsize-1] = 0; + #endif +#else + // FIXME: This should be a safer implementation + OVR_UNUSED(destsize); + ret = (size_t)vsprintf(dest, format, argList); + OVR_ASSERT(ret < destsize); +#endif + return ret; +} + +// Same behavior as ISO C99 vsnprintf. +// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. +// destsize specifies the capacity of the input buffer. +// +// Example usage: +// void Log(char *dest, size_t destsize, const char * format, ...) +// { +// char buffer[1024]; +// va_list argList; +// va_start(argList,format); +// int result = OVR_vsnprintf(dest, destsize, format, argList); +// assert(result < destsize); // Else we'd have to retry with a dynamically allocated buffer (of size=result+1) and new argList copy. +// va_end(argList); +// } + +inline int OVR_CDECL OVR_vsnprintf(char *dest, size_t destsize, const char * format, va_list argList) +{ + int ret; +#if defined(OVR_CC_MSVC) + OVR_DISABLE_MSVC_WARNING(4996) // 'vsnprintf': This function or variable may be unsafe. + ret = vsnprintf(dest, destsize, format, argList); // Microsoft vsnprintf is non-conforming; it returns -1 if destsize is insufficient. + if (ret < 0) // If there was a format error or if destsize was insufficient... + { + ret = _vscprintf(format, argList); // Get the expected dest strlen. If the return value is still -1 then there was a format error. + + if (destsize) // If we can 0-terminate the output... + { + if (ret < 0) + dest[0] = 0; + else + dest[destsize-1] = 0; + } + } + // Else the string was written OK and ret is its strlen. + OVR_RESTORE_MSVC_WARNING() +#else + ret = vsnprintf(dest, destsize, format, argList); +#endif + return ret; +} + + +// Same behavior as ISO C99 snprintf. +// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. +// destsize specifies the capacity of the input buffer. +// +// Example usage: +// char buffer[16]; +// int result = OVR_snprintf(buffer, sizeof(buffer), "%d", 37); +// if (result >= sizeof(buffer)) // If there was insufficient capacity... +// { +// char* p = new char[result + 1]; // Or char* p = (char*)OVR_ALLOC(result + 1); +// OVR_snprintf(p, (size_t)result, "%d", 37); +// delete[] p; +// } +// +inline int OVR_CDECL OVR_snprintf(char *dest, size_t destsize, const char * format, ...) +{ + va_list argList; + va_start(argList,format); + int ret = OVR_vsnprintf(dest, destsize, format, argList); + va_end(argList); + return ret; +} + + +// Returns the strlen of the resulting formatted string, or a negative value if the format is invalid. +// Note: If you are planning on printing a string then it's more efficient to just use OVR_vsnprintf and +// look at the return value and handle the uncommon case that there wasn't enough space. +inline int OVR_CDECL OVR_vscprintf(const char * format, va_list argList) +{ + int ret; +#if defined(OVR_CC_MSVC) + ret = _vscprintf(format, argList); +#else + ret = vsnprintf(NULL, 0, format, argList); +#endif + return ret; +} + + +wchar_t* OVR_CDECL OVR_wcscpy(wchar_t* dest, size_t destsize, const wchar_t* src); +wchar_t* OVR_CDECL OVR_wcsncpy(wchar_t* dest, size_t destsize, const wchar_t* src, size_t count); +wchar_t* OVR_CDECL OVR_wcscat(wchar_t* dest, size_t destsize, const wchar_t* src); +size_t OVR_CDECL OVR_wcslen(const wchar_t* str); +int OVR_CDECL OVR_wcscmp(const wchar_t* a, const wchar_t* b); +int OVR_CDECL OVR_wcsicmp(const wchar_t* a, const wchar_t* b); + +inline int OVR_CDECL OVR_wcsicoll(const wchar_t* a, const wchar_t* b) +{ +#if defined(OVR_OS_MS) + #if defined(OVR_CC_MSVC) && (OVR_CC_MSVC >= 1400) + return ::_wcsicoll(a, b); + #else + return ::wcsicoll(a, b); + #endif +#else + // not supported, use regular wcsicmp + return OVR_wcsicmp(a, b); +#endif +} + +inline int OVR_CDECL OVR_wcscoll(const wchar_t* a, const wchar_t* b) +{ +#if defined(OVR_OS_MS) || defined(OVR_OS_LINUX) + return wcscoll(a, b); +#else + // not supported, use regular wcscmp + return OVR_wcscmp(a, b); +#endif +} + +#ifndef OVR_NO_WCTYPE + +inline int OVR_CDECL UnicodeCharIs(const uint16_t* table, wchar_t charCode) +{ + unsigned offset = table[charCode >> 8]; + if (offset == 0) return 0; + if (offset == 1) return 1; + return (table[offset + ((charCode >> 4) & 15)] & (1 << (charCode & 15))) != 0; +} + +extern const uint16_t UnicodeAlnumBits[]; +extern const uint16_t UnicodeAlphaBits[]; +extern const uint16_t UnicodeDigitBits[]; +extern const uint16_t UnicodeSpaceBits[]; +extern const uint16_t UnicodeXDigitBits[]; + +// Uncomment if necessary +//extern const uint16_t UnicodeCntrlBits[]; +//extern const uint16_t UnicodeGraphBits[]; +//extern const uint16_t UnicodeLowerBits[]; +//extern const uint16_t UnicodePrintBits[]; +//extern const uint16_t UnicodePunctBits[]; +//extern const uint16_t UnicodeUpperBits[]; + +inline int OVR_CDECL OVR_iswalnum (wchar_t charCode) { return UnicodeCharIs(UnicodeAlnumBits, charCode); } +inline int OVR_CDECL OVR_iswalpha (wchar_t charCode) { return UnicodeCharIs(UnicodeAlphaBits, charCode); } +inline int OVR_CDECL OVR_iswdigit (wchar_t charCode) { return UnicodeCharIs(UnicodeDigitBits, charCode); } +inline int OVR_CDECL OVR_iswspace (wchar_t charCode) { return UnicodeCharIs(UnicodeSpaceBits, charCode); } +inline int OVR_CDECL OVR_iswxdigit(wchar_t charCode) { return UnicodeCharIs(UnicodeXDigitBits, charCode); } + +// Uncomment if necessary +//inline int OVR_CDECL OVR_iswcntrl (wchar_t charCode) { return UnicodeCharIs(UnicodeCntrlBits, charCode); } +//inline int OVR_CDECL OVR_iswgraph (wchar_t charCode) { return UnicodeCharIs(UnicodeGraphBits, charCode); } +//inline int OVR_CDECL OVR_iswlower (wchar_t charCode) { return UnicodeCharIs(UnicodeLowerBits, charCode); } +//inline int OVR_CDECL OVR_iswprint (wchar_t charCode) { return UnicodeCharIs(UnicodePrintBits, charCode); } +//inline int OVR_CDECL OVR_iswpunct (wchar_t charCode) { return UnicodeCharIs(UnicodePunctBits, charCode); } +//inline int OVR_CDECL OVR_iswupper (wchar_t charCode) { return UnicodeCharIs(UnicodeUpperBits, charCode); } + +int OVR_CDECL OVR_towupper(wchar_t charCode); +int OVR_CDECL OVR_towlower(wchar_t charCode); + +#else // OVR_NO_WCTYPE + +inline int OVR_CDECL OVR_iswspace(wchar_t c) +{ + return iswspace(c); +} + +inline int OVR_CDECL OVR_iswdigit(wchar_t c) +{ + return iswdigit(c); +} + +inline int OVR_CDECL OVR_iswxdigit(wchar_t c) +{ + return iswxdigit(c); +} + +inline int OVR_CDECL OVR_iswalpha(wchar_t c) +{ + return iswalpha(c); +} + +inline int OVR_CDECL OVR_iswalnum(wchar_t c) +{ + return iswalnum(c); +} + +inline wchar_t OVR_CDECL OVR_towlower(wchar_t c) +{ + return (wchar_t)towlower(c); +} + +inline wchar_t OVR_towupper(wchar_t c) +{ + return (wchar_t)towupper(c); +} + +#endif // OVR_NO_WCTYPE + +// ASCII versions of tolower and toupper. Don't use "char" +inline int OVR_CDECL OVR_tolower(int c) +{ + return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; +} + +inline int OVR_CDECL OVR_toupper(int c) +{ + return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; +} + + + +inline double OVR_CDECL OVR_wcstod(const wchar_t* string, wchar_t** tailptr) +{ +#if defined(OVR_OS_OTHER) + OVR_UNUSED(tailptr); + char buffer[64]; + char* tp = NULL; + size_t max = OVR_wcslen(string); + if (max > 63) max = 63; + unsigned char c = 0; + for (size_t i=0; i < max; i++) + { + c = (unsigned char)string[i]; + buffer[i] = ((c) < 128 ? (char)c : '!'); + } + buffer[max] = 0; + return OVR_strtod(buffer, &tp); +#else + return wcstod(string, tailptr); +#endif +} + +inline long OVR_CDECL OVR_wcstol(const wchar_t* string, wchar_t** tailptr, int radix) +{ +#if defined(OVR_OS_OTHER) + OVR_UNUSED(tailptr); + char buffer[64]; + char* tp = NULL; + size_t max = OVR_wcslen(string); + if (max > 63) max = 63; + unsigned char c = 0; + for (size_t i=0; i < max; i++) + { + c = (unsigned char)string[i]; + buffer[i] = ((c) < 128 ? (char)c : '!'); + } + buffer[max] = 0; + return strtol(buffer, &tp, radix); +#else + return wcstol(string, tailptr, radix); +#endif +} + +} // OVR + +#endif // OVR_Std_h diff --git a/LibOVRKernel/Src/Kernel/OVR_String.cpp b/LibOVRKernel/Src/Kernel/OVR_String.cpp new file mode 100644 index 0000000..a539992 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_String.cpp @@ -0,0 +1,779 @@ +/************************************************************************************ + +Filename : OVR_String.cpp +Content : String UTF8 string implementation with copy-on-write semantics + (thread-safe for assignment but not modification). +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_String.h" + +#include +#include + +#ifdef OVR_OS_QNX +# include +#endif + +namespace OVR { + +#define String_LengthIsSize (size_t(1) << String::Flag_LengthIsSizeShift) + +String::DataDesc String::NullData = {String_LengthIsSize, 1, {0} }; + + +String::String() +{ + pData = &NullData; + pData->AddRef(); +}; + +String::String(const char* pdata) +{ + // Obtain length in bytes; it doesn't matter if _data is UTF8. + size_t size = pdata ? OVR_strlen(pdata) : 0; + pData = AllocDataCopy1(size, 0, pdata, size); +}; + +String::String(const char* pdata1, const char* pdata2, const char* pdata3) +{ + // Obtain length in bytes; it doesn't matter if _data is UTF8. + size_t size1 = pdata1 ? OVR_strlen(pdata1) : 0; + size_t size2 = pdata2 ? OVR_strlen(pdata2) : 0; + size_t size3 = pdata3 ? OVR_strlen(pdata3) : 0; + + DataDesc *pdataDesc = AllocDataCopy2(size1 + size2 + size3, 0, + pdata1, size1, pdata2, size2); + memcpy(pdataDesc->Data + size1 + size2, pdata3, size3); + pData = pdataDesc; +} + +String::String(const char* pdata, size_t size) +{ + OVR_ASSERT((size == 0) || (pdata != 0)); + pData = AllocDataCopy1(size, 0, pdata, size); +}; + + +String::String(const InitStruct& src, size_t size) +{ + pData = AllocData(size, 0); + src.InitString(GetData()->Data, size); +} + +String::String(const String& src) +{ + pData = src.GetData(); + pData->AddRef(); +} + +String::String(const StringBuffer& src) +{ + pData = AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize()); +} + +String::String(const wchar_t* data) +{ + pData = &NullData; + pData->AddRef(); + // Simplified logic for wchar_t constructor. + if (data) + *this = data; +} + + +String::DataDesc* String::AllocData(size_t size, size_t lengthIsSize) +{ + String::DataDesc* pdesc; + + if (size == 0) + { + pdesc = &NullData; + pdesc->AddRef(); + return pdesc; + } + + pdesc = (DataDesc*)OVR_ALLOC(sizeof(DataDesc)+ size); + pdesc->Data[size] = 0; + pdesc->RefCount = 1; + pdesc->Size = size | lengthIsSize; + return pdesc; +} + + +String::DataDesc* String::AllocDataCopy1(size_t size, size_t lengthIsSize, + const char* pdata, size_t copySize) +{ + String::DataDesc* pdesc = AllocData(size, lengthIsSize); + memcpy(pdesc->Data, pdata, copySize); + return pdesc; +} + +String::DataDesc* String::AllocDataCopy2(size_t size, size_t lengthIsSize, + const char* pdata1, size_t copySize1, + const char* pdata2, size_t copySize2) +{ + String::DataDesc* pdesc = AllocData(size, lengthIsSize); + memcpy(pdesc->Data, pdata1, copySize1); + memcpy(pdesc->Data + copySize1, pdata2, copySize2); + return pdesc; +} + + +size_t String::GetLength() const +{ + // Optimize length accesses for non-UTF8 character strings. + DataDesc* pdata = GetData(); + size_t length, size = pdata->GetSize(); + + if (pdata->LengthIsSize()) + return size; + + length = (size_t)UTF8Util::GetLength(pdata->Data, (size_t)size); + + if (length == size) + pdata->Size |= String_LengthIsSize; + + return length; +} + + +//static uint32_t String_CharSearch(const char* buf, ) + + +uint32_t String::GetCharAt(size_t index) const +{ + intptr_t i = (intptr_t) index; + DataDesc* pdata = GetData(); + const char* buf = pdata->Data; + uint32_t c; + + if (pdata->LengthIsSize()) + { + OVR_ASSERT(index < pdata->GetSize()); + buf += i; + return UTF8Util::DecodeNextChar_Advance0(&buf); + } + + c = UTF8Util::GetCharAt(index, buf, pdata->GetSize()); + return c; +} + +uint32_t String::GetFirstCharAt(size_t index, const char** offset) const +{ + DataDesc* pdata = GetData(); + intptr_t i = (intptr_t) index; + const char* buf = pdata->Data; + const char* end = buf + pdata->GetSize(); + uint32_t c; + + do + { + c = UTF8Util::DecodeNextChar_Advance0(&buf); + i--; + + if (buf >= end) + { + // We've hit the end of the string; don't go further. + OVR_ASSERT(i == 0); + return c; + } + } while (i >= 0); + + *offset = buf; + + return c; +} + +uint32_t String::GetNextChar(const char** offset) const +{ + return UTF8Util::DecodeNextChar(offset); +} + + + +void String::AppendChar(uint32_t ch) +{ + DataDesc* pdata = GetData(); + size_t size = pdata->GetSize(); + char buff[8]; + intptr_t encodeSize = 0; + + // Converts ch into UTF8 string and fills it into buff. + UTF8Util::EncodeChar(buff, &encodeSize, ch); + OVR_ASSERT(encodeSize >= 0); + + SetData(AllocDataCopy2(size + (size_t)encodeSize, 0, + pdata->Data, size, buff, (size_t)encodeSize)); + pdata->Release(); +} + + +void String::AppendString(const wchar_t* pstr, intptr_t len) +{ + if (!pstr) + return; + + DataDesc* pdata = GetData(); + size_t oldSize = pdata->GetSize(); + size_t encodeSize = (size_t)UTF8Util::GetEncodeStringSize(pstr, len); + + DataDesc* pnewData = AllocDataCopy1(oldSize + (size_t)encodeSize, 0, + pdata->Data, oldSize); + UTF8Util::EncodeString(pnewData->Data + oldSize, pstr, len); + + SetData(pnewData); + pdata->Release(); +} + + +void String::AppendString(const char* putf8str, intptr_t utf8StrSz) +{ + if (!putf8str || !utf8StrSz) + return; + if (utf8StrSz == -1) + utf8StrSz = (intptr_t)OVR_strlen(putf8str); + + DataDesc* pdata = GetData(); + size_t oldSize = pdata->GetSize(); + + SetData(AllocDataCopy2(oldSize + (size_t)utf8StrSz, 0, + pdata->Data, oldSize, putf8str, (size_t)utf8StrSz)); + pdata->Release(); +} + +void String::AssignString(const InitStruct& src, size_t size) +{ + DataDesc* poldData = GetData(); + DataDesc* pnewData = AllocData(size, 0); + src.InitString(pnewData->Data, size); + SetData(pnewData); + poldData->Release(); +} + +void String::AssignString(const char* putf8str, size_t size) +{ + DataDesc* poldData = GetData(); + SetData(AllocDataCopy1(size, 0, putf8str, size)); + poldData->Release(); +} + +void String::operator = (const char* pstr) +{ + AssignString(pstr, pstr ? OVR_strlen(pstr) : 0); +} + +void String::operator = (const wchar_t* pwstr) +{ + pwstr = pwstr ? pwstr : L""; + + DataDesc* poldData = GetData(); + size_t size = (size_t)UTF8Util::GetEncodeStringSize(pwstr); + + DataDesc* pnewData = AllocData(size, 0); + UTF8Util::EncodeString(pnewData->Data, pwstr); + SetData(pnewData); + poldData->Release(); +} + + +void String::operator = (const String& src) +{ + DataDesc* psdata = src.GetData(); + DataDesc* pdata = GetData(); + + SetData(psdata); + psdata->AddRef(); + pdata->Release(); +} + + +void String::operator = (const StringBuffer& src) +{ + DataDesc* polddata = GetData(); + SetData(AllocDataCopy1(src.GetSize(), 0, src.ToCStr(), src.GetSize())); + polddata->Release(); +} + +void String::operator += (const String& src) +{ + DataDesc *pourData = GetData(), + *psrcData = src.GetData(); + size_t ourSize = pourData->GetSize(), + srcSize = psrcData->GetSize(); + size_t lflag = pourData->GetLengthFlag() & psrcData->GetLengthFlag(); + + SetData(AllocDataCopy2(ourSize + srcSize, lflag, + pourData->Data, ourSize, psrcData->Data, srcSize)); + pourData->Release(); +} + + +String String::operator + (const char* str) const +{ + String tmp1(*this); + tmp1 += (str ? str : ""); + return tmp1; +} + +String String::operator + (const String& src) const +{ + String tmp1(*this); + tmp1 += src; + return tmp1; +} + +void String::Remove(size_t posAt, intptr_t removeLength) +{ + DataDesc* pdata = GetData(); + size_t oldSize = pdata->GetSize(); + // Length indicates the number of characters to remove. + size_t length = GetLength(); + + // If index is past the string, nothing to remove. + if (posAt >= length) + return; + // Otherwise, cap removeLength to the length of the string. + if ((posAt + removeLength) > length) + removeLength = length - posAt; + + // Get the byte position of the UTF8 char at position posAt. + intptr_t bytePos = UTF8Util::GetByteIndex(posAt, pdata->Data, oldSize); + intptr_t removeSize = UTF8Util::GetByteIndex(removeLength, pdata->Data + bytePos, oldSize-bytePos); + + SetData(AllocDataCopy2(oldSize - removeSize, pdata->GetLengthFlag(), + pdata->Data, bytePos, + pData->Data + bytePos + removeSize, (oldSize - bytePos - removeSize))); + pdata->Release(); +} + + +String String::Substring(size_t start, size_t end) const +{ + size_t length = GetLength(); + if ((start >= length) || (start >= end)) + return String(); + + DataDesc* pdata = GetData(); + + // If size matches, we know the exact index range. + if (pdata->LengthIsSize()) + return String(pdata->Data + start, end - start); + + // Get position of starting character. + intptr_t byteStart = UTF8Util::GetByteIndex(start, pdata->Data, pdata->GetSize()); + intptr_t byteSize = UTF8Util::GetByteIndex(end - start, pdata->Data + byteStart, pdata->GetSize()-byteStart); + return String(pdata->Data + byteStart, (size_t)byteSize); +} + +void String::Clear() +{ + NullData.AddRef(); + GetData()->Release(); + SetData(&NullData); +} + + +String String::ToUpper() const +{ + uint32_t c; + const char* psource = GetData()->Data; + const char* pend = psource + GetData()->GetSize(); + String str; + intptr_t bufferOffset = 0; + char buffer[512]; + + while(psource < pend) + { + do { + c = UTF8Util::DecodeNextChar_Advance0(&psource); + UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towupper(wchar_t(c))); + } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8))); + + // Append string a piece at a time. + str.AppendString(buffer, bufferOffset); + bufferOffset = 0; + } + + return str; +} + +String String::ToLower() const +{ + uint32_t c; + const char* psource = GetData()->Data; + const char* pend = psource + GetData()->GetSize(); + String str; + intptr_t bufferOffset = 0; + char buffer[512]; + + while(psource < pend) + { + do { + c = UTF8Util::DecodeNextChar_Advance0(&psource); + UTF8Util::EncodeChar(buffer, &bufferOffset, OVR_towlower(wchar_t(c))); + } while ((psource < pend) && (bufferOffset < intptr_t(sizeof(buffer)-8))); + + // Append string a piece at a time. + str.AppendString(buffer, bufferOffset); + bufferOffset = 0; + } + + return str; +} + + + +String& String::Insert(const char* substr, size_t posAt, intptr_t strSize) +{ + DataDesc* poldData = GetData(); + size_t oldSize = poldData->GetSize(); + size_t insertSize = (strSize < 0) ? OVR_strlen(substr) : (size_t)strSize; + size_t byteIndex = (poldData->LengthIsSize()) ? + posAt : (size_t)UTF8Util::GetByteIndex(posAt, poldData->Data, oldSize); + + OVR_ASSERT(byteIndex <= oldSize); + + DataDesc* pnewData = AllocDataCopy2(oldSize + insertSize, 0, + poldData->Data, byteIndex, substr, insertSize); + memcpy(pnewData->Data + byteIndex + insertSize, + poldData->Data + byteIndex, oldSize - byteIndex); + SetData(pnewData); + poldData->Release(); + return *this; +} + +/* +String& String::Insert(const uint32_t* substr, size_t posAt, intptr_t len) +{ + for (intptr_t i = 0; i < len; ++i) + { + size_t charw = InsertCharAt(substr[i], posAt); + posAt += charw; + } + return *this; +} +*/ + +size_t String::InsertCharAt(uint32_t c, size_t posAt) +{ + char buf[8]; + intptr_t index = 0; + UTF8Util::EncodeChar(buf, &index, c); + OVR_ASSERT(index >= 0); + buf[(size_t)index] = 0; + + Insert(buf, posAt, index); + return (size_t)index; +} + + +int String::CompareNoCase(const char* a, const char* b) +{ + return OVR_stricmp(a, b); +} + +int String::CompareNoCase(const char* a, const char* b, intptr_t len) +{ + if (len) + { + intptr_t f,l; + intptr_t slen = len; + const char *s = b; + do { + f = (intptr_t)OVR_tolower((int)(*(a++))); + l = (intptr_t)OVR_tolower((int)(*(b++))); + } while (--len && f && (f == l) && *b != 0); + + if (f == l && (len != 0 || *b != 0)) + { + f = (intptr_t)slen; + l = (intptr_t)OVR_strlen(s); + return int(f - l); + } + + return int(f - l); + } + else + return (0-(int)OVR_strlen(b)); +} + +// ***** Implement hash static functions + +// Hash function +size_t String::BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed) +{ + const uint8_t* pdata = (const uint8_t*) pdataIn; + size_t h = seed; + while (size > 0) + { + size--; + h = ((h << 5) + h) ^ (unsigned) pdata[size]; + } + + return h; +} + +// Hash function, case-insensitive +size_t String::BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed) +{ + const uint8_t* pdata = (const uint8_t*) pdataIn; + size_t h = seed; + while (size > 0) + { + size--; + h = ((h << 5) + h) ^ OVR_tolower(pdata[size]); + } + + // Alternative: "sdbm" hash function, suggested at same web page above. + // h = 0; + // for bytes { h = (h << 16) + (h << 6) - hash + *p; } + return h; +} + + + +// ***** String Buffer used for Building Strings + + +#define OVR_SBUFF_DEFAULT_GROW_SIZE 512 +// Constructors / Destructor. +StringBuffer::StringBuffer() + : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) +{ +} + +StringBuffer::StringBuffer(size_t growSize) + : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) +{ + SetGrowSize(growSize); +} + +StringBuffer::StringBuffer(const char* data) + : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) +{ + AppendString(data); +} + +StringBuffer::StringBuffer(const char* data, size_t dataSize) + : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) +{ + AppendString(data, dataSize); +} + +StringBuffer::StringBuffer(const String& src) + : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) +{ + AppendString(src.ToCStr(), src.GetSize()); +} + +StringBuffer::StringBuffer(const StringBuffer& src) + : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) +{ + AppendString(src.ToCStr(), src.GetSize()); +} + +StringBuffer::StringBuffer(const wchar_t* data) + : pData(NULL), Size(0), BufferSize(0), GrowSize(OVR_SBUFF_DEFAULT_GROW_SIZE), LengthIsSize(false) +{ + *this = data; +} + +StringBuffer::~StringBuffer() +{ + if (pData) + OVR_FREE(pData); +} +void StringBuffer::SetGrowSize(size_t growSize) +{ + if (growSize <= 16) + GrowSize = 16; + else + { + uint8_t bits = Alg::UpperBit(uint32_t(growSize-1)); + size_t size = (size_t)1 << bits; + GrowSize = size == growSize ? growSize : size; + } +} + +size_t StringBuffer::GetLength() const +{ + size_t length, size = GetSize(); + if (LengthIsSize) + return size; + + length = (size_t)UTF8Util::GetLength(pData, (size_t)GetSize()); + + if (length == GetSize()) + LengthIsSize = true; + return length; +} + +void StringBuffer::Reserve(size_t _size) +{ + if (_size >= BufferSize) // >= because of trailing zero! (!AB) + { + BufferSize = (_size + 1 + GrowSize - 1)& ~(GrowSize-1); + if (!pData) + pData = (char*)OVR_ALLOC(BufferSize); + else + pData = (char*)OVR_REALLOC(pData, BufferSize); + } +} +void StringBuffer::Resize(size_t _size) +{ + Reserve(_size); + LengthIsSize = false; + Size = _size; + if (pData) + pData[Size] = 0; +} + +void StringBuffer::Clear() +{ + Resize(0); + /* + if (pData != pEmptyNullData) + { + OVR_FREE(pHeap, pData); + pData = pEmptyNullData; + Size = BufferSize = 0; + LengthIsSize = false; + } + */ +} +// Appends a character +void StringBuffer::AppendChar(uint32_t ch) +{ + char buff[8]; + size_t origSize = GetSize(); + + // Converts ch into UTF8 string and fills it into buff. Also increments index according to the number of bytes + // in the UTF8 string. + intptr_t srcSize = 0; + UTF8Util::EncodeChar(buff, &srcSize, ch); + OVR_ASSERT(srcSize >= 0); + + size_t size = origSize + srcSize; + Resize(size); + OVR_ASSERT(pData != NULL); + memcpy(pData + origSize, buff, srcSize); +} + +// Append a string +void StringBuffer::AppendString(const wchar_t* pstr, intptr_t len) +{ + if (!pstr || !len) + return; + + intptr_t srcSize = UTF8Util::GetEncodeStringSize(pstr, len); + size_t origSize = GetSize(); + size_t size = srcSize + origSize; + + Resize(size); + OVR_ASSERT(pData != NULL); + UTF8Util::EncodeString(pData + origSize, pstr, len); +} + +void StringBuffer::AppendString(const char* putf8str, intptr_t utf8StrSz) +{ + if (!putf8str || !utf8StrSz) + return; + if (utf8StrSz == -1) + utf8StrSz = (intptr_t)OVR_strlen(putf8str); + + size_t origSize = GetSize(); + size_t size = utf8StrSz + origSize; + + Resize(size); + OVR_ASSERT(pData != NULL); + memcpy(pData + origSize, putf8str, utf8StrSz); +} + +// If pstr is NULL then the StringBuffer is cleared. +void StringBuffer::operator = (const char* pstr) +{ + pstr = pstr ? pstr : ""; + size_t size = OVR_strlen(pstr); + Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); + memcpy(pData, pstr, size); +} + +// If pstr is NULL then the StringBuffer is cleared. +void StringBuffer::operator = (const wchar_t* pstr) +{ + pstr = pstr ? pstr : L""; + size_t size = (size_t)UTF8Util::GetEncodeStringSize(pstr); + Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); + UTF8Util::EncodeString(pData, pstr); +} + +void StringBuffer::operator = (const String& src) +{ + const size_t size = src.GetSize(); + Resize(size); + OVR_ASSERT((pData != NULL) || (size == 0)); + memcpy(pData, src.ToCStr(), size); +} + +void StringBuffer::operator = (const StringBuffer& src) +{ + Clear(); + AppendString(src.ToCStr(), src.GetSize()); +} + + +// Inserts substr at posAt +void StringBuffer::Insert(const char* substr, size_t posAt, intptr_t len) +{ + size_t oldSize = Size; + size_t insertSize = (len < 0) ? OVR_strlen(substr) : (size_t)len; + size_t byteIndex = LengthIsSize ? posAt : + (size_t)UTF8Util::GetByteIndex(posAt, pData, (intptr_t)Size); + + OVR_ASSERT(byteIndex <= oldSize); + Reserve(oldSize + insertSize); + + OVR_ASSERT(pData != NULL); // pData is unilaterally written to below. + memmove(pData + byteIndex + insertSize, pData + byteIndex, oldSize - byteIndex + 1); + memcpy (pData + byteIndex, substr, insertSize); + LengthIsSize = false; + Size = oldSize + insertSize; + pData[Size] = 0; +} + +// Inserts character at posAt +size_t StringBuffer::InsertCharAt(uint32_t c, size_t posAt) +{ + char buf[8]; + intptr_t len = 0; + UTF8Util::EncodeChar(buf, &len, c); + OVR_ASSERT(len >= 0); + buf[(size_t)len] = 0; + + Insert(buf, posAt, len); + return (size_t)len; +} + +} // OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_String.h b/LibOVRKernel/Src/Kernel/OVR_String.h new file mode 100644 index 0000000..ecef940 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_String.h @@ -0,0 +1,658 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_String.h +Content : String UTF8 string implementation with copy-on-write semantics + (thread-safe for assignment but not modification). +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_String_h +#define OVR_String_h + +#include "OVR_Types.h" +#include "OVR_Allocator.h" +#include "OVR_UTF8Util.h" +#include "OVR_Atomic.h" +#include "OVR_Std.h" +#include "OVR_Alg.h" + +namespace OVR { + +// ***** Classes + +class String; +class StringBuffer; + + +//----------------------------------------------------------------------------------- +// ***** String Class + +// String is UTF8 based string class with copy-on-write implementation +// for assignment. + +class String +{ +protected: + + enum FlagConstants + { + //Flag_GetLength = 0x7FFFFFFF, + // This flag is set if GetLength() == GetSize() for a string. + // Avoid extra scanning is Substring and indexing logic. + Flag_LengthIsSizeShift = (sizeof(size_t)*8 - 1) + }; + + + // Internal structure to hold string data + struct DataDesc + { + // Number of bytes. Will be the same as the number of chars if the characters + // are ascii, may not be equal to number of chars in case string data is UTF8. + size_t Size; + volatile int32_t RefCount; + char Data[1]; + + void AddRef() + { + AtomicOps::ExchangeAdd_NoSync(&RefCount, 1); + } + // Decrement ref count. This needs to be thread-safe, since + // a different thread could have also decremented the ref count. + // For example, if u start off with a ref count = 2. Now if u + // decrement the ref count and check against 0 in different + // statements, a different thread can also decrement the ref count + // in between our decrement and checking against 0 and will find + // the ref count = 0 and delete the object. This will lead to a crash + // when context switches to our thread and we'll be trying to delete + // an already deleted object. Hence decrementing the ref count and + // checking against 0 needs to made an atomic operation. + void Release() + { + if ((AtomicOps::ExchangeAdd_NoSync(&RefCount, -1) - 1) == 0) + OVR_FREE(this); + } + + static size_t GetLengthFlagBit() { return size_t(1) << Flag_LengthIsSizeShift; } + size_t GetSize() const { return Size & ~GetLengthFlagBit() ; } + size_t GetLengthFlag() const { return Size & GetLengthFlagBit(); } + bool LengthIsSize() const { return GetLengthFlag() != 0; } + }; + + // Heap type of the string is encoded in the lower bits. + enum HeapType + { + HT_Global = 0, // Heap is global. + HT_Local = 1, // SF::String_loc: Heap is determined based on string's address. + HT_Dynamic = 2, // SF::String_temp: Heap is stored as a part of the class. + HT_Mask = 3 + }; + + union { + DataDesc* pData; + size_t HeapTypeBits; + }; + typedef union { + DataDesc* pData; + size_t HeapTypeBits; + } DataDescUnion; + + inline HeapType GetHeapType() const { return (HeapType) (HeapTypeBits & HT_Mask); } + + inline DataDesc* GetData() const + { + DataDescUnion u; + u.pData = pData; + u.HeapTypeBits = (u.HeapTypeBits & ~(size_t)HT_Mask); + return u.pData; + } + + inline void SetData(DataDesc* pdesc) + { + HeapType ht = GetHeapType(); + pData = pdesc; + OVR_ASSERT((HeapTypeBits & HT_Mask) == 0); + HeapTypeBits |= ht; + } + + + DataDesc* AllocData(size_t size, size_t lengthIsSize); + DataDesc* AllocDataCopy1(size_t size, size_t lengthIsSize, + const char* pdata, size_t copySize); + DataDesc* AllocDataCopy2(size_t size, size_t lengthIsSize, + const char* pdata1, size_t copySize1, + const char* pdata2, size_t copySize2); + + // Special constructor to avoid data initalization when used in derived class. + struct NoConstructor { }; + String(const NoConstructor&) { } + +public: + + // For initializing string with dynamic buffer + struct InitStruct + { + virtual ~InitStruct() { } + virtual void InitString(char* pbuffer, size_t size) const = 0; + }; + + + // Constructors / Destructors. + String(); + String(const char* data); + String(const char* data1, const char* pdata2, const char* pdata3 = 0); + String(const char* data, size_t buflen); + String(const String& src); + String(const StringBuffer& src); + String(const InitStruct& src, size_t size); + explicit String(const wchar_t* data); + + // Destructor (Captain Obvious guarantees!) + ~String() + { + GetData()->Release(); + } + + // Declaration of NullString + static DataDesc NullData; + + + // *** General Functions + + void Clear(); + + // For casting to a pointer to char. + operator const char*() const { return GetData()->Data; } + // Pointer to raw buffer. + const char* ToCStr() const { return GetData()->Data; } + + // Returns number of bytes + size_t GetSize() const { return GetData()->GetSize() ; } + // Tells whether or not the string is empty + bool IsEmpty() const { return GetSize() == 0; } + + // Returns number of characters + size_t GetLength() const; + int GetLengthI() const { return (int)GetLength(); } + + // Returns character at the specified index + uint32_t GetCharAt(size_t index) const; + uint32_t GetFirstCharAt(size_t index, const char** offset) const; + uint32_t GetNextChar(const char** offset) const; + + // Appends a character + void AppendChar(uint32_t ch); + + // Append a string + void AppendString(const wchar_t* pstr, intptr_t len = -1); + void AppendString(const char* putf8str, intptr_t utf8StrSz = -1); + + // Assigned a string with dynamic data (copied through initializer). + void AssignString(const InitStruct& src, size_t size); + // Assigns string with known size. + void AssignString(const char* putf8str, size_t size); + + // Resize the string to the new size +// void Resize(size_t _size); + + // Removes the character at posAt + void Remove(size_t posAt, intptr_t len = 1); + + // Returns a String that's a substring of this. + // -start is the index of the first UTF8 character you want to include. + // -end is the index one past the last UTF8 character you want to include. + String Substring(size_t start, size_t end) const; + + // Case-conversion + String ToUpper() const; + String ToLower() const; + + // Inserts substr at posAt + String& Insert (const char* substr, size_t posAt, intptr_t len = -1); + + // Inserts character at posAt + size_t InsertCharAt(uint32_t c, size_t posAt); + + // Inserts substr at posAt, which is an index of a character (not byte). + // Of size is specified, it is in bytes. +// String& Insert(const uint32_t* substr, size_t posAt, intptr_t size = -1); + + // Get Byte index of the character at position = index + size_t GetByteIndex(size_t index) const { return (size_t)UTF8Util::GetByteIndex(index, GetData()->Data); } + + // Utility: case-insensitive string compare. stricmp() & strnicmp() are not + // ANSI or POSIX, do not seem to appear in Linux. + static int OVR_STDCALL CompareNoCase(const char* a, const char* b); + static int OVR_STDCALL CompareNoCase(const char* a, const char* b, intptr_t len); + + // Hash function, case-insensitive + static size_t OVR_STDCALL BernsteinHashFunctionCIS(const void* pdataIn, size_t size, size_t seed = 5381); + + // Hash function, case-sensitive + static size_t OVR_STDCALL BernsteinHashFunction(const void* pdataIn, size_t size, size_t seed = 5381); + + + // ***** File path parsing helper functions. + // Implemented in OVR_String_FilePath.cpp. + + // Absolute paths can star with: + // - protocols: 'file://', 'http://' + // - windows drive: 'c:\' + // - UNC share name: '\\share' + // - unix root '/' + static bool HasAbsolutePath(const char* path); + static bool HasExtension(const char* path); + static bool HasProtocol(const char* path); + + bool HasAbsolutePath() const { return HasAbsolutePath(ToCStr()); } + bool HasExtension() const { return HasExtension(ToCStr()); } + bool HasProtocol() const { return HasProtocol(ToCStr()); } + + String GetProtocol() const; // Returns protocol, if any, with trailing '://'. + String GetPath() const; // Returns path with trailing '/'. + String GetFilename() const; // Returns filename, including extension. + String GetExtension() const; // Returns extension with a dot. + + void StripProtocol(); // Strips front protocol, if any, from the string. + void StripExtension(); // Strips off trailing extension. + + + // Operators + // Assignment + void operator = (const char* str); + void operator = (const wchar_t* str); + void operator = (const String& src); + void operator = (const StringBuffer& src); + + // Addition + void operator += (const String& src); + void operator += (const char* psrc) { AppendString(psrc); } + void operator += (const wchar_t* psrc) { AppendString(psrc); } + void operator += (char ch) { AppendChar(ch); } + String operator + (const char* str) const; + String operator + (const String& src) const; + + // Comparison + bool operator == (const String& str) const + { + return (OVR_strcmp(GetData()->Data, str.GetData()->Data)== 0); + } + + bool operator != (const String& str) const + { + return !operator == (str); + } + + bool operator == (const char* str) const + { + return OVR_strcmp(GetData()->Data, str) == 0; + } + + bool operator != (const char* str) const + { + return !operator == (str); + } + + bool operator < (const char* pstr) const + { + return OVR_strcmp(GetData()->Data, pstr) < 0; + } + + bool operator < (const String& str) const + { + return *this < str.GetData()->Data; + } + + bool operator > (const char* pstr) const + { + return OVR_strcmp(GetData()->Data, pstr) > 0; + } + + bool operator > (const String& str) const + { + return *this > str.GetData()->Data; + } + + int CompareNoCase(const char* pstr) const + { + return CompareNoCase(GetData()->Data, pstr); + } + int CompareNoCase(const String& str) const + { + return CompareNoCase(GetData()->Data, str.ToCStr()); + } + + // Accesses raw bytes + const char& operator [] (int index) const + { + OVR_ASSERT(index >= 0 && (size_t)index < GetSize()); + return GetData()->Data[index]; + } + const char& operator [] (size_t index) const + { + OVR_ASSERT(index < GetSize()); + return GetData()->Data[index]; + } + + + // Case insensitive keys are used to look up insensitive string in hash tables + // for SWF files with version before SWF 7. + struct NoCaseKey + { + const String* pStr; + NoCaseKey(const String &str) : pStr(&str){}; + }; + + bool operator == (const NoCaseKey& strKey) const + { + return (CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0); + } + bool operator != (const NoCaseKey& strKey) const + { + return !(CompareNoCase(ToCStr(), strKey.pStr->ToCStr()) == 0); + } + + // Hash functor used for strings. + struct HashFunctor + { + size_t operator()(const String& data) const + { + size_t size = data.GetSize(); + return String::BernsteinHashFunction((const char*)data, size); + } + }; + // Case-insensitive hash functor used for strings. Supports additional + // lookup based on NoCaseKey. + struct NoCaseHashFunctor + { + size_t operator()(const String& data) const + { + size_t size = data.GetSize(); + return String::BernsteinHashFunctionCIS((const char*)data, size); + } + size_t operator()(const NoCaseKey& data) const + { + size_t size = data.pStr->GetSize(); + return String::BernsteinHashFunctionCIS((const char*)data.pStr->ToCStr(), size); + } + }; + +}; + + +//----------------------------------------------------------------------------------- +// ***** String Buffer used for Building Strings + +class StringBuffer +{ + char* pData; + size_t Size; + size_t BufferSize; + size_t GrowSize; + mutable bool LengthIsSize; + +public: + + // Constructors / Destructor. + StringBuffer(); + explicit StringBuffer(size_t growSize); + StringBuffer(const char* data); + StringBuffer(const char* data, size_t buflen); + StringBuffer(const String& src); + StringBuffer(const StringBuffer& src); + explicit StringBuffer(const wchar_t* data); + ~StringBuffer(); + + + // Modify grow size used for growing/shrinking the buffer. + size_t GetGrowSize() const { return GrowSize; } + void SetGrowSize(size_t growSize); + + + // *** General Functions + // Does not release memory, just sets Size to 0 + void Clear(); + + // For casting to a pointer to char. + operator const char*() const { return (pData) ? pData : ""; } + // Pointer to raw buffer. + const char* ToCStr() const { return (pData) ? pData : ""; } + + // Returns number of bytes. + size_t GetSize() const { return Size ; } + // Tells whether or not the string is empty. + bool IsEmpty() const { return GetSize() == 0; } + + // Returns number of characters + size_t GetLength() const; + + // Returns character at the specified index + uint32_t GetCharAt(size_t index) const; + uint32_t GetFirstCharAt(size_t index, const char** offset) const; + uint32_t GetNextChar(const char** offset) const; + + + // Resize the string to the new size + void Resize(size_t _size); + void Reserve(size_t _size); + + // Appends a character + void AppendChar(uint32_t ch); + + // Append a string + void AppendString(const wchar_t* pstr, intptr_t len = -1); + void AppendString(const char* putf8str, intptr_t utf8StrSz = -1); + void AppendFormat(const char* format, ...); + + // Assigned a string with dynamic data (copied through initializer). + //void AssignString(const InitStruct& src, size_t size); + + // Inserts substr at posAt + void Insert (const char* substr, size_t posAt, intptr_t len = -1); + // Inserts character at posAt + size_t InsertCharAt(uint32_t c, size_t posAt); + + // Assignment + void operator = (const char* str); + void operator = (const wchar_t* str); + void operator = (const String& src); + void operator = (const StringBuffer& src); + + // Addition + void operator += (const String& src) { AppendString(src.ToCStr(),src.GetSize()); } + void operator += (const char* psrc) { AppendString(psrc); } + void operator += (const wchar_t* psrc) { AppendString(psrc); } + void operator += (char ch) { AppendChar(ch); } + //String operator + (const char* str) const ; + //String operator + (const String& src) const ; + + // Accesses raw bytes + char& operator [] (int index) + { + OVR_ASSERT(((size_t)index) < GetSize()); + return pData[index]; + } + char& operator [] (size_t index) + { + OVR_ASSERT(index < GetSize()); + return pData[index]; + } + + const char& operator [] (int index) const + { + OVR_ASSERT(((size_t)index) < GetSize()); + return pData[index]; + } + const char& operator [] (size_t index) const + { + OVR_ASSERT(index < GetSize()); + return pData[index]; + } +}; + + +// +// Wrapper for string data. The data must have a guaranteed +// lifespan throughout the usage of the wrapper. Not intended for +// cached usage. Not thread safe. +// +class StringDataPtr +{ +public: + StringDataPtr() : pStr(NULL), Size(0) {} + StringDataPtr(const StringDataPtr& p) + : pStr(p.pStr), Size(p.Size) {} + StringDataPtr(const char* pstr, size_t sz) + : pStr(pstr), Size(sz) {} + StringDataPtr(const char* pstr) + : pStr(pstr), Size((pstr != NULL) ? OVR_strlen(pstr) : 0) {} + explicit StringDataPtr(const String& str) + : pStr(str.ToCStr()), Size(str.GetSize()) {} + template + StringDataPtr(const T (&v)[N]) + : pStr(v), Size(N) {} + +public: + const char* ToCStr() const { return pStr; } + size_t GetSize() const { return Size; } + bool IsEmpty() const { return GetSize() == 0; } + + // value is a prefix of this string + // Character's values are not compared. + bool IsPrefix(const StringDataPtr& value) const + { + return ToCStr() == value.ToCStr() && GetSize() >= value.GetSize(); + } + // value is a suffix of this string + // Character's values are not compared. + bool IsSuffix(const StringDataPtr& value) const + { + return ToCStr() <= value.ToCStr() && (End()) == (value.End()); + } + + // Find first character. + // init_ind - initial index. + intptr_t FindChar(char c, size_t init_ind = 0) const + { + for (size_t i = init_ind; i < GetSize(); ++i) + if (pStr[i] == c) + return static_cast(i); + + return -1; + } + + // Find last character. + // init_ind - initial index. + intptr_t FindLastChar(char c, size_t init_ind = ~0) const + { + if (init_ind == (size_t)~0 || init_ind > GetSize()) + init_ind = GetSize(); + else + ++init_ind; + + for (size_t i = init_ind; i > 0; --i) + if (pStr[i - 1] == c) + return static_cast(i - 1); + + return -1; + } + + // Create new object and trim size bytes from the left. + StringDataPtr GetTrimLeft(size_t size) const + { + // Limit trim size to the size of the string. + size = Alg::PMin(GetSize(), size); + + return StringDataPtr(ToCStr() + size, GetSize() - size); + } + // Create new object and trim size bytes from the right. + StringDataPtr GetTrimRight(size_t size) const + { + // Limit trim to the size of the string. + size = Alg::PMin(GetSize(), size); + + return StringDataPtr(ToCStr(), GetSize() - size); + } + + // Create new object, which contains next token. + // Useful for parsing. + StringDataPtr GetNextToken(char separator = ':') const + { + size_t cur_pos = 0; + const char* cur_str = ToCStr(); + + for (; cur_pos < GetSize() && cur_str[cur_pos]; ++cur_pos) + { + if (cur_str[cur_pos] == separator) + { + break; + } + } + + return StringDataPtr(ToCStr(), cur_pos); + } + + // Trim size bytes from the left. + StringDataPtr& TrimLeft(size_t size) + { + // Limit trim size to the size of the string. + size = Alg::PMin(GetSize(), size); + pStr += size; + Size -= size; + + return *this; + } + // Trim size bytes from the right. + StringDataPtr& TrimRight(size_t size) + { + // Limit trim to the size of the string. + size = Alg::PMin(GetSize(), size); + Size -= size; + + return *this; + } + + const char* Begin() const { return ToCStr(); } + const char* End() const { return ToCStr() + GetSize(); } + + // Hash functor used string data pointers + struct HashFunctor + { + size_t operator()(const StringDataPtr& data) const + { + return String::BernsteinHashFunction(data.ToCStr(), data.GetSize()); + } + }; + + bool operator== (const StringDataPtr& data) const + { + return (OVR_strncmp(pStr, data.pStr, data.Size) == 0); + } + +protected: + const char* pStr; + size_t Size; +}; + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_StringHash.h b/LibOVRKernel/Src/Kernel/OVR_StringHash.h new file mode 100644 index 0000000..410a578 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_StringHash.h @@ -0,0 +1,100 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_StringHash.h +Content : String hash table used when optional case-insensitive + lookup is required. +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_StringHash_h +#define OVR_StringHash_h + +#include "OVR_String.h" +#include "OVR_Hash.h" + +namespace OVR { + +//----------------------------------------------------------------------------------- +// *** StringHash + +// This is a custom string hash table that supports case-insensitive +// searches through special functions such as GetCaseInsensitive, etc. +// This class is used for Flash labels, exports and other case-insensitive tables. + +template > +class StringHash : public Hash +{ +public: + typedef U ValueType; + typedef StringHash SelfType; + typedef Hash BaseType; + +public: + + void operator = (const SelfType& src) { BaseType::operator = (src); } + + bool GetCaseInsensitive(const String& key, U* pvalue) const + { + String::NoCaseKey ikey(key); + return BaseType::GetAlt(ikey, pvalue); + } + // Pointer-returning get variety. + const U* GetCaseInsensitive(const String& key) const + { + String::NoCaseKey ikey(key); + return BaseType::GetAlt(ikey); + } + U* GetCaseInsensitive(const String& key) + { + String::NoCaseKey ikey(key); + return BaseType::GetAlt(ikey); + } + + + typedef typename BaseType::Iterator base_iterator; + + base_iterator FindCaseInsensitive(const String& key) + { + String::NoCaseKey ikey(key); + return BaseType::FindAlt(ikey); + } + + // Set just uses a find and assigns value if found. The key is not modified; + // this behavior is identical to Flash string variable assignment. + void SetCaseInsensitive(const String& key, const U& value) + { + base_iterator it = FindCaseInsensitive(key); + if (it != BaseType::End()) + { + it->Second = value; + } + else + { + BaseType::Add(key, value); + } + } +}; + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp b/LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp new file mode 100644 index 0000000..d52b6bb --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_String_FormatUtil.cpp @@ -0,0 +1,76 @@ +/************************************************************************************ + +Filename : OVR_String_FormatUtil.cpp +Content : String format functions. +Created : February 27, 2013 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_String.h" +#include "OVR_Log.h" + +namespace OVR { + +void StringBuffer::AppendFormat(const char* format, ...) +{ + va_list argList; + char buffer[512]; + char* bufferUsed = buffer; + char* bufferAllocated = NULL; + + va_start(argList, format); + + #if !defined(OVR_CC_MSVC) // Non-Microsoft compilers require you to save a copy of the va_list. + va_list argListSaved; + va_copy(argListSaved, argList); + #endif + + int requiredStrlen = OVR_vsnprintf(bufferUsed, OVR_ARRAY_COUNT(buffer), format, argList); // The large majority of the time this will succeed. + + if(requiredStrlen >= (int)sizeof(buffer)) // If the initial capacity wasn't enough... + { + bufferAllocated = (char*)OVR_ALLOC(sizeof(char) * (requiredStrlen + 1)); + bufferUsed = bufferAllocated; + if(bufferAllocated) + { + #if !defined(OVR_CC_MSVC) + va_end(argList); + va_copy(argList, argListSaved); + #endif + requiredStrlen = OVR_vsnprintf(bufferAllocated, (requiredStrlen + 1), format, argList); + } + } + + if(requiredStrlen < 0) // If there was a printf format error... + { + bufferUsed = NULL; + } + + va_end(argList); + + if(bufferUsed) + AppendString(bufferUsed); + + if(bufferAllocated) + OVR_FREE(bufferAllocated); +} + +} // OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp b/LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp new file mode 100644 index 0000000..8ed826e --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_String_PathUtil.cpp @@ -0,0 +1,210 @@ +/************************************************************************************ + +Filename : OVR_String_PathUtil.cpp +Content : String filename/url helper function +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_String.h" +#include "OVR_UTF8Util.h" + +namespace OVR { + +//-------------------------------------------------------------------- +// ***** Path-Scanner helper function + +// Scans file path finding filename start and extension start, fills in their addess. +void ScanFilePath(const char* url, const char** pfilename, const char** pext) +{ + const char* urlStart = url; + const char *filename = 0; + const char *lastDot = 0; + + uint32_t charVal = UTF8Util::DecodeNextChar(&url); + + while (charVal != 0) + { + if ((charVal == '/') || (charVal == '\\')) + { + filename = url; + lastDot = 0; + } + else if (charVal == '.') + { + lastDot = url - 1; + } + + charVal = UTF8Util::DecodeNextChar(&url); + } + + if (pfilename) + { + if (filename) + *pfilename = filename; + else + *pfilename = urlStart; + } + + if (pext) + { + *pext = lastDot; + } +} + +// Scans till the end of protocol. Returns first character past protocol, +// 0 if not found. +// - protocol: 'file://', 'http://' +const char* ScanPathProtocol(const char* url) +{ + uint32_t charVal = UTF8Util::DecodeNextChar(&url); + uint32_t charVal2; + + while (charVal != 0) + { + // Treat a colon followed by a slash as absolute. + if (charVal == ':') + { + charVal2 = UTF8Util::DecodeNextChar(&url); + charVal = UTF8Util::DecodeNextChar(&url); + if ((charVal == '/') && (charVal2 == '\\')) + return url; + } + charVal = UTF8Util::DecodeNextChar(&url); + } + return 0; +} + + +//-------------------------------------------------------------------- +// ***** String Path API implementation + +bool String::HasAbsolutePath(const char* url) +{ + // Absolute paths can star with: + // - protocols: 'file://', 'http://' + // - windows drive: 'c:\' + // - UNC share name: '\\share' + // - unix root '/' + + // On the other hand, relative paths are: + // - directory: 'directory/file' + // - this directory: './file' + // - parent directory: '../file' + // + // For now, we don't parse '.' or '..' out, but instead let it be concatenated + // to string and let the OS figure it out. This, however, is not good for file + // name matching in library/etc, so it should be improved. + + if (!url || !*url) + return true; // Treat empty strings as absolute. + + uint32_t charVal = UTF8Util::DecodeNextChar(&url); + + // Fist character of '/' or '\\' means absolute url. + if ((charVal == '/') || (charVal == '\\')) + return true; + + while (charVal != 0) + { + // Treat a colon followed by a slash as absolute. + if (charVal == ':') + { + charVal = UTF8Util::DecodeNextChar(&url); + // Protocol or windows drive. Absolute. + if ((charVal == '/') || (charVal == '\\')) + return true; + } + else if ((charVal == '/') || (charVal == '\\')) + { + // Not a first character (else 'if' above the loop would have caught it). + // Must be a relative url. + break; + } + + charVal = UTF8Util::DecodeNextChar(&url); + } + + // We get here for relative paths. + return false; +} + + +bool String::HasExtension(const char* path) +{ + const char* ext = 0; + ScanFilePath(path, 0, &ext); + return ext != 0; +} +bool String::HasProtocol(const char* path) +{ + return ScanPathProtocol(path) != 0; +} + + +String String::GetPath() const +{ + const char* filename = 0; + ScanFilePath(ToCStr(), &filename, 0); + + // Technically we can have extra logic somewhere for paths, + // such as enforcing protocol and '/' only based on flags, + // but we keep it simple for now. + return String(ToCStr(), filename ? (filename-ToCStr()) : GetSize()); +} + +String String::GetProtocol() const +{ + const char* protocolEnd = ScanPathProtocol(ToCStr()); + return String(ToCStr(), protocolEnd ? (protocolEnd-ToCStr()) : 0); +} + +String String::GetFilename() const +{ + const char* filename = 0; + ScanFilePath(ToCStr(), &filename, 0); + return String(filename); +} +String String::GetExtension() const +{ + const char* ext = 0; + ScanFilePath(ToCStr(), 0, &ext); + return String(ext); +} + +void String::StripExtension() +{ + const char* ext = 0; + ScanFilePath(ToCStr(), 0, &ext); + if (ext) + { + *this = String(ToCStr(), ext-ToCStr()); + } +} + +void String::StripProtocol() +{ + const char* protocol = ScanPathProtocol(ToCStr()); + if (protocol) + AssignString(protocol, OVR_strlen(protocol)); +} + +} // OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_SysFile.cpp b/LibOVRKernel/Src/Kernel/OVR_SysFile.cpp new file mode 100644 index 0000000..6ef27c7 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_SysFile.cpp @@ -0,0 +1,138 @@ +/************************************************************************** + +Filename : OVR_SysFile.cpp +Content : File wrapper class implementation (Win32) + +Created : April 5, 1999 +Authors : Michael Antonov + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +**************************************************************************/ + +#define GFILE_CXX + +// Standard C library (Captain Obvious guarantees!) +#include + +#include "OVR_SysFile.h" +#include "OVR_Log.h" + +namespace OVR { + +// This is - a dummy file that fails on all calls. + +class UnopenedFile : public File +{ +public: + UnopenedFile() { } + ~UnopenedFile() { } + + virtual const char* GetFilePath() { return 0; } + + // ** File Information + virtual bool IsValid() { return 0; } + virtual bool IsWritable() { return 0; } + + // Return position / file size + virtual int Tell() { return 0; } + virtual int64_t LTell() { return 0; } + virtual int GetLength() { return 0; } + virtual int64_t LGetLength() { return 0; } + +// virtual bool Stat(FileStats *pfs) { return 0; } + virtual int GetErrorCode() { return Error_FileNotFound; } + + // ** Stream implementation & I/O + virtual int Write(const uint8_t * /*pbuffer*/, int /*numBytes*/) { return -1; } + virtual int Read(uint8_t * /*pbuffer*/, int /*numBytes*/) { return -1; } + virtual int SkipBytes(int /*numBytes*/) { return 0; } + virtual int BytesAvailable() { return 0; } + virtual bool Flush() { return 0; } + virtual int Seek(int /*offset*/, int /*origin*/) { return -1; } + virtual int64_t LSeek(int64_t /*offset*/, int /*origin*/) { return -1; } + + virtual int CopyFromStream(File * /*pstream*/, int /*byteSize*/) { return -1; } + virtual bool Close() { return 0; } +}; + + + +// ***** System File + +// System file is created to access objects on file system directly +// This file can refer directly to path + +// ** Constructor +SysFile::SysFile() : DelegatedFile(0) +{ + pFile = *new UnopenedFile; +} + +Ptr FileFILEOpen(const String& path, int flags, int mode); + +// Opens a file +SysFile::SysFile(const String& path, int flags, int mode) : DelegatedFile(0) +{ + Open(path, flags, mode); +} + + +// ** Open & management +// Will fail if file's already open +bool SysFile::Open(const String& path, int flags, int mode) +{ + pFile = FileFILEOpen(path, flags, mode); + if ((!pFile) || (!pFile->IsValid())) + { + pFile = *new UnopenedFile; + OVR_DEBUG_LOG(("Failed to open file: %s", path.ToCStr())); + return 0; + } + //pFile = *OVR_NEW DelegatedFile(pFile); // MA Testing + if (flags & Open_Buffered) + pFile = *new BufferedFile(pFile); + return 1; +} + + +// ** Overrides + +int SysFile::GetErrorCode() +{ + return pFile ? pFile->GetErrorCode() : Error_FileNotFound; +} + + +// Overrides to provide re-open support +bool SysFile::IsValid() +{ + return pFile && pFile->IsValid(); +} +bool SysFile::Close() +{ + if (IsValid()) + { + DelegatedFile::Close(); + pFile = *new UnopenedFile; + return 1; + } + return 0; +} + +} // OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_SysFile.h b/LibOVRKernel/Src/Kernel/OVR_SysFile.h new file mode 100644 index 0000000..925c51d --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_SysFile.h @@ -0,0 +1,104 @@ +/************************************************************************************ + +PublicHeader: Kernel +Filename : OVR_SysFile.h +Content : Header for all internal file management - functions and structures + to be inherited by OS specific subclasses. +Created : September 19, 2012 +Notes : + +Notes : errno may not be preserved across use of GBaseFile member functions + : Directories cannot be deleted while files opened from them are in use + (For the GetFullName function) + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_SysFile_h +#define OVR_SysFile_h + +#include "OVR_File.h" + +namespace OVR { + +// ***** Declared classes +class SysFile; + +//----------------------------------------------------------------------------------- +// *** File Statistics + +// This class contents are similar to _stat, providing +// creation, modify and other information about the file. +struct FileStat +{ + // No change or create time because they are not available on most systems + int64_t ModifyTime; + int64_t AccessTime; + int64_t FileSize; + + bool operator== (const FileStat& stat) const + { + return ( (ModifyTime == stat.ModifyTime) && + (AccessTime == stat.AccessTime) && + (FileSize == stat.FileSize) ); + } +}; + +//----------------------------------------------------------------------------------- +// *** System File + +// System file is created to access objects on file system directly +// This file can refer directly to path. +// System file can be open & closed several times; however, such use is not recommended +// This class is realy a wrapper around an implementation of File interface for a +// particular platform. + +class SysFile : public DelegatedFile +{ +protected: + SysFile(const SysFile &source) : DelegatedFile () { OVR_UNUSED(source); } +public: + + // ** Constructor + SysFile(); + // Opens a file + SysFile(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite); + + // ** Open & management + bool Open(const String& path, int flags = Open_Read|Open_Buffered, int mode = Mode_ReadWrite); + + OVR_FORCE_INLINE bool Create(const String& path, int mode = Mode_ReadWrite) + { return Open(path, Open_ReadWrite|Open_Create, mode); } + + // Helper function: obtain file statistics information. In OVR, this is used to detect file changes. + // Return 0 if function failed, most likely because the file doesn't exist. + static bool OVR_CDECL GetFileStat(FileStat* pfileStats, const String& path); + + // ** Overrides + // Overridden to provide re-open support + virtual int GetErrorCode(); + + virtual bool IsValid(); + + virtual bool Close(); +}; + +} // Namespace OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_System.cpp b/LibOVRKernel/Src/Kernel/OVR_System.cpp new file mode 100644 index 0000000..6ab1294 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_System.cpp @@ -0,0 +1,148 @@ +/************************************************************************************ + +Filename : OVR_System.cpp +Content : General kernel initialization/cleanup, including that + of the memory allocator. +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_System.h" +#include "OVR_Threads.h" +#include "OVR_Timer.h" +#include "OVR_DebugHelp.h" + +#ifdef OVR_OS_MS + #pragma warning(push, 0) + #include "OVR_Win32_IncludeWindows.h" // GetModuleHandleEx + #pragma warning(pop) +#endif + +namespace OVR { + + +//----------------------------------------------------------------------------- +// Initialization/Shutdown Callbacks + +static SystemSingletonInternal *SystemShutdownListenerList = nullptr; // Points to the most recent SystemSingletonInternal added to the list. + +static Lock& GetSSILock() +{ // Put listLock in a function so that it can be constructed on-demand. + static Lock listLock; // Will construct on the first usage. However, the guarding of this construction is not thread-safe + return listLock; // under all compilers. However, since we are initially calling this on startup before other threads +} // could possibly exist, the first usage of this will be before other threads exist. + +void SystemSingletonInternal::RegisterDestroyCallback() +{ + Lock::Locker locker(&GetSSILock()); + + // Insert the listener at the front of the list (top of the stack). This is an analogue of a C++ forward_list::push_front or stack::push. + NextShutdownSingleton = SystemShutdownListenerList; + SystemShutdownListenerList = this; +} + + +//----------------------------------------------------------------------------- +// System + +// Initializes System core, installing allocator. +void System::Init(Log* log, Allocator *palloc) +{ + if (!Allocator::GetInstance()) + { + if (Allocator::IsTrackingLeaks()) + { + SymbolLookup::Initialize(); + } + + Log::SetGlobalLog(log); + Timer::initializeTimerSystem(); + Allocator::setInstance(palloc); + } + else + { + OVR_DEBUG_LOG(("[System] Init failed - duplicate call.")); + } +} + +void System::Destroy() +{ + if (Allocator::GetInstance()) + { + // Invoke all of the post-finish callbacks (normal case) + for (SystemSingletonInternal *listener = SystemShutdownListenerList; listener; listener = listener->NextShutdownSingleton) + { + listener->OnThreadDestroy(); + } + + #ifdef OVR_ENABLE_THREADS + // Wait for all threads to finish; this must be done so that memory + // allocator and all destructors finalize correctly. + Thread::FinishAllThreads(); + #endif + + // Invoke all of the post-finish callbacks (normal case) + for (SystemSingletonInternal* next, *listener = SystemShutdownListenerList; listener; listener = next) + { + next = listener->NextShutdownSingleton; + + listener->OnSystemDestroy(); + } + + SystemShutdownListenerList = nullptr; + + // Shutdown heap and destroy SysAlloc singleton, if any. + Allocator::GetInstance()->onSystemShutdown(); + Allocator::setInstance(nullptr); + + if (Allocator::IsTrackingLeaks()) + { + SymbolLookup::Shutdown(); + } + + Timer::shutdownTimerSystem(); + Log::SetGlobalLog(Log::GetDefaultLog()); + + if (Allocator::IsTrackingLeaks()) + { + int ovrLeakCount = DumpMemory(); + + OVR_ASSERT(ovrLeakCount == 0); + if (ovrLeakCount == 0) + { + OVR_DEBUG_LOG(("[System] No OVR object leaks detected.")); + } + } + } + else + { + OVR_DEBUG_LOG(("[System] Destroy failed - System not initialized.")); + } +} + +// Returns 'true' if system was properly initialized. +bool System::IsInitialized() +{ + return Allocator::GetInstance() != nullptr; +} + + +} // namespace OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_System.h b/LibOVRKernel/Src/Kernel/OVR_System.h new file mode 100644 index 0000000..d66fbe7 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_System.h @@ -0,0 +1,174 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_System.h +Content : General kernel initialization/cleanup, including that + of the memory allocator. +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_System_h +#define OVR_System_h + +#include "OVR_Allocator.h" +#include "OVR_Log.h" +#include "OVR_Atomic.h" + +namespace OVR { + + +//----------------------------------------------------------------------------- +// SystemSingleton + +// Subsystems are implemented using the Singleton pattern. +// To avoid code duplication in all the places where Singletons are defined, +// The pattern is defined once here and used everywhere. + +class SystemSingletonInternal +{ + friend class System; + + // Allows for including this class in the shutdown list. + SystemSingletonInternal* NextShutdownSingleton; + + // No copying allowed + OVR_NON_COPYABLE(SystemSingletonInternal); + +public: + // Call this to register for a call to OnThreadDestroy and OnSystemDestroy before the + // Kernel is shut down. OnThreadDestroy is called before any remaining existing threads + // are exited. Registered callbacks are called in the reverse order they were registered. + // You would typically call this at the end of your SystemSingletonInternal subclass' constructor. + // The registered objects are not deleted on shutdown; they would have to do that themselves within + // OnSystemDestroy or via a compiler-generated static destruction. + void RegisterDestroyCallback(); + void PushDestroyCallbacks() { RegisterDestroyCallback(); } // For backward compatibility. + +protected: + SystemSingletonInternal() : + NextShutdownSingleton(nullptr) + { + } + + virtual ~SystemSingletonInternal(){} + + // Initializes the SystemSingletonInternal. + // You can register for an automatic call to this function by calling PushInitCallbacks. + // The registration of an automatic call to this is not required, but may be useful if + // you need to postpone your initialization until after Kernel is initialized. + // You cannot call PushInitCallbacks or PushDestroyCallbacks while within this function. + virtual void OnSystemInit() {} + + // Called just before waiting for threads to exit. + // Listeners are called in the opposite order they were registered. + // This function is useful for terminating threads at the right time before the rest of the system is shut down. + // Note: The singleton must not delete itself here, as OnSystemDestroy will subsequently be called for it. + virtual void OnThreadDestroy() {} + + // Shuts down the SystemSingletonInternal. + // You can register for an automatic call to this function by calling PushDestroyCallbacks. + // The registration of an automatic call to this is not required, but may be useful if + // you need to delay your shutdown until application exit time. + // You cannot call PushInitCallbacks or PushDestroyCallbacks while within this function. + // This function may delete this. + virtual void OnSystemDestroy() {} +}; + +// Singletons derive from this class +template +class SystemSingletonBase : public SystemSingletonInternal +{ + static AtomicPtr SingletonInstance; + static T* SlowGetInstance(); + +protected: + ~SystemSingletonBase() + { + // Make sure the instance gets set to zero on dtor + if (SingletonInstance == this) + SingletonInstance = nullptr; + } + +public: + static OVR_FORCE_INLINE T* GetInstance() + { + // Fast version + // Note: The singleton instance is stored in an AtomicPtr<> to allow it to be accessed + // atomically from multiple threads without locks. + T* instance = SingletonInstance; + return instance ? instance : SlowGetInstance(); + } +}; + +// For reference, see N3337 14.5.1.3 (Static data members of class templates): +template OVR::AtomicPtr OVR::SystemSingletonBase::SingletonInstance; + +// Place this in the singleton class in the header file +#define OVR_DECLARE_SINGLETON(T) \ + friend class OVR::SystemSingletonBase; \ +private: \ + T(); \ + virtual ~T(); \ + virtual void OnSystemDestroy(); + +// Place this in the singleton class source file +#define OVR_DEFINE_SINGLETON(T) \ + namespace OVR { \ + template<> T* SystemSingletonBase::SlowGetInstance() \ + { \ + static OVR::Lock lock; \ + OVR::Lock::Locker locker(&lock); \ + if (!SingletonInstance) \ + SingletonInstance = new T; \ + return SingletonInstance; \ + } \ + } + + +// ***** System Core Initialization class + +// System initialization must take place before any other OVR_Kernel objects are used; +// this is done my calling System::Init(). Among other things, this is necessary to +// initialize the memory allocator. Similarly, System::Destroy must be +// called before program exist for proper cleanup. Both of these tasks can be achieved by +// simply creating System object first, allowing its constructor/destructor do the work. + +class System +{ +public: + // Returns 'true' if system was properly initialized. + static bool OVR_CDECL IsInitialized(); + + // Initializes System core. Users can override memory implementation by passing + // a different Allocator here. + static void OVR_CDECL Init(Log* log = Log::ConfigureDefaultLog(LogMask_Debug), + Allocator *palloc = DefaultAllocator::InitSystemSingleton()); + + // De-initializes System more, finalizing the threading system and destroying + // the global memory allocator. + static void OVR_CDECL Destroy(); +}; + + +} // namespace OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.cpp b/LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.cpp new file mode 100644 index 0000000..8c36ac7 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.cpp @@ -0,0 +1,405 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_ThreadCommandQueue.cpp +Content : Command queue for operations executed on a thread +Created : October 29, 2012 + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_ThreadCommandQueue.h" + +namespace OVR { + + +//------------------------------------------------------------------------ +// ***** CircularBuffer + +// CircularBuffer is a FIFO buffer implemented in a single block of memory, +// which allows writing and reading variable-size data chucks. Write fails +// if buffer is full. + +class CircularBuffer +{ + enum { + AlignSize = 16, + AlignMask = AlignSize - 1 + }; + + uint8_t* pBuffer; + size_t Size; + size_t Tail; // Byte offset of next item to be popped. + size_t Head; // Byte offset of where next push will take place. + size_t End; // When Head < Tail, this is used instead of Size. + + inline size_t roundUpSize(size_t size) + { return (size + AlignMask) & ~(size_t)AlignMask; } + +public: + + CircularBuffer(size_t size) + : Size(size), Tail(0), Head(0), End(0) + { + pBuffer = (uint8_t*)OVR_ALLOC_ALIGNED(roundUpSize(size), AlignSize); + } + ~CircularBuffer() + { + // For ThreadCommands, we must consume everything before shutdown. + OVR_ASSERT(IsEmpty()); + OVR_FREE_ALIGNED(pBuffer); + } + + bool IsEmpty() const { return (Head == Tail); } + + // Allocates a state block of specified size and advances pointers, + // returning 0 if buffer is full. + uint8_t* Write(size_t size); + + // Returns a pointer to next available data block; 0 if none available. + uint8_t* ReadBegin() + { return (Head != Tail) ? (pBuffer + Tail) : 0; } + // Consumes data of specified size; this must match size passed to Write. + void ReadEnd(size_t size); +}; + + +// Allocates a state block of specified size and advances pointers, +// returning 0 if buffer is full. +uint8_t* CircularBuffer::Write(size_t size) +{ + uint8_t* p = 0; + + size = roundUpSize(size); + // Since this is circular buffer, always allow at least one item. + OVR_ASSERT(size < Size/2); + + if (Head >= Tail) + { + OVR_ASSERT(End == 0); + + if (size <= (Size - Head)) + { + p = pBuffer + Head; + Head += size; + } + else if (size < Tail) + { + p = pBuffer; + End = Head; + Head = size; + OVR_ASSERT(Head != Tail); + } + } + else + { + OVR_ASSERT(End != 0); + + if ((Tail - Head) > size) + { + p = pBuffer + Head; + Head += size; + OVR_ASSERT(Head != Tail); + } + } + + return p; +} + +void CircularBuffer::ReadEnd(size_t size) +{ + OVR_ASSERT(Head != Tail); + size = roundUpSize(size); + + Tail += size; + if (Tail == End) + { + Tail = End = 0; + } + else if (Tail == Head) + { + OVR_ASSERT(End == 0); + Tail = Head = 0; + } +} + + +//------------------------------------------------------------------------------------- +// ***** ThreadCommand + +ThreadCommand::PopBuffer::~PopBuffer() +{ + if (Size) { + Destruct(toCommand()); + } +} + +void ThreadCommand::PopBuffer::InitFromBuffer(void* data) +{ + ThreadCommand* cmd = (ThreadCommand*)data; + + if (Size) { + Destruct(toCommand()); + } + Size = cmd->Size; + if (Size > MaxSize) + Size = MaxSize; + memcpy(Buffer, (void*)cmd, Size); +} + +void ThreadCommand::PopBuffer::Execute() +{ + ThreadCommand* command = toCommand(); + OVR_ASSERT(command); + if (command) + { + command->Execute(); + } + if (NeedsWait()) { + GetEvent()->PulseEvent(); + } +} + +//------------------------------------------------------------------------------------- + +class ThreadCommandQueueImpl : public NewOverrideBase +{ + typedef ThreadCommand::NotifyEvent NotifyEvent; + friend class ThreadCommandQueue; + +public: + + ThreadCommandQueueImpl(ThreadCommandQueue* queue) : + pQueue(queue), + ExitEnqueued(false), + ExitProcessed(false), + CommandBuffer(2048), + PullThreadId(0) + { + } + ~ThreadCommandQueueImpl(); + + + bool PushCommand(const ThreadCommand& command); + bool PopCommand(ThreadCommand::PopBuffer* popBuffer); + + + // ExitCommand is used by notify us that Thread is shutting down. + struct ExitCommand : public ThreadCommand + { + ThreadCommandQueueImpl* pImpl; + + ExitCommand(ThreadCommandQueueImpl* impl, bool wait) + : ThreadCommand(sizeof(ExitCommand), wait, true), pImpl(impl) { } + + virtual void Execute() const + { + Lock::Locker lock(&pImpl->QueueLock); + pImpl->ExitProcessed = true; + } + virtual ThreadCommand* CopyConstruct(void* p) const + { return Construct(p, *this); } + }; + + + NotifyEvent* AllocNotifyEvent_NTS() + { + NotifyEvent* p = AvailableEvents.GetFirst(); + + if (!AvailableEvents.IsNull(p)) + p->RemoveNode(); + else + p = new NotifyEvent; + return p; + } + + void FreeNotifyEvent_NTS(NotifyEvent* p) + { + AvailableEvents.PushBack(p); + } + + void FreeNotifyEvents_NTS() + { + while(!AvailableEvents.IsEmpty()) + { + NotifyEvent* p = AvailableEvents.GetFirst(); + p->RemoveNode(); + delete p; + } + } + + ThreadCommandQueue* pQueue; + Lock QueueLock; + volatile bool ExitEnqueued; + volatile bool ExitProcessed; + List AvailableEvents; + List BlockedProducers; + CircularBuffer CommandBuffer; + + // The pull thread id is set to the last thread that pulled commands. + // Since this thread command queue is designed for a single thread, + // reentrant behavior that would cause a dead-lock for messages that + // wait for completion can be avoided by simply comparing the + // thread id of the last pull. + OVR::ThreadId PullThreadId; +}; + +ThreadCommandQueueImpl::~ThreadCommandQueueImpl() +{ + Lock::Locker lock(&QueueLock); + OVR_ASSERT(BlockedProducers.IsEmpty()); + FreeNotifyEvents_NTS(); +} + +bool ThreadCommandQueueImpl::PushCommand(const ThreadCommand& command) +{ + if (command.NeedsWait() && PullThreadId == OVR::GetCurrentThreadId()) + { + command.Execute(); + return true; + } + + ThreadCommand::NotifyEvent* completeEvent = 0; + ThreadCommand::NotifyEvent* queueAvailableEvent = 0; + + // Repeat writing command into buffer until it is available. + for (;;) { + { // Lock Scope + Lock::Locker lock(&QueueLock); + + if (queueAvailableEvent) { + FreeNotifyEvent_NTS(queueAvailableEvent); + queueAvailableEvent = 0; + } + + // Don't allow any commands after PushExitCommand() is called. + if (ExitEnqueued && !command.ExitFlag) { + return false; + } + + bool bufferWasEmpty = CommandBuffer.IsEmpty(); + uint8_t* buffer = CommandBuffer.Write(command.GetSize()); + + if (buffer) { + ThreadCommand* c = command.CopyConstruct(buffer); + + if (c->NeedsWait()) { + completeEvent = c->pEvent = AllocNotifyEvent_NTS(); + } + + // Signal-waker consumer when we add data to buffer. + if (bufferWasEmpty) { + pQueue->OnPushNonEmpty_Locked(); + } + + break; + } + + queueAvailableEvent = AllocNotifyEvent_NTS(); + BlockedProducers.PushBack(queueAvailableEvent); + } // Lock Scope + + queueAvailableEvent->Wait(); + } // Intentional infinite loop + + // Command was enqueued, wait if necessary. + if (completeEvent) { + completeEvent->Wait(); + Lock::Locker lock(&QueueLock); + FreeNotifyEvent_NTS(completeEvent); + } + + return true; +} + + +// Pops the next command from the thread queue, if any is available. +bool ThreadCommandQueueImpl::PopCommand(ThreadCommand::PopBuffer* popBuffer) +{ + PullThreadId = OVR::GetCurrentThreadId(); + + Lock::Locker lock(&QueueLock); + + uint8_t* buffer = CommandBuffer.ReadBegin(); + if (!buffer) + { + // Notify thread while in lock scope, enabling initialization of wait. + pQueue->OnPopEmpty_Locked(); + return false; + } + + popBuffer->InitFromBuffer(buffer); + CommandBuffer.ReadEnd(popBuffer->GetSize()); + + if (!BlockedProducers.IsEmpty()) + { + ThreadCommand::NotifyEvent* queueAvailableEvent = BlockedProducers.GetFirst(); + queueAvailableEvent->RemoveNode(); + queueAvailableEvent->PulseEvent(); + // Event is freed later by waiter. + } + return true; +} + + +//------------------------------------------------------------------------------------- + +ThreadCommandQueue::ThreadCommandQueue() +{ + pImpl = new ThreadCommandQueueImpl(this); +} +ThreadCommandQueue::~ThreadCommandQueue() +{ + delete pImpl; +} + +bool ThreadCommandQueue::PushCommand(const ThreadCommand& command) +{ + return pImpl->PushCommand(command); +} + +bool ThreadCommandQueue::PopCommand(ThreadCommand::PopBuffer* popBuffer) +{ + return pImpl->PopCommand(popBuffer); +} + +void ThreadCommandQueue::PushExitCommand(bool wait) +{ + // Exit is processed in two stages: + // - First, ExitEnqueued flag is set to block further commands from queuing up. + // - Second, the actual exit call is processed on the consumer thread, flushing + // any prior commands. + // IsExiting() only returns true after exit has flushed. + { + Lock::Locker lock(&pImpl->QueueLock); + if (pImpl->ExitEnqueued) + return; + pImpl->ExitEnqueued = true; + } + + PushCommand(ThreadCommandQueueImpl::ExitCommand(pImpl, wait)); +} + +bool ThreadCommandQueue::IsExiting() const +{ + return pImpl->ExitProcessed; +} + + +} // namespace OVR diff --git a/LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.h b/LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.h new file mode 100644 index 0000000..d8aa14e --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_ThreadCommandQueue.h @@ -0,0 +1,318 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_ThreadCommandQueue.h +Content : Command queue for operations executed on a thread +Created : October 29, 2012 +Author : Michael Antonov + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_ThreadCommandQueue_h +#define OVR_ThreadCommandQueue_h + +#include "OVR_Types.h" +#include "OVR_List.h" +#include "OVR_Atomic.h" +#include "OVR_Threads.h" + +namespace OVR { + +class ThreadCommand; +class ThreadCommandQueue; + + +//------------------------------------------------------------------------------------- +// ***** ThreadCommand + +// ThreadCommand is a base class implementation for commands stored in ThreadCommandQueue. +class ThreadCommand +{ +public: + // NotifyEvent is used by ThreadCommandQueue::PushCallAndWait to notify the + // calling (producer) thread when command is completed or queue slot is available. + class NotifyEvent : public ListNode, public NewOverrideBase + { + Event E; + public: + NotifyEvent() { } + + void Wait() { E.Wait(); } + void PulseEvent() { E.PulseEvent(); } + }; + + // ThreadCommand::PopBuffer is temporary storage for a command popped off + // by ThreadCommandQueue::PopCommand. + class PopBuffer + { + enum { MaxSize = 256 }; + + size_t Size; + union { + uint8_t Buffer[MaxSize]; + size_t Align; + }; + + ThreadCommand* toCommand() const { return (ThreadCommand*)Buffer; } + + public: + PopBuffer() : Size(0) { } + ~PopBuffer(); + + void InitFromBuffer(void* data); + + bool HasCommand() const { return Size != 0; } + size_t GetSize() const { return Size; } + bool NeedsWait() const { return toCommand()->NeedsWait(); } + NotifyEvent* GetEvent() const { return toCommand()->pEvent; } + + // Execute the command and also notifies caller to finish waiting, + // if necessary. + void Execute(); + }; + + uint16_t Size; + bool WaitFlag; + bool ExitFlag; // Marks the last exit command. + NotifyEvent* pEvent; + + ThreadCommand(size_t size, bool waitFlag, bool exitFlag = false) + : Size((uint16_t)size), WaitFlag(waitFlag), ExitFlag(exitFlag), pEvent(0) { } + virtual ~ThreadCommand() { } + + bool NeedsWait() const { return WaitFlag; } + size_t GetSize() const { return Size; } + + virtual void Execute() const = 0; + // Copy constructor used for serializing this to memory buffer. + virtual ThreadCommand* CopyConstruct(void* p) const = 0; +}; + + +//------------------------------------------------------------------------------------- + +// CleanType is a template that strips 'const' and '&' modifiers from the argument type; +// for example, typename CleanType::Type is equivalent to A. +template struct CleanType { typedef T Type; }; +template struct CleanType { typedef T Type; }; +template struct CleanType { typedef T Type; }; +template struct CleanType { typedef T Type; }; + +// SelfType is a template that yields the argument type. This helps avoid conflicts with +// automatic template argument deduction for function calls when identical argument +// is already defined. +template struct SelfType { typedef T Type; }; + + + +//------------------------------------------------------------------------------------- +// ThreadCommand specializations for member functions with different number of +// arguments and argument types. + +// Used to return nothing from a ThreadCommand, to avoid problems with 'void'. +struct Void +{ + Void() {} + Void(int) {} +}; + +// ThreadCommand for member function with 0 arguments. +template +class ThreadCommandMF0 : public ThreadCommand +{ + typedef R (C::*FnPtr)(); + C* pClass; + FnPtr pFn; + R* pRet; + + void executeImpl() const + { + pRet ? (void)(*pRet = (pClass->*pFn)()) : + (void)(pClass->*pFn)(); + } + +public: + ThreadCommandMF0(C* pclass, FnPtr fn, R* ret, bool needsWait) + : ThreadCommand(sizeof(ThreadCommandMF0), needsWait), + pClass(pclass), pFn(fn), pRet(ret) { } + + virtual void Execute() const { executeImpl(); } + virtual ThreadCommand* CopyConstruct(void* p) const + { return Construct(p, *this); } +}; + + +// ThreadCommand for member function with 1 argument. +template +class ThreadCommandMF1 : public ThreadCommand +{ + typedef R (C::*FnPtr)(A0); + C* pClass; + FnPtr pFn; + R* pRet; + typename CleanType::Type AVal0; + + void executeImpl() const + { + pRet ? (void)(*pRet = (pClass->*pFn)(AVal0)) : + (void)(pClass->*pFn)(AVal0); + } + +public: + ThreadCommandMF1(C* pclass, FnPtr fn, R* ret, A0 a0, bool needsWait) + : ThreadCommand(sizeof(ThreadCommandMF1), needsWait), + pClass(pclass), pFn(fn), pRet(ret), AVal0(a0) { } + + virtual void Execute() const { executeImpl(); } + virtual ThreadCommand* CopyConstruct(void* p) const + { return Construct(p, *this); } +}; + +// ThreadCommand for member function with 2 arguments. +template +class ThreadCommandMF2 : public ThreadCommand +{ + typedef R (C::*FnPtr)(A0, A1); + C* pClass; + FnPtr pFn; + R* pRet; + typename CleanType::Type AVal0; + typename CleanType::Type AVal1; + + void executeImpl() const + { + pRet ? (void)(*pRet = (pClass->*pFn)(AVal0, AVal1)) : + (void)(pClass->*pFn)(AVal0, AVal1); + } + +public: + ThreadCommandMF2(C* pclass, FnPtr fn, R* ret, A0 a0, A1 a1, bool needsWait) + : ThreadCommand(sizeof(ThreadCommandMF2), needsWait), + pClass(pclass), pFn(fn), pRet(ret), AVal0(a0), AVal1(a1) { } + + virtual void Execute() const { executeImpl(); } + virtual ThreadCommand* CopyConstruct(void* p) const + { return Construct(p, *this); } +}; + + +//------------------------------------------------------------------------------------- +// ***** ThreadCommandQueue + +// ThreadCommandQueue is a queue of executable function-call commands intended to be +// serviced by a single consumer thread. Commands are added to the queue with PushCall +// and removed with PopCall; they are processed in FIFO order. Multiple producer threads +// are supported and will be blocked if internal data buffer is full. + +class ThreadCommandQueue +{ +public: + + ThreadCommandQueue(); + virtual ~ThreadCommandQueue(); + + + // Pops the next command from the thread queue, if any is available. + // The command should be executed by calling popBuffer->Execute(). + // Returns 'false' if no command is available at the time of the call. + bool PopCommand(ThreadCommand::PopBuffer* popBuffer); + + // Generic implementaion of PushCommand; enqueues a command for execution. + // Returns 'false' if push failed, usually indicating thread shutdown. + bool PushCommand(const ThreadCommand& command); + + // + void PushExitCommand(bool wait); + + // Returns 'true' once ExitCommand has been processed, so the thread can shut down. + bool IsExiting() const; + + + // These two virtual functions serve as notifications for derived + // thread waiting. + virtual void OnPushNonEmpty_Locked() { } + virtual void OnPopEmpty_Locked() { } + + + // *** PushCall with no result + + // Enqueue a member function of 'this' class to be called on consumer thread. + // By default the function returns immediately; set 'wait' argument to 'true' to + // wait for completion. + template + bool PushCall(R (C::*fn)(), bool wait = false) + { return PushCommand(ThreadCommandMF0(static_cast(this), fn, 0, wait)); } + template + bool PushCall(R (C::*fn)(A0), typename SelfType::Type a0, bool wait = false) + { return PushCommand(ThreadCommandMF1(static_cast(this), fn, 0, a0, wait)); } + template + bool PushCall(R (C::*fn)(A0, A1), + typename SelfType::Type a0, typename SelfType::Type a1, bool wait = false) + { return PushCommand(ThreadCommandMF2(static_cast(this), fn, 0, a0, a1, wait)); } + // Enqueue a specified member function call of class C. + // By default the function returns immediately; set 'wait' argument to 'true' to + // wait for completion. + template + bool PushCall(C* p, R (C::*fn)(), bool wait = false) + { return PushCommand(ThreadCommandMF0(p, fn, 0, wait)); } + template + bool PushCall(C* p, R (C::*fn)(A0), typename SelfType::Type a0, bool wait = false) + { return PushCommand(ThreadCommandMF1(p, fn, 0, a0, wait)); } + template + bool PushCall(C* p, R (C::*fn)(A0, A1), + typename SelfType::Type a0, typename SelfType::Type a1, bool wait = false) + { return PushCommand(ThreadCommandMF2(p, fn, 0, a0, a1, wait)); } + + + // *** PushCall with Result + + // Enqueue a member function of 'this' class call and wait for call to complete + // on consumer thread before returning. + template + bool PushCallAndWaitResult(R (C::*fn)(), R* ret) + { return PushCommand(ThreadCommandMF0(static_cast(this), fn, ret, true)); } + template + bool PushCallAndWaitResult(R (C::*fn)(A0), R* ret, typename SelfType::Type a0) + { return PushCommand(ThreadCommandMF1(static_cast(this), fn, ret, a0, true)); } + template + bool PushCallAndWaitResult(R (C::*fn)(A0, A1), R* ret, + typename SelfType::Type a0, typename SelfType::Type a1) + { return PushCommand(ThreadCommandMF2(static_cast(this), fn, ret, a0, a1, true)); } + // Enqueue a member function call for class C and wait for the call to complete + // on consumer thread before returning. + template + bool PushCallAndWaitResult(C* p, R (C::*fn)(), R* ret) + { return PushCommand(ThreadCommandMF0(p, fn, ret, true)); } + template + bool PushCallAndWaitResult(C* p, R (C::*fn)(A0), R* ret, typename SelfType::Type a0) + { return PushCommand(ThreadCommandMF1(p, fn, ret, a0, true)); } + template + bool PushCallAndWaitResult(C* p, R (C::*fn)(A0, A1), R* ret, + typename SelfType::Type a0, typename SelfType::Type a1) + { return PushCommand(ThreadCommandMF2(p, fn, ret, a0, a1, true)); } + +private: + class ThreadCommandQueueImpl* pImpl; +}; + + +} // namespace OVR + +#endif // OVR_ThreadCommandQueue_h diff --git a/LibOVRKernel/Src/Kernel/OVR_Threads.h b/LibOVRKernel/Src/Kernel/OVR_Threads.h new file mode 100644 index 0000000..fb5c9f1 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Threads.h @@ -0,0 +1,437 @@ +/************************************************************************************ + +PublicHeader: None +Filename : OVR_Threads.h +Content : Contains thread-related (safe) functionality +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ +#ifndef OVR_Threads_h +#define OVR_Threads_h + +#include "OVR_Types.h" +#include "OVR_Atomic.h" +#include "OVR_RefCount.h" +#include "OVR_Array.h" + +// Defines the infinite wait delay timeout +#define OVR_WAIT_INFINITE 0xFFFFFFFF + +// To be defined in the project configuration options +#ifdef OVR_ENABLE_THREADS + + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ****** Declared classes + +// Declared with thread support only +class Mutex; +class WaitCondition; +class Event; +// Implementation forward declarations +class MutexImpl; +class WaitConditionImpl; + + + +//----------------------------------------------------------------------------------- +// ***** Mutex + +// Mutex class represents a system Mutex synchronization object that provides access +// serialization between different threads, allowing one thread mutually exclusive access +// to a resource. Mutex is more heavy-weight then Lock, but supports WaitCondition. + +class Mutex +{ + friend class WaitConditionImpl; + friend class MutexImpl; + + MutexImpl *pImpl; + +public: + // Constructor/destructor + Mutex(bool recursive = 1); + ~Mutex(); + + // Locking functions + void DoLock(); + bool TryLock(); + void Unlock(); + + // Returns 1 if the mutes is currently locked by another thread + // Returns 0 if the mutex is not locked by another thread, and can therefore be acquired. + bool IsLockedByAnotherThread(); + + // Locker class; Used for automatic locking of a mutex withing scope + class Locker + { + public: + Mutex *pMutex; + Locker(Mutex *pmutex) + { pMutex = pmutex; pMutex->DoLock(); } + ~Locker() + { pMutex->Unlock(); } + }; +}; + + +//----------------------------------------------------------------------------------- +// ***** WaitCondition + +/* + WaitCondition is a synchronization primitive that can be used to implement what is known as a monitor. + Dependent threads wait on a wait condition by calling Wait(), and get woken up by other threads that + call Notify() or NotifyAll(). + + The unique feature of this class is that it provides an atomic way of first releasing a Mutex, and then + starting a wait on a wait condition. If both the mutex and the wait condition are associated with the same + resource, this ensures that any condition checked for while the mutex was locked does not change before + the wait on the condition is actually initiated. +*/ + +class WaitCondition +{ + friend class WaitConditionImpl; + // Internal implementation structure + WaitConditionImpl *pImpl; + +public: + // Constructor/destructor + WaitCondition(); + ~WaitCondition(); + + // Release mutex and wait for condition. The mutex is re-aquired after the wait. + // Delay is specified in milliseconds (1/1000 of a second). + bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE); + + // Notify a condition, releasing at one object waiting + void Notify(); + // Notify a condition, releasing all objects waiting + void NotifyAll(); +}; + + +//----------------------------------------------------------------------------------- +// ***** Event + +// Event is a wait-able synchronization object similar to Windows event. +// Event can be waited on until it's signaled by another thread calling +// either SetEvent or PulseEvent. + +class Event +{ + // Event state, its mutex and the wait condition + volatile bool State; + volatile bool Temporary; + mutable Mutex StateMutex; + WaitCondition StateWaitCondition; + + void updateState(bool newState, bool newTemp, bool mustNotify); + +public: + Event(bool setInitially = 0) : State(setInitially), Temporary(false) { } + ~Event() { } + + // Wait on an event condition until it is set + // Delay is specified in milliseconds (1/1000 of a second). + bool Wait(unsigned delay = OVR_WAIT_INFINITE); + + // Set an event, releasing objects waiting on it + void SetEvent() + { updateState(true, false, true); } + + // Reset an event, un-signaling it + void ResetEvent() + { updateState(false, false, false); } + + // Set and then reset an event once a waiter is released. + // If threads are already waiting, they will be notified and released + // If threads are not waiting, the event is set until the first thread comes in + void PulseEvent() + { updateState(true, true, true); } +}; + + +//----------------------------------------------------------------------------------- +// ***** Thread class + +// ThreadHandle is a handle to a thread, which on some platforms (e.g. Windows) is +// different from ThreadId. On Unix platforms, a ThreadHandle is the same as a +// ThreadId and is pthread_t. +typedef void* ThreadHandle; + +// ThreadId uniquely identifies a thread; returned by Windows GetCurrentThreadId(), +// Unix pthread_self() and Thread::GetThreadId. +typedef void* ThreadId; + + +// *** Thread flags + +// Indicates that the thread is has been started, i.e. Start method has been called, and threads +// OnExit() method has not yet been called/returned. +#define OVR_THREAD_STARTED 0x01 +// This flag is set once the thread has ran, and finished. +#define OVR_THREAD_FINISHED 0x02 +// This flag is set temporarily if this thread was started suspended. It is used internally. +#define OVR_THREAD_START_SUSPENDED 0x08 +// This flag is used to ask a thread to exit. Message driven threads will usually check this flag +// and finish once it is set. +#define OVR_THREAD_EXIT 0x10 + + +class Thread : public RefCountBase +{ // NOTE: Waitable must be the first base since it implements RefCountImpl. +public: + // *** Callback functions, can be used instead of overriding Run + + // Run function prototypes. + // Thread function and user handle passed to it, executed by the default + // Thread::Run implementation if not null. + typedef int (*ThreadFn)(Thread *pthread, void* h); + + // Thread ThreadFunction1 is executed if not 0, otherwise ThreadFunction2 is tried + ThreadFn ThreadFunction; + // User handle passes to a thread + void* UserHandle; + + // Thread state to start a thread with + enum ThreadState + { + NotRunning = 0, + Running = 1, + Suspended = 2 + }; + + // Thread priority + enum ThreadPriority + { + CriticalPriority, + HighestPriority, + AboveNormalPriority, + NormalPriority, + BelowNormalPriority, + LowestPriority, + IdlePriority, + }; + + // Thread constructor parameters + struct CreateParams + { + CreateParams(ThreadFn func = 0, void* hand = 0, size_t ssize = 128 * 1024, + int proc = -1, ThreadState state = NotRunning, ThreadPriority prior = NormalPriority) + : threadFunction(func), userHandle(hand), stackSize(ssize), + processor(proc), initialState(state), priority(prior) {} + ThreadFn threadFunction; // Thread function + void* userHandle; // User handle passes to a thread + size_t stackSize; // Thread stack size + int processor; // Thread hardware processor + ThreadState initialState; // + ThreadPriority priority; // Thread priority + }; + + + // *** Constructors + + // A default constructor always creates a thread in NotRunning state, because + // the derived class has not yet been initialized. The derived class can call Start explicitly. + // "processor" parameter specifies which hardware processor this thread will be run on. + // -1 means OS decides this. Implemented only on Win32 + Thread(size_t stackSize = 128 * 1024, int processor = -1); + // Constructors that initialize the thread with a pointer to function. + // An option to start a thread is available, but it should not be used if classes are derived from Thread. + // "processor" parameter specifies which hardware processor this thread will be run on. + // -1 means OS decides this. Implemented only on Win32 + Thread(ThreadFn threadFunction, void* userHandle = 0, size_t stackSize = 128 * 1024, + int processor = -1, ThreadState initialState = NotRunning); + // Constructors that initialize the thread with a create parameters structure. + explicit Thread(const CreateParams& params); + + // Destructor. + virtual ~Thread(); + + // Waits for all Threads to finish; should be called only from the root + // application thread. Once this function returns, we know that all other + // thread's references to Thread object have been released. + static void OVR_CDECL FinishAllThreads(); + + + // *** Overridable Run function for thread processing + + // - returning from this method will end the execution of the thread + // - return value is usually 0 for success + virtual int Run(); + // Called after return/exit function + virtual void OnExit(); + + + // *** Thread management + + // Starts the thread if its not already running + // - internally sets up the threading and calls Run() + // - initial state can either be Running or Suspended, NotRunning will just fail and do nothing + // - returns the exit code + virtual bool Start(ThreadState initialState = Running); + + // Quits with an exit code + virtual void Exit(int exitCode=0); + + // Suspend the thread until resumed + // Returns 1 for success, 0 for failure. + bool Suspend(); + // Resumes currently suspended thread + // Returns 1 for success, 0 for failure. + bool Resume(); + + // Static function to return a pointer to the current thread + //static Thread* GetThread(); + + + // *** Thread status query functions + + bool GetExitFlag() const; + void SetExitFlag(bool exitFlag); + + // Determines whether the thread was running and is now finished + bool IsFinished() const; + // Determines if the thread is currently suspended + bool IsSuspended() const; + // Returns current thread state + ThreadState GetThreadState() const; + + // Wait for thread to finish for a maxmimum number of milliseconds + // For maxWaitMs = 0 it simply polls and then returns if the thread is not finished + // For maxWaitMs < 0 it will wait forever + bool Join(int maxWaitMs = -1) const; + + // Returns the number of available CPUs on the system + static int GetCPUCount(); + + // Returns the thread exit code. Exit code is initialized to 0, + // and set to the return value if Run function after the thread is finished. + inline int GetExitCode() const { return ExitCode; } + // Returns an OS handle +#if defined(OVR_OS_MS) + void* GetOSHandle() const { return ThreadHandle; } +#else + pthread_t GetOSHandle() const { return ThreadHandle; } +#endif + +#if defined(OVR_OS_MS) + ThreadId GetThreadId() const { return IdValue; } +#else + ThreadId GetThreadId() const { return (ThreadId)GetOSHandle(); } +#endif + + // Returns the platform-specific equivalent const that corresponds to the given ThreadPriority. + static int GetOSPriority(ThreadPriority); + static ThreadPriority GetOVRPriority(int osPriority); // May return a value outside the ThreadPriority enum range in unusual cases. + + // Gets this instance's priority. + ThreadPriority GetPriority(); + + // Gets the current thread's priority. + static ThreadPriority GetCurrentPriority(); + + // Sets this instance's thread's priority. + // Some platforms (e.g. Unix) don't let you set thread priorities unless you have root privileges/ + bool SetPriority(ThreadPriority); + + // Sets the current thread's priority. + static bool SetCurrentPriority(ThreadPriority); + + // *** Sleep + + // Sleep secs seconds + static bool Sleep(unsigned secs); + // Sleep msecs milliseconds + static bool MSleep(unsigned msecs); + + // Notifies the scheduler that this thread is willing to release its processor + // to other threads of equal or higher priority. + static void YieldCurrentThread(); + + // *** Debugging functionality + virtual void SetThreadName(const char* name); + static void SetThreadName(const char* name, ThreadId threadId); + static void SetCurrentThreadName(const char* name); + + static void GetThreadName(char* name, size_t nameCapacity, ThreadId threadId); + static void GetCurrentThreadName(char* name, size_t nameCapacity); + +private: +#if defined(OVR_OS_WIN32) + friend unsigned WINAPI Thread_Win32StartFn(void *phandle); +#elif defined(OVR_OS_MS) // Any other Microsoft OS... + friend DWORD WINAPI Thread_Win32StartFn(void *phandle); +#else + friend void *Thread_PthreadStartFn(void * phandle); + + static int InitAttr; + static pthread_attr_t Attr; +#endif + +protected: + // Thread state flags + AtomicInt ThreadFlags; + AtomicInt SuspendCount; + size_t StackSize; + + // Hardware processor which this thread is running on. + int Processor; + ThreadPriority Priority; + +#if defined(OVR_OS_MS) + void* ThreadHandle; + volatile ThreadId IdValue; + + // System-specific cleanup function called from destructor + void CleanupSystemThread(); + +#else + pthread_t ThreadHandle; +#endif + + // Exit code of the thread, as returned by Run. + int ExitCode; + + // Internal run function. + int PRun(); + // Finishes the thread and releases internal reference to it. + void FinishAndRelease(); + + void Init(const CreateParams& params); + + // Protected copy constructor + Thread(const Thread &source) : RefCountBase() { OVR_UNUSED(source); } + +}; + +// Returns the unique Id of a thread it is called on, intended for +// comparison purposes. +ThreadId GetCurrentThreadId(); + + +} // OVR + +#endif // OVR_ENABLE_THREADS +#endif // OVR_Threads_h diff --git a/LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp b/LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp new file mode 100644 index 0000000..0d8851b --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_ThreadsPthread.cpp @@ -0,0 +1,1006 @@ +/************************************************************************************ + +Filename : OVR_ThreadsPthread.cpp +Content : +Created : +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#if !defined(_WIN32) // Skip the entire file under Windows + +#include "OVR_Threads.h" +#include "OVR_Hash.h" + +#ifdef OVR_ENABLE_THREADS + +#include "OVR_Timer.h" +#include "OVR_Log.h" + +#include +#include +#include +#include +#include +#include + +#if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) + #include + #include + #if !defined(OVR_OS_MAC) + #include + #endif +#endif + + + +namespace OVR { + +// ***** Mutex implementation + + +// *** Internal Mutex implementation structure + +class MutexImpl : public NewOverrideBase +{ + // System mutex or semaphore + pthread_mutex_t SMutex; + bool Recursive; + unsigned LockCount; + pthread_t LockedBy; + + friend class WaitConditionImpl; + +public: + // Constructor/destructor + MutexImpl(Mutex* pmutex, bool recursive = 1); + ~MutexImpl(); + + // Locking functions + void DoLock(); + bool TryLock(); + void Unlock(Mutex* pmutex); + // Returns 1 if the mutes is currently locked + bool IsLockedByAnotherThread(Mutex* pmutex); + bool IsSignaled() const; +}; + +pthread_mutexattr_t Lock::RecursiveAttr; +bool Lock::RecursiveAttrInit = 0; + +// *** Constructor/destructor +MutexImpl::MutexImpl(Mutex* pmutex, bool recursive) +{ + OVR_UNUSED(pmutex); + Recursive = recursive; + LockCount = 0; + + if (Recursive) + { + if (!Lock::RecursiveAttrInit) + { + pthread_mutexattr_init(&Lock::RecursiveAttr); + pthread_mutexattr_settype(&Lock::RecursiveAttr, PTHREAD_MUTEX_RECURSIVE); + Lock::RecursiveAttrInit = 1; + } + + pthread_mutex_init(&SMutex, &Lock::RecursiveAttr); + } + else + pthread_mutex_init(&SMutex, 0); +} + +MutexImpl::~MutexImpl() +{ + pthread_mutex_destroy(&SMutex); +} + + +// Lock and try lock +void MutexImpl::DoLock() +{ + while (pthread_mutex_lock(&SMutex)) + ; + LockCount++; + LockedBy = pthread_self(); +} + +bool MutexImpl::TryLock() +{ + if (!pthread_mutex_trylock(&SMutex)) + { + LockCount++; + LockedBy = pthread_self(); + return 1; + } + + return 0; +} + +void MutexImpl::Unlock(Mutex* pmutex) +{ + OVR_UNUSED(pmutex); + OVR_ASSERT(pthread_self() == LockedBy && LockCount > 0); + + //unsigned lockCount; + LockCount--; + //lockCount = LockCount; + + pthread_mutex_unlock(&SMutex); +} + +bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex) +{ + OVR_UNUSED(pmutex); + // There could be multiple interpretations of IsLocked with respect to current thread + if (LockCount == 0) + return 0; + if (pthread_self() != LockedBy) + return 1; + return 0; +} + +bool MutexImpl::IsSignaled() const +{ + // An mutex is signaled if it is not locked ANYWHERE + // Note that this is different from IsLockedByAnotherThread function, + // that takes current thread into account + return LockCount == 0; +} + + +// *** Actual Mutex class implementation + +Mutex::Mutex(bool recursive) +{ + // NOTE: RefCount mode already thread-safe for all waitables. + pImpl = new MutexImpl(this, recursive); +} + +Mutex::~Mutex() +{ + delete pImpl; +} + +// Lock and try lock +void Mutex::DoLock() +{ + pImpl->DoLock(); +} +bool Mutex::TryLock() +{ + return pImpl->TryLock(); +} +void Mutex::Unlock() +{ + pImpl->Unlock(this); +} +bool Mutex::IsLockedByAnotherThread() +{ + return pImpl->IsLockedByAnotherThread(this); +} + + + +//----------------------------------------------------------------------------------- +// ***** Event + +bool Event::Wait(unsigned delay) +{ + Mutex::Locker lock(&StateMutex); + + // Do the correct amount of waiting + if (delay == OVR_WAIT_INFINITE) + { + while(!State) + StateWaitCondition.Wait(&StateMutex); + } + else if (delay) + { + if (!State) + StateWaitCondition.Wait(&StateMutex, delay); + } + + bool state = State; + // Take care of temporary 'pulsing' of a state + if (Temporary) + { + Temporary = false; + State = false; + } + return state; +} + +void Event::updateState(bool newState, bool newTemp, bool mustNotify) +{ + Mutex::Locker lock(&StateMutex); + State = newState; + Temporary = newTemp; + if (mustNotify) + StateWaitCondition.NotifyAll(); +} + + + +// ***** Wait Condition Implementation + +// Internal implementation class +class WaitConditionImpl : public NewOverrideBase +{ + pthread_mutex_t SMutex; + pthread_cond_t Condv; + +public: + + // Constructor/destructor + WaitConditionImpl(); + ~WaitConditionImpl(); + + // Release mutex and wait for condition. The mutex is re-aqured after the wait. + bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE); + + // Notify a condition, releasing at one object waiting + void Notify(); + // Notify a condition, releasing all objects waiting + void NotifyAll(); +}; + + +WaitConditionImpl::WaitConditionImpl() +{ + pthread_mutex_init(&SMutex, 0); + pthread_cond_init(&Condv, 0); +} + +WaitConditionImpl::~WaitConditionImpl() +{ + pthread_mutex_destroy(&SMutex); + pthread_cond_destroy(&Condv); +} + +bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay) +{ + bool result = 1; + unsigned lockCount = pmutex->pImpl->LockCount; + + // Mutex must have been locked + if (lockCount == 0) + return 0; + + pthread_mutex_lock(&SMutex); + + // Finally, release a mutex or semaphore + if (pmutex->pImpl->Recursive) + { + // Release the recursive mutex N times + pmutex->pImpl->LockCount = 0; + for(unsigned i=0; ipImpl->SMutex); + } + else + { + pmutex->pImpl->LockCount = 0; + pthread_mutex_unlock(&pmutex->pImpl->SMutex); + } + + // Note that there is a gap here between mutex.Unlock() and Wait(). + // The other mutex protects this gap. + + if (delay == OVR_WAIT_INFINITE) + pthread_cond_wait(&Condv,&SMutex); + else + { + timespec ts; + + struct timeval tv; + gettimeofday(&tv, 0); + + ts.tv_sec = tv.tv_sec + (delay / 1000); + ts.tv_nsec = (tv.tv_usec + (delay % 1000) * 1000) * 1000; + + if (ts.tv_nsec > 999999999) + { + ts.tv_sec++; + ts.tv_nsec -= 1000000000; + } + int r = pthread_cond_timedwait(&Condv,&SMutex, &ts); + OVR_ASSERT(r == 0 || r == ETIMEDOUT); + if (r) + result = 0; + } + + pthread_mutex_unlock(&SMutex); + + // Re-aquire the mutex + for(unsigned i=0; iDoLock(); + + // Return the result + return result; +} + +// Notify a condition, releasing the least object in a queue +void WaitConditionImpl::Notify() +{ + pthread_mutex_lock(&SMutex); + pthread_cond_signal(&Condv); + pthread_mutex_unlock(&SMutex); +} + +// Notify a condition, releasing all objects waiting +void WaitConditionImpl::NotifyAll() +{ + pthread_mutex_lock(&SMutex); + pthread_cond_broadcast(&Condv); + pthread_mutex_unlock(&SMutex); +} + + + +// *** Actual implementation of WaitCondition + +WaitCondition::WaitCondition() +{ + pImpl = new WaitConditionImpl; +} +WaitCondition::~WaitCondition() +{ + delete pImpl; +} + +bool WaitCondition::Wait(Mutex *pmutex, unsigned delay) +{ + return pImpl->Wait(pmutex, delay); +} +// Notification +void WaitCondition::Notify() +{ + pImpl->Notify(); +} +void WaitCondition::NotifyAll() +{ + pImpl->NotifyAll(); +} + + +// ***** Current thread + +// Per-thread variable +/* +static __thread Thread* pCurrentThread = 0; + +// Static function to return a pointer to the current thread +void Thread::InitCurrentThread(Thread *pthread) +{ + pCurrentThread = pthread; +} + +// Static function to return a pointer to the current thread +Thread* Thread::GetThread() +{ + return pCurrentThread; +} +*/ + + +// *** Thread constructors. + +Thread::Thread(UPInt stackSize, int processor) +{ + // NOTE: RefCount mode already thread-safe for all Waitable objects. + CreateParams params; + params.stackSize = stackSize; + params.processor = processor; + Init(params); +} + +Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, UPInt stackSize, + int processor, Thread::ThreadState initialState) +{ + CreateParams params(threadFunction, userHandle, stackSize, processor, initialState); + Init(params); +} + +Thread::Thread(const CreateParams& params) +{ + Init(params); +} + +void Thread::Init(const CreateParams& params) +{ + // Clear the variables + ThreadFlags = 0; + ThreadHandle = 0; + ExitCode = 0; + SuspendCount = 0; + StackSize = params.stackSize; + Processor = params.processor; + Priority = params.priority; + + // Clear Function pointers + ThreadFunction = params.threadFunction; + UserHandle = params.userHandle; + if (params.initialState != NotRunning) + Start(params.initialState); +} + +Thread::~Thread() +{ + // Thread should not running while object is being destroyed, + // this would indicate ref-counting issue. + //OVR_ASSERT(IsRunning() == 0); + + // Clean up thread. + ThreadHandle = 0; +} + + + +// *** Overridable User functions. + +// Default Run implementation +int Thread::Run() +{ + // Call pointer to function, if available. + return (ThreadFunction) ? ThreadFunction(this, UserHandle) : 0; +} +void Thread::OnExit() +{ +} + + +// Finishes the thread and releases internal reference to it. +void Thread::FinishAndRelease() +{ + // Note: thread must be US. + ThreadFlags &= (UInt32)~(OVR_THREAD_STARTED); + ThreadFlags |= OVR_THREAD_FINISHED; + + // Release our reference; this is equivalent to 'delete this' + // from the point of view of our thread. + Release(); +} + + + +// *** ThreadList - used to track all created threads + +class ThreadList : public NewOverrideBase +{ + //------------------------------------------------------------------------ + struct ThreadHashOp + { + size_t operator()(const Thread* ptr) + { + return (((size_t)ptr) >> 6) ^ (size_t)ptr; + } + }; + + HashSet ThreadSet; + Mutex ThreadMutex; + WaitCondition ThreadsEmpty; + // Track the root thread that created us. + pthread_t RootThreadId; + + static ThreadList* volatile pRunningThreads; + + void addThread(Thread *pthread) + { + Mutex::Locker lock(&ThreadMutex); + ThreadSet.Add(pthread); + } + + void removeThread(Thread *pthread) + { + Mutex::Locker lock(&ThreadMutex); + ThreadSet.Remove(pthread); + if (ThreadSet.GetSize() == 0) + ThreadsEmpty.Notify(); + } + + void finishAllThreads() + { + // Only original root thread can call this. + OVR_ASSERT(pthread_self() == RootThreadId); + + Mutex::Locker lock(&ThreadMutex); + while (ThreadSet.GetSize() != 0) + ThreadsEmpty.Wait(&ThreadMutex); + } + +public: + + ThreadList() + { + RootThreadId = pthread_self(); + } + ~ThreadList() { } + + + static void AddRunningThread(Thread *pthread) + { + // Non-atomic creation ok since only the root thread + if (!pRunningThreads) + { + pRunningThreads = new ThreadList; + OVR_ASSERT(pRunningThreads); + } + pRunningThreads->addThread(pthread); + } + + // NOTE: 'pthread' might be a dead pointer when this is + // called so it should not be accessed; it is only used + // for removal. + static void RemoveRunningThread(Thread *pthread) + { + OVR_ASSERT(pRunningThreads); + pRunningThreads->removeThread(pthread); + } + + static void FinishAllThreads() + { + // This is ok because only root thread can wait for other thread finish. + if (pRunningThreads) + { + pRunningThreads->finishAllThreads(); + delete pRunningThreads; + pRunningThreads = 0; + } + } +}; + +// By default, we have no thread list. +ThreadList* volatile ThreadList::pRunningThreads = 0; + + +// FinishAllThreads - exposed publicly in Thread. +void Thread::FinishAllThreads() +{ + ThreadList::FinishAllThreads(); +} + +// *** Run override + +int Thread::PRun() +{ + // Suspend us on start, if requested + if (ThreadFlags & OVR_THREAD_START_SUSPENDED) + { + Suspend(); + ThreadFlags &= (UInt32)~OVR_THREAD_START_SUSPENDED; + } + + // Call the virtual run function + ExitCode = Run(); + return ExitCode; +} + + + + +// *** User overridables + +bool Thread::GetExitFlag() const +{ + return (ThreadFlags & OVR_THREAD_EXIT) != 0; +} + +void Thread::SetExitFlag(bool exitFlag) +{ + // The below is atomic since ThreadFlags is AtomicInt. + if (exitFlag) + ThreadFlags |= OVR_THREAD_EXIT; + else + ThreadFlags &= (UInt32) ~OVR_THREAD_EXIT; +} + + +// Determines whether the thread was running and is now finished +bool Thread::IsFinished() const +{ + return (ThreadFlags & OVR_THREAD_FINISHED) != 0; +} +// Determines whether the thread is suspended +bool Thread::IsSuspended() const +{ + return SuspendCount > 0; +} +// Returns current thread state +Thread::ThreadState Thread::GetThreadState() const +{ + if (IsSuspended()) + return Suspended; + if (ThreadFlags & OVR_THREAD_STARTED) + return Running; + return NotRunning; +} + +// Join thread +bool Thread::Join(int maxWaitMs) const +{ + // If polling, + if (maxWaitMs == 0) + { + // Just return if finished + return IsFinished(); + } + // If waiting forever, + else if (maxWaitMs > 0) + { + UInt32 t0 = Timer::GetTicksMs(); + + while (!IsFinished()) + { + UInt32 t1 = Timer::GetTicksMs(); + + // If the wait has expired, + int delta = (int)(t1 - t0); + if (delta >= maxWaitMs) + { + return false; + } + + Thread::MSleep(10); + } + + return true; + } + else + { + while (!IsFinished()) + { + pthread_join(ThreadHandle, NULL); + } + } + + return true; +} + +/* +static const char* mapsched_policy(int policy) +{ + switch(policy) + { + case SCHED_OTHER: + return "SCHED_OTHER"; + case SCHED_RR: + return "SCHED_RR"; + case SCHED_FIFO: + return "SCHED_FIFO"; + + } + return "UNKNOWN"; +} + int policy; + sched_param sparam; + pthread_getschedparam(pthread_self(), &policy, &sparam); + int max_prior = sched_get_priority_max(policy); + int min_prior = sched_get_priority_min(policy); + printf(" !!!! policy: %s, priority: %d, max priority: %d, min priority: %d\n", mapsched_policy(policy), sparam.sched_priority, max_prior, min_prior); +#include +*/ +// ***** Thread management + +// The actual first function called on thread start +void* Thread_PthreadStartFn(void* phandle) +{ + Thread* pthread = (Thread*)phandle; + int result = pthread->PRun(); + // Signal the thread as done and release it atomically. + pthread->FinishAndRelease(); + // At this point Thread object might be dead; however we can still pass + // it to RemoveRunningThread since it is only used as a key there. + ThreadList::RemoveRunningThread(pthread); + return reinterpret_cast(result); +} + +int Thread::InitAttr = 0; +pthread_attr_t Thread::Attr; + +/* static */ +int Thread::GetOSPriority(ThreadPriority p) +{ + OVR_UNUSED(p); + return -1; +} + +/* static */ +Thread::ThreadPriority Thread::GetOVRPriority(int osPriority) +{ + #if defined(OVR_OS_LINUX) + return (ThreadPriority)(Thread::NormalPriority - osPriority); // This works for both SCHED_OTHER, SCHED_RR, and SCHED_FIFO. + #else + // Apple priorities are such that the min is a value less than the max. + static int minPriority = sched_get_priority_min(SCHED_FIFO); // We don't have a means to pass a policy type to this function. + static int maxPriority = sched_get_priority_max(SCHED_FIFO); + + return (ThreadPriority)(Thread::NormalPriority - (osPriority - ((minPriority + maxPriority) / 2))); + #endif +} + + +Thread::ThreadPriority Thread::GetPriority() +{ + int policy; + sched_param param; + + int result = pthread_getschedparam(ThreadHandle, &policy, ¶m); + + if(result == 0) + { + #if !defined(OVR_OS_LINUX) + if(policy == SCHED_OTHER) + { + return Thread::NormalPriority; //SCHED_OTHER allows only normal priority on BSD-style Unix and Mac OS X. + } + #endif + + return GetOVRPriority(param.sched_priority); + } + + return Thread::NormalPriority; +} + +/* static */ +Thread::ThreadPriority Thread::GetCurrentPriority() +{ + int policy; + sched_param param; + pthread_t currentThreadId = pthread_self(); + + int result = pthread_getschedparam(currentThreadId, &policy, ¶m); + + if(result == 0) + { + #if !defined(OVR_OS_LINUX) + if(policy == SCHED_OTHER) + { + return Thread::NormalPriority; //SCHED_OTHER allows only normal priority on BSD-style Unix and Mac OS X. + } + #endif + + return GetOVRPriority(param.sched_priority); + } + + return Thread::NormalPriority; +} + + +bool Thread::SetPriority(ThreadPriority) +{ + // We currently fail. To do: add code to support this via pthread_getschedparam/pthread_attr_setschedparam + // This won't work unless using SCHED_FIFO or SCHED_RR anyway, which require root privileges. + return false; +} + +/* static */ +bool Thread::SetCurrentPriority(ThreadPriority) +{ + // We currently fail. To do: add code to support this via pthread_getschedparam/pthread_attr_setschedparam + // This won't work unless using SCHED_FIFO or SCHED_RR anyway, which require root privileges. + return false; +} + +bool Thread::Start(ThreadState initialState) +{ + if (initialState == NotRunning) + return 0; + if (GetThreadState() != NotRunning) + { + OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this)); + return 0; + } + + if (!InitAttr) + { + pthread_attr_init(&Attr); + pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&Attr, 128 * 1024); + sched_param sparam; + sparam.sched_priority = Thread::GetOSPriority(NormalPriority); + pthread_attr_setschedparam(&Attr, &sparam); + InitAttr = 1; + } + + ExitCode = 0; + SuspendCount = 0; + ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED; + + // AddRef to us until the thread is finished + AddRef(); + ThreadList::AddRunningThread(this); + + int result; + if (StackSize != 128 * 1024 || Priority != NormalPriority) + { + pthread_attr_t attr; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + pthread_attr_setstacksize(&attr, StackSize); + sched_param sparam; + sparam.sched_priority = Thread::GetOSPriority(Priority); + pthread_attr_setschedparam(&attr, &sparam); + result = pthread_create(&ThreadHandle, &attr, Thread_PthreadStartFn, this); + pthread_attr_destroy(&attr); + } + else + result = pthread_create(&ThreadHandle, &Attr, Thread_PthreadStartFn, this); + + if (result) + { + ThreadFlags = 0; + Release(); + ThreadList::RemoveRunningThread(this); + return 0; + } + return 1; +} + + +// Suspend the thread until resumed +bool Thread::Suspend() +{ + OVR_DEBUG_LOG(("Thread::Suspend - cannot suspend threads on this system")); + return 0; +} + +// Resumes currently suspended thread +bool Thread::Resume() +{ + return 0; +} + + +// Quits with an exit code +void Thread::Exit(int exitCode) +{ + // Can only exist the current thread + // if (GetThread() != this) + // return; + + // Call the virtual OnExit function + OnExit(); + + // Signal this thread object as done and release it's references. + FinishAndRelease(); + ThreadList::RemoveRunningThread(this); + + pthread_exit(reinterpret_cast(exitCode)); +} + +ThreadId GetCurrentThreadId() +{ + return (void*)pthread_self(); +} + +// *** Sleep functions + +/* static */ +bool Thread::Sleep(unsigned secs) +{ + sleep(secs); + return 1; +} +/* static */ +bool Thread::MSleep(unsigned msecs) +{ + usleep(msecs*1000); + return 1; +} + +/* static */ +void Thread::YieldCurrentThread() +{ + #if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) + pthread_yield_np(); + #elif defined(OVR_OS_ANDROID) + sched_yield(); + #else // Linux + pthread_yield(); + #endif +} + +/* static */ +int Thread::GetCPUCount() +{ + #if defined(OVR_OS_MAC) || defined(OVR_OS_BSD) + // http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man3/sysctlbyname.3.html + int cpuCount = 0; + size_t len = sizeof(cpuCount); + + if(sysctlbyname("hw.logicalcpu", &cpuCount, &len, NULL, 0) != 0) + cpuCount = 1; + + return cpuCount; + + #else // Linux, Android + + // Alternative: read /proc/cpuinfo + #ifdef _SC_NPROCESSORS_ONLN + return (int)sysconf(_SC_NPROCESSORS_ONLN); + #else + return 1; + #endif + #endif +} + + +void Thread::SetThreadName( const char* name ) +{ + #if defined (OVR_OS_APPLE) + if(ThreadHandle == pthread_self()) + pthread_setname_np(name); + // Else there's nothing we can do. + #else + if(ThreadHandle != 0) + pthread_setname_np(ThreadHandle, name); + // Else we can possibly save this name and set it later when the thread starts. + #endif +} + + +void Thread::SetThreadName(const char* name, ThreadId threadId) +{ + #if defined (OVR_OS_APPLE) + if(pthread_equal((pthread_t)threadId, pthread_self())) + pthread_setname_np(name); + // Else there's no way to set the name of another thread. + #else + pthread_setname_np((pthread_t)threadId, name); + #endif +} + + +void Thread::SetCurrentThreadName(const char* name) +{ + #if defined (OVR_OS_APPLE) + pthread_setname_np(name); + #else + pthread_setname_np(pthread_self(), name); + #endif +} + + +void Thread::GetThreadName(char* name, size_t nameCapacity, ThreadId threadId) +{ + name[0] = 0; +#if !defined (OVR_OS_ANDROID) + // Android does not have pthread_getname_np (or an equivalent) + pthread_getname_np((pthread_t)threadId, name, nameCapacity); +#endif +} + + +void Thread::GetCurrentThreadName(char* name, size_t nameCapacity) +{ + name[0] = 0; +#if !defined (OVR_OS_ANDROID) + // Android does not have pthread_getname_np (or an equivalent) + pthread_getname_np(pthread_self(), name, nameCapacity); +#endif +} + + +} // namespace OVR + +#endif // OVR_ENABLE_THREADS + +#endif // _WIN32 diff --git a/LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp b/LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp new file mode 100644 index 0000000..8cba464 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_ThreadsWinAPI.cpp @@ -0,0 +1,1150 @@ +/************************************************************************************ + +Filename : OVR_ThreadsWinAPI.cpp +Platform : WinAPI +Content : Windows specific thread-related (safe) functionality +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Threads.h" +#include "OVR_Hash.h" +#include "OVR_Log.h" +#include "OVR_Timer.h" + +#ifdef OVR_ENABLE_THREADS + +// For _beginthreadex / _endtheadex +#include + +namespace OVR { + + +//----------------------------------------------------------------------------------- +// *** Internal Mutex implementation class + +class MutexImpl : public NewOverrideBase +{ + // System mutex or semaphore + HANDLE hMutexOrSemaphore; + bool Recursive; + volatile unsigned LockCount; + + friend class WaitConditionImpl; + +public: + // Constructor/destructor + MutexImpl(bool recursive = 1); + ~MutexImpl(); + + // Locking functions + void DoLock(); + bool TryLock(); + void Unlock(Mutex* pmutex); + // Returns 1 if the mutes is currently locked + bool IsLockedByAnotherThread(Mutex* pmutex); +}; + +// *** Constructor/destructor +MutexImpl::MutexImpl(bool recursive) +{ + Recursive = recursive; + LockCount = 0; +#if defined(OVR_OS_WIN32) // Older versions of Windows don't support CreateSemaphoreEx, so stick with CreateSemaphore for portability. + hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphore(NULL, 1, 1, NULL); +#else + // No CreateSemaphore() call, so emulate it. + hMutexOrSemaphore = Recursive ? CreateMutex(NULL, 0, NULL) : CreateSemaphoreEx(NULL, 1, 1, NULL, 0, SEMAPHORE_ALL_ACCESS); +#endif +} +MutexImpl::~MutexImpl() +{ + CloseHandle(hMutexOrSemaphore); +} + + +// Lock and try lock +void MutexImpl::DoLock() +{ + if (::WaitForSingleObject(hMutexOrSemaphore, INFINITE) != WAIT_OBJECT_0) + return; + LockCount++; +} + +bool MutexImpl::TryLock() +{ + DWORD ret; + if ((ret=::WaitForSingleObject(hMutexOrSemaphore, 0)) != WAIT_OBJECT_0) + return 0; + LockCount++; + return 1; +} + +void MutexImpl::Unlock(Mutex* pmutex) +{ + OVR_UNUSED(pmutex); + + unsigned lockCount; + LockCount--; + lockCount = LockCount; + + // Release mutex + if ((Recursive ? ReleaseMutex(hMutexOrSemaphore) : + ReleaseSemaphore(hMutexOrSemaphore, 1, NULL)) != 0) + { + // This used to call Wait handlers if lockCount == 0. + } +} + +bool MutexImpl::IsLockedByAnotherThread(Mutex* pmutex) +{ + // There could be multiple interpretations of IsLocked with respect to current thread + if (LockCount == 0) + return 0; + if (!TryLock()) + return 1; + Unlock(pmutex); + return 0; +} + +/* +bool MutexImpl::IsSignaled() const +{ + // An mutex is signaled if it is not locked ANYWHERE + // Note that this is different from IsLockedByAnotherThread function, + // that takes current thread into account + return LockCount == 0; +} +*/ + + +// *** Actual Mutex class implementation + +Mutex::Mutex(bool recursive) +{ + pImpl = new MutexImpl(recursive); +} +Mutex::~Mutex() +{ + delete pImpl; +} + +// Lock and try lock +void Mutex::DoLock() +{ + pImpl->DoLock(); +} +bool Mutex::TryLock() +{ + return pImpl->TryLock(); +} +void Mutex::Unlock() +{ + pImpl->Unlock(this); +} +bool Mutex::IsLockedByAnotherThread() +{ + return pImpl->IsLockedByAnotherThread(this); +} + +//----------------------------------------------------------------------------------- +// ***** Event + +bool Event::Wait(unsigned delay) +{ + Mutex::Locker lock(&StateMutex); + + // Do the correct amount of waiting + if (delay == OVR_WAIT_INFINITE) + { + while(!State) + StateWaitCondition.Wait(&StateMutex); + } + else if (delay) + { + if (!State) + StateWaitCondition.Wait(&StateMutex, delay); + } + + bool state = State; + // Take care of temporary 'pulsing' of a state + if (Temporary) + { + Temporary = false; + State = false; + } + return state; +} + +void Event::updateState(bool newState, bool newTemp, bool mustNotify) +{ + Mutex::Locker lock(&StateMutex); + State = newState; + Temporary = newTemp; + if (mustNotify) + StateWaitCondition.NotifyAll(); +} + + +//----------------------------------------------------------------------------------- +// ***** Win32 Wait Condition Implementation + +// Internal implementation class +class WaitConditionImpl : public NewOverrideBase +{ + // Event pool entries for extra events + struct EventPoolEntry : public NewOverrideBase + { + HANDLE hEvent; + EventPoolEntry *pNext; + EventPoolEntry *pPrev; + }; + + Lock WaitQueueLoc; + // Stores free events that can be used later + EventPoolEntry * pFreeEventList; + + // A queue of waiting objects to be signaled + EventPoolEntry* pQueueHead; + EventPoolEntry* pQueueTail; + + // Allocation functions for free events + EventPoolEntry* GetNewEvent(); + void ReleaseEvent(EventPoolEntry* pevent); + + // Queue operations + void QueuePush(EventPoolEntry* pentry); + EventPoolEntry* QueuePop(); + void QueueFindAndRemove(EventPoolEntry* pentry); + +public: + + // Constructor/destructor + WaitConditionImpl(); + ~WaitConditionImpl(); + + // Release mutex and wait for condition. The mutex is re-acqured after the wait. + bool Wait(Mutex *pmutex, unsigned delay = OVR_WAIT_INFINITE); + + // Notify a condition, releasing at one object waiting + void Notify(); + // Notify a condition, releasing all objects waiting + void NotifyAll(); +}; + + + +WaitConditionImpl::WaitConditionImpl() +{ + pFreeEventList = 0; + pQueueHead = + pQueueTail = 0; +} + +WaitConditionImpl::~WaitConditionImpl() +{ + // Free all the resources + EventPoolEntry* p = pFreeEventList; + EventPoolEntry* pentry; + + while(p) + { + // Move to next + pentry = p; + p = p->pNext; + // Delete old + ::CloseHandle(pentry->hEvent); + delete pentry; + } + // Shouldn't we also consider the queue? + + // To be safe + pFreeEventList = 0; + pQueueHead = + pQueueTail = 0; +} + + +// Allocation functions for free events +WaitConditionImpl::EventPoolEntry* WaitConditionImpl::GetNewEvent() +{ + EventPoolEntry* pentry; + + // If there are any free nodes, use them + if (pFreeEventList) + { + pentry = pFreeEventList; + pFreeEventList = pFreeEventList->pNext; + } + else + { + // Allocate a new node + pentry = new EventPoolEntry; + pentry->pNext = 0; + pentry->pPrev = 0; + // Non-signaled manual event + pentry->hEvent = ::CreateEvent(NULL, TRUE, 0, NULL); + } + + return pentry; +} + +void WaitConditionImpl::ReleaseEvent(EventPoolEntry* pevent) +{ + // Mark event as non-signaled + ::ResetEvent(pevent->hEvent); + // And add it to free pool + pevent->pNext = pFreeEventList; + pevent->pPrev = 0; + pFreeEventList = pevent; +} + +// Queue operations +void WaitConditionImpl::QueuePush(EventPoolEntry* pentry) +{ + // Items already exist? Just add to tail + if (pQueueTail) + { + pentry->pPrev = pQueueTail; + pQueueTail->pNext = pentry; + pentry->pNext = 0; + pQueueTail = pentry; + } + else + { + // No items in queue + pentry->pNext = + pentry->pPrev = 0; + pQueueHead = + pQueueTail = pentry; + } +} + +WaitConditionImpl::EventPoolEntry* WaitConditionImpl::QueuePop() +{ + EventPoolEntry* pentry = pQueueHead; + + // No items, null pointer + if (pentry) + { + // More items after this one? just grab the first item + if (pQueueHead->pNext) + { + pQueueHead = pentry->pNext; + pQueueHead->pPrev = 0; + } + else + { + // Last item left + pQueueTail = + pQueueHead = 0; + } + } + return pentry; +} + +void WaitConditionImpl::QueueFindAndRemove(EventPoolEntry* pentry) +{ + // Do an exhaustive search looking for an entry + EventPoolEntry* p = pQueueHead; + + while(p) + { + // Entry found? Remove. + if (p == pentry) + { + + // Remove the node form the list + // Prev link + if (pentry->pPrev) + pentry->pPrev->pNext = pentry->pNext; + else + pQueueHead = pentry->pNext; + // Next link + if (pentry->pNext) + pentry->pNext->pPrev = pentry->pPrev; + else + pQueueTail = pentry->pPrev; + // Done + return; + } + + // Move to next item + p = p->pNext; + } +} + + +bool WaitConditionImpl::Wait(Mutex *pmutex, unsigned delay) +{ + bool result = 0; + unsigned i; + unsigned lockCount = pmutex->pImpl->LockCount; + EventPoolEntry* pentry; + + // Mutex must have been locked + if (lockCount == 0) + return 0; + + // Add an object to the wait queue + WaitQueueLoc.DoLock(); + QueuePush(pentry = GetNewEvent()); + WaitQueueLoc.Unlock(); + + // Finally, release a mutex or semaphore + if (pmutex->pImpl->Recursive) + { + // Release the recursive mutex N times + pmutex->pImpl->LockCount = 0; + for(i=0; ipImpl->hMutexOrSemaphore); + } + else + { + pmutex->pImpl->LockCount = 0; + ::ReleaseSemaphore(pmutex->pImpl->hMutexOrSemaphore, 1, NULL); + } + + // Note that there is a gap here between mutex.Unlock() and Wait(). However, + // if notify() comes in at this point in the other thread it will set our + // corresponding event so wait will just fall through, as expected. + + // Block and wait on the event + DWORD waitResult = ::WaitForSingleObject(pentry->hEvent, + (delay == OVR_WAIT_INFINITE) ? INFINITE : delay); + /* +repeat_wait: + DWORD waitResult = + + ::MsgWaitForMultipleObjects(1, &pentry->hEvent, FALSE, + (delay == OVR_WAIT_INFINITE) ? INFINITE : delay, + QS_ALLINPUT); + */ + + WaitQueueLoc.DoLock(); + switch(waitResult) + { + case WAIT_ABANDONED: + case WAIT_OBJECT_0: + result = 1; + // Wait was successful, therefore the event entry should already be removed + // So just add entry back to a free list + ReleaseEvent(pentry); + break; + /* + case WAIT_OBJECT_0 + 1: + // Messages in WINDOWS queue + { + MSG msg; + PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE); + WaitQueueLoc.Unlock(); + goto repeat_wait; + } + break; */ + default: + // Timeout, our entry should still be in a queue + QueueFindAndRemove(pentry); + ReleaseEvent(pentry); + } + WaitQueueLoc.Unlock(); + + // Re-aquire the mutex + for(i=0; iDoLock(); + + // Return the result + return result; +} + +// Notify a condition, releasing the least object in a queue +void WaitConditionImpl::Notify() +{ + Lock::Locker lock(&WaitQueueLoc); + + // Pop last entry & signal it + EventPoolEntry* pentry = QueuePop(); + if (pentry) + ::SetEvent(pentry->hEvent); +} + +// Notify a condition, releasing all objects waiting +void WaitConditionImpl::NotifyAll() +{ + Lock::Locker lock(&WaitQueueLoc); + + // Pop and signal all events + // NOTE : There is no need to release the events, it's the waiters job to do so + EventPoolEntry* pentry = QueuePop(); + while (pentry) + { + ::SetEvent(pentry->hEvent); + pentry = QueuePop(); + } +} + + + +// *** Actual implementation of WaitCondition + +WaitCondition::WaitCondition() +{ + pImpl = new WaitConditionImpl; +} +WaitCondition::~WaitCondition() +{ + delete pImpl; +} + +// Wait without a mutex +bool WaitCondition::Wait(Mutex *pmutex, unsigned delay) +{ + return pImpl->Wait(pmutex, delay); +} +// Notification +void WaitCondition::Notify() +{ + pImpl->Notify(); +} +void WaitCondition::NotifyAll() +{ + pImpl->NotifyAll(); +} + + + +//----------------------------------------------------------------------------------- +// ***** Thread Class + +// Per-thread variable +// MA: Don't use TLS for now - portability issues with DLLs, etc. +/* +#if !defined(OVR_CC_MSVC) || (OVR_CC_MSVC < 1300) +__declspec(thread) Thread* pCurrentThread = 0; +#else +#pragma data_seg(".tls$") +__declspec(thread) Thread* pCurrentThread = 0; +#pragma data_seg(".rwdata") +#endif +*/ + +// *** Thread constructors. + +Thread::Thread(size_t stackSize, int processor) +{ + CreateParams params; + params.stackSize = stackSize; + params.processor = processor; + Init(params); +} + +Thread::Thread(Thread::ThreadFn threadFunction, void* userHandle, size_t stackSize, + int processor, Thread::ThreadState initialState) +{ + CreateParams params(threadFunction, userHandle, stackSize, processor, initialState); + Init(params); +} + +Thread::Thread(const CreateParams& params) +{ + Init(params); +} +void Thread::Init(const CreateParams& params) +{ + // Clear the variables + ThreadFlags = 0; + ThreadHandle = 0; + IdValue = 0; + ExitCode = 0; + SuspendCount = 0; + StackSize = params.stackSize; + Processor = params.processor; + Priority = params.priority; + + // Clear Function pointers + ThreadFunction = params.threadFunction; + UserHandle = params.userHandle; + if (params.initialState != NotRunning) + Start(params.initialState); + +} + +Thread::~Thread() +{ + // Thread should not running while object is being destroyed, + // this would indicate ref-counting issue. + //OVR_ASSERT(IsRunning() == 0); + + // Clean up thread. + CleanupSystemThread(); + ThreadHandle = 0; +} + + +// *** Overridable User functions. + +// Default Run implementation +int Thread::Run() +{ + if (!ThreadFunction) + return 0; + + int ret = ThreadFunction(this, UserHandle); + + return ret; +} + +void Thread::OnExit() +{ +} + +// Finishes the thread and releases internal reference to it. +void Thread::FinishAndRelease() +{ + // Note: thread must be US. + ThreadFlags &= (uint32_t)~(OVR_THREAD_STARTED); + ThreadFlags |= OVR_THREAD_FINISHED; + + // Release our reference; this is equivalent to 'delete this' + // from the point of view of our thread. + Release(); +} + + +// *** ThreadList - used to tack all created threads + +class ThreadList : public NewOverrideBase +{ + //------------------------------------------------------------------------ + struct ThreadHashOp + { + size_t operator()(const Thread* ptr) + { + return (((size_t)ptr) >> 6) ^ (size_t)ptr; + } + }; + + HashSet ThreadSet; + Mutex ThreadMutex; + WaitCondition ThreadsEmpty; + // Track the root thread that created us. + ThreadId RootThreadId; + + static ThreadList* volatile pRunningThreads; + + void addThread(Thread *pthread) + { + Mutex::Locker lock(&ThreadMutex); + ThreadSet.Add(pthread); + } + + void removeThread(Thread *pthread) + { + Mutex::Locker lock(&ThreadMutex); + ThreadSet.Remove(pthread); + if (ThreadSet.GetSize() == 0) + ThreadsEmpty.Notify(); + } + + void finishAllThreads() + { + // Only original root thread can call this. + OVR_ASSERT(GetCurrentThreadId() == RootThreadId); + + Mutex::Locker lock(&ThreadMutex); + while (ThreadSet.GetSize() != 0) + ThreadsEmpty.Wait(&ThreadMutex); + } + +public: + + ThreadList() + { + RootThreadId = GetCurrentThreadId(); + } + ~ThreadList() { } + + + static void AddRunningThread(Thread *pthread) + { + // Non-atomic creation ok since only the root thread + if (!pRunningThreads) + { + pRunningThreads = new ThreadList; + OVR_ASSERT(pRunningThreads); + } + pRunningThreads->addThread(pthread); + } + + // NOTE: 'pthread' might be a dead pointer when this is + // called so it should not be accessed; it is only used + // for removal. + static void RemoveRunningThread(Thread *pthread) + { + OVR_ASSERT(pRunningThreads); + pRunningThreads->removeThread(pthread); + } + + static void FinishAllThreads() + { + // This is ok because only root thread can wait for other thread finish. + if (pRunningThreads) + { + pRunningThreads->finishAllThreads(); + delete pRunningThreads; + pRunningThreads = 0; + } + } +}; + +// By default, we have no thread list. +ThreadList* volatile ThreadList::pRunningThreads = 0; + + +// FinishAllThreads - exposed publicly in Thread. +void Thread::FinishAllThreads() +{ + ThreadList::FinishAllThreads(); +} + + +// *** Run override + +int Thread::PRun() +{ + // Suspend us on start, if requested + if (ThreadFlags & OVR_THREAD_START_SUSPENDED) + { + Suspend(); + ThreadFlags &= (uint32_t)~OVR_THREAD_START_SUSPENDED; + } + + // Call the virtual run function + ExitCode = Run(); + + return ExitCode; +} + + + +/* MA: Don't use TLS for now. + +// Static function to return a pointer to the current thread +void Thread::InitCurrentThread(Thread *pthread) +{ + pCurrentThread = pthread; +} + +// Static function to return a pointer to the current thread +Thread* Thread::GetThread() +{ + return pCurrentThread; +} +*/ + + +// *** User overridables + +bool Thread::GetExitFlag() const +{ + return (ThreadFlags & OVR_THREAD_EXIT) != 0; +} + +void Thread::SetExitFlag(bool exitFlag) +{ + // The below is atomic since ThreadFlags is AtomicInt. + if (exitFlag) + ThreadFlags |= OVR_THREAD_EXIT; + else + ThreadFlags &= (uint32_t) ~OVR_THREAD_EXIT; +} + + +// Determines whether the thread was running and is now finished +bool Thread::IsFinished() const +{ + return (ThreadFlags & OVR_THREAD_FINISHED) != 0; +} +// Determines whether the thread is suspended +bool Thread::IsSuspended() const +{ + return SuspendCount > 0; +} +// Returns current thread state +Thread::ThreadState Thread::GetThreadState() const +{ + if (IsSuspended()) + return Suspended; + if (ThreadFlags & OVR_THREAD_STARTED) + return Running; + return NotRunning; +} +// Join thread +bool Thread::Join(int maxWaitMs) const +{ + // If polling, + if (maxWaitMs == 0) + { + // Just return if finished + return IsFinished(); + } + // If waiting forever, + else if (maxWaitMs > 0) + { + // Try waiting once + WaitForSingleObject(ThreadHandle, maxWaitMs); + + // Return if the wait succeeded + return IsFinished(); + } + + // While not finished, + while (!IsFinished()) + { + // Wait for the thread handle to signal + WaitForSingleObject(ThreadHandle, INFINITE); + } + + return true; +} + + +// ***** Thread management +/* static */ +int Thread::GetOSPriority(ThreadPriority p) +{ + switch(p) + { + // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14. + case Thread::CriticalPriority: return THREAD_PRIORITY_TIME_CRITICAL; // 15 + case Thread::HighestPriority: return THREAD_PRIORITY_HIGHEST; // 2 + case Thread::AboveNormalPriority: return THREAD_PRIORITY_ABOVE_NORMAL; // 1 + case Thread::NormalPriority: return THREAD_PRIORITY_NORMAL; // 0 + case Thread::BelowNormalPriority: return THREAD_PRIORITY_BELOW_NORMAL; // -1 + case Thread::LowestPriority: return THREAD_PRIORITY_LOWEST; // -2 + case Thread::IdlePriority: return THREAD_PRIORITY_IDLE; // -15 + } + return THREAD_PRIORITY_NORMAL; +} + +/* static */ +Thread::ThreadPriority Thread::GetOVRPriority(int osPriority) +{ + // If the process is REALTIME_PRIORITY_CLASS then it could have priority values 3 through14 and -3 through -14. + // As a result, it's possible for those cases that an unknown/invalid ThreadPriority enum be returned. However, + // in practice we don't expect to be using such processes. + + // The ThreadPriority types aren't linearly distributed, so we need to check for some values explicitly. + if(osPriority == THREAD_PRIORITY_TIME_CRITICAL) + return Thread::CriticalPriority; + if(osPriority == THREAD_PRIORITY_IDLE) + return Thread::IdlePriority; + return (ThreadPriority)(Thread::NormalPriority - osPriority); +} + +Thread::ThreadPriority Thread::GetPriority() +{ + int osPriority = ::GetThreadPriority(ThreadHandle); + + if(osPriority != THREAD_PRIORITY_ERROR_RETURN) + { + return GetOVRPriority(osPriority); + } + + return NormalPriority; +} + +/* static */ +Thread::ThreadPriority Thread::GetCurrentPriority() +{ + int osPriority = ::GetThreadPriority(::GetCurrentThread()); + + if(osPriority != THREAD_PRIORITY_ERROR_RETURN) + { + return GetOVRPriority(osPriority); + } + + return NormalPriority; +} + +bool Thread::SetPriority(ThreadPriority p) +{ + BOOL ret = ::SetThreadPriority(ThreadHandle, Thread::GetOSPriority(p)); + return (ret != FALSE); +} + +/* static */ +bool Thread::SetCurrentPriority(ThreadPriority p) +{ + BOOL ret = ::SetThreadPriority(::GetCurrentThread(), Thread::GetOSPriority(p)); + return (ret != FALSE); +} + + + +// The actual first function called on thread start +#if defined(OVR_OS_WIN32) +unsigned WINAPI Thread_Win32StartFn(void * phandle) +#else // Other Micorosft OSs... +DWORD WINAPI Thread_Win32StartFn(void *phandle) +#endif +{ + Thread * pthread = (Thread*)phandle; + if (pthread->Processor != -1) + { + DWORD_PTR ret = SetThreadAffinityMask(GetCurrentThread(), (DWORD)pthread->Processor); + if (ret == 0) + OVR_DEBUG_LOG(("Could not set hardware processor for the thread")); + } + BOOL ret = ::SetThreadPriority(GetCurrentThread(), Thread::GetOSPriority(pthread->Priority)); + if (ret == 0) + OVR_DEBUG_LOG(("Could not set thread priority")); + OVR_UNUSED(ret); + + // Ensure that ThreadId is assigned once thread is running, in case + // beginthread hasn't filled it in yet. + pthread->IdValue = (ThreadId)::GetCurrentThreadId(); + + DWORD result = pthread->PRun(); + // Signal the thread as done and release it atomically. + pthread->FinishAndRelease(); + // At this point Thread object might be dead; however we can still pass + // it to RemoveRunningThread since it is only used as a key there. + ThreadList::RemoveRunningThread(pthread); + return (unsigned) result; +} + +bool Thread::Start(ThreadState initialState) +{ + if (initialState == NotRunning) + return 0; + if (GetThreadState() != NotRunning) + { + OVR_DEBUG_LOG(("Thread::Start failed - thread %p already running", this)); + return 0; + } + + // Free old thread handle before creating the new one + CleanupSystemThread(); + + // AddRef to us until the thread is finished. + AddRef(); + ThreadList::AddRunningThread(this); + + ExitCode = 0; + SuspendCount = 0; + ThreadFlags = (initialState == Running) ? 0 : OVR_THREAD_START_SUSPENDED; +#if defined(OVR_OS_WIN32) + ThreadHandle = (HANDLE) _beginthreadex(0, (unsigned)StackSize, + Thread_Win32StartFn, this, 0, (unsigned*)&IdValue); +#else // Other Micorosft OSs... + DWORD TheThreadId; + ThreadHandle = CreateThread(0, (unsigned)StackSize, + Thread_Win32StartFn, this, 0, &TheThreadId); + IdValue = (ThreadId)TheThreadId; +#endif + + // Failed? Fail the function + if (ThreadHandle == 0) + { + ThreadFlags = 0; + Release(); + ThreadList::RemoveRunningThread(this); + return 0; + } + return 1; +} + + +// Suspend the thread until resumed +bool Thread::Suspend() +{ + // Can't suspend a thread that wasn't started + if (!(ThreadFlags & OVR_THREAD_STARTED)) + return 0; + + if (::SuspendThread(ThreadHandle) != 0xFFFFFFFF) + { + SuspendCount++; + return 1; + } + return 0; +} + +// Resumes currently suspended thread +bool Thread::Resume() +{ + // Can't suspend a thread that wasn't started + if (!(ThreadFlags & OVR_THREAD_STARTED)) + return 0; + + // Decrement count, and resume thread if it is 0 + int32_t oldCount = SuspendCount.ExchangeAdd_Acquire(-1); + if (oldCount >= 1) + { + if (oldCount == 1) + { + if (::ResumeThread(ThreadHandle) != 0xFFFFFFFF) + { + return 1; + } + } + else + { + return 1; + } + } + return 0; +} + + +// Quits with an exit code +void Thread::Exit(int exitCode) +{ + // Can only exist the current thread. + // MA: Don't use TLS for now. + //if (GetThread() != this) + // return; + + // Call the virtual OnExit function. + OnExit(); + + // Signal this thread object as done and release it's references. + FinishAndRelease(); + ThreadList::RemoveRunningThread(this); + + // Call the exit function. +#if defined(OVR_OS_WIN32) // _endthreadex doesn't exist on other Microsoft OSs and instead we need to call ExitThread directly. + _endthreadex((unsigned)exitCode); +#else + ExitThread((unsigned)exitCode); +#endif +} + + +void Thread::CleanupSystemThread() +{ + if (ThreadHandle != 0) + { + ::CloseHandle(ThreadHandle); + ThreadHandle = 0; + } +} + +// *** Sleep functions +// static +bool Thread::Sleep(unsigned secs) +{ + ::Sleep(secs*1000); + return 1; +} + +// static +bool Thread::MSleep(unsigned msecs) +{ + ::Sleep(msecs); + return 1; +} + +// static +void Thread::YieldCurrentThread() +{ + YieldProcessor(); +} + +void Thread::SetThreadName( const char* name ) +{ + if(IdValue) + SetThreadName(name, IdValue); + // Else we don't know what thread to name. We can save the name and wait until the thread is created. +} + + +void Thread::SetThreadName(const char* name, ThreadId threadId) +{ + #if !defined(OVR_BUILD_SHIPPING) || defined(OVR_BUILD_PROFILING) + // http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx + #pragma pack(push,8) + struct THREADNAME_INFO { + DWORD dwType; // Must be 0x1000 + LPCSTR szName; // Pointer to name (in user address space) + DWORD dwThreadID; // Thread ID (-1 for caller thread) + DWORD dwFlags; // Reserved for future use; must be zero + }; + #pragma pack(pop) + + THREADNAME_INFO info = { 0x1000, name, (DWORD)threadId, 0 }; + + __try + { + RaiseException( 0x406D1388, 0, sizeof(info)/sizeof(ULONG_PTR), reinterpret_cast(&info)); + } + __except( GetExceptionCode()==0x406D1388 ? EXCEPTION_CONTINUE_EXECUTION : EXCEPTION_EXECUTE_HANDLER ) + { + return; + } + #endif // OVR_BUILD_SHIPPING +} + + +void Thread::SetCurrentThreadName( const char* name ) +{ + SetThreadName(name, (ThreadId)::GetCurrentThreadId()); +} + + +void Thread::GetThreadName(char* name, size_t /*nameCapacity*/, ThreadId /*threadId*/) +{ + // Not possible on Windows. + name[0] = 0; +} + + +void Thread::GetCurrentThreadName(char* name, size_t /*nameCapacity*/) +{ + // Not possible on Windows. + name[0] = 0; +} + + +// static +int Thread::GetCPUCount() +{ + SYSTEM_INFO sysInfo; + + #if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) // GetNativeSystemInfo requires WinXP+ and a corresponding SDK (0x0501) or later. + GetNativeSystemInfo(&sysInfo); + #else + GetSystemInfo(&sysInfo); + #endif + + return (int) sysInfo.dwNumberOfProcessors; +} + +// Returns the unique Id of a thread it is called on, intended for +// comparison purposes. +ThreadId GetCurrentThreadId() +{ + return (ThreadId)::GetCurrentThreadId(); +} + +} // OVR + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Timer.cpp b/LibOVRKernel/Src/Kernel/OVR_Timer.cpp new file mode 100644 index 0000000..5230c14 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Timer.cpp @@ -0,0 +1,460 @@ +/************************************************************************************ + +Filename : OVR_Timer.cpp +Content : Provides static functions for precise timing +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_Timer.h" +#include "OVR_Log.h" + +#if defined(OVR_OS_MS) && !defined(OVR_OS_MS_MOBILE) +#include "OVR_Win32_IncludeWindows.h" +#include +#pragma comment(lib, "winmm.lib") +#elif defined(OVR_OS_ANDROID) +#include +#include +#else +#include +#endif + + +#if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) + typedef NTSTATUS (NTAPI* NtQueryTimerResolutionType)(PULONG MaximumTime, PULONG MinimumTime, PULONG CurrentTime); + NtQueryTimerResolutionType pNtQueryTimerResolution; +#endif + + + +#if defined(OVR_OS_MS) && !defined(OVR_OS_WIN32) // Non-desktop Microsoft platforms... + +// Add this alias here because we're not going to include OVR_CAPI.cpp +extern "C" { + double ovr_GetTimeInSeconds() + { + return Timer::GetSeconds(); + } +} + +#endif + + + + +namespace OVR { + +// For recorded data playback +bool Timer::useFakeSeconds = false; +double Timer::FakeSeconds = 0; + + + + +//------------------------------------------------------------------------ +// *** Android Specific Timer + +#if defined(OVR_OS_ANDROID) // To consider: This implementation can also work on most Linux distributions + +//------------------------------------------------------------------------ +// *** Timer - Platform Independent functions + +// Returns global high-resolution application timer in seconds. +double Timer::GetSeconds() +{ + if(useFakeSeconds) + return FakeSeconds; + + // Choreographer vsync timestamp is based on. + struct timespec tp; + const int status = clock_gettime(CLOCK_MONOTONIC, &tp); + +#ifdef OVR_BUILD_DEBUG + if (status != 0) + { + OVR_DEBUG_LOG(("clock_gettime status=%i", status )); + } +#else + OVR_UNUSED(status); +#endif + + return (double)tp.tv_sec; +} + + + +uint64_t Timer::GetTicksNanos() +{ + if (useFakeSeconds) + return (uint64_t) (FakeSeconds * NanosPerSecond); + + // Choreographer vsync timestamp is based on. + struct timespec tp; + const int status = clock_gettime(CLOCK_MONOTONIC, &tp); + +#ifdef OVR_BUILD_DEBUG + if (status != 0) + { + OVR_DEBUG_LOG(("clock_gettime status=%i", status )); + } +#else + OVR_UNUSED(status); +#endif + + const uint64_t result = (uint64_t)tp.tv_sec * (uint64_t)(1000 * 1000 * 1000) + uint64_t(tp.tv_nsec); + return result; +} + + +void Timer::initializeTimerSystem() +{ + // Empty for this platform. +} + +void Timer::shutdownTimerSystem() +{ + // Empty for this platform. +} + + + + + +//------------------------------------------------------------------------ +// *** Win32 Specific Timer + +#elif defined (OVR_OS_MS) + + +// This helper class implements high-resolution wrapper that combines timeGetTime() output +// with QueryPerformanceCounter. timeGetTime() is lower precision but drives the high bits, +// as it's tied to the system clock. +struct PerformanceTimer +{ + PerformanceTimer() + : UsingVistaOrLater(false), + TimeCS(), + OldMMTimeMs(0), + MMTimeWrapCounter(0), + PerfFrequency(0), + PerfFrequencyInverse(0), + PerfFrequencyInverseNanos(0), + PerfMinusTicksDeltaNanos(0), + LastResultNanos(0) + { } + + enum { + MMTimerResolutionNanos = 1000000 + }; + + void Initialize(); + void Shutdown(); + + uint64_t GetTimeSeconds(); + double GetTimeSecondsDouble(); + uint64_t GetTimeNanos(); + + UINT64 getFrequency() + { + if (PerfFrequency == 0) + { + LARGE_INTEGER freq; + QueryPerformanceFrequency(&freq); + PerfFrequency = freq.QuadPart; + PerfFrequencyInverse = 1.0 / (double)PerfFrequency; + PerfFrequencyInverseNanos = 1000000000.0 / (double)PerfFrequency; + } + return PerfFrequency; + } + + double GetFrequencyInverse() + { + OVR_ASSERT(PerfFrequencyInverse != 0.0); // Assert that the frequency has been initialized. + return PerfFrequencyInverse; + } + + bool UsingVistaOrLater; + + CRITICAL_SECTION TimeCS; + // timeGetTime() support with wrap. + uint32_t OldMMTimeMs; + uint32_t MMTimeWrapCounter; + // Cached performance frequency result. + uint64_t PerfFrequency; // cycles per second, typically a large value like 3000000, but usually not the same as the CPU clock rate. + double PerfFrequencyInverse; // seconds per cycle (will be a small fractional value). + double PerfFrequencyInverseNanos; // nanoseconds per cycle. + + // Computed as (perfCounterNanos - ticksCounterNanos) initially, + // and used to adjust timing. + uint64_t PerfMinusTicksDeltaNanos; + // Last returned value in nanoseconds, to ensure we don't back-step in time. + uint64_t LastResultNanos; +}; + +static PerformanceTimer Win32_PerfTimer; + + +void PerformanceTimer::Initialize() +{ + #if defined(OVR_OS_WIN32) // Desktop Windows only + // The following has the effect of setting the NT timer resolution (NtSetTimerResolution) to 1 millisecond. + MMRESULT mmr = timeBeginPeriod(1); + OVR_ASSERT(TIMERR_NOERROR == mmr); + OVR_UNUSED(mmr); + #endif + + InitializeCriticalSection(&TimeCS); + MMTimeWrapCounter = 0; + getFrequency(); + + #if defined(OVR_OS_WIN32) // Desktop Windows only + // Set Vista flag. On Vista, we can just use QPC() without all the extra work + OSVERSIONINFOEX ver; + ZeroMemory(&ver, sizeof(OSVERSIONINFOEX)); + ver.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + ver.dwMajorVersion = 6; // Vista+ + + DWORDLONG condMask = 0; + VER_SET_CONDITION(condMask, VER_MAJORVERSION, VER_GREATER_EQUAL); + + // VerifyVersionInfo returns true if the OS meets the conditions set above + UsingVistaOrLater = VerifyVersionInfo(&ver, VER_MAJORVERSION, condMask) != 0; + #else + UsingVistaOrLater = true; + #endif + + OVR_DEBUG_LOG(("PerformanceTimer UsingVistaOrLater = %d", (int)UsingVistaOrLater)); + + #if defined(OVR_BUILD_DEBUG) && defined(OVR_OS_WIN32) + HMODULE hNtDll = LoadLibraryW(L"NtDll.dll"); + if (hNtDll) + { + pNtQueryTimerResolution = (NtQueryTimerResolutionType)GetProcAddress(hNtDll, "NtQueryTimerResolution"); + //pNtSetTimerResolution = (NtSetTimerResolutionType)GetProcAddress(hNtDll, "NtSetTimerResolution"); + + if(pNtQueryTimerResolution) + { + ULONG MinimumResolution; // in 100-ns units + ULONG MaximumResolution; + ULONG ActualResolution; + pNtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &ActualResolution); + OVR_DEBUG_LOG(("NtQueryTimerResolution = Min %ld us, Max %ld us, Current %ld us", MinimumResolution / 10, MaximumResolution / 10, ActualResolution / 10)); + } + + FreeLibrary(hNtDll); + } + #endif +} + +void PerformanceTimer::Shutdown() +{ + DeleteCriticalSection(&TimeCS); + + #if defined(OVR_OS_WIN32) // Desktop Windows only + MMRESULT mmr = timeEndPeriod(1); + OVR_ASSERT(TIMERR_NOERROR == mmr); + OVR_UNUSED(mmr); + #endif +} + + +uint64_t PerformanceTimer::GetTimeSeconds() +{ + if (UsingVistaOrLater) + { + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + OVR_ASSERT(PerfFrequencyInverse != 0); // Initialize should have been called earlier. + return (uint64_t)(li.QuadPart * PerfFrequencyInverse); + } + + return (uint64_t)(GetTimeNanos() * .0000000001); +} + + +double PerformanceTimer::GetTimeSecondsDouble() +{ + if (UsingVistaOrLater) + { + LARGE_INTEGER li; + QueryPerformanceCounter(&li); + OVR_ASSERT(PerfFrequencyInverse != 0); + return (li.QuadPart * PerfFrequencyInverse); + } + + return (GetTimeNanos() * .0000000001); +} + + +uint64_t PerformanceTimer::GetTimeNanos() +{ + uint64_t resultNanos; + LARGE_INTEGER li; + + OVR_ASSERT(PerfFrequencyInverseNanos != 0); // Initialize should have been called earlier. + + if (UsingVistaOrLater) // Includes non-desktop platforms + { + // Then we can use QPC() directly without all that extra work + QueryPerformanceCounter(&li); + resultNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); + } + else + { + // On Win32 QueryPerformanceFrequency is unreliable due to SMP and + // performance levels, so use this logic to detect wrapping and track + // high bits. + ::EnterCriticalSection(&TimeCS); + + // Get raw value and perf counter "At the same time". + QueryPerformanceCounter(&li); + + DWORD mmTimeMs = timeGetTime(); + if (OldMMTimeMs > mmTimeMs) + MMTimeWrapCounter++; + OldMMTimeMs = mmTimeMs; + + // Normalize to nanoseconds. + uint64_t perfCounterNanos = (uint64_t)(li.QuadPart * PerfFrequencyInverseNanos); + uint64_t mmCounterNanos = ((uint64_t(MMTimeWrapCounter) << 32) | mmTimeMs) * 1000000; + if (PerfMinusTicksDeltaNanos == 0) + PerfMinusTicksDeltaNanos = perfCounterNanos - mmCounterNanos; + + // Compute result before snapping. + // + // On first call, this evaluates to: + // resultNanos = mmCounterNanos. + // Next call, assuming no wrap: + // resultNanos = prev_mmCounterNanos + (perfCounterNanos - prev_perfCounterNanos). + // After wrap, this would be: + // resultNanos = snapped(prev_mmCounterNanos +/- 1ms) + (perfCounterNanos - prev_perfCounterNanos). + // + resultNanos = perfCounterNanos - PerfMinusTicksDeltaNanos; + + // Snap the range so that resultNanos never moves further apart then its target resolution. + // It's better to allow more slack on the high side as timeGetTime() may be updated at sporadically + // larger then 1 ms intervals even when 1 ms resolution is requested. + if (resultNanos > (mmCounterNanos + MMTimerResolutionNanos*2)) + { + resultNanos = mmCounterNanos + MMTimerResolutionNanos*2; + if (resultNanos < LastResultNanos) + resultNanos = LastResultNanos; + PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; + } + else if (resultNanos < (mmCounterNanos - MMTimerResolutionNanos)) + { + resultNanos = mmCounterNanos - MMTimerResolutionNanos; + if (resultNanos < LastResultNanos) + resultNanos = LastResultNanos; + PerfMinusTicksDeltaNanos = perfCounterNanos - resultNanos; + } + + LastResultNanos = resultNanos; + ::LeaveCriticalSection(&TimeCS); + } + + //Tom's addition, to keep precision + //static uint64_t initial_time = 0; + //if (!initial_time) initial_time = resultNanos; + //resultNanos -= initial_time; + // FIXME: This cannot be used for cross-process timestamps + + return resultNanos; +} + + +//------------------------------------------------------------------------ +// *** Timer - Platform Independent functions + +// Returns global high-resolution application timer in seconds. +double Timer::GetSeconds() +{ + if(useFakeSeconds) + return FakeSeconds; + + return Win32_PerfTimer.GetTimeSecondsDouble(); +} + + + +// Delegate to PerformanceTimer. +uint64_t Timer::GetTicksNanos() +{ + if (useFakeSeconds) + return (uint64_t) (FakeSeconds * NanosPerSecond); + + return Win32_PerfTimer.GetTimeNanos(); +} + +// Windows version also provides the performance frequency inverse. +double Timer::GetPerfFrequencyInverse() +{ + return Win32_PerfTimer.GetFrequencyInverse(); +} + +void Timer::initializeTimerSystem() +{ + Win32_PerfTimer.Initialize(); +} +void Timer::shutdownTimerSystem() +{ + Win32_PerfTimer.Shutdown(); +} + + +#else // C++11 standard compliant platforms + +double Timer::GetSeconds() +{ + if(useFakeSeconds) + return FakeSeconds; + + using FpSeconds = std::chrono::duration; + + auto now = std::chrono::high_resolution_clock::now(); + return FpSeconds(now.time_since_epoch()).count(); +} + + +uint64_t Timer::GetTicksNanos() +{ + if (useFakeSeconds) + return (uint64_t) (FakeSeconds * NanosPerSecond); + + using Uint64Nanoseconds = std::chrono::duration; + + auto now = std::chrono::high_resolution_clock::now(); + return Uint64Nanoseconds(now.time_since_epoch()).count(); +} + +void Timer::initializeTimerSystem() +{ +} + +void Timer::shutdownTimerSystem() +{ +} + +#endif // OS-specific + +} // OVR + diff --git a/LibOVRKernel/Src/Kernel/OVR_Timer.h b/LibOVRKernel/Src/Kernel/OVR_Timer.h new file mode 100644 index 0000000..b6717ba --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Timer.h @@ -0,0 +1,98 @@ +/************************************************************************************ + +PublicHeader: OVR +Filename : OVR_Timer.h +Content : Provides static functions for precise timing +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Timer_h +#define OVR_Timer_h + +#include "OVR_Types.h" + +namespace OVR { + +//----------------------------------------------------------------------------------- +// ***** Timer + +// Timer class defines a family of static functions used for application +// timing and profiling. + +class Timer +{ +public: + enum { + MsPerSecond = 1000, // Milliseconds in one second. + MksPerSecond = 1000 * 1000, // Microseconds in one second. + NanosPerSecond = 1000 * 1000 * 1000, // Nanoseconds in one second. + }; + + // ***** Timing APIs for Application + + // These APIs should be used to guide animation and other program functions + // that require precision. + + // Returns global high-resolution application timer in seconds. + static double OVR_STDCALL GetSeconds(); + + // Returns time in Nanoseconds, using highest possible system resolution. + static uint64_t OVR_STDCALL GetTicksNanos(); + +#ifdef OVR_OS_MS + static double OVR_STDCALL GetPerfFrequencyInverse(); +#endif + + // Kept for compatibility. + // Returns ticks in milliseconds, as a 32-bit number. May wrap around every 49.2 days. + // Use either time difference of two values of GetTicks to avoid wrap-around. + static uint32_t OVR_STDCALL GetTicksMs() + { return uint32_t(GetTicksNanos() / 1000000); } + + // for recorded data playback + static void SetFakeSeconds(double fakeSeconds, bool enable = true) + { + FakeSeconds = fakeSeconds; + useFakeSeconds = enable; + } + +private: + friend class System; + // System called during program startup/shutdown. + static void initializeTimerSystem(); + static void shutdownTimerSystem(); + + // for recorded data playback + static double FakeSeconds; + static bool useFakeSeconds; + + #if defined(OVR_OS_ANDROID) + // Android-specific data + #elif defined (OVR_OS_MS) + // Microsoft-specific data + #endif +}; + + +} // OVR::Timer + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Types.h b/LibOVRKernel/Src/Kernel/OVR_Types.h new file mode 100644 index 0000000..967389d --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Types.h @@ -0,0 +1,1055 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_Types.h +Content : Standard library defines and simple types +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Types_h +#define OVR_Types_h + +#include "OVR_Compiler.h" + + +// Unsupported compiler configurations +#if _MSC_VER == 0x1600 +# if _MSC_FULL_VER < 160040219 +# error "Oculus does not support VS2010 without SP1 installed: It will crash in Release mode" +# endif +#endif + + +//----------------------------------------------------------------------------------- +// ****** Operating system identification +// +// Try to use the most generic version of these defines as possible in order to achieve +// the simplest portable code. For example, instead of using #if (defined(OVR_OS_IPHONE) || defined(OVR_OS_MAC)), +// consider using #if defined(OVR_OS_APPLE). +// +// Type definitions exist for the following operating systems: (OVR_OS_x) +// +// WIN32 - Win32 and Win64 (Windows XP and later) Does not include Microsoft phone and console platforms, despite that Microsoft's _WIN32 may be defined by the compiler for them. +// WIN64 - Win64 (Windows XP and later) +// MAC - Mac OS X (may be defined in addition to BSD) +// LINUX - Linux +// BSD - BSD Unix +// ANDROID - Android (may be defined in addition to LINUX) +// IPHONE - iPhone +// MS_MOBILE - Microsoft mobile OS. +// +// Meta platforms +// MS - Any OS by Microsoft (e.g. Win32, Win64, phone, console) +// APPLE - Any OS by Apple (e.g. iOS, OS X) +// UNIX - Linux, BSD, Mac OS X. +// MOBILE - iOS, Android, Microsoft phone +// CONSOLE - Console platforms. +// + +#if (defined(__APPLE__) && (defined(__GNUC__) ||\ + defined(__xlC__) || defined(__xlc__))) || defined(__MACOS__) +# if (defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) || defined(__IPHONE_OS_VERSION_MIN_REQUIRED)) +# if !defined(OVR_OS_IPHONE) +# define OVR_OS_IPHONE +# endif +# else +# if !defined(OVR_OS_MAC) +# define OVR_OS_MAC +# endif +# if !defined(OVR_OS_DARWIN) +# define OVR_OS_DARWIN +# endif +# if !defined(OVR_OS_BSD) +# define OVR_OS_BSD +# endif +# endif +#elif (defined(WIN64) || defined(_WIN64) || defined(__WIN64__)) +# if !defined(OVR_OS_WIN64) +# define OVR_OS_WIN64 +# endif +# if !defined(OVR_OS_WIN32) +# define OVR_OS_WIN32 //Can be a 32 bit Windows build or a WOW64 support for Win32. In this case WOW64 support for Win32. +# endif +#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)) +# if !defined(OVR_OS_WIN32) +# define OVR_OS_WIN32 //Can be a 32 bit Windows build or a WOW64 support for Win32. In this case WOW64 support for Win32. +# endif +#elif defined(ANDROID) || defined(__ANDROID__) +# if !defined(OVR_OS_ANDROID) +# define OVR_OS_ANDROID +# endif +# if !defined(OVR_OS_LINUX) +# define OVR_OS_LINUX +# endif +#elif defined(__linux__) || defined(__linux) +# if !defined(OVR_OS_LINUX) +# define OVR_OS_LINUX +# endif +#elif defined(_BSD_) || defined(__FreeBSD__) +# if !defined(OVR_OS_BSD) +# define OVR_OS_BSD +# endif +#else +# if !defined(OVR_OS_OTHER) +# define OVR_OS_OTHER +# endif +#endif + +#if !defined(OVR_OS_MS_MOBILE) +# if (defined(_M_ARM) || defined(_M_IX86) || defined(_M_AMD64)) && !defined(OVR_OS_WIN32) && !defined(OVR_OS_CONSOLE) +# define OVR_OS_MS_MOBILE +# endif +#endif + +#if !defined(OVR_OS_MS) +# if defined(OVR_OS_WIN32) || defined(OVR_OS_WIN64) || defined(OVR_OS_MS_MOBILE) +# define OVR_OS_MS +# endif +#endif + +#if !defined(OVR_OS_APPLE) +# if defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) +# define OVR_OS_APPLE +# endif +#endif + +#if !defined(OVR_OS_UNIX) +# if defined(OVR_OS_ANDROID) || defined(OVR_OS_BSD) || defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) +# define OVR_OS_UNIX +# endif +#endif + +#if !defined(OVR_OS_MOBILE) +# if defined(OVR_OS_ANDROID) || defined(OVR_OS_IPHONE) || defined(OVR_OS_MS_MOBILE) +# define OVR_OS_MOBILE +# endif +#endif + + + + +//----------------------------------------------------------------------------------- +// ***** CPU Architecture +// +// The following CPUs are defined: (OVR_CPU_x) +// +// X86 - x86 (IA-32) +// X86_64 - x86_64 (amd64) +// PPC - PowerPC +// PPC64 - PowerPC64 +// MIPS - MIPS +// OTHER - CPU for which no special support is present or needed + + +#if defined(__x86_64__) || defined(WIN64) || defined(_WIN64) || defined(__WIN64__) || defined(_M_AMD64) +# define OVR_CPU_X86_64 +# define OVR_64BIT_POINTERS +#elif defined(__i386__) || defined(OVR_OS_WIN32) +# define OVR_CPU_X86 +#elif defined(__powerpc64__) +# define OVR_CPU_PPC64 +#elif defined(__ppc__) +# define OVR_CPU_PPC +#elif defined(__mips__) || defined(__MIPSEL__) +# define OVR_CPU_MIPS +#elif defined(__arm__) +# define OVR_CPU_ARM +#else +# define OVR_CPU_OTHER +#endif + +//----------------------------------------------------------------------------------- +// ***** Co-Processor Architecture +// +// The following co-processors are defined: (OVR_CPU_x) +// +// SSE - Available on all modern x86 processors. +// Altivec - Available on all modern ppc processors. +// Neon - Available on some armv7+ processors. + +#if defined(__SSE__) || defined(_M_IX86) || defined(_M_AMD64) // _M_IX86 and _M_AMD64 are Microsoft identifiers for Intel-based platforms. +# define OVR_CPU_SSE +#endif // __SSE__ + +#if defined( __ALTIVEC__ ) +# define OVR_CPU_ALTIVEC +#endif // __ALTIVEC__ + +#if defined(__ARM_NEON__) +# define OVR_CPU_ARM_NEON +#endif // __ARM_NEON__ + + +//----------------------------------------------------------------------------------- +// ***** Compiler Warnings + +// Disable MSVC warnings +#if defined(OVR_CC_MSVC) +# pragma warning(disable : 4127) // Inconsistent dll linkage +# pragma warning(disable : 4530) // Exception handling +# if (OVR_CC_MSVC<1300) +# pragma warning(disable : 4514) // Unreferenced inline function has been removed +# pragma warning(disable : 4710) // Function not inlined +# pragma warning(disable : 4714) // _force_inline not inlined +# pragma warning(disable : 4786) // Debug variable name longer than 255 chars +# endif // (OVR_CC_MSVC<1300) +#endif // (OVR_CC_MSVC) + + + +// *** Linux Unicode - must come before Standard Includes + +#ifdef OVR_OS_LINUX +// Use glibc unicode functions on linux. +# ifndef _GNU_SOURCE +# define _GNU_SOURCE +# endif +#endif + +//----------------------------------------------------------------------------------- +// ***** Standard Includes +// +#include +#include +#include + + +// MSVC Based Memory Leak checking - for now +#if defined(OVR_CC_MSVC) && defined(OVR_BUILD_DEBUG) +# define _CRTDBG_MAP_ALLOC +# include +# include +#endif + + +//----------------------------------------------------------------------------------- +// ***** int8_t, int16_t, etc. + +#if defined(OVR_CC_MSVC) && (OVR_CC_VER <= 1500) // VS2008 and earlier + typedef signed char int8_t; + typedef unsigned char uint8_t; + typedef signed short int16_t; + typedef unsigned short uint16_t; + typedef signed int int32_t; + typedef unsigned int uint32_t; + typedef signed __int64 int64_t; + typedef unsigned __int64 uint64_t; +#else + #include +#endif + + +//----------------------------------------------------------------------------------- +// ***** Type definitions for Common Systems + +namespace OVR { + +typedef char Char; + +// Pointer-sized integer +typedef size_t UPInt; +typedef ptrdiff_t SPInt; + + +#if defined(OVR_OS_MS) + +typedef char SByte; // 8 bit Integer (Byte) +typedef unsigned char UByte; +typedef short SInt16; // 16 bit Integer (Word) +typedef unsigned short UInt16; +typedef long SInt32; // 32 bit Integer +typedef unsigned long UInt32; +typedef __int64 SInt64; // 64 bit Integer (QWord) +typedef unsigned __int64 UInt64; + + +#elif defined(OVR_OS_MAC) || defined(OVR_OS_IPHONE) || defined(OVR_CC_GNU) + +typedef int SByte __attribute__((__mode__ (__QI__))); +typedef unsigned int UByte __attribute__((__mode__ (__QI__))); +typedef int SInt16 __attribute__((__mode__ (__HI__))); +typedef unsigned int UInt16 __attribute__((__mode__ (__HI__))); +typedef int SInt32 __attribute__((__mode__ (__SI__))); +typedef unsigned int UInt32 __attribute__((__mode__ (__SI__))); +typedef int SInt64 __attribute__((__mode__ (__DI__))); +typedef unsigned int UInt64 __attribute__((__mode__ (__DI__))); + +#else + +#include +typedef int8_t SByte; +typedef uint8_t UByte; +typedef int16_t SInt16; +typedef uint16_t UInt16; +typedef int32_t SInt32; +typedef uint32_t UInt32; +typedef int64_t SInt64; +typedef uint64_t UInt64; + +#endif + + +//osx PID is a signed int32 (already defined to pid_t in OSX framework) +//linux PID is a signed int32 (already defined) +//win32 PID is an unsigned int64 +#ifdef OVR_OS_WIN32 +//process ID representation +typedef unsigned long pid_t; +#endif + +struct OVR_GUID +{ + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +}; + + + +} // OVR + + + +//----------------------------------------------------------------------------------- +// ****** Standard C/C++ Library +// +// Identifies which standard library is currently being used. +// +// LIBSTDCPP - GNU libstdc++, used by GCC. +// LIBCPP - LLVM libc++, typically used by clang and GCC. +// DINKUMWARE - Used by Microsoft and various non-Microsoft compilers (e.g. Sony clang). + +#if !defined(OVR_STDLIB_LIBSTDCPP) + #if defined(__GLIBCXX__) + #define OVR_STDLIB_LIBSTDCPP 1 + #endif +#endif + +#if !defined(OVR_STDLIB_LIBCPP) + #if defined(__clang__) + #if defined(__cplusplus) && __has_include(<__config>) + #define OVR_STDLIB_LIBCPP 1 + #endif + #endif +#endif + +#if !defined(OVR_STDLIB_DINKUMWARE) + #if defined(_YVALS) // Dinkumware globally #defines _YVALS from the #includes above. + #define OVR_STDLIB_DINKUMWARE 1 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** Macro Definitions +// +// We define the following: +// +// OVR_BYTE_ORDER - Defined to either OVR_LITTLE_ENDIAN or OVR_BIG_ENDIAN +// OVR_FORCE_INLINE - Forces inline expansion of function +// OVR_ASM - Assembly language prefix +// OVR_STR - Prefixes string with L"" if building unicode +// +// OVR_STDCALL - Use stdcall calling convention (Pascal arg order) +// OVR_CDECL - Use cdecl calling convention (C argument order) +// OVR_FASTCALL - Use fastcall calling convention (registers) +// + +// Byte order constants, OVR_BYTE_ORDER is defined to be one of these. +#define OVR_LITTLE_ENDIAN 1 +#define OVR_BIG_ENDIAN 2 + + +#if defined(OVR_OS_MS) + + // ***** Windows and non-desktop platforms + + // Byte order + #define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN + + // Calling convention - goes after function return type but before function name + #ifdef __cplusplus_cli + # define OVR_FASTCALL __stdcall + #else + # define OVR_FASTCALL __fastcall + #endif + + #define OVR_STDCALL __stdcall + #define OVR_CDECL __cdecl + + + // Assembly macros + #if defined(OVR_CC_MSVC) + # define OVR_ASM _asm + #else + # define OVR_ASM asm + #endif // (OVR_CC_MSVC) + + #ifdef UNICODE + # define OVR_STR(str) L##str + #else + # define OVR_STR(str) str + #endif // UNICODE + +#else + + // **** Standard systems + + #if (defined(BYTE_ORDER) && (BYTE_ORDER == BIG_ENDIAN))|| \ + (defined(_BYTE_ORDER) && (_BYTE_ORDER == _BIG_ENDIAN)) + # define OVR_BYTE_ORDER OVR_BIG_ENDIAN + #elif (defined(__ARMEB__) || defined(OVR_CPU_PPC) || defined(OVR_CPU_PPC64)) + # define OVR_BYTE_ORDER OVR_BIG_ENDIAN + #else + # define OVR_BYTE_ORDER OVR_LITTLE_ENDIAN + #endif + + // Assembly macros + #define OVR_ASM __asm__ + #define OVR_ASM_PROC(procname) OVR_ASM + #define OVR_ASM_END OVR_ASM + + // Calling convention - goes after function return type but before function name + #define OVR_FASTCALL + #define OVR_STDCALL + #define OVR_CDECL + +#endif // defined(OVR_OS_WIN32) + + +//----------------------------------------------------------------------------------- +// ***** OVR_PTR_SIZE +// +// Specifies the byte size of pointers (same as sizeof void*). + +#if !defined(OVR_PTR_SIZE) + #if defined(__WORDSIZE) + #define OVR_PTR_SIZE ((__WORDSIZE) / 8) + #elif defined(_WIN64) || defined(__LP64__) || defined(_LP64) || defined(_M_IA64) || defined(__ia64__) || defined(__arch64__) || defined(__64BIT__) || defined(__Ptr_Is_64) + #define OVR_PTR_SIZE 8 + #elif defined(__CC_ARM) && (__sizeof_ptr == 8) + #define OVR_PTR_SIZE 8 + #else + #define OVR_PTR_SIZE 4 + #endif +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_WORD_SIZE +// +// Specifies the byte size of a machine word/register. Not necessarily the same as +// the size of pointers, but usually >= the size of pointers. + +#if !defined(OVR_WORD_SIZE) + #define OVR_WORD_SIZE OVR_PTR_SIZE // For our currently supported platforms these are equal. +#endif + + +// ------------------------------------------------------------------------ +// ***** OVR_FORCE_INLINE +// +// Force inline substitute - goes before function declaration +// Example usage: +// OVR_FORCE_INLINE void Test(); + +#if !defined(OVR_FORCE_INLINE) + #if defined(OVR_CC_MSVC) + #define OVR_FORCE_INLINE __forceinline + #elif defined(OVR_CC_GNU) + #define OVR_FORCE_INLINE __attribute__((always_inline)) inline + #else + #define OVR_FORCE_INLINE inline + #endif // OVR_CC_MSVC +#endif + + +// ------------------------------------------------------------------------ +// ***** OVR_NO_INLINE +// +// Cannot be used with inline or OVR_FORCE_INLINE. +// Example usage: +// OVR_NO_INLINE void Test(); + +#if !defined(OVR_NO_INLINE) + #if defined(OVR_CC_MSVC) && (_MSC_VER >= 1500) // VS2008+ + #define OVR_NO_INLINE __declspec(noinline) + #elif !defined(OVR_CC_MSVC) + #define OVR_NO_INLINE __attribute__((noinline)) + #endif +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_STRINGIZE +// +// Converts a preprocessor symbol to a string. +// +// Example usage: +// printf("Line: %s", OVR_STRINGIZE(__LINE__)); +// +#if !defined(OVR_STRINGIZE) + #define OVR_STRINGIZEIMPL(x) #x + #define OVR_STRINGIZE(x) OVR_STRINGIZEIMPL(x) +#endif + + +// ----------------------------------------------------------------------------------- +// ***** OVR_JOIN +// +// Joins two preprocessing symbols together. Supports the case when either or the +// the symbols are macros themselves. +// +// Example usage: +// char OVR_JOIN(unique_, __LINE__); // Results in (e.g.) char unique_123; +// +#if !defined(OVR_JOIN) + #define OVR_JOIN(a, b) OVR_JOIN1(a, b) + #define OVR_JOIN1(a, b) OVR_JOIN2(a, b) + #define OVR_JOIN2(a, b) a##b +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_OFFSETOF +// +// Portable implementation of offsetof for structs and classes. offsetof and GCC's +// __builtin_offsetof work only with POD types (standard-layout types under C++11), +// despite that it can safely work with a number of types that aren't POD. This +// version works with more types without generating compiler warnings or errors. +// Returns the offset as a size_t, as per offsetof. +// +// Example usage: +// struct Test{ int i; float f; }; +// size_t fPos = OVR_OFFSETOF(Test, f); + +#if defined(OVR_CC_GNU) + #define OVR_OFFSETOF(class_, member_) ((size_t)(((uintptr_t)&reinterpret_cast((((class_*)65536)->member_))) - 65536)) +#else + #define OVR_OFFSETOF(class_, member_) offsetof(class_, member_) +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_SIZEOF_MEMBER +// +// Implements a portable way to determine the size of struct or class data member. +// C++11 allows this directly via sizeof (see OVR_CPP_NO_EXTENDED_SIZEOF), and this +// macro exists to handle pre-C++11 compilers. +// Returns the offset as a size_t, as per sizeof. +// +// Example usage: +// struct Test{ int i; float f; }; +// size_t fSize = OVR_SIZEOF_MEMBER(Test, f); +// +#if defined(OVR_CPP_NO_EXTENDED_SIZEOF) + #define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(((class_*)0)->member_)) +#else + #define OVR_SIZEOF_MEMBER(class_, member_) (sizeof(class_::member_)) +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_DEBUG_BREAK, OVR_DEBUG_CODE, +// OVR_ASSERT, OVR_ASSERT_M, OVR_ASSERT_AND_UNUSED +// +// Macros have effect only in debug builds. +// +// Example OVR_DEBUG_BREAK usage (note the lack of parentheses): +// #define MY_ASSERT(expression) do { if (!(expression)) { OVR_DEBUG_BREAK; } } while(0) +// +// Example OVR_DEBUG_CODE usage: +// OVR_DEBUG_CODE(printf("debug test\n");) +// or +// OVR_DEBUG_CODE(printf("debug test\n")); +// +// Example OVR_ASSERT usage: +// OVR_ASSERT(count < 100); +// OVR_ASSERT_M(count < 100, "count is too high"); +// +#if defined(OVR_BUILD_DEBUG) + // Causes a debugger breakpoint in debug builds. Has no effect in release builds. + // Microsoft Win32 specific debugging support + #if defined(OVR_CC_MSVC) + // The __debugbreak() intrinsic works for the MSVC debugger, but when the debugger + // is not attached we want our VectoredExceptionHandler to catch assertions, and + // VEH does not trap "int 3" breakpoints. + #define OVR_DEBUG_BREAK __debugbreak() + #elif defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) + #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) + #define OVR_DEBUG_BREAK do { OVR_ASM("int $3\n\t"); } while(0) + #else + #define OVR_DEBUG_BREAK __builtin_trap() + #endif + #else + #define OVR_DEBUG_BREAK do { *((int *) 0) = 1; } while(0) + #endif + + // The expression is defined only in debug builds. It is defined away in release builds. + #define OVR_DEBUG_CODE(c) c + + // In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, + // if true then no action. Has no effect in release builds. + #if defined(__clang_analyzer__) // During static analysis, make it so the analyzer thinks that failed asserts result in program exit. Reduced false positives. + #include + #define OVR_FAIL_M(message) do { OVR_DEBUG_BREAK; exit(0); } while(0) + #define OVR_FAIL() do { OVR_DEBUG_BREAK; exit(0); } while(0) + #define OVR_ASSERT_M(p, message) do { if (!(p)) { OVR_DEBUG_BREAK; exit(0); } } while(0) + #define OVR_ASSERT(p) do { if (!(p)) { OVR_DEBUG_BREAK; exit(0); } } while(0) + #else + #define OVR_FAIL_M(message) \ + { \ + intptr_t ovrAssertUserParam; \ + OVR::OVRAssertionHandler ovrAssertUserHandler = OVR::GetAssertionHandler(&ovrAssertUserParam); \ + \ + if (ovrAssertUserHandler && !OVR::OVRIsDebuggerPresent()) \ + { \ + ovrAssertUserHandler(ovrAssertUserParam, "Assertion failure", message); \ + } \ + else \ + { \ + OVR_DEBUG_BREAK; \ + } \ + } \ + + #define OVR_FAIL() \ + OVR_FAIL_M("Assertion failure") + + // void OVR_ASSERT_M(bool expression, const char message); + // Note: The expression below is expanded into all usage of this assertion macro. + // We should try to minimize the size of the expanded code to the extent possible. + #define OVR_ASSERT_M(p, message) \ + do { \ + if (!(p)) \ + OVR_FAIL_M(message) \ + } while(0) + + // void OVR_ASSERT(bool expression); + #define OVR_ASSERT(p) OVR_ASSERT_M((p), (#p)) + #endif + + // Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. + // Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); + #define OVR_ASSERT_AND_UNUSED(expression, value) OVR_ASSERT(expression); OVR_UNUSED(value) + +#else + + // The expression is defined only in debug builds. It is defined away in release builds. + #define OVR_DEBUG_CODE(c) + + // Causes a debugger breakpoint in debug builds. Has no effect in release builds. + #define OVR_DEBUG_BREAK ((void)0) + + // In debug builds this tests the given expression; if false then executes OVR_DEBUG_BREAK, + // if true then no action. Has no effect in release builds. + #define OVR_FAIL_M(message) ((void)0) + #define OVR_FAIL() ((void)0) + #define OVR_ASSERT_M(p, m) ((void)0) + #define OVR_ASSERT(p) ((void)0) + + // Acts the same as OVR_ASSERT in debug builds. Acts the same as OVR_UNUSED in release builds. + // Example usage: OVR_ASSERT_AND_UNUSED(x < 30, x); + #define OVR_ASSERT_AND_UNUSED(expression, value) OVR_UNUSED(value) + +#endif // OVR_BUILD_DEBUG + + + +// Assert handler +// The user of this library can override the default assertion handler and provide their own. +namespace OVR +{ + // The return value meaning is reserved for future definition and currently has no effect. + typedef intptr_t (*OVRAssertionHandler)(intptr_t userParameter, const char* title, const char* message); + + // Returns the current assertion handler. + OVRAssertionHandler GetAssertionHandler(intptr_t* userParameter = NULL); + + // Sets the current assertion handler. + // The default assertion handler if none is set simply issues a debug break. + // Example usage: + // intptr_t CustomAssertionHandler(intptr_t /*userParameter*/, const char* title, const char* message)) { + // MessageBox(title, message); + // OVR_DEBUG_BREAK; + // } + void SetAssertionHandler(OVRAssertionHandler assertionHandler, intptr_t userParameter = 0); + + // Implements the default assertion handler. + intptr_t DefaultAssertionHandler(intptr_t userParameter, const char* title, const char* message); + + // Currently defined in OVR_DebugHelp.cpp + bool OVRIsDebuggerPresent(); +} + + +// ------------------------------------------------------------------------ +// ***** static_assert +// +// Portable support for C++11 static_assert. +// Acts as if the following were declared: +// void static_assert(bool const_expression, const char* msg); +// +// Example usage: +// static_assert(sizeof(int32_t) == 4, "int32_t expected to be 4 bytes."); + +#if defined(OVR_CPP_NO_STATIC_ASSERT) // If the compiler doesn't provide it intrinsically... + #if !defined(OVR_SA_UNUSED) + #if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) + #define OVR_SA_UNUSED __attribute__((unused)) + #else + #define OVR_SA_UNUSED + #endif + #define OVR_SA_PASTE(a,b) a##b + #define OVR_SA_HELP(a,b) OVR_SA_PASTE(a,b) + #endif + + #if defined(__COUNTER__) + #define static_assert(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __COUNTER__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED + #else + #define static_assert(expression, msg) typedef char OVR_SA_HELP(compileTimeAssert, __LINE__) [((expression) != 0) ? 1 : -1] OVR_SA_UNUSED + #endif +#endif + + +// ------------------------------------------------------------------------ +// ***** OVR_COMPILER_ASSERT +// +// Compile-time assert; produces compiler error if condition is false. +// The expression must be a compile-time constant expression. +// This macro is deprecated in favor of static_assert, which provides better +// compiler output and works in a broader range of contexts. +// +// Example usage: +// OVR_COMPILER_ASSERT(sizeof(int32_t == 4)); + +#if !defined(OVR_COMPILER_ASSERT) + #define OVR_COMPILER_ASSERT(expression) static_assert(expression, #expression) + #define OVR_COMPILER_ASSERT_M(expression, msg) static_assert(expression, msg) +#endif + + +// ***** OVR_PROCESSOR_PAUSE +// +// Yields the processor for other hyperthreads, usually for the purpose of implementing spins and spin locks. +// +// Example usage: +// while(!finished()) +// OVR_PROCESSOR_PAUSE(); + +#if !defined(OVR_PROCESSOR_PAUSE) + #if defined(OVR_CPU_X86) || defined(OVR_CPU_X86_64) + #if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) + #define OVR_PROCESSOR_PAUSE() asm volatile("pause" ::: "memory") // Consumes 38-40 clocks on current Intel x86 and x64 hardware. + #elif defined(OVR_CC_MSVC) + #include + #pragma intrinsic(_mm_pause) // Maps to asm pause. + #define OVR_PROCESSOR_PAUSE _mm_pause + #else + #define OVR_PROCESSOR_PAUSE() + #endif + #else + #define OVR_PROCESSOR_PAUSE() + #endif +#endif + + + +// ------------------------------------------------------------------------ +// ***** OVR_union_cast +// +// Implements a reinterpret cast which is strict-aliasing safe. Recall that +// it's not sufficient to do a C++ reinterpret_cast or C-style cast in order +// to avoid strict-aliasing violation. The downside to this utility is that +// it works by copying the variable through a union, and this can be have +// a performance hit if the type is not small. +// +// Requires both types to be POD (plain old data), such as built-in types +// or C style structs. +// +// Example usage: +// double d = 1.0; +// int64_t i = union_cast(d); +// +// Note that you cannot safetly use union_cast to alias the contents of two +// unrelated pointers. It can be used to alias values, not pointers to values. + +namespace OVR +{ + template + DestType union_cast(SourceType sourceValue) + { + static_assert(sizeof(DestType) == sizeof(SourceType), "union_cast size mismatch"); + static_assert(OVR_ALIGNOF(DestType) == OVR_ALIGNOF(SourceType), "union_cast alignment mismatch"); + + union SourceDest + { + SourceType sourceValue; + DestType destValue; + }; + + SourceDest sd = { sourceValue }; + return sd.destValue; + } +} + + + +// ------------------------------------------------------------------------ +// ***** OVR_VA_COPY +// +// Implements a version of C++11's va_copy that works with pre-C++11 compilers. +// +// Example usage: +// void Printf(char* pFormat, ...) +// { +// va_list argList; +// va_list argListCopy; +// +// va_start(argList, pFormat); +// OVR_VA_COPY(argListCopy, argList); +// +// +// va_end(argList); +// va_end(argListCopy); +// } +// +#if !defined(OVR_VA_COPY) + #if defined(__GNUC__) || defined(__clang__) // GCC / clang + #define OVR_VA_COPY(dest, src) va_copy((dest), (src)) + #elif defined(_MSC_VER) && (_MSC_VER >= 1800) // VS2013+ + #define OVR_VA_COPY(dest, src) va_copy((dest), (src)) + #else + // This may not work for some platforms, depending on their ABI. + // It works for many Microsoft platforms. + #define OVR_VA_COPY(dest, src) memcpy(&(dest), &(src), sizeof(va_list)) + #endif +#endif + + + + + + +// ------------------------------------------------------------------------ +// ***** OVR_ARRAY_COUNT +// +// Returns the element count of a C array. +// +// Example usage: +// float itemArray[16]; +// for(size_t i = 0; i < OVR_ARRAY_COUNT(itemArray); i++) { ... } + +#if defined(OVR_CPP_NO_CONSTEXPR) + #ifndef OVR_ARRAY_COUNT + #define OVR_ARRAY_COUNT(x) (sizeof(x) / sizeof(x[0])) + #endif +#else + // Smarter C++11 version which knows the difference between arrays and pointers. + template + char (&OVRArrayCountHelper(T (&x)[N]))[N]; + #define OVR_ARRAY_COUNT(x) (sizeof(OVRArrayCountHelper(x))) +#endif + + +// ------------------------------------------------------------------------ +// ***** OVR_CURRENT_FUNCTION +// +// Portable wrapper for __PRETTY_FUNCTION__, C99 __func__, __FUNCTION__. +// This represents the most expressive version available. +// Acts as if the following were declared: +// static const char OVR_CURRENT_FUNCTION[] = "function-name"; +// +// Example usage: +// void Test() { printf("%s", OVR_CURRENT_FUNCTION); } + +#if defined(OVR_CC_GNU) || defined(OVR_CC_CLANG) || (defined(__ICC) && (__ICC >= 600)) // GCC, clang, Intel + #define OVR_CURRENT_FUNCTION __PRETTY_FUNCTION__ +#elif defined(__FUNCSIG__) // VC++ + #define OVR_CURRENT_FUNCTION __FUNCSIG__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) // C99 compilers + #define OVR_CURRENT_FUNCTION __func__ +#else + #define OVR_CURRENT_FUNCTION __FUNCTION__ +#endif + + +//----------------------------------------------------------------------------------- +// ***** OVR_DEPRECATED / OVR_DEPRECATED_MSG +// +// Portably annotates a function or struct as deprecated. +// Note that clang supports __deprecated_enum_msg, which may be useful to support. +// +// Example usage: +// OVR_DEPRECATED void Test(); // Use on the function declaration, as opposed to definition. +// +// struct OVR_DEPRECATED Test{ ... }; +// +// OVR_DEPRECATED_MSG("Test is deprecated") +// void Test(); + +#if !defined(OVR_DEPRECATED) + #if defined(OVR_CC_MSVC) && (OVR_CC_VERSION > 1400) // VS2005+ + #define OVR_DEPRECATED __declspec(deprecated) + #define OVR_DEPRECATED_MSG(msg) __declspec(deprecated(msg)) + #elif defined(OVR_CC_CLANG) && OVR_CC_HAS_FEATURE(attribute_deprecated_with_message) + #define OVR_DEPRECATED __declspec(deprecated) + #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) + #elif defined(OVR_CC_GNU) && (OVR_CC_VERSION >= 405) + #define OVR_DEPRECATED __declspec(deprecated) + #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated(msg))) + #elif !defined(OVR_CC_MSVC) + #define OVR_DEPRECATED __attribute__((deprecated)) + #define OVR_DEPRECATED_MSG(msg) __attribute__((deprecated)) + #else + #define OVR_DEPRECATED + #define OVR_DEPRECATED_MSG(msg) + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_SELECTANY +// +// Implements a wrapper for Microsoft's __declspec(selectany) +// +// Example usage: +// SomeFile.h: +// extern const OVR_SELECTANY float OVR_Pi = 3.14f; // Allows you to declare floating point constants in header files. +// +// Example usage: +// SomeStruct.h: +// struct Some { +// static const x = 37; // See below for definition, which is required by C++11: 9.4.2p3. +// }; +// +// SomeStruct.cpp: +// OVR_SELECTANY const int Some::x; // You need to use selectany here for static const member definitions because the VC++ linker requires it. Other linkers do not. +// + +#if !defined(OVR_SELECTANY) + #if defined(_MSC_VER) + #define OVR_SELECTANY __declspec(selectany) + #else + #define OVR_SELECTANY // selectany is similar to weak linking but not enough to attempt to use __attribute__((weak)) here. + #endif +#endif + + + +//----------------------------------------------------------------------------------- +// ***** OVR_UNUSED - Unused Argument handling +// Macro to quiet compiler warnings about unused parameters/variables. +// +// Example usage: +// void Test() { +// int x = SomeFunction(); +// OVR_UNUSED(x); +// } +// + +#if defined(OVR_CC_GNU) +# define OVR_UNUSED(a) do {__typeof__ (&a) __attribute__ ((unused)) __tmp = &a; } while(0) +#else +# define OVR_UNUSED(a) (a) +#endif + +#define OVR_UNUSED1(a1) OVR_UNUSED(a1) +#define OVR_UNUSED2(a1,a2) OVR_UNUSED(a1); OVR_UNUSED(a2) +#define OVR_UNUSED3(a1,a2,a3) OVR_UNUSED2(a1,a2); OVR_UNUSED(a3) +#define OVR_UNUSED4(a1,a2,a3,a4) OVR_UNUSED3(a1,a2,a3); OVR_UNUSED(a4) +#define OVR_UNUSED5(a1,a2,a3,a4,a5) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED(a5) +#define OVR_UNUSED6(a1,a2,a3,a4,a5,a6) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED2(a5,a6) +#define OVR_UNUSED7(a1,a2,a3,a4,a5,a6,a7) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED3(a5,a6,a7) +#define OVR_UNUSED8(a1,a2,a3,a4,a5,a6,a7,a8) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED4(a5,a6,a7,a8) +#define OVR_UNUSED9(a1,a2,a3,a4,a5,a6,a7,a8,a9) OVR_UNUSED4(a1,a2,a3,a4); OVR_UNUSED5(a5,a6,a7,a8,a9) + + +//----------------------------------------------------------------------------------- +// ***** Configuration Macros +// +// Expands to the current build type as a const char string literal. +// Acts as the following declaration: const char OVR_BUILD_STRING[]; + +#ifdef OVR_BUILD_DEBUG +# define OVR_BUILD_STRING "Debug" +#else +# define OVR_BUILD_STRING "Release" +#endif + + +//// Enables SF Debugging information +//# define OVR_BUILD_DEBUG + +// OVR_DEBUG_STATEMENT injects a statement only in debug builds. +// OVR_DEBUG_SELECT injects first argument in debug builds, second argument otherwise. +#ifdef OVR_BUILD_DEBUG +#define OVR_DEBUG_STATEMENT(s) s +#define OVR_DEBUG_SELECT(d, nd) d +#else +#define OVR_DEBUG_STATEMENT(s) +#define OVR_DEBUG_SELECT(d, nd) nd +#endif + + +#define OVR_ENABLE_THREADS +// +// Prevents OVR from defining new within +// type macros, so developers can override +// new using the #define new new(...) trick +// - used with OVR_DEFINE_NEW macro +//# define OVR_BUILD_DEFINE_NEW +// + + +//----------------------------------------------------------------------------------- +// ***** Find normal allocations +// +// Our allocations are all supposed to go through the OVR System Allocator, so that +// they can be run through a game's own preferred allocator. Occasionally we will +// accidentally introduce new code that doesn't adhere to this contract. And it +// then becomes difficult to track down these normal allocations. This piece of +// code makes it easy to check for normal allocations by asserting whenever they +// happen in our code. + +//#define OVR_FIND_NORMAL_ALLOCATIONS +#ifdef OVR_FIND_NORMAL_ALLOCATIONS + +inline void* operator new (size_t size, const char* filename, int line) +{ + void* ptr = new char[size]; + OVR_ASSERT(false); + return ptr; +} + +#define new new(__FILE__, __LINE__) + +#endif // OVR_FIND_NORMAL_ALLOCATIONS + + +#include "OVR_Nullptr.h" + + + + +#endif // OVR_Types_h diff --git a/LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp b/LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp new file mode 100644 index 0000000..68e58ea --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_UTF8Util.cpp @@ -0,0 +1,556 @@ +/************************************************************************** + +Filename : OVR_UTF8Util.cpp +Content : UTF8 Unicode character encoding/decoding support +Created : September 19, 2012 +Notes : +Notes : Much useful info at "UTF-8 and Unicode FAQ" + http://www.cl.cam.ac.uk/~mgk25/unicode.html + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "OVR_UTF8Util.h" + +namespace OVR { namespace UTF8Util { + +intptr_t OVR_STDCALL GetLength(const char* buf, intptr_t buflen) +{ + const char* p = buf; + intptr_t length = 0; + + if (buflen != -1) + { + while (p - buf < buflen) + { + // We should be able to have ASStrings with 0 in the middle. + UTF8Util::DecodeNextChar_Advance0(&p); + length++; + } + } + else + { + while (UTF8Util::DecodeNextChar_Advance0(&p)) + length++; + } + + return length; +} + +uint32_t OVR_STDCALL GetCharAt(intptr_t index, const char* putf8str, intptr_t length) +{ + const char* buf = putf8str; + uint32_t c = 0; + + if (length != -1) + { + while (buf - putf8str < length) + { + c = UTF8Util::DecodeNextChar_Advance0(&buf); + if (index == 0) + return c; + index--; + } + + return c; + } + + do + { + c = UTF8Util::DecodeNextChar_Advance0(&buf); + index--; + + if (c == 0) + { + // We've hit the end of the string; don't go further. + OVR_ASSERT(index == 0); + return c; + } + } while (index >= 0); + + return c; +} + +intptr_t OVR_STDCALL GetByteIndex(intptr_t index, const char *putf8str, intptr_t length) +{ + const char* buf = putf8str; + + if (length != -1) + { + while ((buf - putf8str) < length && index > 0) + { + UTF8Util::DecodeNextChar_Advance0(&buf); + index--; + } + + return buf-putf8str; + } + + while (index > 0) + { + uint32_t c = UTF8Util::DecodeNextChar_Advance0(&buf); + index--; + + if (c == 0) + return buf-putf8str; + }; + + return buf-putf8str; +} + +int OVR_STDCALL GetEncodeCharSize(uint32_t ucs_character) +{ + if (ucs_character <= 0x7F) + return 1; + else if (ucs_character <= 0x7FF) + return 2; + else if (ucs_character <= 0xFFFF) + return 3; + else if (ucs_character <= 0x1FFFFF) + return 4; + else if (ucs_character <= 0x3FFFFFF) + return 5; + else if (ucs_character <= 0x7FFFFFFF) + return 6; + else + return 0; +} + +uint32_t OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer) +{ + uint32_t uc; + char c; + + // Security considerations: + // + // Changed, this is now only the case for DecodeNextChar: + // - If we hit a zero byte, we want to return 0 without stepping + // the buffer pointer past the 0. th + // + // If we hit an "overlong sequence"; i.e. a character encoded + // in a longer multibyte string than is necessary, then we + // need to discard the character. This is so attackers can't + // disguise dangerous characters or character sequences -- + // there is only one valid encoding for each character. + // + // If we decode characters { 0xD800 .. 0xDFFF } or { 0xFFFE, + // 0xFFFF } then we ignore them; they are not valid in UTF-8. + + // This isn't actually an invalid character; it's a valid char that + // looks like an inverted question mark. +#define INVALID_CHAR 0x0FFFD + +#define FIRST_BYTE(mask, shift) \ + uc = (c & (mask)) << (shift); + +#define NEXT_BYTE(shift) \ + c = **putf8Buffer; \ + if (c == 0) return 0; /* end of buffer, do not advance */ \ + if ((c & 0xC0) != 0x80) return INVALID_CHAR; /* standard check */ \ + (*putf8Buffer)++; \ + uc |= (c & 0x3F) << shift; + + c = **putf8Buffer; + (*putf8Buffer)++; + if (c == 0) + return 0; // End of buffer. + + if ((c & 0x80) == 0) return (uint32_t) c; // Conventional 7-bit ASCII. + + // Multi-byte sequences. + if ((c & 0xE0) == 0xC0) + { + // Two-byte sequence. + FIRST_BYTE(0x1F, 6); + NEXT_BYTE(0); + if (uc < 0x80) return INVALID_CHAR; // overlong + return uc; + } + else if ((c & 0xF0) == 0xE0) + { + // Three-byte sequence. + FIRST_BYTE(0x0F, 12); + NEXT_BYTE(6); + NEXT_BYTE(0); + if (uc < 0x800) return INVALID_CHAR; // overlong + // Not valid ISO 10646, but Flash requires these to work + // see AS3 test e15_5_3_2_3 for String.fromCharCode().charCodeAt(0) + // if (uc >= 0x0D800 && uc <= 0x0DFFF) return INVALID_CHAR; + // if (uc == 0x0FFFE || uc == 0x0FFFF) return INVALID_CHAR; // not valid ISO 10646 + return uc; + } + else if ((c & 0xF8) == 0xF0) + { + // Four-byte sequence. + FIRST_BYTE(0x07, 18); + NEXT_BYTE(12); + NEXT_BYTE(6); + NEXT_BYTE(0); + if (uc < 0x010000) return INVALID_CHAR; // overlong + return uc; + } + else if ((c & 0xFC) == 0xF8) + { + // Five-byte sequence. + FIRST_BYTE(0x03, 24); + NEXT_BYTE(18); + NEXT_BYTE(12); + NEXT_BYTE(6); + NEXT_BYTE(0); + if (uc < 0x0200000) return INVALID_CHAR; // overlong + return uc; + } + else if ((c & 0xFE) == 0xFC) + { + // Six-byte sequence. + FIRST_BYTE(0x01, 30); + NEXT_BYTE(24); + NEXT_BYTE(18); + NEXT_BYTE(12); + NEXT_BYTE(6); + NEXT_BYTE(0); + if (uc < 0x04000000) return INVALID_CHAR; // overlong + return uc; + } + else + { + // Invalid. + return INVALID_CHAR; + } +} + + +void OVR_STDCALL EncodeChar(char* pbuffer, intptr_t* pindex, uint32_t ucs_character) +{ + if (ucs_character <= 0x7F) + { + // Plain single-byte ASCII. + pbuffer[(*pindex)++] = (char) ucs_character; + } + else if (ucs_character <= 0x7FF) + { + // Two bytes. + pbuffer[(*pindex)++] = 0xC0 | (char)(ucs_character >> 6); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } + else if (ucs_character <= 0xFFFF) + { + // Three bytes. + pbuffer[(*pindex)++] = 0xE0 | (char)(ucs_character >> 12); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } + else if (ucs_character <= 0x1FFFFF) + { + // Four bytes. + pbuffer[(*pindex)++] = 0xF0 | (char)(ucs_character >> 18); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } + else if (ucs_character <= 0x3FFFFFF) + { + // Five bytes. + pbuffer[(*pindex)++] = 0xF8 | (char)(ucs_character >> 24); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } + else if (ucs_character <= 0x7FFFFFFF) + { + // Six bytes. + pbuffer[(*pindex)++] = 0xFC | (char)(ucs_character >> 30); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 24) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 18) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 12) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 6) & 0x3F); + pbuffer[(*pindex)++] = 0x80 | (char)((ucs_character >> 0) & 0x3F); + } + else + { + // Invalid char; don't encode anything. + } +} + +intptr_t OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, intptr_t length) +{ + intptr_t len = 0; + if (length != -1) + for (int i = 0; i < length; i++) + { + len += GetEncodeCharSize(pchar[i]); + } + else + for (int i = 0;; i++) + { + if (pchar[i] == 0) + return len; + len += GetEncodeCharSize(pchar[i]); + } + return len; +} + +void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, intptr_t length) +{ + intptr_t ofs = 0; + if (length != -1) + { + for (int i = 0; i < length; i++) + { + EncodeChar(pbuff, &ofs, pchar[i]); + } + } + else + { + for (int i = 0;; i++) + { + if (pchar[i] == 0) + break; + EncodeChar(pbuff, &ofs, pchar[i]); + } + } + pbuff[ofs] = 0; +} + +size_t OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, intptr_t bytesLen) +{ + wchar_t *pbegin = pbuff; + if (bytesLen == -1) + { + while (1) + { + uint32_t ch = DecodeNextChar_Advance0(&putf8str); + if (ch == 0) + break; + else if (ch >= 0xFFFF) + ch = 0xFFFD; + *pbuff++ = wchar_t(ch); + } + } + else + { + const char* p = putf8str; + while ((p - putf8str) < bytesLen) + { + uint32_t ch = DecodeNextChar_Advance0(&p); + if (ch >= 0xFFFF) + ch = 0xFFFD; + *pbuff++ = wchar_t(ch); + } + } + + *pbuff = 0; + return pbuff - pbegin; +} + + +#ifdef UTF8_UNIT_TEST + +// Compile this test case with something like: +// +// gcc utf8.cpp -g -I.. -DUTF8_UNIT_TEST -lstdc++ -o utf8_test +// +// or +// +// cl utf8.cpp -Zi -Od -DUTF8_UNIT_TEST -I.. +// +// If possible, try running the test program with the first arg +// pointing at the file: +// +// http://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt +// +// and examine the results by eye to make sure they are acceptable to +// you. + + +#include "base/utility.h" +#include + + +bool check_equal(const char* utf8_in, const uint32_t* ucs_in) +{ + for (;;) + { + uint32_t next_ucs = *ucs_in++; + uint32_t next_ucs_from_utf8 = utf8::decode_next_unicode_character(&utf8_in); + if (next_ucs != next_ucs_from_utf8) + { + return false; + } + if (next_ucs == 0) + { + OVR_ASSERT(next_ucs_from_utf8 == 0); + break; + } + } + + return true; +} + + +void log_ascii(const char* line) +{ + for (;;) + { + unsigned char c = (unsigned char) *line++; + if (c == 0) + { + // End of line. + return; + } + else if (c != '\n' + && (c < 32 || c > 127)) + { + // Non-printable as plain ASCII. + printf("<0x%02X>", (int) c); + } + else + { + printf("%c", c); + } + } +} + + +void log_ucs(const uint32_t* line) +{ + for (;;) + { + uint32_t uc = *line++; + if (uc == 0) + { + // End of line. + return; + } + else if (uc != '\n' + && (uc < 32 || uc > 127)) + { + // Non-printable as plain ASCII. + printf("", uc); + } + else + { + printf("%c", (char) uc); + } + } +} + + +// Simple canned test. +int main(int argc, const char* argv[]) +{ + { + const char* test8 = "Ignacio Castaño"; + const uint32_t test32[] = + { + 0x49, 0x67, 0x6E, 0x61, 0x63, + 0x69, 0x6F, 0x20, 0x43, 0x61, + 0x73, 0x74, 0x61, 0xF1, 0x6F, + 0x00 + }; + + OVR_ASSERT(check_equal(test8, test32)); + } + + // If user passed an arg, try reading the file as UTF-8 encoded text. + if (argc > 1) + { + const char* filename = argv[1]; + FILE* fp = fopen(filename, "rb"); + if (fp == NULL) + { + printf("Can't open file '%s'\n", filename); + return 1; + } + + // Read lines from the file, encode/decode them, and highlight discrepancies. + const int LINE_SIZE = 200; // max line size + char line_buffer_utf8[LINE_SIZE]; + char reencoded_utf8[6 * LINE_SIZE]; + uint32_t line_buffer_ucs[LINE_SIZE]; + + int byte_counter = 0; + for (;;) + { + int c = fgetc(fp); + if (c == EOF) + { + // Done. + break; + } + line_buffer_utf8[byte_counter++] = c; + if (c == '\n' || byte_counter >= LINE_SIZE - 2) + { + // End of line. Process the line. + line_buffer_utf8[byte_counter++] = 0; // terminate. + + // Decode into UCS. + const char* p = line_buffer_utf8; + uint32_t* q = line_buffer_ucs; + for (;;) + { + uint32_t uc = UTF8Util::DecodeNextChar(&p); + *q++ = uc; + + OVR_ASSERT(q < line_buffer_ucs + LINE_SIZE); + OVR_ASSERT(p < line_buffer_utf8 + LINE_SIZE); + + if (uc == 0) break; + } + + // Encode back into UTF-8. + q = line_buffer_ucs; + int index = 0; + for (;;) + { + uint32_t uc = *q++; + OVR_ASSERT(index < LINE_SIZE * 6 - 6); + int last_index = index; + UTF8Util::EncodeChar(reencoded_utf8, &index, uc); + OVR_ASSERT(index <= last_index + 6); + if (uc == 0) break; + } + + // This can be useful for debugging. +#if 0 + // Show the UCS and the re-encoded UTF-8. + log_ucs(line_buffer_ucs); + log_ascii(reencoded_utf8); +#endif // 0 + + OVR_ASSERT(check_equal(line_buffer_utf8, line_buffer_ucs)); + OVR_ASSERT(check_equal(reencoded_utf8, line_buffer_ucs)); + + // Start next line. + byte_counter = 0; + } + } + + fclose(fp); + } + + return 0; +} + + +#endif // UTF8_UNIT_TEST + +}} // namespace UTF8Util::OVR + diff --git a/LibOVRKernel/Src/Kernel/OVR_UTF8Util.h b/LibOVRKernel/Src/Kernel/OVR_UTF8Util.h new file mode 100644 index 0000000..3b640f0 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_UTF8Util.h @@ -0,0 +1,99 @@ +/************************************************************************************ + +PublicHeader: OVR_Kernel.h +Filename : OVR_UTF8Util.h +Content : UTF8 Unicode character encoding/decoding support +Created : September 19, 2012 +Notes : + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_UTF8Util_h +#define OVR_UTF8Util_h + +#include "OVR_Types.h" + +namespace OVR { namespace UTF8Util { + +//----------------------------------------------------------------------------------- + +// *** UTF8 string length and indexing. + +// Determines the length of UTF8 string in characters. +// If source length is specified (in bytes), null 0 character is counted properly. +intptr_t OVR_STDCALL GetLength(const char* putf8str, intptr_t length = -1); + +// Gets a decoded UTF8 character at index; you can access up to the index returned +// by GetLength. 0 will be returned for out of bounds access. +uint32_t OVR_STDCALL GetCharAt(intptr_t index, const char* putf8str, intptr_t length = -1); + +// Converts UTF8 character index into byte offset. +// -1 is returned if index was out of bounds. +intptr_t OVR_STDCALL GetByteIndex(intptr_t index, const char* putf8str, intptr_t length = -1); + + +// *** 16-bit Unicode string Encoding/Decoding routines. + +// Determines the number of bytes necessary to encode a string. +// Does not count the terminating 0 (null) character. +intptr_t OVR_STDCALL GetEncodeStringSize(const wchar_t* pchar, intptr_t length = -1); + +// Encodes a unicode (UCS-2 only) string into a buffer. The size of buffer must be at +// least GetEncodeStringSize() + 1. +void OVR_STDCALL EncodeString(char *pbuff, const wchar_t* pchar, intptr_t length = -1); + +// Decode UTF8 into a wchar_t buffer. Must have GetLength()+1 characters available. +// Characters over 0xFFFF are replaced with 0xFFFD. +// Returns the length of resulting string (number of characters) +size_t OVR_STDCALL DecodeString(wchar_t *pbuff, const char* putf8str, intptr_t bytesLen = -1); + + +// *** Individual character Encoding/Decoding. + +// Determined the number of bytes necessary to encode a UCS character. +int OVR_STDCALL GetEncodeCharSize(uint32_t ucsCharacter); + +// Encodes the given UCS character into the given UTF-8 buffer. +// Writes the data starting at buffer[offset], and +// increments offset by the number of bytes written. +// May write up to 6 bytes, so make sure there's room in the buffer +void OVR_STDCALL EncodeChar(char* pbuffer, intptr_t* poffset, uint32_t ucsCharacter); + +// Return the next Unicode character in the UTF-8 encoded buffer. +// Invalid UTF-8 sequences produce a U+FFFD character as output. +// Advances *utf8_buffer past the character returned. Pointer advance +// occurs even if the terminating 0 character is hit, since that allows +// strings with middle '\0' characters to be supported. +uint32_t OVR_STDCALL DecodeNextChar_Advance0(const char** putf8Buffer); + +// Safer version of DecodeNextChar, which doesn't advance pointer if +// null character is hit. +inline uint32_t DecodeNextChar(const char** putf8Buffer) +{ + uint32_t ch = DecodeNextChar_Advance0(putf8Buffer); + if (ch == 0) + (*putf8Buffer)--; + return ch; +} + + +}} // OVR::UTF8Util + +#endif diff --git a/LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h b/LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h new file mode 100644 index 0000000..dc4c416 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_Win32_IncludeWindows.h @@ -0,0 +1,223 @@ +/************************************************************************************ + +Filename : OVR_Win32_IncludeWindows.h +Content : Small helper header to include Windows.h properly +Created : Oct 16, 2014 +Authors : Chris Taylor, Scott Bassett + +Copyright : Copyright 2014 Oculus, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Win32_IncludeWindows_h +#define OVR_Win32_IncludeWindows_h + +#include "OVR_Types.h" + +// Automatically avoid including the Windows header on non-Windows platforms. +#ifdef OVR_OS_MS + +// It is common practice to define WIN32_LEAN_AND_MEAN to reduce compile times. +// However this then requires us to define our own NTSTATUS data type and other +// irritations throughout our code-base. +//#define WIN32_LEAN_AND_MEAN + +// Prevents from #including , as we use instead. +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ +#endif + +// Prevents from defining min() and max() macro symbols. +#ifndef NOMINMAX +#define NOMINMAX +#endif + +// We support Windows Windows 7 or newer. +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0601 /* Windows 7+ */ +#endif + +#include + +namespace OVR { + + +//----------------------------------------------------------------------------- +// ScopedHANDLE +// +// MSVC 2010, and MSVC 2012 do not support the utility header. +// So we provide our own version of HandleRAII, which is an incredibly +// useful pattern for working with Windows HANDLE values. +// +// HANDLEs have two invalid values in Windows, either nullptr or +// INVALID_HANDLE_VALUE. The invalid value that is correct for the usage must +// be provided as the template argument. + +struct ScopedHANDLE_NullTraits +{ + // We cannot make this a static member variable as it is not an integral type. + inline static HANDLE InvalidValue() + { + return nullptr; + } +}; +struct ScopedHANDLE_InvalidTraits +{ + inline static HANDLE InvalidValue() + { + return INVALID_HANDLE_VALUE; + } +}; + +template +class ScopedHANDLE +{ + HANDLE hAttachedHandle; + +public: + ScopedHANDLE(HANDLE handle) : + hAttachedHandle(handle) + { + } + ScopedHANDLE() + { + hAttachedHandle = Traits::InvalidValue(); + } + ScopedHANDLE& operator=(HANDLE handle) + { + Close(); + hAttachedHandle = handle; + return *this; + } + ~ScopedHANDLE() + { + Close(); + } + + bool IsValid() + { + return hAttachedHandle != Traits::InvalidValue(); + } + HANDLE Get() + { + return hAttachedHandle; + } + HANDLE& GetRawRef() + { + return hAttachedHandle; + } + void Attach(HANDLE handle) + { + Close(); + hAttachedHandle = handle; + } + void Detach() + { + // Do not close handle + hAttachedHandle = Traits::InvalidValue(); + } + bool Close() + { + bool success = true; + if (hAttachedHandle != Traits::InvalidValue()) + { + if (::CloseHandle(hAttachedHandle) != TRUE) + { + success = false; + } + hAttachedHandle = Traits::InvalidValue(); + } + return success; + } +}; + +// Different Windows API functions have different invalid values. +// These types are provided to improve readability. +typedef ScopedHANDLE < ScopedHANDLE_NullTraits > ScopedEventHANDLE; +typedef ScopedHANDLE < ScopedHANDLE_InvalidTraits > ScopedFileHANDLE; +typedef ScopedHANDLE < ScopedHANDLE_NullTraits > ScopedProcessHANDLE; + +// Scoped registry keys +class ScopedHKEY +{ + HKEY hAttachedHandle; + +public: + ScopedHKEY(HKEY handle) : + hAttachedHandle(handle) + { + } + ScopedHKEY() + { + hAttachedHandle = nullptr; + } + ScopedHKEY& operator=(HKEY handle) + { + Close(); + hAttachedHandle = handle; + return *this; + } + ~ScopedHKEY() + { + Close(); + } + + bool IsValid() + { + return hAttachedHandle != nullptr; + } + HKEY Get() + { + return hAttachedHandle; + } + HKEY& GetRawRef() + { + return hAttachedHandle; + } + void Attach(HKEY handle) + { + Close(); + hAttachedHandle = handle; + } + void Detach() + { + // Do not close handle + hAttachedHandle = nullptr; + } + bool Close() + { + bool success = true; + if (hAttachedHandle != nullptr) + { + if (::RegCloseKey(hAttachedHandle) == ERROR_SUCCESS) + { + success = false; + } + hAttachedHandle = nullptr; + } + return success; + } +}; + + +} // namespace OVR + + +#endif // OVR_OS_WIN32 + +#endif // OVR_Win32_IncludeWindows_h diff --git a/LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.c b/LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.c new file mode 100644 index 0000000..59b9345 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.c @@ -0,0 +1,2961 @@ +/* This file was generated by the MIG utility with: + mig /usr/include/mach/mach_exc.defs + We pre-generate them instead of generate them at compile-time because we + need to rename some of the functions to append _OVR so we don't get conflicts + with any other versions of these functions the application may have. +*/ + +/* Begin mach_excUser.c */ + +#if defined(__APPLE__) + +#define __MIG_check__Reply__mach_exc_subsystem__ 1 +#define __NDR_convert__Reply__mach_exc_subsystem__ 1 +#define __NDR_convert__mig_reply_error_subsystem__ 1 + +#include "OVR_mach_exc_OSX.h" + +#if defined(__cplusplus) + extern "C" { +#endif + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __MachMsgErrorWithTimeout +#define __MachMsgErrorWithTimeout(_R_) { \ + switch (_R_) { \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ + break; \ + case MACH_SEND_TIMED_OUT: \ + case MACH_RCV_TIMED_OUT: \ + default: \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + } \ +} +#endif /* __MachMsgErrorWithTimeout */ + +#ifndef __MachMsgErrorWithoutTimeout +#define __MachMsgErrorWithoutTimeout(_R_) { \ + switch (_R_) { \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ + break; \ + default: \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + } \ +} +#endif /* __MachMsgErrorWithoutTimeout */ + +#ifndef __DeclareSendRpc +#define __DeclareSendRpc(_NUM_, _NAME_) +#endif /* __DeclareSendRpc */ + +#ifndef __BeforeSendRpc +#define __BeforeSendRpc(_NUM_, _NAME_) +#endif /* __BeforeSendRpc */ + +#ifndef __AfterSendRpc +#define __AfterSendRpc(_NUM_, _NAME_) +#endif /* __AfterSendRpc */ + +#ifndef __DeclareSendSimple +#define __DeclareSendSimple(_NUM_, _NAME_) +#endif /* __DeclareSendSimple */ + +#ifndef __BeforeSendSimple +#define __BeforeSendSimple(_NUM_, _NAME_) +#endif /* __BeforeSendSimple */ + +#ifndef __AfterSendSimple +#define __AfterSendSimple(_NUM_, _NAME_) +#endif /* __AfterSendSimple */ + +#ifndef msgh_request_port + #define msgh_request_port msgh_remote_port +#endif + +#ifndef msgh_reply_port + #define msgh_reply_port msgh_local_port +#endif + + +#if ( __MigTypeCheck || __NDR_convert__ ) +#if __MIG_check__Reply__mach_exc_subsystem__ +#if !defined(__MIG_check__Reply__mach_exception_raise_t__defined) +#define __MIG_check__Reply__mach_exception_raise_t__defined +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined +#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(a, f) \ + __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) +#elif defined(__NDR_convert__int_rep__kern_return_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(a, f) \ + __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined */ + + + + + +mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_t_OVR(__Reply__mach_exception_raise_t *Out0P) +{ + + typedef __Reply__mach_exception_raise_t __Reply; + if (Out0P->Head.msgh_id != 2505) { + if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) + { return MIG_SERVER_DIED; } + else + { return MIG_REPLY_MISMATCH; } + } + + #if __MigTypeCheck + if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (Out0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Reply))) + { return MIG_TYPE_ERROR ; } + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined) + if (Out0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_t__RetCode__defined */ + { + return Out0P->RetCode; + } +} +#endif /* !defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ +#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ + + +/* Routine mach_exception_raise_OVR */ +mig_external kern_return_t mach_exception_raise_OVR +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +) +{ + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } Request; + #ifdef __MigPackStructs + #pragma pack() + #endif + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_trailer_t trailer; + } Reply; + #ifdef __MigPackStructs + #pragma pack() + #endif + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply; + #ifdef __MigPackStructs + #pragma pack() + #endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + unsigned int msgh_size; + + #ifdef __MIG_check__Reply__mach_exception_raise_t__defined + kern_return_t check_result; + #endif /* __MIG_check__Reply__mach_exception_raise_t__defined */ + + __DeclareSendRpc(2405, "mach_exception_raise_OVR") + + #if UseStaticTemplates + const static mach_msg_port_descriptor_t threadTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; + #endif /* UseStaticTemplates */ + + #if UseStaticTemplates + const static mach_msg_port_descriptor_t taskTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; + #endif /* UseStaticTemplates */ + + InP->msgh_body.msgh_descriptor_count = 2; + #if UseStaticTemplates + InP->thread = threadTemplate; + InP->thread.name = thread; + #else /* UseStaticTemplates */ + InP->thread.name = thread; + InP->thread.disposition = 19; + InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; + #endif /* UseStaticTemplates */ + + #if UseStaticTemplates + InP->task = taskTemplate; + InP->task.name = task; + #else /* UseStaticTemplates */ + InP->task.name = task; + InP->task.disposition = 19; + InP->task.type = MACH_MSG_PORT_DESCRIPTOR; + #endif /* UseStaticTemplates */ + + InP->NDR = NDR_record; + + InP->exception = exception; + + if (codeCnt > 2) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); + + InP->codeCnt = codeCnt; + + msgh_size = (mach_msg_size_t)(sizeof(Request) - 16) + ((8 * codeCnt)); + InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = exception_port; + InP->Head.msgh_reply_port = mig_get_reply_port(); + InP->Head.msgh_id = 2405; + + __BeforeSendRpc(2405, "mach_exception_raise_OVR") + msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(2405, "mach_exception_raise_OVR") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + + #if defined(__MIG_check__Reply__mach_exception_raise_t__defined) + check_result = __MIG_check__Reply__mach_exception_raise_t_OVR((__Reply__mach_exception_raise_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } + #endif /* defined(__MIG_check__Reply__mach_exception_raise_t__defined) */ + + return KERN_SUCCESS; +} + +#if ( __MigTypeCheck || __NDR_convert__ ) +#if __MIG_check__Reply__mach_exc_subsystem__ +#if !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) +#define __MIG_check__Reply__mach_exception_raise_state_t__defined +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined +#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(a, f) \ + __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) +#elif defined(__NDR_convert__int_rep__kern_return_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(a, f) \ + __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined */ + + +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined +#if defined(__NDR_convert__int_rep__mach_exc__int__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__int_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__int__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__int_rep__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__int_rep__int32_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__int_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined */ + + +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined +#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__thread_state_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__int_rep__natural_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) +#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__int_rep__uint32_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined */ + + +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(a, f) \ + __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(a, f) \ + __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined */ + + + +#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined +#if defined(__NDR_convert__char_rep__mach_exc__int__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__char_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__int__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__char_rep__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__char_rep__int32_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__char_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined */ + + +#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined +#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__thread_state_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__char_rep__natural_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) +#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__char_rep__uint32_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined */ + + + + +#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined +#if defined(__NDR_convert__float_rep__mach_exc__int__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__float_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__int__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__float_rep__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__float_rep__int32_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__float_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined */ + + +#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined +#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__thread_state_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__float_rep__natural_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) +#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__float_rep__uint32_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined */ + + + + +mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_t_OVR(__Reply__mach_exception_raise_state_t *Out0P) +{ + + typedef __Reply__mach_exception_raise_state_t __Reply; + #if __MigTypeCheck + unsigned int msgh_size; + #endif /* __MigTypeCheck */ + + if (Out0P->Head.msgh_id != 2506) { + if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) + { return MIG_SERVER_DIED; } + else + { return MIG_REPLY_MISMATCH; } + } + + #if __MigTypeCheck + msgh_size = Out0P->Head.msgh_size; + + if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 576)) && + (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || + Out0P->RetCode == KERN_SUCCESS))) + { return MIG_TYPE_ERROR ; } + #endif /* __MigTypeCheck */ + + if (Out0P->RetCode != KERN_SUCCESS) { + #ifdef __NDR_convert__mig_reply_error_t__defined + __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); + #endif /* __NDR_convert__mig_reply_error_t__defined */ + return ((mig_reply_error_t *)Out0P)->RetCode; + } + + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined) + if (Out0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt(&Out0P->new_stateCnt, Out0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined */ + #if __MigTypeCheck + if ( Out0P->new_stateCnt > 144 ) + return MIG_TYPE_ERROR; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 576)) / 4 != Out0P->new_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 576) + Out0P->new_stateCnt * 4)) + { return MIG_TYPE_ERROR ; } + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined) || \ + defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ + defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ + defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_stateCnt__defined) + if (Out0P->NDR.int_rep != NDR_record.int_rep) { + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined) + __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__RetCode__defined */ + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined) + __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__flavor__defined */ + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined) + __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.int_rep, Out0P->new_stateCnt); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_t__new_state__defined */ + } + #endif /* defined(__NDR_convert__int_rep...) */ + + #if 0 || \ + defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ + defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ + 0 + if (Out0P->NDR.char_rep != NDR_record.char_rep) { + #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined) + __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.char_rep); + #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__flavor__defined */ + #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined) + __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.char_rep, Out0P->new_stateCnt); + #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_t__new_state__defined */ + } + #endif /* defined(__NDR_convert__char_rep...) */ + + #if 0 || \ + defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined) || \ + defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined) || \ + 0 + if (Out0P->NDR.float_rep != NDR_record.float_rep) { + #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined) + __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor(&Out0P->flavor, Out0P->NDR.float_rep); + #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__flavor__defined */ + #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined) + __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state(&Out0P->new_state, Out0P->NDR.float_rep, Out0P->new_stateCnt); + #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_t__new_state__defined */ + } + #endif /* defined(__NDR_convert__float_rep...) */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ +#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ + + +/* Routine mach_exception_raise_state_OVR */ +mig_external kern_return_t mach_exception_raise_state_OVR +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +) +{ + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[144]; + } Request; + #ifdef __MigPackStructs + #pragma pack() + #endif + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[144]; + mach_msg_trailer_t trailer; + } Reply; + #ifdef __MigPackStructs + #pragma pack() + #endif + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[144]; + } __Reply; + #ifdef __MigPackStructs + #pragma pack() + #endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + unsigned int msgh_size; + unsigned int msgh_size_delta; + + + #ifdef __MIG_check__Reply__mach_exception_raise_state_t__defined + kern_return_t check_result; + #endif /* __MIG_check__Reply__mach_exception_raise_state_t__defined */ + + __DeclareSendRpc(2406, "mach_exception_raise_state_OVR") + + InP->NDR = NDR_record; + + InP->exception = exception; + + if (codeCnt > 2) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); + + InP->codeCnt = codeCnt; + + msgh_size_delta = (8 * codeCnt); + msgh_size = (mach_msg_size_t)(sizeof(Request) - 592) + msgh_size_delta; + InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); + + InP->flavor = *flavor; + + if (old_stateCnt > 144) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); + + InP->old_stateCnt = old_stateCnt; + + msgh_size += (4 * old_stateCnt); + InP = &Mess.In; + InP->Head.msgh_bits = + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = exception_port; + InP->Head.msgh_reply_port = mig_get_reply_port(); + InP->Head.msgh_id = 2406; + + __BeforeSendRpc(2406, "mach_exception_raise_state_OVR") + msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(2406, "mach_exception_raise_state_OVR") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + + #if defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) + check_result = __MIG_check__Reply__mach_exception_raise_state_t_OVR((__Reply__mach_exception_raise_state_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } + #endif /* defined(__MIG_check__Reply__mach_exception_raise_state_t__defined) */ + + *flavor = Out0P->flavor; + + if (Out0P->new_stateCnt > 144) { + (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 144); + *new_stateCnt = Out0P->new_stateCnt; + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); + + *new_stateCnt = Out0P->new_stateCnt; + + return KERN_SUCCESS; +} + +#if ( __MigTypeCheck || __NDR_convert__ ) +#if __MIG_check__Reply__mach_exc_subsystem__ +#if !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) +#define __MIG_check__Reply__mach_exception_raise_state_identity_t__defined +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined +#if defined(__NDR_convert__int_rep__mach_exc__kern_return_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(a, f) \ + __NDR_convert__int_rep__mach_exc__kern_return_t((kern_return_t *)(a), f) +#elif defined(__NDR_convert__int_rep__kern_return_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(a, f) \ + __NDR_convert__int_rep__kern_return_t((kern_return_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined */ + + +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#if defined(__NDR_convert__int_rep__mach_exc__int__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__int_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__int__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__int_rep__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__int_rep__int32_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__int_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ + + +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__thread_state_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__int_rep__natural_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) +#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__int_rep__uint32_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ + + +#ifndef __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(a, f) \ + __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined +#define __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(a, f) \ + __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined */ + + + +#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#if defined(__NDR_convert__char_rep__mach_exc__int__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__char_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__int__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__char_rep__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__char_rep__int32_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__char_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ + + +#ifndef __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__thread_state_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__char_rep__natural_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) +#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__char_rep__uint32_t__defined) +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ + + + + +#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#if defined(__NDR_convert__float_rep__mach_exc__int__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__float_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__int__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__float_rep__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__float_rep__int32_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__float_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ + + +#ifndef __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__thread_state_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__float_rep__natural_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) +#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__float_rep__uint32_t__defined) +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined +#define __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ + + + + +mig_internal kern_return_t __MIG_check__Reply__mach_exception_raise_state_identity_t(__Reply__mach_exception_raise_state_identity_t *Out0P) +{ + + typedef __Reply__mach_exception_raise_state_identity_t __Reply; + #if __MigTypeCheck + unsigned int msgh_size; + #endif /* __MigTypeCheck */ + + if (Out0P->Head.msgh_id != 2507) { + if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) + { return MIG_SERVER_DIED; } + else + { return MIG_REPLY_MISMATCH; } + } + + #if __MigTypeCheck + msgh_size = Out0P->Head.msgh_size; + + if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + ((msgh_size > (mach_msg_size_t)sizeof(__Reply) || msgh_size < (mach_msg_size_t)(sizeof(__Reply) - 576)) && + (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || + Out0P->RetCode == KERN_SUCCESS))) + { return MIG_TYPE_ERROR ; } + #endif /* __MigTypeCheck */ + + if (Out0P->RetCode != KERN_SUCCESS) { + #ifdef __NDR_convert__mig_reply_error_t__defined + __NDR_convert__mig_reply_error_t((mig_reply_error_t *)Out0P); + #endif /* __NDR_convert__mig_reply_error_t__defined */ + return ((mig_reply_error_t *)Out0P)->RetCode; + } + + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined) + if (Out0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt(&Out0P->new_stateCnt, Out0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined */ + #if __MigTypeCheck + if ( Out0P->new_stateCnt > 144 ) + return MIG_TYPE_ERROR; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Reply) - 576)) / 4 != Out0P->new_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Reply) - 576) + Out0P->new_stateCnt * 4)) + { return MIG_TYPE_ERROR ; } + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined) || \ + defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ + defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ + defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_stateCnt__defined) + if (Out0P->NDR.int_rep != NDR_record.int_rep) { + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined) + __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode(&Out0P->RetCode, Out0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__RetCode__defined */ + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) + __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ + #if defined(__NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) + __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.int_rep, Out0P->new_stateCnt); + #endif /* __NDR_convert__int_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ + } + #endif /* defined(__NDR_convert__int_rep...) */ + + #if 0 || \ + defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ + defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ + 0 + if (Out0P->NDR.char_rep != NDR_record.char_rep) { + #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) + __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.char_rep); + #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ + #if defined(__NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) + __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.char_rep, Out0P->new_stateCnt); + #endif /* __NDR_convert__char_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ + } + #endif /* defined(__NDR_convert__char_rep...) */ + + #if 0 || \ + defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) || \ + defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) || \ + 0 + if (Out0P->NDR.float_rep != NDR_record.float_rep) { + #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined) + __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor(&Out0P->flavor, Out0P->NDR.float_rep); + #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__flavor__defined */ + #if defined(__NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined) + __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state(&Out0P->new_state, Out0P->NDR.float_rep, Out0P->new_stateCnt); + #endif /* __NDR_convert__float_rep__Reply__mach_exception_raise_state_identity_t__new_state__defined */ + } + #endif /* defined(__NDR_convert__float_rep...) */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ +#endif /* __MIG_check__Reply__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ + + +/* Routine mach_exception_raise_state_identity_OVR */ +mig_external kern_return_t mach_exception_raise_state_identity_OVR +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +) +{ + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[144]; + } Request; + #ifdef __MigPackStructs + #pragma pack() + #endif + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[144]; + mach_msg_trailer_t trailer; + } Reply; + #ifdef __MigPackStructs + #pragma pack() + #endif + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[144]; + } __Reply; + #ifdef __MigPackStructs + #pragma pack() + #endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + unsigned int msgh_size; + unsigned int msgh_size_delta; + + + #ifdef __MIG_check__Reply__mach_exception_raise_state_identity_t__defined + kern_return_t check_result; + #endif /* __MIG_check__Reply__mach_exception_raise_state_identity_t__defined */ + + __DeclareSendRpc(2407, "mach_exception_raise_state_identity_OVR") + + #if UseStaticTemplates + const static mach_msg_port_descriptor_t threadTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; + #endif /* UseStaticTemplates */ + + #if UseStaticTemplates + const static mach_msg_port_descriptor_t taskTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; + #endif /* UseStaticTemplates */ + + InP->msgh_body.msgh_descriptor_count = 2; + #if UseStaticTemplates + InP->thread = threadTemplate; + InP->thread.name = thread; + #else /* UseStaticTemplates */ + InP->thread.name = thread; + InP->thread.disposition = 19; + InP->thread.type = MACH_MSG_PORT_DESCRIPTOR; + #endif /* UseStaticTemplates */ + + #if UseStaticTemplates + InP->task = taskTemplate; + InP->task.name = task; + #else /* UseStaticTemplates */ + InP->task.name = task; + InP->task.disposition = 19; + InP->task.type = MACH_MSG_PORT_DESCRIPTOR; + #endif /* UseStaticTemplates */ + + InP->NDR = NDR_record; + + InP->exception = exception; + + if (codeCnt > 2) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->code, (const char *) code, 8 * codeCnt); + + InP->codeCnt = codeCnt; + + msgh_size_delta = (8 * codeCnt); + msgh_size = (mach_msg_size_t)(sizeof(Request) - 592) + msgh_size_delta; + InP = (Request *) ((pointer_t) InP + msgh_size_delta - 16); + + InP->flavor = *flavor; + + if (old_stateCnt > 144) { + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) InP->old_state, (const char *) old_state, 4 * old_stateCnt); + + InP->old_stateCnt = old_stateCnt; + + msgh_size += (4 * old_stateCnt); + InP = &Mess.In; + InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = exception_port; + InP->Head.msgh_reply_port = mig_get_reply_port(); + InP->Head.msgh_id = 2407; + + __BeforeSendRpc(2407, "mach_exception_raise_state_identity_OVR") + msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, msgh_size, (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(2407, "mach_exception_raise_state_identity_OVR") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + { return msg_result; } + } + + + #if defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) + check_result = __MIG_check__Reply__mach_exception_raise_state_identity_t((__Reply__mach_exception_raise_state_identity_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) + { return check_result; } + #endif /* defined(__MIG_check__Reply__mach_exception_raise_state_identity_t__defined) */ + + *flavor = Out0P->flavor; + + if (Out0P->new_stateCnt > 144) { + (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * 144); + *new_stateCnt = Out0P->new_stateCnt; + { return MIG_ARRAY_TOO_LARGE; } + } + (void)memcpy((char *) new_state, (const char *) Out0P->new_state, 4 * Out0P->new_stateCnt); + + *new_stateCnt = Out0P->new_stateCnt; + + return KERN_SUCCESS; +} + +#if defined(__cplusplus) + } /* extern "C" */ +#endif + +/* End mach_excUser.c */ + + + + +/* Begin mach_excServer.c */ + +/* Module mach_exc */ + +#define __MIG_check__Request__mach_exc_subsystem__ 1 +#define __NDR_convert__Request__mach_exc_subsystem__ 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(__cplusplus) + extern "C" { +#endif + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef __DeclareRcvRpc +#define __DeclareRcvRpc(_NUM_, _NAME_) +#endif /* __DeclareRcvRpc */ + +#ifndef __BeforeRcvRpc +#define __BeforeRcvRpc(_NUM_, _NAME_) +#endif /* __BeforeRcvRpc */ + +#ifndef __AfterRcvRpc +#define __AfterRcvRpc(_NUM_, _NAME_) +#endif /* __AfterRcvRpc */ + +#ifndef __DeclareRcvSimple +#define __DeclareRcvSimple(_NUM_, _NAME_) +#endif /* __DeclareRcvSimple */ + +#ifndef __BeforeRcvSimple +#define __BeforeRcvSimple(_NUM_, _NAME_) +#endif /* __BeforeRcvSimple */ + +#ifndef __AfterRcvSimple +#define __AfterRcvSimple(_NUM_, _NAME_) +#endif /* __AfterRcvSimple */ + +#define novalue void + +#ifndef msgh_request_port + #define msgh_request_port msgh_local_port +#endif +#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) +#ifndef msgh_reply_port + #define msgh_reply_port msgh_remote_port +#endif +#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) + +#define MIG_RETURN_ERROR(X, code) {\ + ((mig_reply_error_t *)X)->RetCode = code;\ + ((mig_reply_error_t *)X)->NDR = NDR_record;\ + return;\ + } + +/* typedefs for all requests */ + +#ifndef __Request__mach_exc_subsystem__defined +#define __Request__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } __Request__mach_exception_raise_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[144]; + } __Request__mach_exception_raise_state_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[144]; + } __Request__mach_exception_raise_state_identity_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_exc_subsystem__defined */ + +/* typedefs for all replies */ + +#ifndef __Reply__mach_exc_subsystem__defined +#define __Reply__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_exception_raise_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[144]; + } __Reply__mach_exception_raise_state_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[144]; + } __Reply__mach_exception_raise_state_identity_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_exc_subsystem__defined */ + + +/* union of all replies */ + +#ifndef __ReplyUnion__catch_mach_exc_subsystem__defined +#define __ReplyUnion__catch_mach_exc_subsystem__defined +union __ReplyUnion__catch_mach_exc_subsystem { + __Reply__mach_exception_raise_t Reply_mach_exception_raise; + __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; + __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; +}; +#endif /* __RequestUnion__catch_mach_exc_subsystem__defined */ +/* Forward Declarations */ + + +mig_internal novalue _Xmach_exception_raise_OVR + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state_OVR + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +mig_internal novalue _Xmach_exception_raise_state_identity_OVR + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + + +#if ( __MigTypeCheck || __NDR_convert__ ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_t__defined) +#define __MIG_check__Request__mach_exception_raise_t__defined +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined +#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__int_rep__exception_type_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__int_rep__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__int_rep__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__int_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__int_rep__int64_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(a, f) \ + __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(a, f) \ + __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined +#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__char_rep__exception_type_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__char_rep__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__char_rep__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__char_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined +#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__char_rep__int64_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined +#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__float_rep__exception_type_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__float_rep__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__float_rep__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(a, f) \ + __NDR_convert__float_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined +#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__float_rep__int64_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined */ + + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_t *In0P) +{ + const size_t sizeofRequest = sizeof(__Request__mach_exception_raise_t); + + typedef __Request__mach_exception_raise_t __Request; + #if __MigTypeCheck + unsigned int msgh_size; + #endif /* __MigTypeCheck */ + + #if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeofRequest - 16)) || (msgh_size > (mach_msg_size_t)sizeofRequest)) + return MIG_BAD_ARGUMENTS; + #endif /* __MigTypeCheck */ + + #if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; + #endif /* __MigTypeCheck */ + + #if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined */ + #if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 16)) / 8 != In0P->codeCnt) || + (msgh_size != (mach_msg_size_t)(sizeofRequest - 16) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) { + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__exception__defined */ + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_t__code__defined */ + } + #endif /* defined(__NDR_convert__int_rep...) */ + + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined) || \ + defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined) || \ + 0 + if (In0P->NDR.char_rep != NDR_record.char_rep) { + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.char_rep); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__exception__defined */ + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_t__code__defined */ + } + #endif /* defined(__NDR_convert__char_rep...) */ + + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined) || \ + defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined) || \ + 0 + if (In0P->NDR.float_rep != NDR_record.float_rep) { + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_t__exception(&In0P->exception, In0P->NDR.float_rep); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__exception__defined */ + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_t__code__defined */ + } + #endif /* defined(__NDR_convert__float_rep...) */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ + + +/* Routine catch_mach_exception_raise_OVR */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_OVR +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine _Xmach_exception_raise_OVR */ +mig_internal novalue _Xmach_exception_raise_OVR + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + mach_msg_trailer_t trailer; + } Request; + #ifdef __MigPackStructs + #pragma pack() + #endif + typedef __Request__mach_exception_raise_t __Request; + typedef __Reply__mach_exception_raise_t Reply; + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Reply *OutP = (Reply *) OutHeadP; + #ifdef __MIG_check__Request__mach_exception_raise_t__defined + kern_return_t check_result; + #endif /* __MIG_check__Request__mach_exception_raise_t__defined */ + + __DeclareRcvRpc(2405, "mach_exception_raise_OVR") + __BeforeRcvRpc(2405, "mach_exception_raise_OVR") + + #if defined(__MIG_check__Request__mach_exception_raise_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_t_OVR((__Request *)In0P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } + #endif /* defined(__MIG_check__Request__mach_exception_raise_t__defined) */ + + OutP->RetCode = catch_mach_exception_raise_OVR(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt); + + OutP->NDR = NDR_record; + + + __AfterRcvRpc(2405, "mach_exception_raise_OVR") +} + +#if ( __MigTypeCheck || __NDR_convert__ ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_t__defined +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined +#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__int_rep__exception_type_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__int_rep__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__int_rep__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__int_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__int_rep__int64_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(a, f) \ + __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(a, f) \ + __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined +#if defined(__NDR_convert__int_rep__mach_exc__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__int_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__int_rep__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__int_rep__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__int_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined +#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__thread_state_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__int_rep__natural_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) +#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__int_rep__uint32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(a, f) \ + __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(a, f) \ + __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined +#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__char_rep__exception_type_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__char_rep__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__char_rep__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__char_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined +#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__char_rep__int64_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined +#if defined(__NDR_convert__char_rep__mach_exc__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__char_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__char_rep__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__char_rep__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__char_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined +#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__thread_state_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__char_rep__natural_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) +#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__char_rep__uint32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined +#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__float_rep__exception_type_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__float_rep__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__float_rep__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(a, f) \ + __NDR_convert__float_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined +#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__float_rep__int64_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined +#if defined(__NDR_convert__float_rep__mach_exc__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__float_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__float_rep__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__float_rep__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(a, f) \ + __NDR_convert__float_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined +#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__thread_state_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__float_rep__natural_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) +#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__float_rep__uint32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined */ + + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_state_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_t **In1PP) +{ + + typedef __Request__mach_exception_raise_state_t __Request; + __Request *In1P; + #if __MigTypeCheck + unsigned int msgh_size; + #endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + + #if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if ((In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 592)) || (msgh_size > (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); + #if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 592)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeof(__Request) - 592) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; + #endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined */ + #if __MigTypeCheck + if ( In1P->old_stateCnt > 144 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeof(__Request) - 592)) / 4 != In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeof(__Request) - 592) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__codeCnt__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) { + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__exception__defined */ + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__code__defined */ + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__flavor__defined */ + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.int_rep, In1P->old_stateCnt); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_t__old_state__defined */ + } + #endif /* defined(__NDR_convert__int_rep...) */ + + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined) || \ + defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined) || \ + 0 || \ + defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ + defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ + 0 + if (In0P->NDR.char_rep != NDR_record.char_rep) { + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.char_rep); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__exception__defined */ + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__code__defined */ + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.char_rep); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__flavor__defined */ + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.char_rep, In1P->old_stateCnt); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_t__old_state__defined */ + } + #endif /* defined(__NDR_convert__char_rep...) */ + + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined) || \ + defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined) || \ + 0 || \ + defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined) || \ + defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined) || \ + 0 + if (In0P->NDR.float_rep != NDR_record.float_rep) { + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception(&In0P->exception, In0P->NDR.float_rep); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__exception__defined */ + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__code__defined */ + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor(&In1P->flavor, In0P->NDR.float_rep); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__flavor__defined */ + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state(&In1P->old_state, In0P->NDR.float_rep, In1P->old_stateCnt); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_t__old_state__defined */ + } + #endif /* defined(__NDR_convert__float_rep...) */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ + + +/* Routine mach_exception_raise_state_OVR */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state_OVR +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine _Xmach_exception_raise_state_OVR */ +mig_internal novalue _Xmach_exception_raise_state_OVR + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[144]; + mach_msg_trailer_t trailer; + } Request; + #ifdef __MigPackStructs + #pragma pack() + #endif + typedef __Request__mach_exception_raise_state_t __Request; + typedef __Reply__mach_exception_raise_state_t Reply; + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; + #ifdef __MIG_check__Request__mach_exception_raise_state_t__defined + kern_return_t check_result; + #endif /* __MIG_check__Request__mach_exception_raise_state_t__defined */ + + __DeclareRcvRpc(2406, "mach_exception_raise_state_OVR") + __BeforeRcvRpc(2406, "mach_exception_raise_state_OVR") + + #if defined(__MIG_check__Request__mach_exception_raise_state_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_t_OVR((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } + #endif /* defined(__MIG_check__Request__mach_exception_raise_state_t__defined) */ + + OutP->new_stateCnt = 144; + + OutP->RetCode = catch_mach_exception_raise_state_OVR(In0P->Head.msgh_request_port, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 576) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2406, "mach_exception_raise_state_OVR") +} + +#if ( __MigTypeCheck || __NDR_convert__ ) +#if __MIG_check__Request__mach_exc_subsystem__ +#if !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) +#define __MIG_check__Request__mach_exception_raise_state_identity_t__defined +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#if defined(__NDR_convert__int_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__int_rep__exception_type_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__int_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__int_rep__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__int_rep__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__int_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__int_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exception_data_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__int_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exc__int64_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__int_rep__int64_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__int_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(a, f) \ + __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(a, f) \ + __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#if defined(__NDR_convert__int_rep__mach_exc__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__int_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__int__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__int_rep__int((int *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_exc__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__int_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__int_rep__int32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__int_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#if defined(__NDR_convert__int_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__int_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__thread_state_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__int_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__int_rep__mach_exc__natural_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__int_rep__natural_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__int_rep__natural_t) +#elif defined(__NDR_convert__int_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__int_rep__uint32_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__int_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ + +#ifndef __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined +#if defined(__NDR_convert__int_rep__mach_exc__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(a, f) \ + __NDR_convert__int_rep__mach_exc__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#elif defined(__NDR_convert__int_rep__mach_msg_type_number_t__defined) +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined +#define __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(a, f) \ + __NDR_convert__int_rep__mach_msg_type_number_t((mach_msg_type_number_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#if defined(__NDR_convert__char_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__char_rep__exception_type_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__char_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__char_rep__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__char_rep__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__char_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined +#if defined(__NDR_convert__char_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__char_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exception_data_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__char_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exc__int64_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__char_rep__int64_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__char_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#if defined(__NDR_convert__char_rep__mach_exc__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__char_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__int__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__char_rep__int((int *)(a), f) +#elif defined(__NDR_convert__char_rep__mach_exc__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__char_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__char_rep__int32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__char_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ + +#ifndef __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#if defined(__NDR_convert__char_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__char_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__thread_state_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__char_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__char_rep__mach_exc__natural_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__char_rep__natural_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__char_rep__natural_t) +#elif defined(__NDR_convert__char_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__char_rep__uint32_t__defined) +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__char_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#if defined(__NDR_convert__float_rep__mach_exc__exception_type_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__float_rep__exception_type_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__float_rep__exception_type_t((exception_type_t *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__float_rep__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__float_rep__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(a, f) \ + __NDR_convert__float_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined +#if defined(__NDR_convert__float_rep__mach_exc__mach_exception_data_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__float_rep__mach_exc__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exception_data_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__float_rep__mach_exception_data_t((mach_exception_data_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exc__int64_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__int64_t) +#elif defined(__NDR_convert__float_rep__int64_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(a, f, c) \ + __NDR_convert__ARRAY((int64_t *)(a), f, c, __NDR_convert__float_rep__int64_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#if defined(__NDR_convert__float_rep__mach_exc__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__float_rep__mach_exc__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__int__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__float_rep__int((int *)(a), f) +#elif defined(__NDR_convert__float_rep__mach_exc__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__float_rep__mach_exc__int32_t((int32_t *)(a), f) +#elif defined(__NDR_convert__float_rep__int32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(a, f) \ + __NDR_convert__float_rep__int32_t((int32_t *)(a), f) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ + +#ifndef __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#if defined(__NDR_convert__float_rep__mach_exc__thread_state_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__float_rep__mach_exc__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__thread_state_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__float_rep__thread_state_t((thread_state_t *)(a), f, c) +#elif defined(__NDR_convert__float_rep__mach_exc__natural_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__natural_t) +#elif defined(__NDR_convert__float_rep__natural_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((natural_t *)(a), f, c, __NDR_convert__float_rep__natural_t) +#elif defined(__NDR_convert__float_rep__mach_exc__uint32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__mach_exc__uint32_t) +#elif defined(__NDR_convert__float_rep__uint32_t__defined) +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined +#define __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(a, f, c) \ + __NDR_convert__ARRAY((uint32_t *)(a), f, c, __NDR_convert__float_rep__uint32_t) +#endif /* defined(__NDR_convert__*__defined) */ +#endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ + + +mig_internal kern_return_t __MIG_check__Request__mach_exception_raise_state_identity_t_OVR(__attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t *In0P, __attribute__((__unused__)) __Request__mach_exception_raise_state_identity_t **In1PP) +{ + const size_t sizeofRequest = sizeof(__Request__mach_exception_raise_state_identity_t); + + typedef __Request__mach_exception_raise_state_identity_t __Request; + __Request *In1P; + #if __MigTypeCheck + unsigned int msgh_size; + #endif /* __MigTypeCheck */ + unsigned int msgh_size_delta; + + #if __MigTypeCheck + msgh_size = In0P->Head.msgh_size; + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 2) || + (msgh_size < (mach_msg_size_t)(sizeofRequest - 592)) || (msgh_size > (mach_msg_size_t)sizeofRequest)) + return MIG_BAD_ARGUMENTS; + #endif /* __MigTypeCheck */ + + #if __MigTypeCheck + if (In0P->thread.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->thread.disposition != 17) + return MIG_TYPE_ERROR; + #endif /* __MigTypeCheck */ + + #if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt(&In0P->codeCnt, In0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined */ + msgh_size_delta = (8 * In0P->codeCnt); + #if __MigTypeCheck + if ( In0P->codeCnt > 2 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 592)) / 8 < In0P->codeCnt) || + (msgh_size < (mach_msg_size_t)(sizeofRequest - 592) + (8 * In0P->codeCnt))) + return MIG_BAD_ARGUMENTS; + msgh_size -= msgh_size_delta; + #endif /* __MigTypeCheck */ + + *In1PP = In1P = (__Request *) ((pointer_t) In0P + msgh_size_delta - 16); + + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt(&In1P->old_stateCnt, In1P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined */ + #if __MigTypeCheck + if ( In1P->old_stateCnt > 144 ) + return MIG_BAD_ARGUMENTS; + if (((msgh_size - (mach_msg_size_t)(sizeofRequest - 592)) / 4 != In1P->old_stateCnt) || + (msgh_size != (mach_msg_size_t)(sizeofRequest - 592) + (4 * In1P->old_stateCnt))) + return MIG_BAD_ARGUMENTS; + #endif /* __MigTypeCheck */ + + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__codeCnt__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ + defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_stateCnt__defined) + if (In0P->NDR.int_rep != NDR_record.int_rep) { + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.int_rep, In0P->codeCnt); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__code__defined */ + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.int_rep); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ + #if defined(__NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) + __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.int_rep, In1P->old_stateCnt); + #endif /* __NDR_convert__int_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ + } + #endif /* defined(__NDR_convert__int_rep...) */ + + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ + defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ + 0 || \ + defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ + defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ + 0 + if (In0P->NDR.char_rep != NDR_record.char_rep) { + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.char_rep); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.char_rep, In0P->codeCnt); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__code__defined */ + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.char_rep); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ + #if defined(__NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) + __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.char_rep, In1P->old_stateCnt); + #endif /* __NDR_convert__char_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ + } + #endif /* defined(__NDR_convert__char_rep...) */ + + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined) || \ + defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined) || \ + 0 || \ + defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) || \ + defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) || \ + 0 + if (In0P->NDR.float_rep != NDR_record.float_rep) { + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception(&In0P->exception, In0P->NDR.float_rep); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__exception__defined */ + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code(&In0P->code, In0P->NDR.float_rep, In0P->codeCnt); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__code__defined */ + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor(&In1P->flavor, In0P->NDR.float_rep); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__flavor__defined */ + #if defined(__NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined) + __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state(&In1P->old_state, In0P->NDR.float_rep, In1P->old_stateCnt); + #endif /* __NDR_convert__float_rep__Request__mach_exception_raise_state_identity_t__old_state__defined */ + } + #endif /* defined(__NDR_convert__float_rep...) */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ +#endif /* __MIG_check__Request__mach_exc_subsystem__ */ +#endif /* ( __MigTypeCheck || __NDR_convert__ ) */ + + +/* Routine catch_mach_exception_raise_state_identity_OVR */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t catch_mach_exception_raise_state_identity_OVR +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state_identity_OVR */ +mig_internal novalue _Xmach_exception_raise_state_identity_OVR + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + + #ifdef __MigPackStructs + #pragma pack(4) + #endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[144]; + mach_msg_trailer_t trailer; + } Request; + #ifdef __MigPackStructs + #pragma pack() + #endif + typedef __Request__mach_exception_raise_state_identity_t __Request; + typedef __Reply__mach_exception_raise_state_identity_t Reply; + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Request *In1P; + Reply *OutP = (Reply *) OutHeadP; + #ifdef __MIG_check__Request__mach_exception_raise_state_identity_t__defined + kern_return_t check_result; + #endif /* __MIG_check__Request__mach_exception_raise_state_identity_t__defined */ + + __DeclareRcvRpc(2407, "mach_exception_raise_state_identity_OVR") + __BeforeRcvRpc(2407, "mach_exception_raise_state_identity_OVR") + + #if defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) + check_result = __MIG_check__Request__mach_exception_raise_state_identity_t_OVR((__Request *)In0P, (__Request **)&In1P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } + #endif /* defined(__MIG_check__Request__mach_exception_raise_state_identity_t__defined) */ + + OutP->new_stateCnt = 144; + + OutP->RetCode = catch_mach_exception_raise_state_identity_OVR(In0P->Head.msgh_request_port, In0P->thread.name, In0P->task.name, In0P->exception, In0P->code, In0P->codeCnt, &In1P->flavor, In1P->old_state, In1P->old_stateCnt, OutP->new_state, &OutP->new_stateCnt); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->flavor = In1P->flavor; + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply) - 576) + (((4 * OutP->new_stateCnt))); + + __AfterRcvRpc(2407, "mach_exception_raise_state_identity_OVR") +} + + +#ifdef mig_external + mig_external +#else + extern +#endif /* mig_external */ + boolean_t mach_exc_server_OVR(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +#ifdef mig_external + mig_external +#else + extern +#endif /* mig_external */ + mig_routine_t mach_exc_server_routine_OVR(mach_msg_header_t *InHeadP); + + +/* Description of this subsystem, for use in direct RPC */ +const struct catch_mach_exc_subsystem_OVR { + mig_server_routine_t server; /* Server routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + unsigned int maxsize; /* Max msg size */ + vm_address_t reserved; /* Reserved */ + struct routine_descriptor /*Array of routine descriptors */ + routine[3]; +} catch_mach_exc_subsystem_OVR = { + mach_exc_server_routine_OVR, + 2405, + 2408, + (mach_msg_size_t)sizeof(union __ReplyUnion__catch_mach_exc_subsystem), + (vm_address_t)0, + { + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_OVR, 6, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state_OVR, 9, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_t)}, + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xmach_exception_raise_state_identity_OVR, 11, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__mach_exception_raise_state_identity_t)}, + } +}; + +mig_external boolean_t mach_exc_server_OVR + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + register mig_routine_t routine; + + OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); + OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; + /* Minimal size: routine() will update it if different */ + OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); + OutHeadP->msgh_local_port = MACH_PORT_NULL; + OutHeadP->msgh_id = InHeadP->msgh_id + 100; + + if ((InHeadP->msgh_id > 2407) || (InHeadP->msgh_id < 2405) || + ((routine = catch_mach_exc_subsystem_OVR.routine[InHeadP->msgh_id - 2405].stub_routine) == 0)) + { + ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; + ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; + return FALSE; + } + (*routine) (InHeadP, OutHeadP); + return TRUE; +} + +mig_external mig_routine_t mach_exc_server_routine_OVR + (mach_msg_header_t *InHeadP) +{ + register int msgh_id; + + msgh_id = InHeadP->msgh_id - 2405; + + if ((msgh_id > 2) || (msgh_id < 0)) + return 0; + + return catch_mach_exc_subsystem_OVR.routine[msgh_id].stub_routine; +} + +#if defined(__cplusplus) + } /* extern "C" */ +#endif +/* End mach_excServer.c */ + +#elif defined(_MSC_VER) + +#pragma warning(disable: 4206) // nonstandard extension used : translation unit is empty + +#endif // __APPLE__ + diff --git a/LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.h b/LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.h new file mode 100644 index 0000000..4a1bcf0 --- /dev/null +++ b/LibOVRKernel/Src/Kernel/OVR_mach_exc_OSX.h @@ -0,0 +1,277 @@ +#ifndef _mach_exc_user_ +#define _mach_exc_user_ + +/* Module mach_exc */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef AUTOTEST +#ifndef FUNCTION_PTR_T +#define FUNCTION_PTR_T +typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); +typedef struct { + char *name; + function_ptr_t function; +} function_table_entry; +typedef function_table_entry *function_table_t; +#endif /* FUNCTION_PTR_T */ +#endif /* AUTOTEST */ + +#ifndef mach_exc_MSG_COUNT +#define mach_exc_MSG_COUNT 3 +#endif /* mach_exc_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + +#if defined(__cplusplus) + extern "C" { +#endif + +/* Routine mach_exception_raise_OVR */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_exception_raise_OVR +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine mach_exception_raise_state_OVR */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_exception_raise_state_OVR +( + mach_port_t exception_port, + exception_type_t exception, + const mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine mach_exception_raise_state_identity_OVR */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_exception_raise_state_identity_OVR +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + mach_exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +__END_DECLS + +/********************** Caution **************************/ +/* The following data types should be used to calculate */ +/* maximum message sizes only. The actual message may be */ +/* smaller, and the position of the arguments within the */ +/* message layout may vary from what is presented here. */ +/* For example, if any of the arguments are variable- */ +/* sized, and less than the maximum is sent, the data */ +/* will be packed tight in the actual message to reduce */ +/* the presence of holes. */ +/********************** Caution **************************/ + +/* typedefs for all requests */ + +#ifndef __Request__mach_exc_subsystem__defined +#define __Request__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + } __Request__mach_exception_raise_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[144]; + } __Request__mach_exception_raise_state_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_port_descriptor_t thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + int64_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[144]; + } __Request__mach_exception_raise_state_identity_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Request__mach_exc_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__mach_exc_subsystem__defined +#define __RequestUnion__mach_exc_subsystem__defined +union __RequestUnion__mach_exc_subsystem { + __Request__mach_exception_raise_t Request_mach_exception_raise; + __Request__mach_exception_raise_state_t Request_mach_exception_raise_state; + __Request__mach_exception_raise_state_identity_t Request_mach_exception_raise_state_identity; +}; +#endif /* !__RequestUnion__mach_exc_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_exc_subsystem__defined +#define __Reply__mach_exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_exception_raise_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[144]; + } __Reply__mach_exception_raise_state_t; +#ifdef __MigPackStructs +#pragma pack() +#endif + +#ifdef __MigPackStructs +#pragma pack(4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[144]; + } __Reply__mach_exception_raise_state_identity_t; +#ifdef __MigPackStructs +#pragma pack() +#endif +#endif /* !__Reply__mach_exc_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__mach_exc_subsystem__defined +#define __ReplyUnion__mach_exc_subsystem__defined +union __ReplyUnion__mach_exc_subsystem { + __Reply__mach_exception_raise_t Reply_mach_exception_raise; + __Reply__mach_exception_raise_state_t Reply_mach_exception_raise_state; + __Reply__mach_exception_raise_state_identity_t Reply_mach_exception_raise_state_identity; +}; +#endif /* !__RequestUnion__mach_exc_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_exc +#define subsystem_to_name_map_mach_exc \ + { "mach_exception_raise_OVR", 2405 },\ + { "mach_exception_raise_state_OVR", 2406 },\ + { "mach_exception_raise_state_identity_OVR", 2407 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +boolean_t mach_exc_server_OVR( + mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + + +#if defined(__cplusplus) + } // extern"C" +#endif + + +#endif /* _mach_exc_user_ */ diff --git a/LibOVRKernel/Src/Tracing/LibOVREvents.h b/LibOVRKernel/Src/Tracing/LibOVREvents.h new file mode 100644 index 0000000..dcdd688 --- /dev/null +++ b/LibOVRKernel/Src/Tracing/LibOVREvents.h @@ -0,0 +1,1076 @@ +//**********************************************************************` +//* This is an include file generated by Message Compiler. *` +//* *` +//* Copyright (c) Microsoft Corporation. All Rights Reserved. *` +//**********************************************************************` +#pragma once +#include +#include +#include "evntprov.h" +// +// Initial Defs +// +#if !defined(ETW_INLINE) +#define ETW_INLINE DECLSPEC_NOINLINE __inline +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +// +// Allow Diasabling of code generation +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION +#if !defined(McGenDebug) +#define McGenDebug(a,b) +#endif + + +#if !defined(MCGEN_TRACE_CONTEXT_DEF) +#define MCGEN_TRACE_CONTEXT_DEF +typedef struct _MCGEN_TRACE_CONTEXT +{ + TRACEHANDLE RegistrationHandle; + TRACEHANDLE Logger; + ULONGLONG MatchAnyKeyword; + ULONGLONG MatchAllKeyword; + ULONG Flags; + ULONG IsEnabled; + UCHAR Level; + UCHAR Reserve; + USHORT EnableBitsCount; + PULONG EnableBitMask; + const ULONGLONG* EnableKeyWords; + const UCHAR* EnableLevel; +} MCGEN_TRACE_CONTEXT, *PMCGEN_TRACE_CONTEXT; +#endif + +#if !defined(MCGEN_LEVEL_KEYWORD_ENABLED_DEF) +#define MCGEN_LEVEL_KEYWORD_ENABLED_DEF +FORCEINLINE +BOOLEAN +McGenLevelKeywordEnabled( + _In_ PMCGEN_TRACE_CONTEXT EnableInfo, + _In_ UCHAR Level, + _In_ ULONGLONG Keyword + ) +{ + // + // Check if the event Level is lower than the level at which + // the channel is enabled. + // If the event Level is 0 or the channel is enabled at level 0, + // all levels are enabled. + // + + if ((Level <= EnableInfo->Level) || // This also covers the case of Level == 0. + (EnableInfo->Level == 0)) { + + // + // Check if Keyword is enabled + // + + if ((Keyword == (ULONGLONG)0) || + ((Keyword & EnableInfo->MatchAnyKeyword) && + ((Keyword & EnableInfo->MatchAllKeyword) == EnableInfo->MatchAllKeyword))) { + return TRUE; + } + } + + return FALSE; + +} +#endif + +#if !defined(MCGEN_EVENT_ENABLED_DEF) +#define MCGEN_EVENT_ENABLED_DEF +FORCEINLINE +BOOLEAN +McGenEventEnabled( + _In_ PMCGEN_TRACE_CONTEXT EnableInfo, + _In_ PCEVENT_DESCRIPTOR EventDescriptor + ) +{ + + return McGenLevelKeywordEnabled(EnableInfo, EventDescriptor->Level, EventDescriptor->Keyword); + +} +#endif + + +// +// EnableCheckMacro +// +#ifndef MCGEN_ENABLE_CHECK +#define MCGEN_ENABLE_CHECK(Context, Descriptor) (Context.IsEnabled && McGenEventEnabled(&Context, &Descriptor)) +#endif + +#if !defined(MCGEN_CONTROL_CALLBACK) +#define MCGEN_CONTROL_CALLBACK + +DECLSPEC_NOINLINE __inline +VOID +__stdcall +McGenControlCallbackV2( + _In_ LPCGUID SourceId, + _In_ ULONG ControlCode, + _In_ UCHAR Level, + _In_ ULONGLONG MatchAnyKeyword, + _In_ ULONGLONG MatchAllKeyword, + _In_opt_ PEVENT_FILTER_DESCRIPTOR FilterData, + _Inout_opt_ PVOID CallbackContext + ) +/*++ + +Routine Description: + + This is the notification callback for Vista. + +Arguments: + + SourceId - The GUID that identifies the session that enabled the provider. + + ControlCode - The parameter indicates whether the provider + is being enabled or disabled. + + Level - The level at which the event is enabled. + + MatchAnyKeyword - The bitmask of keywords that the provider uses to + determine the category of events that it writes. + + MatchAllKeyword - This bitmask additionally restricts the category + of events that the provider writes. + + FilterData - The provider-defined data. + + CallbackContext - The context of the callback that is defined when the provider + called EtwRegister to register itself. + +Remarks: + + ETW calls this function to notify provider of enable/disable + +--*/ +{ + PMCGEN_TRACE_CONTEXT Ctx = (PMCGEN_TRACE_CONTEXT)CallbackContext; + ULONG Ix; +#ifndef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + UNREFERENCED_PARAMETER(SourceId); + UNREFERENCED_PARAMETER(FilterData); +#endif + + if (Ctx == NULL) { + return; + } + + switch (ControlCode) { + + case EVENT_CONTROL_CODE_ENABLE_PROVIDER: + Ctx->Level = Level; + Ctx->MatchAnyKeyword = MatchAnyKeyword; + Ctx->MatchAllKeyword = MatchAllKeyword; + Ctx->IsEnabled = EVENT_CONTROL_CODE_ENABLE_PROVIDER; + + for (Ix = 0; Ix < Ctx->EnableBitsCount; Ix += 1) { + if (McGenLevelKeywordEnabled(Ctx, Ctx->EnableLevel[Ix], Ctx->EnableKeyWords[Ix]) != FALSE) { + Ctx->EnableBitMask[Ix >> 5] |= (1 << (Ix % 32)); + } else { + Ctx->EnableBitMask[Ix >> 5] &= ~(1 << (Ix % 32)); + } + } + break; + + case EVENT_CONTROL_CODE_DISABLE_PROVIDER: + Ctx->IsEnabled = EVENT_CONTROL_CODE_DISABLE_PROVIDER; + Ctx->Level = 0; + Ctx->MatchAnyKeyword = 0; + Ctx->MatchAllKeyword = 0; + if (Ctx->EnableBitsCount > 0) { + RtlZeroMemory(Ctx->EnableBitMask, (((Ctx->EnableBitsCount - 1) / 32) + 1) * sizeof(ULONG)); + } + break; + + default: + break; + } + +#ifdef MCGEN_PRIVATE_ENABLE_CALLBACK_V2 + // + // Call user defined callback + // + MCGEN_PRIVATE_ENABLE_CALLBACK_V2( + SourceId, + ControlCode, + Level, + MatchAnyKeyword, + MatchAllKeyword, + FilterData, + CallbackContext + ); +#endif + + return; +} + +#endif +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION +//+ +// Provider OVR-SDK-LibOVR Event Count 19 +//+ +EXTERN_C __declspec(selectany) const GUID LibOVRProvider = {0x553787fc, 0xd3d7, 0x4f5e, {0xac, 0xb2, 0x15, 0x97, 0xc7, 0x20, 0x9b, 0x3c}}; + +// +// Channel +// +#define DEBUG_CHANNEL 0x10 +#define ANALYTIC_CHANNEL 0x11 +#define ERROR_CHANNEL 0x12 + +// +// Opcodes +// +#define FN_CALL 0xa +#define FN_RETURN 0xb +#define FN_WAYPOINT 0xc +#define DIS_BEGIN 0xd +#define DIS_WAITGPU 0xe +#define DIS_PRESENT 0xf +#define DIS_END 0x10 +#define HMD_DESC 0x11 +#define CAM_RECEIVE 0x12 +#define CAM_REQUEST 0x13 + +// +// Tasks +// +#define FN_TRACE 0x1 +#define DIS_TRACE 0x2 +#define HMD_TRACE 0x3 +#define CAMERA_TRACE 0x4 +#define LOG_TRACE 0x5 + +// +// Event Descriptors +// +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Call = {0x0, 0x0, 0x11, 0x4, 0xa, 0x1, 0x4000000000000000}; +#define Call_value 0x0 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Return = {0x1, 0x0, 0x11, 0x4, 0xb, 0x1, 0x4000000000000000}; +#define Return_value 0x1 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR Waypoint = {0x2, 0x0, 0x10, 0x4, 0xc, 0x1, 0x8000000000000000}; +#define Waypoint_value 0x2 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR DistortionBegin = {0x4, 0x0, 0x11, 0x4, 0xd, 0x2, 0x4000000000000000}; +#define DistortionBegin_value 0x4 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR DistortionWaitGPU = {0x5, 0x0, 0x11, 0x4, 0xe, 0x2, 0x4000000000000000}; +#define DistortionWaitGPU_value 0x5 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR DistortionPresent = {0x6, 0x0, 0x11, 0x4, 0xf, 0x2, 0x4000000000000000}; +#define DistortionPresent_value 0x6 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR DistortionEnd = {0x7, 0x0, 0x11, 0x4, 0x10, 0x2, 0x4000000000000000}; +#define DistortionEnd_value 0x7 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR HmdDesc = {0x8, 0x0, 0x11, 0x4, 0x11, 0x3, 0x4000000000000000}; +#define HmdDesc_value 0x8 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR CameraFrameReceived = {0x9, 0x0, 0x11, 0x4, 0x12, 0x4, 0x4000000000000000}; +#define CameraFrameReceived_value 0x9 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR CameraBeginProcessing = {0xa, 0x0, 0x11, 0x4, 0xd, 0x4, 0x4000000000000000}; +#define CameraBeginProcessing_value 0xa +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR CameraFrameRequest = {0xb, 0x0, 0x11, 0x4, 0x13, 0x4, 0x4000000000000000}; +#define CameraFrameRequest_value 0xb +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR CameraEndProcessing = {0xc, 0x0, 0x11, 0x4, 0x10, 0x4, 0x4000000000000000}; +#define CameraEndProcessing_value 0xc +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR CameraSkippedFrames = {0xd, 0x0, 0x11, 0x4, 0xc, 0x4, 0x4000000000000000}; +#define CameraSkippedFrames_value 0xd +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR JSONChunk = {0xe, 0x0, 0x11, 0x4, 0xc, 0x3, 0x4000000000000000}; +#define JSONChunk_value 0xe +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR LogDebugMessage = {0xf, 0x0, 0x10, 0x5, 0xc, 0x5, 0x8000000000000000}; +#define LogDebugMessage_value 0xf +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR LogInfoMessage = {0x10, 0x0, 0x11, 0x4, 0xc, 0x5, 0x4000000000000000}; +#define LogInfoMessage_value 0x10 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR LogErrorMessage = {0x11, 0x0, 0x12, 0x2, 0xc, 0x5, 0x2000000000000000}; +#define LogErrorMessage_value 0x11 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR HmdTrackingState = {0x12, 0x0, 0x11, 0x4, 0xc, 0x3, 0x4000000000000000}; +#define HmdTrackingState_value 0x12 +EXTERN_C __declspec(selectany) const EVENT_DESCRIPTOR CameraBlobs = {0x13, 0x0, 0x11, 0x4, 0xc, 0x4, 0x4000000000000000}; +#define CameraBlobs_value 0x13 + +// +// Note on Generate Code from Manifest Windows Vista and above +// +//Structures : are handled as a size and pointer pairs. The macro for the event will have an extra +//parameter for the size in bytes of the structure. Make sure that your structures have no extra padding. +// +//Strings: There are several cases that can be described in the manifest. For array of variable length +//strings, the generated code will take the count of characters for the whole array as an input parameter. +// +//SID No support for array of SIDs, the macro will take a pointer to the SID and use appropriate +//GetLengthSid function to get the length. +// + +// +// Allow Diasabling of code generation +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Globals +// + + +// +// Event Enablement Bits +// + +EXTERN_C __declspec(selectany) DECLSPEC_CACHEALIGN ULONG OVR_SDK_LibOVREnableBits[1]; +EXTERN_C __declspec(selectany) const ULONGLONG OVR_SDK_LibOVRKeywords[4] = {0x4000000000000000, 0x8000000000000000, 0x8000000000000000, 0x2000000000000000}; +EXTERN_C __declspec(selectany) const UCHAR OVR_SDK_LibOVRLevels[4] = {4, 4, 5, 2}; +EXTERN_C __declspec(selectany) MCGEN_TRACE_CONTEXT LibOVRProvider_Context = {0, 0, 0, 0, 0, 0, 0, 0, 4, OVR_SDK_LibOVREnableBits, OVR_SDK_LibOVRKeywords, OVR_SDK_LibOVRLevels}; + +EXTERN_C __declspec(selectany) REGHANDLE OVR_SDK_LibOVRHandle = (REGHANDLE)0; + +#if !defined(McGenEventRegisterUnregister) +#define McGenEventRegisterUnregister +DECLSPEC_NOINLINE __inline +ULONG __stdcall +McGenEventRegister( + _In_ LPCGUID ProviderId, + _In_opt_ PENABLECALLBACK EnableCallback, + _In_opt_ PVOID CallbackContext, + _Inout_ PREGHANDLE RegHandle + ) +/*++ + +Routine Description: + + This function register the provider with ETW USER mode. + +Arguments: + ProviderId - Provider Id to be register with ETW. + + EnableCallback - Callback to be used. + + CallbackContext - Context for this provider. + + RegHandle - Pointer to Registration handle. + +Remarks: + + If the handle != NULL will return ERROR_SUCCESS + +--*/ +{ + ULONG Error; + + + if (*RegHandle) { + // + // already registered + // + return ERROR_SUCCESS; + } + + Error = EventRegister( ProviderId, EnableCallback, CallbackContext, RegHandle); + + return Error; +} + + +DECLSPEC_NOINLINE __inline +ULONG __stdcall +McGenEventUnregister(_Inout_ PREGHANDLE RegHandle) +/*++ + +Routine Description: + + Unregister from ETW USER mode + +Arguments: + RegHandle this is the pointer to the provider context +Remarks: + If Provider has not register RegHandle = NULL, + return ERROR_SUCCESS +--*/ +{ + ULONG Error; + + + if(!(*RegHandle)) { + // + // Provider has not registerd + // + return ERROR_SUCCESS; + } + + Error = EventUnregister(*RegHandle); + *RegHandle = (REGHANDLE)0; + + return Error; +} +#endif +// +// Register with ETW Vista + +// +#ifndef EventRegisterOVR_SDK_LibOVR +#define EventRegisterOVR_SDK_LibOVR() McGenEventRegister(&LibOVRProvider, McGenControlCallbackV2, &LibOVRProvider_Context, &OVR_SDK_LibOVRHandle) +#endif + +// +// UnRegister with ETW +// +#ifndef EventUnregisterOVR_SDK_LibOVR +#define EventUnregisterOVR_SDK_LibOVR() McGenEventUnregister(&OVR_SDK_LibOVRHandle) +#endif + +// +// Enablement check macro for Call +// + +#define EventEnabledCall() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for Call +// +#define EventWriteCall(Name, Line, FrameID)\ + EventEnabledCall() ?\ + Template_zdq(OVR_SDK_LibOVRHandle, &Call, Name, Line, FrameID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for Return +// + +#define EventEnabledReturn() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for Return +// +#define EventWriteReturn(Name, Line, FrameID)\ + EventEnabledReturn() ?\ + Template_zdq(OVR_SDK_LibOVRHandle, &Return, Name, Line, FrameID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for Waypoint +// + +#define EventEnabledWaypoint() ((OVR_SDK_LibOVREnableBits[0] & 0x00000002) != 0) + +// +// Event Macro for Waypoint +// +#define EventWriteWaypoint(Name, Line, FrameID)\ + EventEnabledWaypoint() ?\ + Template_zdq(OVR_SDK_LibOVRHandle, &Waypoint, Name, Line, FrameID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for DistortionBegin +// + +#define EventEnabledDistortionBegin() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for DistortionBegin +// +#define EventWriteDistortionBegin(VidPnTargetId, FrameID)\ + EventEnabledDistortionBegin() ?\ + Template_qq(OVR_SDK_LibOVRHandle, &DistortionBegin, VidPnTargetId, FrameID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for DistortionWaitGPU +// + +#define EventEnabledDistortionWaitGPU() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for DistortionWaitGPU +// +#define EventWriteDistortionWaitGPU(VidPnTargetId, FrameID)\ + EventEnabledDistortionWaitGPU() ?\ + Template_qq(OVR_SDK_LibOVRHandle, &DistortionWaitGPU, VidPnTargetId, FrameID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for DistortionPresent +// + +#define EventEnabledDistortionPresent() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for DistortionPresent +// +#define EventWriteDistortionPresent(VidPnTargetId, FrameID)\ + EventEnabledDistortionPresent() ?\ + Template_qq(OVR_SDK_LibOVRHandle, &DistortionPresent, VidPnTargetId, FrameID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for DistortionEnd +// + +#define EventEnabledDistortionEnd() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for DistortionEnd +// +#define EventWriteDistortionEnd(VidPnTargetId, FrameID)\ + EventEnabledDistortionEnd() ?\ + Template_qq(OVR_SDK_LibOVRHandle, &DistortionEnd, VidPnTargetId, FrameID)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for HmdDesc +// + +#define EventEnabledHmdDesc() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for HmdDesc +// +#define EventWriteHmdDesc(Type, VendorId, ProductId, SerialNumber, FirmwareMajor, FirmwareMinor, HmdCaps, TrackingCaps, DistortionCaps, ResolutionWidth, ResolutionHeight)\ + EventEnabledHmdDesc() ?\ + Template_qlls24llqqqdd(OVR_SDK_LibOVRHandle, &HmdDesc, Type, VendorId, ProductId, SerialNumber, FirmwareMajor, FirmwareMinor, HmdCaps, TrackingCaps, DistortionCaps, ResolutionWidth, ResolutionHeight)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for CameraFrameReceived +// + +#define EventEnabledCameraFrameReceived() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraFrameReceived +// +#define EventWriteCameraFrameReceived(FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames)\ + EventEnabledCameraFrameReceived() ?\ + Template_fqggq(OVR_SDK_LibOVRHandle, &CameraFrameReceived, FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for CameraBeginProcessing +// + +#define EventEnabledCameraBeginProcessing() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraBeginProcessing +// +#define EventWriteCameraBeginProcessing(FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames)\ + EventEnabledCameraBeginProcessing() ?\ + Template_fqggq(OVR_SDK_LibOVRHandle, &CameraBeginProcessing, FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for CameraFrameRequest +// + +#define EventEnabledCameraFrameRequest() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraFrameRequest +// +#define EventWriteCameraFrameRequest(RequestNumber, FrameCounter, LastFrameNumber)\ + EventEnabledCameraFrameRequest() ?\ + Template_xxq(OVR_SDK_LibOVRHandle, &CameraFrameRequest, RequestNumber, FrameCounter, LastFrameNumber)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for CameraEndProcessing +// + +#define EventEnabledCameraEndProcessing() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraEndProcessing +// +#define EventWriteCameraEndProcessing(FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames)\ + EventEnabledCameraEndProcessing() ?\ + Template_fqggq(OVR_SDK_LibOVRHandle, &CameraEndProcessing, FrameRate, FrameNumber, ArrivalTimeSeconds, CaptureTime, LostFrames)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for CameraSkippedFrames +// + +#define EventEnabledCameraSkippedFrames() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraSkippedFrames +// +#define EventWriteCameraSkippedFrames(RequestNumber, FrameCounter, LastFrameNumber)\ + EventEnabledCameraSkippedFrames() ?\ + Template_xxq(OVR_SDK_LibOVRHandle, &CameraSkippedFrames, RequestNumber, FrameCounter, LastFrameNumber)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for JSONChunk +// + +#define EventEnabledJSONChunk() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for JSONChunk +// +#define EventWriteJSONChunk(Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk)\ + EventEnabledJSONChunk() ?\ + Template_zqqqqqb(OVR_SDK_LibOVRHandle, &JSONChunk, Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for LogDebugMessage +// + +#define EventEnabledLogDebugMessage() ((OVR_SDK_LibOVREnableBits[0] & 0x00000004) != 0) + +// +// Event Macro for LogDebugMessage +// +#define EventWriteLogDebugMessage(Message)\ + EventEnabledLogDebugMessage() ?\ + Template_s(OVR_SDK_LibOVRHandle, &LogDebugMessage, Message)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for LogInfoMessage +// + +#define EventEnabledLogInfoMessage() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for LogInfoMessage +// +#define EventWriteLogInfoMessage(Message)\ + EventEnabledLogInfoMessage() ?\ + Template_s(OVR_SDK_LibOVRHandle, &LogInfoMessage, Message)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for LogErrorMessage +// + +#define EventEnabledLogErrorMessage() ((OVR_SDK_LibOVREnableBits[0] & 0x00000008) != 0) + +// +// Event Macro for LogErrorMessage +// +#define EventWriteLogErrorMessage(Message)\ + EventEnabledLogErrorMessage() ?\ + Template_s(OVR_SDK_LibOVRHandle, &LogErrorMessage, Message)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for HmdTrackingState +// + +#define EventEnabledHmdTrackingState() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for HmdTrackingState +// +#define EventWriteHmdTrackingState(TimeInSeconds, HeadPoseQuat, HeadPoseTranslation, HeadAngularVelocity, HeadLinearVelocity, CameraPoseQuat, CameraPoseTranslation, SensorAccelerometer, SensorGyro, SensorMagnetometer, SensorTemperature, SensortTimeInSeconds, StatusFlags, LastCameraFrameCounter)\ + EventEnabledHmdTrackingState() ?\ + Template_gF4F3F3F3F4F3F3F3F3ffqq(OVR_SDK_LibOVRHandle, &HmdTrackingState, TimeInSeconds, HeadPoseQuat, HeadPoseTranslation, HeadAngularVelocity, HeadLinearVelocity, CameraPoseQuat, CameraPoseTranslation, SensorAccelerometer, SensorGyro, SensorMagnetometer, SensorTemperature, SensortTimeInSeconds, StatusFlags, LastCameraFrameCounter)\ + : ERROR_SUCCESS\ + +// +// Enablement check macro for CameraBlobs +// + +#define EventEnabledCameraBlobs() ((OVR_SDK_LibOVREnableBits[0] & 0x00000001) != 0) + +// +// Event Macro for CameraBlobs +// +#define EventWriteCameraBlobs(BlobCount, PositionX, PositionY, Size)\ + EventEnabledCameraBlobs() ?\ + Template_qGR0GR0DR0(OVR_SDK_LibOVRHandle, &CameraBlobs, BlobCount, PositionX, PositionY, Size)\ + : ERROR_SUCCESS\ + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + + +// +// Allow Diasabling of code generation +// +#ifndef MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +// +// Template Functions +// +// +//Template from manifest : FunctionWaypoint +// +#ifndef Template_zdq_def +#define Template_zdq_def +ETW_INLINE +ULONG +Template_zdq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_opt_ PCWSTR _Arg0, + _In_ const signed int _Arg1, + _In_ const unsigned int _Arg2 + ) +{ +#define ARGUMENT_COUNT_zdq 3 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zdq]; + + EventDataDescCreate(&EventData[0], + (_Arg0 != NULL) ? _Arg0 : L"NULL", + (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed int) ); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const unsigned int) ); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zdq, EventData); +} +#endif + +// +//Template from manifest : Distortion +// +#ifndef Template_qq_def +#define Template_qq_def +ETW_INLINE +ULONG +Template_qq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const unsigned int _Arg1 + ) +{ +#define ARGUMENT_COUNT_qq 2 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qq]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int) ); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qq, EventData); +} +#endif + +// +//Template from manifest : HmdDesc +// +#ifndef Template_qlls24llqqqdd_def +#define Template_qlls24llqqqdd_def +ETW_INLINE +ULONG +Template_qlls24llqqqdd( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_ const signed short _Arg1, + _In_ const signed short _Arg2, + _In_reads_(24) LPCCH _Arg3, + _In_ const signed short _Arg4, + _In_ const signed short _Arg5, + _In_ const unsigned int _Arg6, + _In_ const unsigned int _Arg7, + _In_ const unsigned int _Arg8, + _In_ const signed int _Arg9, + _In_ const signed int _Arg10 + ) +{ +#define ARGUMENT_COUNT_qlls24llqqqdd 11 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qlls24llqqqdd]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const signed short) ); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const signed short) ); + + EventDataDescCreate(&EventData[3], _Arg3, (ULONG)(sizeof(CHAR)*24)); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const signed short) ); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const signed short) ); + + EventDataDescCreate(&EventData[6], &_Arg6, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[7], &_Arg7, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[8], &_Arg8, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[9], &_Arg9, sizeof(const signed int) ); + + EventDataDescCreate(&EventData[10], &_Arg10, sizeof(const signed int) ); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qlls24llqqqdd, EventData); +} +#endif + +// +//Template from manifest : CameraFrameData +// +#ifndef Template_fqggq_def +#define Template_fqggq_def +ETW_INLINE +ULONG +Template_fqggq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const float _Arg0, + _In_ const unsigned int _Arg1, + _In_ const double _Arg2, + _In_ const double _Arg3, + _In_ const unsigned int _Arg4 + ) +{ +#define ARGUMENT_COUNT_fqggq 5 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_fqggq]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const float) ); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const double) ); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const double) ); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const unsigned int) ); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_fqggq, EventData); +} +#endif + +// +//Template from manifest : CameraFrameRequest +// +#ifndef Template_xxq_def +#define Template_xxq_def +ETW_INLINE +ULONG +Template_xxq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ unsigned __int64 _Arg0, + _In_ unsigned __int64 _Arg1, + _In_ const unsigned int _Arg2 + ) +{ +#define ARGUMENT_COUNT_xxq 3 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_xxq]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(unsigned __int64) ); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(unsigned __int64) ); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const unsigned int) ); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_xxq, EventData); +} +#endif + +// +//Template from manifest : JSONChunk +// +#ifndef Template_zqqqqqb_def +#define Template_zqqqqqb_def +ETW_INLINE +ULONG +Template_zqqqqqb( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_opt_ PCWSTR _Arg0, + _In_ const unsigned int _Arg1, + _In_ const unsigned int _Arg2, + _In_ const unsigned int _Arg3, + _In_ const unsigned int _Arg4, + _In_ const unsigned int _Arg5, + _In_reads_(_Arg4) const BYTE* _Arg6 + ) +{ +#define ARGUMENT_COUNT_zqqqqqb 7 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_zqqqqqb]; + + EventDataDescCreate(&EventData[0], + (_Arg0 != NULL) ? _Arg0 : L"NULL", + (_Arg0 != NULL) ? (ULONG)((wcslen(_Arg0) + 1) * sizeof(WCHAR)) : (ULONG)sizeof(L"NULL")); + + EventDataDescCreate(&EventData[1], &_Arg1, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[2], &_Arg2, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[3], &_Arg3, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[4], &_Arg4, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[5], &_Arg5, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[6], _Arg6, (ULONG)sizeof(char)*_Arg4); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_zqqqqqb, EventData); +} +#endif + +// +//Template from manifest : Log +// +#ifndef Template_s_def +#define Template_s_def +ETW_INLINE +ULONG +Template_s( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_opt_ LPCSTR _Arg0 + ) +{ +#define ARGUMENT_COUNT_s 1 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_s]; + + EventDataDescCreate(&EventData[0], + (_Arg0 != NULL) ? _Arg0 : "NULL", + (_Arg0 != NULL) ? (ULONG)((strlen(_Arg0) + 1) * sizeof(CHAR)) : (ULONG)sizeof("NULL")); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_s, EventData); +} +#endif + +// +//Template from manifest : HmdTrackingState +// +#ifndef Template_gF4F3F3F3F4F3F3F3F3ffqq_def +#define Template_gF4F3F3F3F4F3F3F3F3ffqq_def +ETW_INLINE +ULONG +Template_gF4F3F3F3F4F3F3F3F3ffqq( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const double _Arg0, + _In_reads_(4) const float *_Arg1, + _In_reads_(3) const float *_Arg2, + _In_reads_(3) const float *_Arg3, + _In_reads_(3) const float *_Arg4, + _In_reads_(4) const float *_Arg5, + _In_reads_(3) const float *_Arg6, + _In_reads_(3) const float *_Arg7, + _In_reads_(3) const float *_Arg8, + _In_reads_(3) const float *_Arg9, + _In_ const float _Arg10, + _In_ const float _Arg11, + _In_ const unsigned int _Arg12, + _In_ const unsigned int _Arg13 + ) +{ +#define ARGUMENT_COUNT_gF4F3F3F3F4F3F3F3F3ffqq 14 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_gF4F3F3F3F4F3F3F3F3ffqq]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const double) ); + + EventDataDescCreate(&EventData[1], _Arg1, sizeof(const float)*4); + + EventDataDescCreate(&EventData[2], _Arg2, sizeof(const float)*3); + + EventDataDescCreate(&EventData[3], _Arg3, sizeof(const float)*3); + + EventDataDescCreate(&EventData[4], _Arg4, sizeof(const float)*3); + + EventDataDescCreate(&EventData[5], _Arg5, sizeof(const float)*4); + + EventDataDescCreate(&EventData[6], _Arg6, sizeof(const float)*3); + + EventDataDescCreate(&EventData[7], _Arg7, sizeof(const float)*3); + + EventDataDescCreate(&EventData[8], _Arg8, sizeof(const float)*3); + + EventDataDescCreate(&EventData[9], _Arg9, sizeof(const float)*3); + + EventDataDescCreate(&EventData[10], &_Arg10, sizeof(const float) ); + + EventDataDescCreate(&EventData[11], &_Arg11, sizeof(const float) ); + + EventDataDescCreate(&EventData[12], &_Arg12, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[13], &_Arg13, sizeof(const unsigned int) ); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_gF4F3F3F3F4F3F3F3F3ffqq, EventData); +} +#endif + +// +//Template from manifest : CameraBlobs +// +#ifndef Template_qGR0GR0DR0_def +#define Template_qGR0GR0DR0_def +ETW_INLINE +ULONG +Template_qGR0GR0DR0( + _In_ REGHANDLE RegHandle, + _In_ PCEVENT_DESCRIPTOR Descriptor, + _In_ const unsigned int _Arg0, + _In_reads_(_Arg0) const double *_Arg1, + _In_reads_(_Arg0) const double *_Arg2, + _In_reads_(_Arg0) const signed int *_Arg3 + ) +{ +#define ARGUMENT_COUNT_qGR0GR0DR0 4 + + EVENT_DATA_DESCRIPTOR EventData[ARGUMENT_COUNT_qGR0GR0DR0]; + + EventDataDescCreate(&EventData[0], &_Arg0, sizeof(const unsigned int) ); + + EventDataDescCreate(&EventData[1], _Arg1, sizeof(const double)*_Arg0); + + EventDataDescCreate(&EventData[2], _Arg2, sizeof(const double)*_Arg0); + + EventDataDescCreate(&EventData[3], _Arg3, sizeof(const signed int)*_Arg0); + + return EventWrite(RegHandle, Descriptor, ARGUMENT_COUNT_qGR0GR0DR0, EventData); +} +#endif + +#endif // MCGEN_DISABLE_PROVIDER_CODE_GENERATION + +#if defined(__cplusplus) +}; +#endif + +#define MSG_OVR_SDK_LibOVR_opcode_FN_CALL_message 0x3000000AL +#define MSG_OVR_SDK_LibOVR_opcode_FN_RETURN_message 0x3000000BL +#define MSG_OVR_SDK_LibOVR_opcode_FN_WAYPOINT_message 0x3000000CL +#define MSG_OVR_SDK_LibOVR_opcode_DIS_BEGIN_message 0x3000000DL +#define MSG_OVR_SDK_LibOVR_opcode_DIS_WAITGPU_message 0x3000000EL +#define MSG_OVR_SDK_LibOVR_opcode_DIS_PRESENT_message 0x3000000FL +#define MSG_OVR_SDK_LibOVR_opcode_DIS_END_message 0x30000010L +#define MSG_OVR_SDK_LibOVR_opcode_HMD_DESC_message 0x30000011L +#define MSG_OVR_SDK_LibOVR_opcode_CAM_RECEIVE_message 0x30000012L +#define MSG_OVR_SDK_LibOVR_opcode_CAM_REQUEST_message 0x30000013L +#define MSG_level_Error 0x50000002L +#define MSG_level_Informational 0x50000004L +#define MSG_level_Verbose 0x50000005L +#define MSG_OVR_SDK_LibOVR_task_FN_TRACE_message 0x70000001L +#define MSG_OVR_SDK_LibOVR_task_DIS_TRACE_message 0x70000002L +#define MSG_OVR_SDK_LibOVR_task_HMD_TRACE_message 0x70000003L +#define MSG_OVR_SDK_LibOVR_task_CAMERA_TRACE_message 0x70000004L +#define MSG_OVR_SDK_LibOVR_task_LOG_TRACE_message 0x70000005L +#define MSG_OVR_SDK_LibOVR_event_0_message 0xB0000000L +#define MSG_OVR_SDK_LibOVR_event_1_message 0xB0000001L +#define MSG_OVR_SDK_LibOVR_event_2_message 0xB0000002L +#define MSG_OVR_SDK_LibOVR_event_4_message 0xB0000004L +#define MSG_OVR_SDK_LibOVR_event_5_message 0xB0000005L +#define MSG_OVR_SDK_LibOVR_event_6_message 0xB0000006L +#define MSG_OVR_SDK_LibOVR_event_7_message 0xB0000007L +#define MSG_OVR_SDK_LibOVR_event_8_message 0xB0000008L +#define MSG_OVR_SDK_LibOVR_event_9_message 0xB0000009L +#define MSG_OVR_SDK_LibOVR_event_10_message 0xB000000AL +#define MSG_OVR_SDK_LibOVR_event_11_message 0xB000000BL +#define MSG_OVR_SDK_LibOVR_event_12_message 0xB000000CL +#define MSG_OVR_SDK_LibOVR_event_13_message 0xB000000DL +#define MSG_OVR_SDK_LibOVR_event_14_message 0xB000000EL +#define MSG_OVR_SDK_LibOVR_event_15_message 0xB000000FL +#define MSG_OVR_SDK_LibOVR_event_16_message 0xB0000010L +#define MSG_OVR_SDK_LibOVR_event_17_message 0xB0000011L +#define MSG_OVR_SDK_LibOVR_event_18_message 0xB0000012L +#define MSG_OVR_SDK_LibOVR_event_19_message 0xB0000013L diff --git a/LibOVRKernel/Src/Tracing/LibOVREvents.man b/LibOVRKernel/Src/Tracing/LibOVREvents.man new file mode 100644 index 0000000..368d90b Binary files /dev/null and b/LibOVRKernel/Src/Tracing/LibOVREvents.man differ diff --git a/LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN b/LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN new file mode 100644 index 0000000..acb7d7b Binary files /dev/null and b/LibOVRKernel/Src/Tracing/LibOVREventsTEMP.BIN differ diff --git a/LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin b/LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin new file mode 100644 index 0000000..56365b0 Binary files /dev/null and b/LibOVRKernel/Src/Tracing/LibOVREvents_MSG00001.bin differ diff --git a/LibOVRKernel/Src/Tracing/README.md b/LibOVRKernel/Src/Tracing/README.md new file mode 100644 index 0000000..cbf3739 --- /dev/null +++ b/LibOVRKernel/Src/Tracing/README.md @@ -0,0 +1,55 @@ +#Setup + +If you want stack walking to work on x64: + + > reg add "HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management" -v DisablePagingExecutive -d 0x1 -t REG_DWORD -f + +Add USERS Read & Execute privileges to the folder (or one of its parents) containing the LibOVREvents.man file: + + > icacls . /grant BUILTIN\Users:(OI)(CI)(RX) + +To install or reinstall the ETW manifest after building LibOVR run `install.cmd` as Administrator: + + > install + +Note: the install script will also attempt to install the manifests for the driver and runtime. Also note that the install +script installs the manifest from the newest version of LibOVR.dll, which might not be the version you are debugging in +Visual Studio (this will only matter if the two versions have specified different events). To be safe make sure your build +is up-to-date. + +#Adding trace points + +See [./Tracing.h] and the examples in [../OVR_CAPI.cpp]. + +The following macros can be used to trace call/return and progress through a function: + + TraceCall(frameIndex) + TraceReturn(frameIndex) + TraceWaypoint(frameIndex) + +Try to place the Call/Return instrumentation as close as possible to the function entry/exit points, and don't forget +to instrument all return paths. + +Supply a frame index of 0 if a frame index is not applicable/available. + +#Adding new trace events + +Use the `ECManGen.exe` utility from the Windows 8.1 SDK to edit the `LibOVREvents.man` manifest. + +See [http://msdn.microsoft.com/en-us/library/windows/desktop/dd996930%28v=vs.85%29.aspx] +The `F1` help is also useful. + +#Rebuilding the ETW headers and resources + +Use the `build.cmd` script to regenerate the `LibOVREvents.h`, `LibOVREvents.rc` and `LibOVREvents*.bin` files. +`clean.cmd` will remove all generated files. + +Note that the outputs are checked into the repository so you'll need to `p4 edit` them first. + +#Capturing ETW traces + +See [../../../Tools/XPerf/README.md] + +#Viewing ETW traces with GPUView + +See [http://msdn.microsoft.com/en-us/library/windows/desktop/jj585574(v=vs.85).aspx] diff --git a/LibOVRKernel/Src/Tracing/Tracing.h b/LibOVRKernel/Src/Tracing/Tracing.h new file mode 100644 index 0000000..c14dc4a --- /dev/null +++ b/LibOVRKernel/Src/Tracing/Tracing.h @@ -0,0 +1,197 @@ +/************************************************************************************ + +PublicHeader: n/a +Filename : Tracing.h +Content : Performance tracing +Created : December 4, 2014 +Author : Ed Hutchins + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Tracing_h +#define OVR_Tracing_h + +//----------------------------------------------------------------------------------- +// ***** OVR_ENABLE_ETW_TRACING definition (XXX default to on for windows builds?) +// + +#ifdef OVR_OS_WIN32 +#define OVR_ENABLE_ETW_TRACING +#endif + +//----------------------------------------------------------------------------------- +// ***** Trace* definitions +// + +#ifdef OVR_ENABLE_ETW_TRACING + + #define TracingIsEnabled() (OVR_SDK_LibOVREnableBits[0] != 0) + + #ifdef TRACE_STATE_CAPTURE_FUNC + // hook in our own state capture callback to record the state of all opened HMDs (supress unused parameter warnings with void() casts) + #define MCGEN_PRIVATE_ENABLE_CALLBACK_V2(SourceId, ControlCode, Level, MatchAnyKeyword, MatchAllKeywords, FilterData, CallbackContext) \ + ( \ + void(SourceId), \ + void(Level), \ + void(MatchAnyKeyword), \ + void(MatchAllKeywords), \ + void(FilterData), \ + void(CallbackContext), \ + (((ControlCode) == EVENT_CONTROL_CODE_CAPTURE_STATE) ? (TRACE_STATE_CAPTURE_FUNC) : 0) \ + ) + #endif + + #if !defined(_In_reads_) + // get VS2010 working + #define _In_reads_(x) + #endif + + #include "LibOVREvents.h" + + // Register/Unregister the OVR_SDK_LibOVR provider with ETW + // (MCGEN_PRIVATE_ENABLE_CALLBACK_V2 hooks in our state capture) + #define TraceInit() \ + do { \ + ULONG status = EventRegisterOVR_SDK_LibOVR(); \ + if (ERROR_SUCCESS != status) { \ + LogError("[LibOVR] Failed to register ETW provider (%ul)", status); \ + } \ + } while (0) + #define TraceFini() EventUnregisterOVR_SDK_LibOVR() + + // Trace function call and return for perf, and waypoints for debug + #define TraceCall(frameIndex) EventWriteCall(__FUNCTIONW__, __LINE__, (frameIndex)) + #define TraceReturn(frameIndex) EventWriteReturn(__FUNCTIONW__, __LINE__, (frameIndex)) + #define TraceWaypoint(frameIndex) EventWriteWaypoint(__FUNCTIONW__, __LINE__, (frameIndex)) + + // DistortionRenderer events + #define TraceDistortionBegin(id, frameIndex) EventWriteDistortionBegin((id), (frameIndex)) + #define TraceDistortionWaitGPU(id, frameIndex) EventWriteDistortionWaitGPU((id), (frameIndex)) + #define TraceDistortionPresent(id, frameIndex) EventWriteDistortionPresent((id), (frameIndex)) + #define TraceDistortionEnd(id, frameIndex) EventWriteDistortionEnd((id), (frameIndex)) + + // Tracking Camera events + #define _TraceCameraFrameData(fn,img) \ + fn( \ + 0, \ + (img).FrameNumber, \ + (img).ArrivalTime, \ + (img).CaptureTime, \ + 0 \ + ) + #define TraceCameraFrameReceived(img) _TraceCameraFrameData(EventWriteCameraFrameReceived,(img)) + #define TraceCameraBeginProcessing(img) _TraceCameraFrameData(EventWriteCameraBeginProcessing,(img)) + #define TraceCameraFrameRequest(requestNumber, frameCount, lastFrameNumber) EventWriteCameraFrameRequest(requestNumber, frameCount, lastFrameNumber) + #define TraceCameraEndProcessing(img) _TraceCameraFrameData(EventWriteCameraEndProcessing,(img)) + #define TraceCameraSkippedFrames(requestNumber, frameCount, lastFrameNumber) EventWriteCameraSkippedFrames(requestNumber, frameCount, lastFrameNumber) + + // Trace the interesting parts of an ovrHmdDesc structure + #define TraceHmdDesc(desc) \ + EventWriteHmdDesc( \ + (desc).Type, \ + (desc).VendorId, \ + (desc).ProductId, \ + (desc).SerialNumber, \ + (desc).FirmwareMajor, \ + (desc).FirmwareMinor, \ + (desc).HmdCaps, \ + (desc).TrackingCaps, \ + (desc).DistortionCaps, \ + (desc).Resolution.w, \ + (desc).Resolution.h \ + ) + + // Trace part of a JSON string (events have a 64k limit) + #define TraceJSONChunk(Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk) \ + EventWriteJSONChunk(Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk) + + // Trace messages from the public ovr_Trace API and our internal logger + #define TraceLogDebug(message) EventWriteLogDebugMessage(message) + #define TraceLogInfo(message) EventWriteLogInfoMessage(message) + #define TraceLogError(message) EventWriteLogErrorMessage(message) + + // Trace an ovrTrackingState + #define TraceTrackingState(ts) \ + EventWriteHmdTrackingState( \ + (ts).HeadPose.TimeInSeconds, \ + &(ts).HeadPose.ThePose.Orientation.x, \ + &(ts).HeadPose.ThePose.Position.x, \ + &(ts).HeadPose.AngularVelocity.x, \ + &(ts).HeadPose.LinearVelocity.x, \ + &(ts).CameraPose.Orientation.x, \ + &(ts).CameraPose.Position.x, \ + &(ts).RawSensorData.Accelerometer.x, \ + &(ts).RawSensorData.Gyro.x, \ + &(ts).RawSensorData.Magnetometer.x, \ + (ts).RawSensorData.Temperature, \ + (ts).RawSensorData.TimeInSeconds, \ + (ts).StatusFlags, \ + (ts).LastCameraFrameCounter \ + ) + + #define TraceCameraBlobs(blobs) \ + if (EventEnabledCameraBlobs()) \ + { \ + const int max_blobs = 80; \ + int count = (blobs).GetSizeI(); \ + double x[max_blobs]; \ + double y[max_blobs]; \ + int size[max_blobs]; \ + if (count > max_blobs) \ + count = max_blobs; \ + for (int i = 0; i < count; ++i) \ + { \ + x[i] = (blobs)[i].Position.x; \ + y[i] = (blobs)[i].Position.y; \ + size[i] = (blobs)[i].BlobSize; \ + } \ + EventWriteCameraBlobs(count, x, y, size); \ + } \ + else ((void)0) + +#else // OVR_ENABLE_ETW_TRACING + + // Eventually other platforms could support their form of performance tracing + #define TracingIsEnabled() (false) + #define TraceInit() ((void)0) + #define TraceFini() ((void)0) + #define TraceCall(frameIndex) ((void)0) + #define TraceReturn(frameIndex) ((void)0) + #define TraceWaypoint(frameIndex) ((void)0) + #define TraceDistortionBegin(id, frameIndex) ((void)0) + #define TraceDistortionWaitGPU(id, frameIndex) ((void)0) + #define TraceDistortionPresent(id, frameIndex) ((void)0) + #define TraceDistortionEnd(id, frameIndex) ((void)0) + #define TraceCameraFrameReceived(cfd) ((void)0) + #define TraceCameraBeginProcessing(cfd) ((void)0) + #define TraceCameraFrameRequest(requestNumber, frameCount, lastFrameNumber) ((void)0) + #define TraceCameraEndProcessing(cfd) ((void)0) + #define TraceCameraSkippedFrames(requestNumber, frameCount, lastFrameNumber) ((void)0) + #define TraceHmdDesc(desc) ((void)0) + #define TraceJSONChunk(Name, TotalChunks, ChunkSequence, TotalSize, ChunkSize, ChunkOffset, Chunk) ((void)0) + #define TraceLogDebug(message) ((void)0) + #define TraceLogInfo(message) ((void)0) + #define TraceLogError(message) ((void)0) + #define TraceTrackingState(ts) ((void)0) + #define TraceCameraBlobs(blobs) ((void)0) + +#endif // OVR_ENABLE_ETW_TRACING + +#endif // OVR_Tracing_h diff --git a/LibOVRKernel/Src/Tracing/build.cmd b/LibOVRKernel/Src/Tracing/build.cmd new file mode 100644 index 0000000..7251627 --- /dev/null +++ b/LibOVRKernel/Src/Tracing/build.cmd @@ -0,0 +1,15 @@ +@echo off +REM +REM build.cmd - rebuild generated ETW tracing files from LibOVREvents.man +REM + +REM assume mc.exe is in a path relative to xperf.exe +for /f "delims=" %%a in ('where /F Xperf') do set XPERF_PATH=%%~dpa + +set OSTYPE=x86 +if not "%PROCESSOR_ARCHITECTURE%"=="x86" set OSTYPE=x64 +if not "%PROCESSOR_ARCHITEW6432%"=="" set OSTYPE=x64 + +set MC="%XPERF_PATH%..\bin\%OSTYPE%\mc.exe" + +%MC% -v -a -A -n -um .\LibOVREvents.man -h . -z LibOVREvents diff --git a/LibOVRKernel/Src/Tracing/clean.cmd b/LibOVRKernel/Src/Tracing/clean.cmd new file mode 100644 index 0000000..77200b5 --- /dev/null +++ b/LibOVRKernel/Src/Tracing/clean.cmd @@ -0,0 +1,6 @@ +@echo off +REM +REM clean.cmd - remove generated ETW tracing files +REM + +del LibOVREvents.h LibOVREvents.rc LibOVREvents*.bin *LibOVRRT*.dll diff --git a/LibOVRKernel/Src/Tracing/install.cmd b/LibOVRKernel/Src/Tracing/install.cmd new file mode 100644 index 0000000..5f64640 --- /dev/null +++ b/LibOVRKernel/Src/Tracing/install.cmd @@ -0,0 +1,115 @@ +@echo off +setlocal +REM run this script from an Admin shell to set up ETW tracing + +REM set SDK_MANIFEST_PATH to the SDK install path (e.g. C:\Program Files (x86)\Oculus) +for /f "delims=" %%a in ('reg query "HKLM\System\CurrentControlSet\Services\OVRService" -v "ImagePath"') do set SDK_MANIFEST_PATH=%%a +set SDK_MANIFEST_PATH=%SDK_MANIFEST_PATH:~34,-31%\Tools\ETW + +REM Add USERS Read & Execute privileges to the folder +icacls . /grant BUILTIN\Users:(OI)(CI)(RX) >nul +if %errorlevel% equ 0 goto CaclsOk + +echo Failed to set cacls, installation may fail + +:CaclsOk + +set OSTYPE=x64 +set RIFTENABLER_SYS=%windir%\System32\drivers\RiftEnabler.sys +set OCUSBVID_SYS=%windir%\System32\drivers\OCUSBVID.sys +set OVRDISPLAYRT_DLL=%windir%\System32\OVRDisplayRT64.dll +if "%PROCESSOR_ARCHITECTURE%"=="AMD64" goto GotOSTYPE +if "%PROCESSOR_ARCHITEW6432%"=="AMD64" goto GotOSTYPE +set OSTYPE=x86 +REM XXX is this right? +set RIFTENABLER_SYS=%windir%\System32\drivers\RiftEnabler.sys +set OCUSBVID_SYS=%windir%\System32\drivers\OCUSBVID.sys +set OVRDISPLAYRT_DLL=%windir%\System32\OVRDisplayRT32.dll + +:GotOSTYPE + +REM disable paging on x64 systems if stack walks are desired +if %OSTYPE% neq x64 goto SkipRegCheck +for /f "delims=" %%a in ('reg query "HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management" -v "DisablePagingExecutive"') do set REG_DPA=%%a + +if %REG_DPA:~-3% equ 0x1 goto SkipRegCheck +echo ************************ +echo DisablePagingExecutive should be set if you want stack tracing to work on %OSTYPE% +echo To disable paging run the following as Administrator: +echo reg add "HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management" -v DisablePagingExecutive -d 0x1 -t REG_DWORD -f +echo and reboot +echo ************************ + +:SkipRegCheck + +set RIFTDISPLAYDRIVER_DIR=..\..\..\RiftDisplayDriver +set RIFTCAMERADRIVER_DIR=..\..\..\RiftPTDriver + +if exist "%SDK_MANIFEST_PATH%\OVRKernelEvents.man" set KERNEL_EVENTS_MAN=%SDK_MANIFEST_PATH%\OVRKernelEvents.man +if exist "%RIFTDISPLAYDRIVER_DIR%\RiftEnabler\OVRKernelEvents.man" set KERNEL_EVENTS_MAN=%RIFTDISPLAYDRIVER_DIR%\RiftEnabler\OVRKernelEvents.man +if exist ".\OVRKernelEvents.man" set KERNEL_EVENTS_MAN=.\OVRKernelEvents.man + +echo Installing %RIFTENABLER_SYS% manifest... +REM uninstall any existing manifest first +wevtutil.exe uninstall-manifest "%KERNEL_EVENTS_MAN%" +if %errorlevel% neq 0 echo WARNING: This step failed. +wevtutil.exe install-manifest "%KERNEL_EVENTS_MAN%" /rf:%RIFTENABLER_SYS% /mf:%RIFTENABLER_SYS% +REM make sure it worked +wevtutil get-publisher OVR-Kernel > nul +if %errorlevel% neq 0 echo WARNING: This step failed. +echo Installed %KERNEL_EVENTS_MAN% + +if exist "%SDK_MANIFEST_PATH%\RTFilterEvents.man" set RFILTER_EVENTS_MAN=%SDK_MANIFEST_PATH%\RTFilterEvents.man +if exist "%RIFTDISPLAYDRIVER_DIR%\rt_filter\RTFilterEvents.man" set RFILTER_EVENTS_MAN=%RIFTDISPLAYDRIVER_DIR%\rt_filter\RTFilterEvents.man +if exist ".\RTFilterEvents.man" set RFILTER_EVENTS_MAN=.\RTFilterEvents.man + +echo Installing %OVRDISPLAYRT_DLL% manifest... +REM uninstall any existing manifest first +wevtutil.exe uninstall-manifest "%RFILTER_EVENTS_MAN%" +if %errorlevel% neq 0 echo WARNING: This step failed. +wevtutil.exe install-manifest "%RFILTER_EVENTS_MAN%" /rf:%OVRDISPLAYRT_DLL% /mf:%OVRDISPLAYRT_DLL% +REM make sure it worked +wevtutil get-publisher OVR-RTFilter > nul +if %errorlevel% neq 0 echo WARNING: This step failed. +echo Installed %RFILTER_EVENTS_MAN% + +if exist "%SDK_MANIFEST_PATH%\OVRUSBVidEvents.man" set USBVID_EVENTS_MAN=%SDK_MANIFEST_PATH%\OVRUSBVidEvents.man +if exist "%RIFTCAMERADRIVER_DIR%\OCUSBVID\OVRUSBVidEvents.man" set USBVID_EVENTS_MAN=%RIFTCAMERADRIVER_DIR%\OCUSBVID\OVRUSBVidEvents.man +if exist ".\OVRUSBVidEvents.man" set USBVID_EVENTS_MAN=.\OVRUSBVidEvents.man + +echo Installing %OCUSBVID_SYS% manifest... +REM uninstall any existing manifest first +wevtutil.exe uninstall-manifest "%USBVID_EVENTS_MAN%" +if %errorlevel% neq 0 echo WARNING: This step failed. +wevtutil.exe install-manifest "%USBVID_EVENTS_MAN%" /rf:%OCUSBVID_SYS% /mf:%OCUSBVID_SYS% +REM make sure it worked +wevtutil get-publisher OVR-USBVid > nul +if %errorlevel% neq 0 echo WARNING: This step failed. +echo Installed %USBVID_EVENTS_MAN% + +REM XXX eventually add OVR-Compositor here... + +if exist "%SDK_MANIFEST_PATH%\LibOVREvents.man" set LIBOVR_EVENTS_MAN=%SDK_MANIFEST_PATH%\LibOVREvents.man +if exist ".\LibOVREvents.man" set LIBOVR_EVENTS_MAN=.\LibOVREvents.man + +REM this nightmare command copies the newest version of LibOVRRT*.dll into the current directory without prompting... +forfiles /p:c:\Windows\System32 /m:LibOVRRT*.dll /c "cmd /c xcopy /y /f /d @path %cd% >nul" >nul 2>nul +forfiles /s /p:..\..\..\LibOVR\Lib\Windows /m:LibOVRRT*.dll /c "cmd /c xcopy /y /f /d @path %cd% >nul" >nul 2>nul +for /f "delims=" %%a in ('dir /b /o:d LibOVRRT*.dll') do set LIBOVR_DLL=%%a +set LIBOVR_DLL=%cd%\%LIBOVR_DLL% +echo Installing %LIBOVR_DLL% manifest... +REM uninstall any existing manifest first +wevtutil uninstall-manifest "%LIBOVR_EVENTS_MAN%" +if %errorlevel% neq 0 exit /b 1 +wevtutil install-manifest "%LIBOVR_EVENTS_MAN%" /rf:%LIBOVR_DLL% /mf:%LIBOVR_DLL% +REM make sure it worked +wevtutil get-publisher OVR-SDK-LibOVR > nul +if %errorlevel% neq 0 exit /b 1 +echo Installed %LIBOVR_EVENTS_MAN% + +echo You can now start/stop traces with the GUI: +echo cd ..\..\..\Tools\TraceScript\ovrtap +echo .\startovrtap.cmd +echo or (command-line): +echo cd ..\..\..\Tools\Xperf +echo log diff --git a/LibOVRKernel/Src/Util/GUIConsole.h b/LibOVRKernel/Src/Util/GUIConsole.h new file mode 100644 index 0000000..b5a3784 --- /dev/null +++ b/LibOVRKernel/Src/Util/GUIConsole.h @@ -0,0 +1,48 @@ +/************************************************************************************ + +Filename : GUIConsole.h +Content : A stdout console window that runs alongside Windows GUI applications +Created : Feb 4, 2013 +Authors : Brant Lewis + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_GuiConsole_h +#define OVR_Util_GuiConsole_h + +#include "../../Include/OVR_Kernel.h" + +#ifdef OVR_INTERNAL_USE + +#include "../Kernel/OVR_Win32_IncludeWindows.h" + +class GUIConsole +{ +public: + // constructors + GUIConsole(); + ~GUIConsole(); + + // member variables + HANDLE hStdIn, hStdOut, hStdError; +}; +#endif // #ifdef OVR_INTERNAL_USE + +#endif //OVR_Util_GuiConsole_h diff --git a/LibOVRKernel/Src/Util/Util_Direct3D.cpp b/LibOVRKernel/Src/Util/Util_Direct3D.cpp new file mode 100644 index 0000000..5aff711 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_Direct3D.cpp @@ -0,0 +1,154 @@ +/************************************************************************************ + +Filename : Util_Direct3D.cpp +Content : Shared code for Direct3D +Created : Oct 14, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Util_Direct3D.h" + +#include "Kernel/OVR_Log.h" + +namespace OVR { namespace D3DUtil { + + +bool VerifyHRESULT(const char* file, int line, HRESULT hr) +{ + if (FAILED(hr)) + { + LogError("D3D function returned fail HRESULT at %s on line %d : %s", + file, line, D3DUtil::GetWindowsErrorString(hr).ToCStr()); + OVR_ASSERT(false); + return false; + } + + return true; +} + +bool CheckD3D9Ex() +{ + bool available = false; + HMODULE libHandle = LoadLibraryW(L"d3d9.dll"); + + if (libHandle != nullptr) + { + available = (GetProcAddress(libHandle, "Direct3DCreate9Ex") != nullptr); + FreeLibrary(libHandle); + } + + return available; +} + +String GetWindowsErrorString(HRESULT hr) +{ + // DirectX 9 error strings + switch (hr) + { + case D3DERR_WRONGTEXTUREFORMAT: return "D3DERR_WRONGTEXTUREFORMAT"; + case D3DERR_UNSUPPORTEDCOLOROPERATION: return "D3DERR_UNSUPPORTEDCOLOROPERATION"; + case D3DERR_UNSUPPORTEDCOLORARG: return "D3DERR_UNSUPPORTEDCOLORARG"; + case D3DERR_UNSUPPORTEDALPHAOPERATION: return "D3DERR_UNSUPPORTEDALPHAOPERATION"; + case D3DERR_UNSUPPORTEDALPHAARG: return "D3DERR_UNSUPPORTEDALPHAARG"; + case D3DERR_TOOMANYOPERATIONS: return "D3DERR_TOOMANYOPERATIONS"; + case D3DERR_CONFLICTINGTEXTUREFILTER: return "D3DERR_CONFLICTINGTEXTUREFILTER"; + case D3DERR_UNSUPPORTEDFACTORVALUE: return "D3DERR_UNSUPPORTEDFACTORVALUE"; + case D3DERR_CONFLICTINGRENDERSTATE: return "D3DERR_CONFLICTINGRENDERSTATE"; + case D3DERR_UNSUPPORTEDTEXTUREFILTER: return "D3DERR_UNSUPPORTEDTEXTUREFILTER"; + case D3DERR_CONFLICTINGTEXTUREPALETTE: return "D3DERR_CONFLICTINGTEXTUREPALETTE"; + case D3DERR_DRIVERINTERNALERROR: return "D3DERR_DRIVERINTERNALERROR"; + case D3DERR_NOTFOUND: return "D3DERR_NOTFOUND"; + case D3DERR_MOREDATA: return "D3DERR_MOREDATA"; + case D3DERR_DEVICELOST: return "D3DERR_DEVICELOST"; + case D3DERR_DEVICENOTRESET: return "D3DERR_DEVICENOTRESET"; + case D3DERR_NOTAVAILABLE: return "D3DERR_NOTAVAILABLE"; + case D3DERR_OUTOFVIDEOMEMORY: return "D3DERR_OUTOFVIDEOMEMORY"; + case D3DERR_INVALIDDEVICE: return "D3DERR_INVALIDDEVICE"; + case D3DERR_INVALIDCALL: return "D3DERR_INVALIDCALL"; + case D3DERR_DRIVERINVALIDCALL: return "D3DERR_DRIVERINVALIDCALL"; + case D3DERR_WASSTILLDRAWING: return "D3DERR_WASSTILLDRAWING"; + case D3DOK_NOAUTOGEN: return "D3DOK_NOAUTOGEN"; + case D3DERR_DEVICEREMOVED: return "D3DERR_DEVICEREMOVED"; + case S_NOT_RESIDENT: return "S_NOT_RESIDENT"; + case S_RESIDENT_IN_SHARED_MEMORY: return "S_RESIDENT_IN_SHARED_MEMORY"; + case S_PRESENT_MODE_CHANGED: return "S_PRESENT_MODE_CHANGED"; + case S_PRESENT_OCCLUDED: return "S_PRESENT_OCCLUDED"; + case D3DERR_DEVICEHUNG: return "D3DERR_DEVICEHUNG"; + case D3DERR_UNSUPPORTEDOVERLAY: return "D3DERR_UNSUPPORTEDOVERLAY"; + case D3DERR_UNSUPPORTEDOVERLAYFORMAT: return "D3DERR_UNSUPPORTEDOVERLAYFORMAT"; + case D3DERR_CANNOTPROTECTCONTENT: return "D3DERR_CANNOTPROTECTCONTENT"; + case D3DERR_UNSUPPORTEDCRYPTO: return "D3DERR_UNSUPPORTEDCRYPTO"; + case D3DERR_PRESENT_STATISTICS_DISJOINT: return "D3DERR_PRESENT_STATISTICS_DISJOINT"; + default: break; // Not a DirectX 9 error, use FormatMessageA... + } + + char errorTextAddr[256] = {}; + + DWORD slen = FormatMessageA( + // use system message tables to retrieve error text + FORMAT_MESSAGE_FROM_SYSTEM + // allocate buffer on local heap for error text + | FORMAT_MESSAGE_ALLOCATE_BUFFER + // Important! will fail otherwise, since we're not + // (and CANNOT) pass insertion parameters + | FORMAT_MESSAGE_IGNORE_INSERTS, + nullptr, // unused with FORMAT_MESSAGE_FROM_SYSTEM + hr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + errorTextAddr, // output + 256, // minimum size for output buffer + nullptr); // arguments - see note + + char* errorText = *(char**)errorTextAddr; + + char formatStr[512]; + OVR_snprintf(formatStr, sizeof(formatStr), "[Code=%x = %d]", hr, hr); + + String retStr = formatStr; + + if (slen > 0 && errorText) + { + retStr += " "; + retStr += errorText; + + // release memory allocated by FormatMessage() + LocalFree(errorText); + } + + return retStr; +} + +void LogD3DCompileError(HRESULT hr, ID3DBlob* blob) +{ + if (FAILED(hr)) + { + char* errStr = (char*)blob->GetBufferPointer(); + SIZE_T len = blob->GetBufferSize(); + + if (errStr && len > 0) + { + LogError("Error compiling shader: %s", errStr); + } + } +} + + +}} // namespace OVR::D3DUtil diff --git a/LibOVRKernel/Src/Util/Util_Direct3D.h b/LibOVRKernel/Src/Util/Util_Direct3D.h new file mode 100644 index 0000000..958ef2b --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_Direct3D.h @@ -0,0 +1,102 @@ +/************************************************************************************ + +Filename : Util_Direct3D.h +Content : Shared code for Direct3D +Created : Oct 14, 2014 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#ifndef OVR_Util_Direct3D_h +#define OVR_Util_Direct3D_h + +// Include Windows correctly first before implicitly including it below +#include "Kernel/OVR_Win32_IncludeWindows.h" +#include "Kernel/OVR_String.h" + +// DirectX 9 Ex +#include + +// Direct3D 11 +#include +#include + +#if _MSC_VER >= 1800 + // Visual Studio 2013+ support newer D3D/DXGI headers. + #define OVR_D3D11_VER 2 + #include + #define OVR_DXGI_VER 3 + #include // Used in place of 1.2 for IDXGIFactory2 debug version (when available) +#elif _MSC_VER >= 1700 + // Visual Studio 2012+ only supports older D3D/DXGI headers. + #define OVR_D3D11_VER 1 + #include +#else + // Visual Studio 2010+ only supports original D3D/DXGI headers. + #define OVR_D3D11_VER 1 + #include +#endif + +namespace OVR { namespace D3DUtil { + + +// Check if D3D9Ex support exists in the environment +bool CheckD3D9Ex(); + +String GetWindowsErrorString(HRESULT hr); + + +//----------------------------------------------------------------------------- +// Helper macros for verifying HRESULT values from Direct3D API calls +// +// These will assert on failure in debug mode, and in release or debug mode +// these functions will report the file and line where the error occurred, +// and what the error code was to the log at Error-level. + +// Assert on HRESULT failure +bool VerifyHRESULT(const char* file, int line, HRESULT hr); + +#define OVR_D3D_CHECK(hr) OVR::D3DUtil::VerifyHRESULT(__FILE__, __LINE__, hr) + +// Returns provided value on failure +#define OVR_D3D_CHECK_RET_VAL(hr, failureValue) \ + { \ + if (!OVR_D3D_CHECK(hr)) \ + { \ + return failureValue; \ + } \ + } + +// Returns void on failure +#define OVR_D3D_CHECK_RET(hr) OVR_D3D_CHECK_RET_VAL(hr, ;) + +// Returns false on failure +#define OVR_D3D_CHECK_RET_FALSE(hr) OVR_D3D_CHECK_RET_VAL(hr, false) + +// Returns nullptr on failure +#define OVR_D3D_CHECK_RET_NULL(hr) OVR_D3D_CHECK_RET_VAL(hr, nullptr) + +// If the result is a failure, it will write the exact compile error to the error log +void LogD3DCompileError(HRESULT hr, ID3DBlob* errorBlob); + + +}} // namespace OVR::D3DUtil + +#endif // OVR_Util_Direct3D_h diff --git a/LibOVRKernel/Src/Util/Util_GetSystemSpecs.cpp b/LibOVRKernel/Src/Util/Util_GetSystemSpecs.cpp new file mode 100644 index 0000000..d2cbbab --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_GetSystemSpecs.cpp @@ -0,0 +1,455 @@ +/************************************************************************************ + +Filename : Util_GetSystemSpecs.cpp +Content : This code needs to be shared by applications, but can't be in LibOVR. + Define GET_SYSTEM_SPECS and include directly in a cpp file. +Created : Feb 27, 2015 +Authors : Kevin Jenkins (moved from RiftConfigUtil) + +Copyright : Copyright 2015 Oculus, Inc. All Rights reserved. + +Use of this software is subject to the terms of the Oculus Inc license +agreement provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +*************************************************************************************/ + +#if defined(GET_SYSTEM_SPECS) + +#ifndef WCHAR_TO_OVR_STRING +//Qt redefines wchar_t , but our String has an explicit constructor. Use this hack for desired behavior +#define WCHAR_TO_OVR_STRING(wchar_array) String() + wchar_array +#endif + +#include +#include +#include "Util/Util_SystemInfo.h" + +#if defined(OVR_OS_WIN32) + +#define _WIN32_DCOM +#include +#include +# pragma comment(lib, "wbemuuid.lib") +#include "DXGI.h" + +JSON* GetSystemSpecs() +{ + JSON* specs = JSON::CreateObject(); + HRESULT hres; + + IWbemLocator *pLoc = NULL; + + hres = CoCreateInstance( + CLSID_WbemLocator, + 0, + CLSCTX_INPROC_SERVER, + IID_IWbemLocator, (LPVOID *)&pLoc); + + if (FAILED(hres)) + { + + return specs; // Program has failed. + } + + IWbemServices *pSvc = NULL; + + // Connect to the root\cimv2 namespace with + // the current user and obtain pointer pSvc + // to make IWbemServices calls. + hres = pLoc->ConnectServer( + _bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace + NULL, // User name. NULL = current user + NULL, // User password. NULL = current + 0, // Locale. NULL indicates current + NULL, // Security flags. + 0, // Authority (for example, Kerberos) + 0, // Context object + &pSvc // pointer to IWbemServices proxy + ); + + if (FAILED(hres)) + { + + pLoc->Release(); + return specs; // Program has failed. + } + + hres = CoSetProxyBlanket( + pSvc, // Indicates the proxy to set + RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx + RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx + NULL, // Server principal name + RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx + RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx + NULL, // client identity + EOAC_NONE // proxy capabilities + ); + + if (FAILED(hres)) + { + + pSvc->Release(); + pLoc->Release(); + return specs; // Program has failed. + } + + + IEnumWbemClassObject* pEnumerator = NULL; + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT Caption FROM Win32_OperatingSystem"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator); + + if (FAILED(hres)) + { + + pSvc->Release(); + pLoc->Release(); + return specs; // Program has failed. + } + + IWbemClassObject *pclsObj; + ULONG uReturn = 0; + + while (pEnumerator) + { + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, + &pclsObj, &uReturn); + + if (0 == uReturn) + { + break; + } + + VARIANT vtProp; + + // Get the value of the Name property + hr = pclsObj->Get(L"Caption", 0, &vtProp, 0, 0); + specs->AddStringItem("Operating System", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + pclsObj->Release(); + } + pEnumerator = NULL; + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT Name FROM Win32_processor"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator); + + if (FAILED(hres)) + { + + pSvc->Release(); + pLoc->Release(); + return specs; // Program has failed. + } + + uReturn = 0; + while (pEnumerator) + { + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, + &pclsObj, &uReturn); + + if (0 == uReturn) + { + break; + } + + VARIANT vtProp; + + // Get the value of the Name property + hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0); + specs->AddStringItem("Processor", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + pclsObj->Release(); + } + + pEnumerator = NULL; + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT Name , AdapterRam, DriverVersion, VideoModeDescription FROM Win32_VideoController"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator); + + if (FAILED(hres)) + { + + pSvc->Release(); + pLoc->Release(); + return specs; // Program has failed. + } + + JSON* graphicsadapters = JSON::CreateArray(); + + uReturn = 0; + while (pEnumerator) + { + JSON* graphicscard = JSON::CreateObject(); + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, + &pclsObj, &uReturn); + + if (0 == uReturn) + { + break; + } + + VARIANT vtProp; + + // Get the value of the Name property + hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0); + graphicscard->AddStringItem("Name", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + // Get the value of the Name property + hr = pclsObj->Get(L"AdapterRam", 0, &vtProp, 0, 0); + uint32_t capacity = vtProp.uintVal; + graphicscard->AddNumberItem("Video Controller RAM (MB)", capacity / 1048576); + VariantClear(&vtProp); + + //get driver version + hr = pclsObj->Get(L"DriverVersion", 0, &vtProp, 0, 0); + graphicscard->AddStringItem("Driver Version", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + + //get resolution + hr = pclsObj->Get(L"VideoModeDescription", 0, &vtProp, 0, 0); + graphicscard->AddStringItem("Video Mode", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + + VariantClear(&vtProp); + pclsObj->Release(); + + graphicsadapters->AddArrayElement(graphicscard); + } + + specs->AddItem("Graphics Adapters", graphicsadapters); + + pEnumerator = NULL; + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT Capacity FROM Win32_PhysicalMemory"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator); + + if (FAILED(hres)) + { + + pSvc->Release(); + pLoc->Release(); + return specs; // Program has failed. + } + + uint64_t totalram = 0; + uReturn = 0; + while (pEnumerator) + { + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, + &pclsObj, &uReturn); + + if (0 == uReturn) + { + break; + } + + VARIANT vtProp; + + // Get the value of the Name property + hr = pclsObj->Get(L"Capacity", 0, &vtProp, 0, 0); + uint64_t capacity = QString::fromWCharArray(vtProp.bstrVal).toLongLong(); + totalram += capacity; + VariantClear(&vtProp); + pclsObj->Release(); + } + + specs->AddNumberItem("Total RAM (GB)", totalram / 1073741824.0); + + JSON* usbtree = JSON::CreateArray(); + + QMap antecedents; + + pEnumerator = NULL; + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT Antecedent,Dependent FROM Win32_USBControllerDevice"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator); + + if (FAILED(hres)) + { + + pSvc->Release(); + pLoc->Release(); + return specs; // Program has failed. + } + + VARIANT vtProp; + + while (pEnumerator) + { + HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, + &pclsObj, &uReturn); + + if (0 == uReturn) + { + break; + } + + // Get the reference value of the Antecedent property. There is not a function to dereference the value. + hr = pclsObj->Get(L"Antecedent", 0, &vtProp, 0, 0); + BSTR name = vtProp.bstrVal; + //sanitize the string input to just the output + QString antecedent = QString::fromWCharArray(name).split("=")[1].replace("\"", ""); + VariantClear(&vtProp); + + // Get the reference value of the Dependent property. There is not a function to dereference the value. + hr = pclsObj->Get(L"Dependent", 0, &vtProp, 0, 0); + name = vtProp.bstrVal; + //sanitize the string input to just the output + QString dependent = QString::fromWCharArray(name).split("=")[1].replace("\"", ""); + antecedents[antecedent].append(dependent); + VariantClear(&vtProp); + + } + for (int ant = 0; ant < antecedents.size(); ant++) + { + QString antecedent_name = antecedents.keys()[ant]; + //get antecedent object in a new enumerator + IEnumWbemClassObject* pEnumerator2 = NULL; + IWbemClassObject *pclsObj2; + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT Manufacturer, Name, DeviceID, Caption FROM WIN32_USBController where deviceid = '") + bstr_t(antecedent_name.toUtf8()) + bstr_t("'"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator2); + if (FAILED(hres)) + { + + pSvc->Release(); + pLoc->Release(); + return specs; // Program has failed. + } + + JSON* USBAntecedent = JSON::CreateObject(); + + while (pEnumerator2) + { + HRESULT hr = pEnumerator2->Next(WBEM_INFINITE, 1, + &pclsObj2, &uReturn); + + if (0 == uReturn) + { + break; + } + + VARIANT vtProp; + + // Get the value of the Name property + hr = pclsObj2->Get(L"Name", 0, &vtProp, 0, 0); + USBAntecedent->AddStringItem("name", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + // Get the value of the DeviceID property + hr = pclsObj2->Get(L"DeviceID", 0, &vtProp, 0, 0); + USBAntecedent->AddStringItem("deviceid", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + // Get the value of the caption property + hr = pclsObj2->Get(L"Caption", 0, &vtProp, 0, 0); + USBAntecedent->AddStringItem("caption", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + // Get the value of the manufacturer property + hr = pclsObj2->Get(L"Manufacturer", 0, &vtProp, 0, 0); + USBAntecedent->AddStringItem("manufacturer", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + pclsObj2->Release(); + } + JSON* devices = JSON::CreateArray(); + for (int dev = 0; dev < antecedents[antecedent_name].size(); ++dev) + { + //get antecedent object in a new enumerator + pEnumerator2 = NULL; + if (!pclsObj2) pclsObj2->Release(); + hres = pSvc->ExecQuery( + bstr_t("WQL"), + bstr_t("SELECT Manufacturer,Name FROM Win32_PnPEntity where DeviceID = '") + bstr_t(antecedents[antecedent_name][dev].toUtf8()) + bstr_t("'"), + WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, + NULL, + &pEnumerator2); + if (FAILED(hres)) + { + + pSvc->Release(); + pLoc->Release(); + return specs; // Program has failed. + } + + + while (pEnumerator2) + { + HRESULT hr = pEnumerator2->Next(WBEM_INFINITE, 1, + &pclsObj2, &uReturn); + + if (0 == uReturn) + { + break; + } + + VARIANT vtProp; + + JSON* properties = JSON::CreateObject(); + + // Get the value of the Manufacturer property + hr = pclsObj2->Get(L"Manufacturer", 0, &vtProp, 0, 0); + properties->AddStringItem("manufacturer", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + // Get the value of the Manufacturer property + hr = pclsObj2->Get(L"Name", 0, &vtProp, 0, 0); + properties->AddStringItem("name", WCHAR_TO_OVR_STRING(vtProp.bstrVal)); + VariantClear(&vtProp); + + pclsObj2->Release(); + devices->AddArrayElement(properties); + } + } + + USBAntecedent->AddItem("Devices", devices); + usbtree->AddArrayElement(USBAntecedent); + } + + specs->AddItem("USB Tree", usbtree); + + + // Cleanup + // ======== + pSvc->Release(); + pLoc->Release(); + pEnumerator->Release(); + if (!pclsObj) pclsObj->Release(); + return specs; +} +#endif +#ifdef OVR_OS_MAC +JSON* GetSystemSpecs() +{ + return nullptr; +} +#endif +#ifdef OVR_OS_LINUX +JSON* GetSystemSpecs() +{ + return nullptr; +} +#endif + +#endif // GET_SYSTEM_SPECS diff --git a/LibOVRKernel/Src/Util/Util_ImageWindow.cpp b/LibOVRKernel/Src/Util/Util_ImageWindow.cpp new file mode 100644 index 0000000..93a1aa4 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_ImageWindow.cpp @@ -0,0 +1,591 @@ +/************************************************************************************ + +Filename : Util_ImageWindow.cpp +Content : An output object for windows that can display raw images for testing +Created : March 13, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + + +#include "Kernel/OVR_Types.h" + +OVR_DISABLE_ALL_MSVC_WARNINGS() + +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_RefCount.h" +#include "Kernel/OVR_Log.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Nullptr.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Timer.h" +#include "Kernel/OVR_SysFile.h" + +#include "Util_ImageWindow.h" + +#if defined(OVR_OS_WIN32) + #include "Kernel/OVR_Win32_IncludeWindows.h" + #include "DWrite.h" +#endif + +OVR_RESTORE_ALL_MSVC_WARNINGS() + + +#if defined(OVR_OS_WIN32) + +typedef HRESULT (WINAPI *D2D1CreateFactoryFn)( + _In_ D2D1_FACTORY_TYPE, + _In_ REFIID, + _In_opt_ const D2D1_FACTORY_OPTIONS*, + _Out_ ID2D1Factory ** + ); + +typedef HRESULT (WINAPI *DWriteCreateFactoryFn)( + _In_ DWRITE_FACTORY_TYPE factoryType, + _In_ REFIID iid, + _Out_ IUnknown **factory + ); + + +namespace OVR { namespace Util { + +ID2D1Factory* ImageWindow::pD2DFactory = NULL; +IDWriteFactory* ImageWindow::pDWriteFactory = NULL; +HINSTANCE ImageWindow::hInstD2d1 = NULL; +HINSTANCE ImageWindow::hInstDwrite = NULL; + + +// TODO(review): This appears to be (at present) necessary, the global list is accessed by the +// render loop in Samples. In the current version, windows will just be lost when windowCount +// exceeds MaxWindows; I've left that in place, since this is unfamiliar code. I'm not sure what +// thread-safety guarantees this portion of the code needs to satisfy, so I don't want to +// change it to a list or whatever. Asserts added to catch the error. +ImageWindow* ImageWindow::globalWindow[ImageWindow::MaxWindows]; +int ImageWindow::windowCount = 0; + +LRESULT CALLBACK MainWndProc( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch (uMsg) + { + case WM_CREATE: + return 0; + + case WM_PAINT: + { + LONG_PTR ptr = GetWindowLongPtr( hwnd, GWLP_USERDATA ); + if( ptr ) + { + ImageWindow* iw = (ImageWindow*)ptr; + iw->OnPaint(); + } + } + + return 0; + + case WM_SIZE: + // Set the size and position of the window. + return 0; + + case WM_DESTROY: + // Clean up window-specific data objects. + return 0; + + // + // Process other messages. + // + + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } + //return 0; +} + + +ImageWindow::ImageWindow( uint32_t width, uint32_t height ) : + hWindow(NULL), + pRT(NULL), + //resolution(), + frontBufferMutex( new Mutex() ), + frames(), + greyBitmap(NULL), + colorBitmap(NULL) +{ + D2D1CreateFactoryFn createFactory = NULL; + DWriteCreateFactoryFn writeFactory = NULL; + + if (!hInstD2d1) + { + hInstD2d1 = LoadLibraryW( L"d2d1.dll" ); + } + + if (!hInstD2d1) + { + hInstD2d1 = LoadLibraryW( L"Dwrite.dll" ); + } + + if( hInstD2d1 ) + { + createFactory = (D2D1CreateFactoryFn)GetProcAddress( hInstD2d1, "D2D1CreateFactory" ); + } + + if( hInstDwrite ) + { + writeFactory = (DWriteCreateFactoryFn)GetProcAddress( hInstDwrite, "DWriteCreateFactory" ); + } + + // TODO: see note where globalWindow is declared. + globalWindow[windowCount++ % MaxWindows] = this; + OVR_ASSERT(windowCount < MaxWindows); + + if( pD2DFactory == NULL && createFactory && writeFactory ) + { + // Create a Direct2D factory. + HRESULT hResult = createFactory( + D2D1_FACTORY_TYPE_MULTI_THREADED, + __uuidof(ID2D1Factory), + NULL, + &pD2DFactory // This will be AddRef'd for us. + ); + OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); + + // Create a DirectWrite factory. + hResult = writeFactory( + DWRITE_FACTORY_TYPE_SHARED, + __uuidof(pDWriteFactory), // This probably should instead be __uuidof(IDWriteFactory) + reinterpret_cast(&pDWriteFactory) // This will be AddRef'd for us. + ); + OVR_ASSERT_AND_UNUSED(hResult == S_OK, hResult); + } + + resolution = D2D1::SizeU( width, height ); + + if (hWindow) + { + SetWindowLongPtr( hWindow, GWLP_USERDATA, (LONG_PTR)this ); + } +} + +ImageWindow::~ImageWindow() +{ + for( int i = 0; i < MaxWindows; ++i ) + { + if( globalWindow[i] == this ) + { + globalWindow[i] = NULL; + break; + } + } + + if( greyBitmap ) + greyBitmap->Release(); + + if( colorBitmap ) + colorBitmap->Release(); + + if( pRT ) + pRT->Release(); + + { + Mutex::Locker locker( frontBufferMutex ); + + while( frames.GetSize() ) + { + Ptr aFrame = frames.PopBack(); + } + } + + delete frontBufferMutex; + + if (hWindow) + { + ShowWindow( hWindow, SW_HIDE ); + DestroyWindow( hWindow ); + } + + if (pD2DFactory) + { + pD2DFactory->Release(); + pD2DFactory = NULL; + } + + if (pDWriteFactory) + { + pDWriteFactory->Release(); + pDWriteFactory = NULL; + } + + if( hInstD2d1 ) + { + FreeLibrary(hInstD2d1); + hInstD2d1 = NULL; + } + + if( hInstDwrite ) + { + FreeLibrary(hInstDwrite); + hInstDwrite = NULL; + } +} + +void ImageWindow::AssociateSurface( void* surface ) +{ + if (pD2DFactory) + { + // Assume an IUnknown + IUnknown* unknown = (IUnknown*)surface; + + IDXGISurface *pDxgiSurface = NULL; + HRESULT hr = unknown->QueryInterface(&pDxgiSurface); + if( hr == S_OK ) + { + D2D1_RENDER_TARGET_PROPERTIES props = + D2D1::RenderTargetProperties( + D2D1_RENDER_TARGET_TYPE_DEFAULT, + D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), + 96, + 96 + ); + + pRT = NULL; + ID2D1RenderTarget* tmpTarget; + + hr = pD2DFactory->CreateDxgiSurfaceRenderTarget( pDxgiSurface, &props, &tmpTarget ); + + if( hr == S_OK ) + { + DXGI_SURFACE_DESC desc = {0}; + pDxgiSurface->GetDesc( &desc ); + int width = desc.Width; + int height = desc.Height; + + D2D1_SIZE_U size = D2D1::SizeU( width, height ); + + D2D1_PIXEL_FORMAT pixelFormat = D2D1::PixelFormat( + DXGI_FORMAT_A8_UNORM, + D2D1_ALPHA_MODE_PREMULTIPLIED + ); + + D2D1_PIXEL_FORMAT colorPixelFormat = D2D1::PixelFormat( + DXGI_FORMAT_B8G8R8A8_UNORM, + D2D1_ALPHA_MODE_PREMULTIPLIED + ); + + D2D1_BITMAP_PROPERTIES bitmapProps; + bitmapProps.dpiX = 96; + bitmapProps.dpiY = 96; + bitmapProps.pixelFormat = pixelFormat; + + D2D1_BITMAP_PROPERTIES colorBitmapProps; + colorBitmapProps.dpiX = 96; + colorBitmapProps.dpiY = 96; + colorBitmapProps.pixelFormat = colorPixelFormat; + + HRESULT result = tmpTarget->CreateBitmap( size, bitmapProps, &greyBitmap ); + if( result != S_OK ) + { + tmpTarget->Release(); + tmpTarget = NULL; + } + + if (tmpTarget) + { + result = tmpTarget->CreateBitmap(size, colorBitmapProps, &colorBitmap); + if (result != S_OK) + { + tmpTarget->Release(); + tmpTarget = NULL; + } + } + pRT = tmpTarget; + } + } + } +} + +void ImageWindow::Process() +{ + if( pRT && greyBitmap ) + { + OnPaint(); + + pRT->Flush(); + } +} + +void ImageWindow::Complete() +{ + Mutex::Locker locker( frontBufferMutex ); + + if( frames.IsEmpty() ) + return; + + if( frames.PeekBack(0)->ready ) + return; + + Ptr frame = frames.PeekBack(0); + + frame->ready = true; +} + +void ImageWindow::OnPaint() +{ + Mutex::Locker locker( frontBufferMutex ); + + // Nothing to do + if( frames.IsEmpty() ) + return; + + if( !frames.PeekFront(0)->ready ) + return; + + Ptr currentFrame = frames.PopFront(); + + Ptr nextFrame = NULL; + + if( !frames.IsEmpty() ) + nextFrame = frames.PeekFront(0); + + while( nextFrame && nextFrame->ready ) + { + // Free up the current frame since it's been removed from the deque + currentFrame = frames.PopFront(); + + if( frames.IsEmpty() ) + break; + + nextFrame = frames.PeekFront(0); + } + + if( currentFrame->imageData ) + greyBitmap->CopyFromMemory( NULL, currentFrame->imageData, currentFrame->width ); + + if( currentFrame->colorImageData ) + colorBitmap->CopyFromMemory( NULL, currentFrame->colorImageData, currentFrame->colorPitch ); + + pRT->BeginDraw(); + + pRT->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED); + + pRT->Clear( D2D1::ColorF(D2D1::ColorF::Black) ); + + // This will mirror our image + D2D1_MATRIX_3X2_F m; + m._11 = -1; m._12 = 0; + m._21 = 0; m._22 = 1; + m._31 = 0; m._32 = 0; + pRT->SetTransform( m ); + + ID2D1SolidColorBrush* whiteBrush; + + pRT->CreateSolidColorBrush( D2D1::ColorF(D2D1::ColorF::White, 1.0f), &whiteBrush ); + + if( currentFrame->imageData ) + { + pRT->FillOpacityMask( greyBitmap, whiteBrush, + D2D1_OPACITY_MASK_CONTENT_TEXT_NATURAL, + D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), + //D2D1::RectF( 0.0f, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ), + D2D1::RectF( 0.0f, 0.0f, (FLOAT)resolution.width, (FLOAT)resolution.height ) ); + } + else if( currentFrame->colorImageData ) + { + pRT->DrawBitmap( colorBitmap, + D2D1::RectF( -(FLOAT)resolution.width, 0.0f, (FLOAT)0.0f, (FLOAT)resolution.height ) ); + + } + + pRT->SetTransform(D2D1::Matrix3x2F::Identity()); + + whiteBrush->Release(); + + Array::Iterator it; + + for( it = currentFrame->plots.Begin(); it != currentFrame->plots.End(); ++it ) + { + ID2D1SolidColorBrush* aBrush; + + pRT->CreateSolidColorBrush( D2D1::ColorF( it->r, it->g, it->b), &aBrush ); + + D2D1_ELLIPSE ellipse; + ellipse.point.x = it->x; + ellipse.point.y = it->y; + ellipse.radiusX = it->radius; + ellipse.radiusY = it->radius; + + if( it->fill ) + pRT->FillEllipse( &ellipse, aBrush ); + else + pRT->DrawEllipse( &ellipse, aBrush ); + + aBrush->Release(); + } + + static const WCHAR msc_fontName[] = L"Verdana"; + static const FLOAT msc_fontSize = 20; + + IDWriteTextFormat* textFormat = NULL; + + // Create a DirectWrite text format object. + pDWriteFactory->CreateTextFormat( + msc_fontName, + NULL, + DWRITE_FONT_WEIGHT_NORMAL, + DWRITE_FONT_STYLE_NORMAL, + DWRITE_FONT_STRETCH_NORMAL, + msc_fontSize, + L"", //locale + &textFormat + ); + + D2D1_SIZE_F renderTargetSize = pRT->GetSize(); + + Array::Iterator textIt; + for( textIt = currentFrame->textLines.Begin(); textIt != currentFrame->textLines.End(); ++textIt ) + { + ID2D1SolidColorBrush* aBrush; + + pRT->CreateSolidColorBrush( D2D1::ColorF( textIt->r, textIt->g, textIt->b), &aBrush ); + + WCHAR* tmpString = (WCHAR*)calloc( textIt->text.GetLength(), sizeof( WCHAR ) ); + for( unsigned i = 0; i < textIt->text.GetLength(); ++i ) + { + tmpString[i] = (WCHAR)textIt->text.GetCharAt( i ); + } + + pRT->DrawText( tmpString, (UINT32)textIt->text.GetLength(), textFormat, + D2D1::RectF(textIt->x, textIt->y, renderTargetSize.width, renderTargetSize.height), aBrush ); + + free( tmpString ); + + aBrush->Release(); + } + + if( textFormat ) + textFormat->Release(); + + pRT->EndDraw(); + + pRT->Flush(); +} + +Ptr ImageWindow::lastUnreadyFrame() +{ + static int framenumber = 0; + + if( frames.GetSize() && !frames.PeekBack( 0 )->ready ) + return frames.PeekBack( 0 ); + + // Create a new frame if an unready one doesn't already exist + Ptr tmpFrame = *new Frame( framenumber ); + frames.PushBack( tmpFrame ); + + ++framenumber; + + return tmpFrame; +} + +void ImageWindow::UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) +{ + if( pRT && greyBitmap ) + { + Mutex::Locker locker( frontBufferMutex ); + + Ptr frame = lastUnreadyFrame(); + frame->imageData = malloc( width * height ); + frame->width = width; + frame->height = height; + memcpy( frame->imageData, imageData, width * height ); + } +} + +void ImageWindow::UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) +{ + if( pRT && colorBitmap ) + { + Mutex::Locker locker( frontBufferMutex ); + + Ptr frame = lastUnreadyFrame(); + frame->colorImageData = malloc( pitch * height ); + frame->width = width; + frame->height = height; + frame->colorPitch = pitch; + memcpy( frame->colorImageData, imageData, pitch * height ); + } +} + +void ImageWindow::addCircle( float x, float y, float radius, float r, float g, float b, bool fill ) +{ + if( pRT ) + { + CirclePlot cp; + + cp.x = x; + cp.y = y; + cp.radius = radius; + cp.r = r; + cp.g = g; + cp.b = b; + cp.fill = fill; + + Mutex::Locker locker( frontBufferMutex ); + + Ptr frame = lastUnreadyFrame(); + frame->plots.PushBack( cp ); + } + +} + +void ImageWindow::addText( float x, float y, float r, float g, float b, OVR::String text ) +{ + if( pRT ) + { + TextPlot tp; + + tp.x = x; + tp.y = y; + tp.r = r; + tp.g = g; + tp.b = b; + tp.text = text; + + Mutex::Locker locker( frontBufferMutex ); + Ptr frame = lastUnreadyFrame(); + frame->textLines.PushBack( tp ); + } +} + +}} + +#else //defined(OVR_OS_WIN32) + +namespace OVR { namespace Util { + +ImageWindow* ImageWindow::globalWindow[4]; +int ImageWindow::windowCount = 0; + +}} + +#endif //#else //defined(OVR_OS_WIN32) + diff --git a/LibOVRKernel/Src/Util/Util_ImageWindow.h b/LibOVRKernel/Src/Util/Util_ImageWindow.h new file mode 100644 index 0000000..9874178 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_ImageWindow.h @@ -0,0 +1,201 @@ +/************************************************************************************ + +Filename : Util_ImageWindow.h +Content : An output object for windows that can display raw images for testing +Created : March 13, 2014 +Authors : Dean Beeler + +Copyright : Copyright 2014 Oculus, Inc. All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_ImageWindow_h +#define OVR_Util_ImageWindow_h + +#if defined(OVR_OS_WIN32) +#include "Kernel/OVR_Win32_IncludeWindows.h" +#include +#include +#endif + +#include "Kernel/OVR_Hash.h" +#include "Kernel/OVR_Array.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_Deque.h" + +#include + +namespace OVR { namespace Util { + +typedef struct +{ + float x; + float y; + float radius; + float r; + float g; + float b; + bool fill; +} CirclePlot; + +typedef struct +{ + float x; + float y; + float r; + float g; + float b; +OVR::String text; +} TextPlot; + +class Frame : virtual public RefCountBaseV +{ +public: + + Frame( int frame ) : + frameNumber( frame ), + plots(), + textLines(), + imageData( NULL ), + colorImageData( NULL ), + width( 0 ), + height( 0 ), + colorPitch( 0 ), + ready( false ) + { + + } + + ~Frame() + { + if( imageData ) + free( imageData ); + if( colorImageData ) + free( colorImageData ); + + plots.ClearAndRelease(); + textLines.ClearAndRelease(); + } + + int frameNumber; + + Array plots; + Array textLines; + void* imageData; + void* colorImageData; + int width; + int height; + int colorPitch; + bool ready; +}; + +#if defined(OVR_OS_WIN32) +class ImageWindow +{ + HWND hWindow; + ID2D1RenderTarget* pRT; + D2D1_SIZE_U resolution; + + Mutex* frontBufferMutex; + + InPlaceMutableDeque< Ptr > frames; + + ID2D1Bitmap* greyBitmap; + ID2D1Bitmap* colorBitmap; + +public: + // constructors + ImageWindow(); + ImageWindow( uint32_t width, uint32_t height ); + virtual ~ImageWindow(); + + void GetResolution( size_t& width, size_t& height ) { width = resolution.width; height = resolution.height; } + + void OnPaint(); // Called by Windows when it receives a WM_PAINT message + + void UpdateImage( const uint8_t* imageData, uint32_t width, uint32_t height ) { UpdateImageBW( imageData, width, height ); } + void UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ); + void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ); + void Complete(); // Called by drawing thread to submit a frame + + void Process(); // Called by rendering thread to do window processing + + void AssociateSurface( void* surface ); + + void addCircle( float x , float y, float radius, float r, float g, float b, bool fill ); + void addText( float x, float y, float r, float g, float b, OVR::String text ); + + static ImageWindow* GlobalWindow( int window ) { return globalWindow[window]; } + static int WindowCount() { return windowCount; } + +private: + + Ptr lastUnreadyFrame(); + + static const int MaxWindows = 4; + static ImageWindow* globalWindow[MaxWindows]; + static int windowCount; + static ID2D1Factory* pD2DFactory; + static IDWriteFactory* pDWriteFactory; + static HINSTANCE hInstD2d1; + static HINSTANCE hInstDwrite; + +}; + +#else + +class ImageWindow +{ +public: + // constructors + ImageWindow() {} + ImageWindow( uint32_t width, uint32_t height ) { OVR_UNUSED( width ); OVR_UNUSED( height ); } + virtual ~ImageWindow() { } + + void GetResolution( size_t& width, size_t& height ) { width = 0; height = 0; } + + void OnPaint() { } + + void UpdateImage( const uint8_t* imageData, uint32_t width, uint32_t height ) { UpdateImageBW( imageData, width, height ); } + void UpdateImageBW( const uint8_t* imageData, uint32_t width, uint32_t height ) { OVR_UNUSED( imageData ); OVR_UNUSED( width ); OVR_UNUSED( height ); } + void UpdateImageRGBA( const uint8_t* imageData, uint32_t width, uint32_t height, uint32_t pitch ) { OVR_UNUSED( imageData ); OVR_UNUSED( width ); OVR_UNUSED( height ); OVR_UNUSED( pitch ); } + void Complete() { } + + void Process() { } + + void AssociateSurface( void* surface ) { OVR_UNUSED(surface); } + + void addCircle( float x , float y, float radius, float r, float g, float b, bool fill ) { OVR_UNUSED( x ); OVR_UNUSED( y ); OVR_UNUSED( radius ); OVR_UNUSED( r ); OVR_UNUSED( g ); OVR_UNUSED( b ); OVR_UNUSED( fill ); } + void addText( float x, float y, float r, float g, float b, OVR::String text ) { OVR_UNUSED( x ); OVR_UNUSED( y ); OVR_UNUSED( r ); OVR_UNUSED( g ); OVR_UNUSED( b ); OVR_UNUSED( text ); } + + static ImageWindow* GlobalWindow( int window ) { return globalWindow[window]; } + static int WindowCount() { return windowCount; } + +private: + + static const int MaxWindows = 4; + static ImageWindow* globalWindow[4]; + static int windowCount; +}; + +#endif + +}} // namespace OVR::Util + + +#endif diff --git a/LibOVRKernel/Src/Util/Util_LongPollThread.cpp b/LibOVRKernel/Src/Util/Util_LongPollThread.cpp new file mode 100644 index 0000000..4feffc1 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_LongPollThread.cpp @@ -0,0 +1,97 @@ +/************************************************************************************ + +Filename : Util_LongPollThread.cpp +Content : Allows us to do all long polling tasks from a single thread to minimize deadlock risk +Created : June 30, 2013 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Util_LongPollThread.h" +#include "Util_Watchdog.h" + +OVR_DEFINE_SINGLETON(OVR::Util::LongPollThread); + +namespace OVR { namespace Util { + + +void LongPollThread::AddPollFunc(CallbackListener* func) +{ + PollSubject.AddListener(func); +} + +LongPollThread::LongPollThread() : + Terminated(false) +{ + Start(); + + // Must be at end of function + PushDestroyCallbacks(); +} + +LongPollThread::~LongPollThread() +{ + fireTermination(); + + Join(); +} + +void LongPollThread::OnThreadDestroy() +{ + fireTermination(); +} + +void LongPollThread::Wake() +{ + WakeEvent.SetEvent(); +} + +void LongPollThread::fireTermination() +{ + Terminated = true; + Wake(); +} + +void LongPollThread::OnSystemDestroy() +{ + Release(); +} + +int LongPollThread::Run() +{ + SetThreadName("LongPoll"); + WatchDog watchdog("LongPoll"); + + // While not terminated, + do + { + watchdog.Feed(10000); + + PollSubject.Call(); + + WakeEvent.Wait(WakeupInterval); + WakeEvent.ResetEvent(); + } while (!Terminated); + + return 0; +} + + +}} // namespace OVR::Util diff --git a/LibOVRKernel/Src/Util/Util_LongPollThread.h b/LibOVRKernel/Src/Util/Util_LongPollThread.h new file mode 100644 index 0000000..ac89781 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_LongPollThread.h @@ -0,0 +1,72 @@ +/************************************************************************************ + +Filename : Util_LongPollThread.h +Content : Allows us to do all long polling tasks from a single thread to minimize deadlock risk +Created : June 30, 2013 +Authors : Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_LongPollThread_h +#define OVR_Util_LongPollThread_h + +#include "Kernel/OVR_Timer.h" +#include "Kernel/OVR_Atomic.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_Callbacks.h" + +namespace OVR { namespace Util { + + +//----------------------------------------------------------------------------- +// LongPollThread + +// This thread runs long-polling subsystems that wake up every second or so +// The motivation is to reduce the number of threads that are running to minimize the risk of deadlock +class LongPollThread : public Thread, public SystemSingletonBase +{ + OVR_DECLARE_SINGLETON(LongPollThread); + virtual void OnThreadDestroy(); + +public: + typedef Delegate0 PollFunc; + static const int WakeupInterval = 1000; // milliseconds + + void AddPollFunc(CallbackListener* func); + + void Wake(); + +protected: + CallbackEmitter PollSubject; + + bool Terminated; + Event WakeEvent; + void fireTermination(); + + virtual int Run(); +}; + + +}} // namespace OVR::Util + +#endif // OVR_Util_LongPollThread_h diff --git a/LibOVRKernel/Src/Util/Util_SystemGUI.cpp b/LibOVRKernel/Src/Util/Util_SystemGUI.cpp new file mode 100644 index 0000000..ffab71e --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_SystemGUI.cpp @@ -0,0 +1,239 @@ +/************************************************************************************ + +Filename : Util_SystemGUI.cpp +Content : OS GUI access, usually for diagnostics. +Created : October 20, 2014 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Util_SystemGUI.h" + +#include "Kernel/OVR_UTF8Util.h" +#if defined(OVR_OS_WIN32) + #include "Kernel/OVR_Win32_IncludeWindows.h" +#endif // OVR_OS_WIN32 +#include "Kernel/OVR_Std.h" +#include +#include + + +namespace OVR { namespace Util { + + +static bool DisplayMessageBoxVaList(const char* pTitle, const char* pFormat, va_list argList) +{ + char buffer[512]; + char* pBuffer = buffer; + char* pAllocated = nullptr; + + va_list argListSaved; + OVR_VA_COPY(argListSaved, argList); + + int result = OVR_vsnprintf(buffer, OVR_ARRAY_COUNT(buffer), pFormat, argList); // Returns the required strlen of buffer. + + if(result >= (int)OVR_ARRAY_COUNT(buffer)) // If there was insufficient capacity... + { + pAllocated = new char[result + 1]; + pBuffer = pAllocated; + + va_end(argList); // The caller owns argList and will call va_end on it. + OVR_VA_COPY(argList, argListSaved); + + OVR_vsnprintf(pBuffer, (size_t)result + 1, pFormat, argList); + } + + bool returnValue = DisplayMessageBox(pTitle, pBuffer); + + delete[] pAllocated; // OK if it's nullptr. + + return returnValue; +} + + +bool DisplayMessageBoxF(const char* pTitle, const char* pFormat, ...) +{ + va_list argList; + va_start(argList, pFormat); + bool returnValue = DisplayMessageBoxVaList(pTitle, pFormat, argList); + va_end(argList); + return returnValue; +} + + + +#if defined(OVR_OS_MS) + +// On Windows we implement a manual dialog message box. The reason for this is that there's no way to +// have a message box like this without either using MFC or WinForms or relying on Windows Vista+. + +bool DisplayMessageBox(const char* pTitle, const char* pText) +{ + #define ID_EDIT 100 + + struct Dialog + { + static size_t LineCount(const char* pText) + { + size_t count = 0; + while(*pText) + { + if(*pText++ == '\n') + count++; + } + return count; + } + + static WORD* WordUp(WORD* pIn){ return (WORD*)((((uintptr_t)pIn + 3) >> 2) << 2); } + + static BOOL CALLBACK Proc(HWND hDlg, UINT iMsg, WPARAM wParam, LPARAM lParam) + { + switch (iMsg) + { + case WM_INITDIALOG: + { + HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT); + + const char* pText = (const char*)lParam; + SetWindowTextA(hWndEdit, pText); + + HFONT hFont = CreateFontW(-11, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, L"Courier New"); + if(hFont) + SendMessage(hWndEdit, WM_SETFONT, WPARAM(hFont), TRUE); + + SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0); + + return TRUE; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case ID_EDIT: + { + // Handle messages from the edit control here. + HWND hWndEdit = GetDlgItem(hDlg, ID_EDIT); + SendMessage(hWndEdit, EM_SETSEL, (WPARAM)0, (LPARAM)0); + return TRUE; + } + + case IDOK: + EndDialog(hDlg, 0); + return TRUE; + } + break; + case WM_CLOSE: + + EndDialog(hDlg, 0); + return TRUE; + } + + return FALSE; + } + }; + + + char dialogTemplateMemory[1024]; + memset(dialogTemplateMemory, 0, sizeof(dialogTemplateMemory)); + DLGTEMPLATE* pDlg = (LPDLGTEMPLATE)dialogTemplateMemory; + + const size_t textLength = strlen(pText); + const size_t textLineCount = Dialog::LineCount(pText); + + // Sizes are in Windows dialog units, which are relative to a character size. Depends on the font and environment settings. Often the pixel size will be ~3x the dialog unit x size. Often the pixel size will be ~3x the dialog unit y size. + const int kGutterSize = 6; // Empty border space around controls within the dialog + const int kButtonWidth = 24; + const int kButtonHeight = 10; + const int kDialogWidth = ((textLength > 1000) ? 600 : ((textLength > 400) ? 300 : 200)); // To do: Clip this against screen bounds. + const int kDialogHeight = ((textLineCount > 100) ? 400 : ((textLineCount > 25) ? 300 : ((textLineCount > 10) ? 200 : 100))); + + // Define a dialog box. + pDlg->style = WS_POPUP | WS_BORDER | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION; + pDlg->cdit = 2; // Control count + pDlg->x = 10; // X position To do: Center the dialog. + pDlg->y = 10; + pDlg->cx = (short)kDialogWidth; + pDlg->cy = (short)kDialogHeight; + WORD* pWord = (WORD*)(pDlg + 1); + *pWord++ = 0; // No menu + *pWord++ = 0; // Default dialog box class + + WCHAR* pWchar = (WCHAR*)pWord; + const size_t titleLength = strlen(pTitle); + size_t wcharCount = OVR::UTF8Util::DecodeString(pWchar, pTitle, (titleLength > 128) ? 128 : titleLength); + pWord += wcharCount + 1; + + // Define an OK button. + pWord = Dialog::WordUp(pWord); + + DLGITEMTEMPLATE* pDlgItem = (DLGITEMTEMPLATE*)pWord; + pDlgItem->x = pDlg->cx - (kGutterSize + kButtonWidth); + pDlgItem->y = pDlg->cy - (kGutterSize + kButtonHeight); + pDlgItem->cx = kButtonWidth; + pDlgItem->cy = kButtonHeight; + pDlgItem->id = IDOK; + pDlgItem->style = WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON; + + pWord = (WORD*)(pDlgItem + 1); + *pWord++ = 0xFFFF; + *pWord++ = 0x0080; // button class + + pWchar = (WCHAR*)pWord; + pWchar[0] = 'O'; pWchar[1] = 'K'; pWchar[2] = '\0'; // Not currently localized. + pWord += 3; // OK\0 + *pWord++ = 0; // no creation data + + // Define an EDIT contol. + pWord = Dialog::WordUp(pWord); + + pDlgItem = (DLGITEMTEMPLATE*)pWord; + pDlgItem->x = kGutterSize; + pDlgItem->y = kGutterSize; + pDlgItem->cx = pDlg->cx - (kGutterSize + kGutterSize); + pDlgItem->cy = pDlg->cy - (kGutterSize + kButtonHeight + kGutterSize + (kGutterSize / 2)); + pDlgItem->id = ID_EDIT; + pDlgItem->style = ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | ES_READONLY | WS_VSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD | WS_VISIBLE; + + pWord = (WORD*)(pDlgItem + 1); + *pWord++ = 0xFFFF; + *pWord++ = 0x0081; // edit class atom + *pWord++ = 0; // no creation data + + LRESULT ret = DialogBoxIndirectParam(NULL, (LPDLGTEMPLATE)pDlg, NULL, (DLGPROC)Dialog::Proc, (LPARAM)pText); + + return (ret != 0); +} + +#elif defined(OVR_OS_MAC) + +// For Apple we use the Objective C implementation in Util_GUI.mm + +#else + +// To do. +bool DisplayMessageBox(const char* pTitle, const char* pText) +{ + printf("\n\nMessageBox\n%s\n", pTitle); + printf("%s\n\n", pText); + return false; +} + +#endif + + +}} // namespace OVR::Util diff --git a/LibOVRKernel/Src/Util/Util_SystemGUI.h b/LibOVRKernel/Src/Util/Util_SystemGUI.h new file mode 100644 index 0000000..1cf99a2 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_SystemGUI.h @@ -0,0 +1,40 @@ +/************************************************************************************ + +Filename : Util_SystemGUI.h +Content : OS GUI access, usually for diagnostics. +Created : October 20, 2014 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_GUI_h +#define OVR_Util_GUI_h + + +namespace OVR { namespace Util { + + // Displays a modal message box on the default GUI display (not on a VR device). + // The message box interface (e.g. OK button) is not localized. + bool DisplayMessageBox(const char* pTitle, const char* pText); + + bool DisplayMessageBoxF(const char* pTitle, const char* pFormat, ...); + +} } // namespace OVR::Util + + +#endif diff --git a/LibOVRKernel/Src/Util/Util_SystemGUI_OSX.mm b/LibOVRKernel/Src/Util/Util_SystemGUI_OSX.mm new file mode 100644 index 0000000..cbfd057 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_SystemGUI_OSX.mm @@ -0,0 +1,69 @@ +/************************************************************************************ + +Filename : Util_SystemGUI.mm +Content : OS GUI access, usually for diagnostics. +Created : October 20, 2014 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + + + +#include "Util_SystemGUI.h" + +#include +#include + + +namespace OVR { namespace Util { + + +bool DisplayMessageBox(const char* pTitle, const char* pText) +{ + // To consider: Replace usage of CFUserNotificationDisplayAlert with something a little smarter. + + size_t titleLength = strlen(pTitle); + size_t textLength = strlen(pText); + if(textLength > 1500) // CFUserNotificationDisplayAlert isn't smart enough to handle large text sizes and screws up its size if so. + textLength = 1500; // Problem: this can theoretically split a UTF8 multibyte sequence. Need to find a divisible boundary. + CFAllocatorRef allocator = NULL; // To do: support alternative allocator. + CFStringRef titleRef = CFStringCreateWithBytes(allocator, (const UInt8*)pTitle, (CFIndex)titleLength, kCFStringEncodingUTF8, false); + CFStringRef textRef = CFStringCreateWithBytes(allocator, (const UInt8*)pText, (CFIndex)textLength, kCFStringEncodingUTF8, false); + CFOptionFlags result; + + CFUserNotificationDisplayAlert(0, // No timeout + kCFUserNotificationNoteAlertLevel, + NULL, // Icon URL, use default. + NULL, // Unused + NULL, // Localization of strings + titleRef, // Title text + textRef, // Body text + CFSTR("OK"), // Default "OK" text in button + CFSTR("Cancel"), // Other button title + NULL, // Yet another button title, NULL means no other button. + &result); // response flags + CFRelease(titleRef); + CFRelease(textRef); + + return (result == kCFUserNotificationDefaultResponse); +} + + +} } // namespace OVR { namespace Util { + + diff --git a/LibOVRKernel/Src/Util/Util_SystemInfo.cpp b/LibOVRKernel/Src/Util/Util_SystemInfo.cpp new file mode 100644 index 0000000..5ebdf65 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_SystemInfo.cpp @@ -0,0 +1,416 @@ +/************************************************************************************ + +Filename : Util_SystemInfo.cpp +Content : Various operations to get information about the system +Created : September 26, 2014 +Author : Kevin Jenkins + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + +#include "Util_SystemInfo.h" +#include "Kernel/OVR_Timer.h" +#include "Kernel/OVR_Threads.h" +#include "Kernel/OVR_Log.h" +#include "Kernel/OVR_Array.h" + +#if defined(OVR_OS_LINUX) +#include +#endif + +/* +// Disabled, can't link RiftConfigUtil +#ifdef OVR_OS_WIN32 +#define _WIN32_DCOM +#include +#include + +# pragma comment(lib, "wbemuuid.lib") +#endif +*/ + + +namespace OVR { namespace Util { + +// From http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx +#if defined (OVR_OS_WIN64) || defined (OVR_OS_WIN32) + +#pragma comment(lib, "version.lib") + +typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL); +BOOL Is64BitWindows() +{ +#if defined(_WIN64) + return TRUE; // 64-bit programs run only on Win64 +#elif defined(_WIN32) + // 32-bit programs run on both 32-bit and 64-bit Windows + // so must sniff + BOOL f64 = FALSE; + LPFN_ISWOW64PROCESS fnIsWow64Process; + + fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandleW(L"kernel32"), "IsWow64Process"); + if (NULL != fnIsWow64Process) + { + return fnIsWow64Process(GetCurrentProcess(), &f64) && f64; + } + return FALSE; +#else + return FALSE; // Win64 does not support Win16 +#endif +} +#endif + +const char * OSAsString() +{ +#if defined (OVR_OS_IPHONE) + return "IPhone"; +#elif defined (OVR_OS_DARWIN) + return "Darwin"; +#elif defined (OVR_OS_MAC) + return "Mac"; +#elif defined (OVR_OS_BSD) + return "BSD"; +#elif defined (OVR_OS_WIN64) || defined (OVR_OS_WIN32) + if (Is64BitWindows()) + return "Win64"; + else + return "Win32"; +#elif defined (OVR_OS_ANDROID) + return "Android"; +#elif defined (OVR_OS_LINUX) + return "Linux"; +#elif defined (OVR_OS_BSD) + return "BSD"; +#else + return "Other"; +#endif +} + +uint64_t GetGuidInt() +{ + uint64_t g = Timer::GetTicksNanos(); + + uint64_t lastTime, thisTime; + int j; + // Sleep a small random time, then use the last 4 bits as a source of randomness + for (j = 0; j < 8; j++) + { + lastTime = Timer::GetTicksNanos(); + Thread::MSleep(1); + Thread::MSleep(0); + thisTime = Timer::GetTicksNanos(); + uint64_t diff = thisTime - lastTime; + unsigned int diff4Bits = (unsigned int)(diff & 15); + diff4Bits <<= 32 - 4; + diff4Bits >>= j * 4; + ((char*)&g)[j] ^= diff4Bits; + } + + return g; +} +String GetGuidString() +{ + uint64_t guid = GetGuidInt(); + + char buff[64]; +#if defined(OVR_CC_MSVC) + OVR_sprintf(buff, sizeof(buff), "%I64u", guid); +#else + OVR_sprintf(buff, sizeof(buff), "%llu", (unsigned long long) guid); +#endif + return String(buff); +} + +const char * GetProcessInfo() +{ + #if defined (OVR_CPU_X86_64 ) + return "64 bit"; +#elif defined (OVR_CPU_X86) + return "32 bit"; +#else + return "TODO"; +#endif +} +#ifdef OVR_OS_WIN32 + + +String OSVersionAsString() +{ + return GetSystemFileVersionString("\\kernel32.dll"); +} +String GetSystemFileVersionString(String filePath) +{ + char strFilePath[MAX_PATH]; // Local variable + UINT sysDirLen = GetSystemDirectoryA(strFilePath, ARRAYSIZE(strFilePath)); + if (sysDirLen != 0) + { + OVR_strcat(strFilePath, MAX_PATH, filePath.ToCStr()); + return GetFileVersionString(strFilePath); + } + else + { + return "GetSystemDirectoryA failed"; + } +} +// See http://stackoverflow.com/questions/940707/how-do-i-programatically-get-the-version-of-a-dll-or-exe-file +String GetFileVersionString(String filePath) +{ + String result; + + DWORD dwSize = GetFileVersionInfoSizeA(filePath.ToCStr(), NULL); + if (dwSize == 0) + { + OVR_DEBUG_LOG(("Error in GetFileVersionInfoSizeA: %d (for %s)", GetLastError(), filePath.ToCStr())); + result = filePath + " not found"; + } + else + { + BYTE* pVersionInfo = new BYTE[dwSize]; + if (!pVersionInfo) + { + OVR_DEBUG_LOG(("Out of memory allocating %d bytes (for %s)", dwSize, filePath.ToCStr())); + result = "Out of memory"; + } + else + { + if (!GetFileVersionInfoA(filePath.ToCStr(), 0, dwSize, pVersionInfo)) + { + OVR_DEBUG_LOG(("Error in GetFileVersionInfo: %d (for %s)", GetLastError(), filePath.ToCStr())); + result = "Cannot get version info"; + } + else + { + VS_FIXEDFILEINFO* pFileInfo = NULL; + UINT pLenFileInfo = 0; + if (!VerQueryValue(pVersionInfo, TEXT("\\"), (LPVOID*)&pFileInfo, &pLenFileInfo)) + { + OVR_DEBUG_LOG(("Error in VerQueryValue: %d (for %s)", GetLastError(), filePath.ToCStr())); + result = "File has no version info"; + } + else + { + int major = (pFileInfo->dwFileVersionMS >> 16) & 0xffff; + int minor = (pFileInfo->dwFileVersionMS) & 0xffff; + int hotfix = (pFileInfo->dwFileVersionLS >> 16) & 0xffff; + int other = (pFileInfo->dwFileVersionLS) & 0xffff; + + char str[128]; + OVR::OVR_sprintf(str, 128, "%d.%d.%d.%d", major, minor, hotfix, other); + + result = str; + } + } + + delete[] pVersionInfo; + } + } + + return result; +} + + +String GetDisplayDriverVersion() +{ + return GetSystemFileVersionString("\\OVRDisplay32.dll"); +} +String GetCameraDriverVersion() +{ + return GetSystemFileVersionString("\\drivers\\OCUSBVID.sys"); +} + +// From http://stackoverflow.com/questions/9524309/enumdisplaydevices-function-not-working-for-me +void GetGraphicsCardList( Array< String > &gpus) +{ + gpus.Clear(); + + DISPLAY_DEVICEA dd; + + dd.cb = sizeof(dd); + + DWORD deviceNum = 0; + while( EnumDisplayDevicesA(NULL, deviceNum, &dd, 0) ){ + if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE) + gpus.PushBack(dd.DeviceString); + deviceNum++; + } +} + + +String GetProcessorInfo() +{ + char brand[0x40] = {}; + int cpui[4] = { -1 }; + + __cpuidex(cpui, 0x80000002, 0); + + //unsigned int blocks = cpui[0]; + for (int i = 0; i <= 2; ++i) + { + __cpuidex(cpui, 0x80000002 + i, 0); + *reinterpret_cast(brand + i * 16) = cpui[0]; + *reinterpret_cast(brand + 4 + i * 16) = cpui[1]; + *reinterpret_cast(brand + 8 + i * 16) = cpui[2]; + *reinterpret_cast(brand + 12 + i * 16) = cpui[3]; + + } + return String(brand, 0x40); +} + +#else + +#ifdef OVR_OS_MAC +//use objective c source + +// used for driver files +String GetFileVersionString(String /*filePath*/) +{ + return String(); +} + +String GetSystemFileVersionString(String /*filePath*/) +{ + return String(); +} + +String GetDisplayDriverVersion() +{ + return String(); +} + +String GetCameraDriverVersion() +{ + return String(); +} + +#else + +// used for driver files +String GetFileVersionString(String /*filePath*/) +{ + return String(); +} + +String GetSystemFileVersionString(String /*filePath*/) +{ + return String(); +} + +String GetDisplayDriverVersion() +{ + char info[256] = { 0 }; + FILE *file = popen("/usr/bin/glxinfo", "r"); + if (file) + { + int status = 0; + while (status == 0) + { + status = fscanf(file, "%*[^\n]\n"); // Read up till the end of the current line, leaving the file pointer at the beginning of the next line (skipping any leading whitespace). + OVR_UNUSED(status); // Prevent GCC compiler warning: "ignoring return value of ‘int fscanf(FILE*, const char*, ...)" + + status = fscanf(file, "OpenGL version string: %255[^\n]", info); + } + pclose(file); + if (status == 1) + { + return String(info); + } + } + return String("No graphics driver details found."); +} + +String GetCameraDriverVersion() +{ + struct utsname kver; + if (uname(&kver)) + { + return String(); + } + return String(kver.release); +} + +void GetGraphicsCardList(OVR::Array< OVR::String > &gpus) +{ + gpus.Clear(); + + char info[256] = { 0 }; + FILE *file = popen("/usr/bin/lspci", "r"); + if (file) + { + int status = 0; + while (status >= 0) + { + status = fscanf(file, "%*[^\n]\n"); // Read up till the end of the current line, leaving the file pointer at the beginning of the next line (skipping any leading whitespace). + OVR_UNUSED(status); // Prevent GCC compiler warning: "ignoring return value of ‘int fscanf(FILE*, const char*, ...)" + + status = fscanf(file, "%*[^ ] VGA compatible controller: %255[^\n]", info); + if (status == 1) + { + gpus.PushBack(String(info)); + } + } + pclose(file); + } + if (gpus.GetSizeI() <= 0) + { + gpus.PushBack(String("No video card details found.")); + } +} + +String OSVersionAsString() +{ + char info[256] = { 0 }; + FILE *file = fopen("/etc/issue", "r"); + if (file) + { + int status = fscanf(file, "%255[^\n\\]", info); + fclose(file); + if (status == 1) + { + return String(info); + } + } + return String("No OS version details found."); +} + +String GetProcessorInfo() +{ + char info[256] = { 0 }; + FILE *file = fopen("/proc/cpuinfo", "r"); + if (file) + { + int status = 0; + while (status == 0) + { + status = fscanf(file, "%*[^\n]\n"); // Read up till the end of the current line, leaving the file pointer at the beginning of the next line (skipping any leading whitespace). + OVR_UNUSED(status); // Prevent GCC compiler warning: "ignoring return value of ‘int fscanf(FILE*, const char*, ...)" + + status = fscanf(file, "model name : %255[^\n]", info); + } + fclose(file); + if (status == 1) + { + return String(info); + } + } + return String("No processor details found."); +} +#endif //OVR_OS_MAC +#endif // WIN32 + +} } // namespace OVR { namespace Util { diff --git a/LibOVRKernel/Src/Util/Util_SystemInfo.h b/LibOVRKernel/Src/Util/Util_SystemInfo.h new file mode 100644 index 0000000..5c886c7 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_SystemInfo.h @@ -0,0 +1,52 @@ +/************************************************************************************ + +Filename : Util_SystemInfo.h +Content : Various operations to get information about the system +Created : September 26, 2014 +Author : Kevin Jenkins + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +************************************************************************************/ + + +#ifndef OVR_Util_SystemInfo_h +#define OVR_Util_SystemInfo_h + +#include "../Kernel/OVR_String.h" +#include "../Kernel/OVR_Types.h" +#include "../Kernel/OVR_Array.h" + +namespace OVR { namespace Util { + +const char * OSAsString(); +String OSVersionAsString(); +uint64_t GetGuidInt(); +String GetGuidString(); +const char * GetProcessInfo(); +String GetFileVersionString(String filePath); +String GetSystemFileVersionString(String filePath); +String GetDisplayDriverVersion(); +String GetCameraDriverVersion(); +void GetGraphicsCardList(OVR::Array< OVR::String > &gpus); +String GetProcessorInfo(); + + +} } // namespace OVR { namespace Util { + +#endif // OVR_Util_SystemInfo_h diff --git a/LibOVRKernel/Src/Util/Util_SystemInfo_OSX.mm b/LibOVRKernel/Src/Util/Util_SystemInfo_OSX.mm new file mode 100644 index 0000000..6ee8ff5 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_SystemInfo_OSX.mm @@ -0,0 +1,111 @@ + /************************************************************************************ + + Filename : Util_SystemInfo_OSX.mm + Content : Various operations to get information about the mac system + Created : October 2, 2014 + + Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + + Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); + you may not use the Oculus VR Rift SDK except in compliance with the License, + which is provided at the time of installation or download, or which + otherwise accompanies this software in either electronic or hard copy form. + + You may obtain a copy of the License at + + http://www.oculusvr.com/licenses/LICENSE-3.2 + + Unless required by applicable law or agreed to in writing, the Oculus VR SDK + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + ************************************************************************************/ + +#include "Util_SystemInfo.h" + +#include + +#include +#include + +#include "../Kernel/OVR_String.h" +#include "../Kernel/OVR_System.h" + +using namespace OVR; +namespace OVR { namespace Util { + +//from http://opensource.apple.com/source/CF/CF-744/CFUtilities.c +OVR::String OSVersionAsString(){ + + NSDictionary *systemVersionDictionary = + [NSDictionary dictionaryWithContentsOfFile: + @"/System/Library/CoreServices/SystemVersion.plist"]; + + NSString *systemVersion = + [systemVersionDictionary objectForKey:@"ProductVersion"]; + return OVR::String([systemVersion UTF8String]); +} + + +//from http://www.starcoder.com/wordpress/2011/10/using-iokit-to-detect-graphics-hardware/ +void GetGraphicsCardList(Array< String > &gpus) +{ + // Check the PCI devices for video cards. + CFMutableDictionaryRef match_dictionary = IOServiceMatching("IOPCIDevice"); + + // Create a iterator to go through the found devices. + io_iterator_t entry_iterator; + + if (IOServiceGetMatchingServices(kIOMasterPortDefault, + match_dictionary, + &entry_iterator) == kIOReturnSuccess) + { + // Actually iterate through the found devices. + io_registry_entry_t serviceObject; + while ((serviceObject = IOIteratorNext(entry_iterator))) + { + // Put this services object into a dictionary object. + CFMutableDictionaryRef serviceDictionary; + if (IORegistryEntryCreateCFProperties(serviceObject, + &serviceDictionary, + kCFAllocatorDefault, + kNilOptions) != kIOReturnSuccess) + { + // Failed to create a service dictionary, release and go on. + IOObjectRelease(serviceObject); + continue; + } + + // + // that points to a CFDataRef. + const void *modelarr = CFDictionaryGetValue(serviceDictionary, CFSTR("model")); + if (modelarr != nil) { + if(CFGetTypeID(modelarr) == CFDataGetTypeID()) + { + NSData *data = (__bridge NSData*)(CFDataRef)modelarr; + NSString *s = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease]; + gpus.PushBack([s UTF8String]); + } + } + + // Release the dictionary created by IORegistryEntryCreateCFProperties. + CFRelease(serviceDictionary); + + // Release the serviceObject returned by IOIteratorNext. + IOObjectRelease(serviceObject); + } + + // Release the entry_iterator created by IOServiceGetMatchingServices. + IOObjectRelease(entry_iterator); + } +} + +OVR::String GetProcessorInfo() +{ + return OVR::String(); +} + +} } // namespace OVR { namespace Util { + diff --git a/LibOVRKernel/Src/Util/Util_Watchdog.cpp b/LibOVRKernel/Src/Util/Util_Watchdog.cpp new file mode 100644 index 0000000..a5420b1 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_Watchdog.cpp @@ -0,0 +1,249 @@ +/************************************************************************************ + +Filename : Util_Watchdog.cpp +Content : Deadlock reaction +Created : June 27, 2013 +Authors : Kevin Jenkins, Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#include "Util_Watchdog.h" +#include +#include + +#if defined(OVR_OS_LINUX) || defined(OVR_OS_MAC) + #include + #include + #include + + #if defined(OVR_OS_LINUX) + #include + #endif +#endif + +OVR_DEFINE_SINGLETON(OVR::Util::WatchDogObserver); + +namespace OVR { namespace Util { + +const int DefaultThreshhold = 60000; // milliseconds + +//----------------------------------------------------------------------------- +// Tools + +static uint32_t GetFastMsTime() +{ +#if defined(OVR_OS_MS) + return ::GetTickCount(); +#else + return Timer::GetTicksMs(); +#endif +} + + +//----------------------------------------------------------------------------- +// WatchDogObserver + +static bool ExitingOnDeadlock = false; + +bool WatchDogObserver::IsExitingOnDeadlock() +{ + return ExitingOnDeadlock; +} + +void WatchDogObserver::SetExitingOnDeadlock(bool enabled) +{ + ExitingOnDeadlock = enabled; +} + +WatchDogObserver::WatchDogObserver() : + IsReporting(false) +{ + Start(); + + // Must be at end of function + PushDestroyCallbacks(); +} + +WatchDogObserver::~WatchDogObserver() +{ + TerminationEvent.SetEvent(); + + Join(); +} + +void WatchDogObserver::OnThreadDestroy() +{ + TerminationEvent.SetEvent(); +} + +void WatchDogObserver::OnSystemDestroy() +{ + Release(); +} + +int WatchDogObserver::Run() +{ + OVR_DEBUG_LOG(("[WatchDogObserver] Starting")); + + SetThreadName("WatchDog"); + + while (!TerminationEvent.Wait(WakeupInterval)) + { + Lock::Locker locker(&ListLock); + + const uint32_t t1 = GetFastMsTime(); + + const int count = DogList.GetSizeI(); + for (int i = 0; i < count; ++i) + { + WatchDog* dog = DogList[i]; + + const int threshold = dog->ThreshholdMilliseconds; + const uint32_t t0 = dog->WhenLastFedMilliseconds; + + // If threshold exceeded, assume there is thread deadlock of some sort. + int delta = (int)(t1 - t0); + if (delta > threshold) + { + // Expected behavior: + // SingleProcessDebug, SingleProcessRelease, Debug: This is only ever done for internal testing, so we don't want it to trigger the deadlock termination. + // Release: This is our release configuration where we want it to terminate itself. + + // Print a stack trace of all threads if there's no debugger present. + const bool debuggerPresent = OVRIsDebuggerPresent(); + + LogError("{ERR-027} [WatchDogObserver] Deadlock detected: %s", dog->ThreadName.ToCStr()); + if (!debuggerPresent) // We don't print threads if a debugger is present because otherwise every time the developer paused the app to debug, it would spit out a long thread trace upon resuming. + { + if (SymbolLookup::Initialize()) + { + // symbolLookup is static here to avoid putting 32 KB on the stack + // and potentially overflowing the stack. This function is only ever + // run by one thread so it should be safe. + static SymbolLookup symbolLookup; + String threadListOutput, moduleListOutput; + symbolLookup.ReportThreadCallstacks(threadListOutput); + symbolLookup.ReportModuleInformation(moduleListOutput); + LogText("---DEADLOCK STATE---\n\n%s\n\n%s\n---END OF DEADLOCK STATE---\n", threadListOutput.ToCStr(), moduleListOutput.ToCStr()); + } + + if (IsReporting) + { + ExceptionHandler::ReportDeadlock(DogList[i]->ThreadName, OrganizationName , ApplicationName); + + // Disable reporting after the first deadlock report. + IsReporting = false; + } + } + + if (IsExitingOnDeadlock()) + { + OVR_ASSERT_M(false, "Watchdog detected a deadlock. Exiting the process."); // This won't have an effect unless asserts are enabled in release builds. + OVR::ExitProcess(-1); + } + } + } + } + + OVR_DEBUG_LOG(("[WatchDogObserver] Good night")); + + return 0; +} + +void WatchDogObserver::Add(WatchDog *dog) +{ + Lock::Locker locker(&ListLock); + + if (!dog->Listed) + { + DogList.PushBack(dog); + dog->Listed = true; + } +} + +void WatchDogObserver::Remove(WatchDog *dog) +{ + Lock::Locker locker(&ListLock); + + if (dog->Listed) + { + for (int i = 0; i < DogList.GetSizeI(); ++i) + { + if (DogList[i] == dog) + { + DogList.RemoveAt(i--); + } + } + + dog->Listed = false; + } +} + +void WatchDogObserver::EnableReporting(const String organization, const String application) +{ + OrganizationName = organization; + ApplicationName = application; + IsReporting = true; +} + +void WatchDogObserver::DisableReporting() +{ + IsReporting = false; +} + + +//----------------------------------------------------------------------------- +// WatchDog + +WatchDog::WatchDog(const String& threadName) : + ThreshholdMilliseconds(DefaultThreshhold), + ThreadName(threadName), + Listed(false) +{ + WhenLastFedMilliseconds = GetFastMsTime(); +} + +WatchDog::~WatchDog() +{ + Disable(); +} + +void WatchDog::Disable() +{ + WatchDogObserver::GetInstance()->Remove(this); +} + +void WatchDog::Enable() +{ + WatchDogObserver::GetInstance()->Add(this); +} + +void WatchDog::Feed(int threshold) +{ + WhenLastFedMilliseconds = GetFastMsTime(); + ThreshholdMilliseconds = threshold; + + if (!Listed) + { + Enable(); + } +} + +}} // namespace OVR::Util diff --git a/LibOVRKernel/Src/Util/Util_Watchdog.h b/LibOVRKernel/Src/Util/Util_Watchdog.h new file mode 100644 index 0000000..5dfe8c6 --- /dev/null +++ b/LibOVRKernel/Src/Util/Util_Watchdog.h @@ -0,0 +1,113 @@ +/************************************************************************************ + +Filename : Util_Watchdog.h +Content : Deadlock reaction +Created : June 27, 2013 +Authors : Kevin Jenkins, Chris Taylor + +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. + +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); +you may not use the Oculus VR Rift SDK except in compliance with the License, +which is provided at the time of installation or download, or which +otherwise accompanies this software in either electronic or hard copy form. + +You may obtain a copy of the License at + +http://www.oculusvr.com/licenses/LICENSE-3.2 + +Unless required by applicable law or agreed to in writing, the Oculus VR SDK +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +*************************************************************************************/ + +#ifndef OVR_Util_Watchdog_h +#define OVR_Util_Watchdog_h + +#include "Kernel/OVR_Timer.h" +#include "Kernel/OVR_Atomic.h" +#include "Kernel/OVR_Allocator.h" +#include "Kernel/OVR_String.h" +#include "Kernel/OVR_System.h" +#include "Kernel/OVR_Threads.h" + +namespace OVR { namespace Util { + + +//----------------------------------------------------------------------------- +// WatchDog + +class WatchDog : public NewOverrideBase +{ + friend class WatchDogObserver; + +public: + WatchDog(const String& threadName); + ~WatchDog(); + + void Disable(); + void Enable(); + + void Feed(int threshold); + +protected: + // Use 32 bit int so assignment and comparison is atomic + AtomicInt WhenLastFedMilliseconds; + AtomicInt ThreshholdMilliseconds; + + String ThreadName; + bool Listed; +}; + + +//----------------------------------------------------------------------------- +// WatchDogObserver + +class WatchDogObserver : public Thread, public SystemSingletonBase +{ + OVR_DECLARE_SINGLETON(WatchDogObserver); + virtual void OnThreadDestroy(); + + friend class WatchDog; + +public: + // Uses the exception logger to write deadlock reports + void EnableReporting(const String organization = String(), + const String application = String()); + + // Disables deadlock reports + void DisableReporting(); + +protected: + Lock ListLock; + Array< WatchDog* > DogList; + + static const int WakeupInterval = 1000; // milliseconds between checks + Event TerminationEvent; + + // Used in deadlock reporting. + bool IsReporting; + + // On Windows, deadlock logs are stored in %AppData%\OrganizationName\ApplicationName\. + // See ExceptionHandler::ReportDeadlock() for how these are used. + String ApplicationName; + String OrganizationName; + +protected: + virtual int Run(); + + void Add(WatchDog* dog); + void Remove(WatchDog* dog); + +public: + static bool IsExitingOnDeadlock(); + static void SetExitingOnDeadlock(bool enabled); +}; + + +}} // namespace OVR::Util + +#endif // OVR_Util_Watchdog_h diff --git a/Makefile b/Makefile index 62a3687..b3ab57e 100755 --- a/Makefile +++ b/Makefile @@ -1,82 +1,82 @@ -############################################################################# -# -# Filename : Makefile -# Content : Makefile for building linux libovr and OculusWorldDemo -# Created : 2013 -# Authors : Simon Hallam and Peter Giokaris -# Copyright : Copyright 2013 OculusVR, Inc. All Rights Reserved -# Instruction : The g++ compiler and stdndard lib packages need to be -# installed on the system. Navigate in a shell to the -# directory where this Makefile is located and enter: -# -# make builds the release versions for the -# current architechture -# make clean delete intermediate release object files -# and library and executable -# make DEBUG=1 builds the debug version for the current -# architechture -# make clean DEBUG=1 deletes intermediate debug object files -# and the library and executable -# -# Output : Relative to the directory this Makefile lives in, libraries -# and executables are built at the following locations -# depending upon the architechture of the system you are -# running: -# -# ./LibOVR/Lib/Linux/Debug/i386/libovr.a -# ./LibOVR/Lib/Linux/Debug/x86_64/libovr.a -# ./LibOVR/Lib/Linux/Release/i386/libovr.a -# ./LibOVR/Lib/Linux/Release/x86_64/libovr.a -# ./Samples/OculusWorldDemo/Release/OculusWorldDemo_i386_Release -# ./Samples/OculusWorldDemo/Release/OculusWorldDemo_x86_64_Release -# ./Samples/OculusWorldDemo/Release/OculusWorldDemo_i386_Debug -# ./Samples/OculusWorldDemo/Release/OculusWorldDemo_x86_64_Debug -# -############################################################################# +include LibOVR/Projects/Linux/LibOVRConfig.mk -####### Detect system architecture +DESTDIR = +PREFIX = $(DESTDIR)/usr/local +BINDIR = $(PREFIX)/bin +LIBDIR = $(PREFIX)/lib +INCDIR = $(PREFIX)/include +SHRDIR = $(PREFIX)/share -SYSARCH = i386 -ifeq ($(shell uname -m),x86_64) -SYSARCH = x86_64 -endif +CFLAGS += -DLIBDIR=$(LIBDIR) -DSHRDIR=$(SHRDIR) +CXXFLAGS += -DLIBDIR=$(LIBDIR) -DSHRDIR=$(SHRDIR) -####### Compiler, tools and options +CC = gcc +CXX = g++ -CXX = g++ -LINK = ar rvs -DELETEFILE = rm -f +all: debug -####### Detect debug or release +release: + CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) -C Samples/OculusWorldDemo/Projects/Linux -f OculusWorldDemo.mk -DEBUG = 0 -ifeq ($(DEBUG), 1) - RELEASETYPE = Debug -else - RELEASETYPE = Release -endif - -####### Paths - -LIBOVRPATH = ./LibOVR -DEMOPATH = ./Samples/OculusWorldDemo - -####### Files - -LIBOVRTARGET = $(LIBOVRPATH)/Lib/Linux/$(RELEASETYPE)/$(SYSARCH)/libovr.a -DEMOTARGET = $(DEMOPATH)/Release/OculusWorldDemo_$(RELEASETYPE)/$(SYSARCH) - -####### Rules - -all: $(LIBOVRTARGET) $(DEMOTARGET) - -$(DEMOTARGET): $(DEMOPATH)/Makefile - $(MAKE) -C $(DEMOPATH) DEBUG=$(DEBUG) - -$(LIBOVRTARGET): $(LIBOVRPATH)/Makefile - $(MAKE) -C $(LIBOVRPATH) DEBUG=$(DEBUG) +debug: + CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" $(MAKE) -C Samples/OculusWorldDemo/Projects/Linux -f OculusWorldDemo.mk DEBUG=1 clean: - $(MAKE) -C $(LIBOVRPATH) clean DEBUG=$(DEBUG) - $(MAKE) -C $(DEMOPATH) clean DEBUG=$(DEBUG) - + $(MAKE) -C Samples/OculusWorldDemo/Projects/Linux -f OculusWorldDemo.mk clean + +install: release + mkdir -p $(LIBDIR) + install LibOVR/Lib/Linux/$(SYSARCH)/Release/libOVR.a $(LIBDIR) + install LibOVR/Lib/Linux/$(SYSARCH)/Release/libOVRRT64_$(OVR_PRODUCT_VERSION).so.$(OVR_MAJOR_VERSION) $(LIBDIR) + install LibOVR/Lib/Linux/$(SYSARCH)/Release/libOVRRT64_$(OVR_PRODUCT_VERSION).so.$(OVR_MAJOR_VERSION).$(OVR_MINOR_VERSION).$(OVR_PATCH_VERSION) $(LIBDIR) + + mkdir -p $(SHRDIR)/OculusWorldDemo/Assets/Tuscany + install Samples/OculusWorldDemo/Assets/Tuscany/* $(SHRDIR)/OculusWorldDemo/Assets/Tuscany + + mkdir -p $(BINDIR) + install Service/OVRServer/Bin/Linux/$(SYSARCH)/ReleaseStatic/ovrd $(BINDIR) + install Samples/OculusWorldDemo/Bin/$(SYSARCH)/Release/OculusWorldDemo $(BINDIR) + install Tools/RiftConfigUtil/Bin/Linux/$(SYSARCH)/ReleaseStatic/RiftConfigUtil $(BINDIR) + + mkdir -p $(INCDIR)/Extras + install LibOVR/Include/OVR_CAPI_$(OVR_PRODUCT_VERSION)_$(OVR_MAJOR_VERSION)_$(OVR_MINOR_VERSION).h $(INCDIR) + install LibOVR/Include/OVR_CAPI_GL.h $(INCDIR) + install LibOVR/Include/OVR_CAPI.h $(INCDIR) + install LibOVR/Include/OVR_CAPI_Keys.h $(INCDIR) + install LibOVR/Include/OVR_CAPI_Util.h $(INCDIR) + install LibOVR/Include/OVR_ErrorCode.h $(INCDIR) + install LibOVR/Include/OVR.h $(INCDIR) + install LibOVR/Include/OVR_Kernel.h $(INCDIR) + install LibOVR/Include/OVR_Version.h $(INCDIR) + install LibOVR/Include/Extras/OVR_Math.h $(INCDIR)/Extras + +uninstall: + rm -vf $(LIBDIR)/libOVR.a + rm -vf $(LIBDIR)/libOVRRT64_$(OVR_PRODUCT_VERSION).so.$(OVR_MAJOR_VERSION) + rm -vf $(LIBDIR)/libOVRRT64_$(OVR_PRODUCT_VERSION).so.$(OVR_MAJOR_VERSION).$(OVR_MINOR_VERSION).$(OVR_PATCH_VERSION) + + rm -vf $(BINDIR)/ovrd + rm -vf $(BINDIR)/OculusWorldDemo + + rm -vf $(SHRDIR)/OculusWorldDemo/Assets/Tuscany/* + rm -vfr $(SHRDIR)/OculusWorldDemo/Assets/Tuscany || true + rm -vfr $(SHRDIR)/OculusWorldDemo/Assets || true + rm -vfr $(SHRDIR)/OculusWorldDemo || true + rm -vf $(SHRDIR)/RiftConfigUtil/Resources/DeskScene*.* + rm -vfr $(SHRDIR)/RiftConfigUtil/Resources/DeskScene || true + rm -vf $(SHRDIR)/RiftConfigUtil/Resources/*.* + rm -vfr $(SHRDIR)/RiftConfigUtil/Resources || true + rm -vfr $(SHRDIR)/RiftConfigUtil || true + rm -vfr $(SHRDIR) || true + + rm -vf $(INCDIR)/OVR_CAPI_$(OVR_PRODUCT_VERSION)_$(OVR_MAJOR_VERSION)_$(OVR_PATCH_VERSION).h + rm -vf $(INCDIR)/OVR_CAPI_GL.h + rm -vf $(INCDIR)/OVR_CAPI.h + rm -vf $(INCDIR)/OVR_CAPI_Keys.h + rm -vf $(INCDIR)/OVR_CAPI_Util.h + rm -vf $(INCDIR)/OVR_ErrorCode.h + rm -vf $(INCDIR)/OVR.h + rm -vf $(INCDIR)/OVR_Kernel.h + rm -vf $(INCDIR)/OVR_Version.h + rm -vf $(INCDIR)/Extras/OVR_Math.h + rm -vfr $(INCDIR)/Extras || true -- cgit v1.2.3